Compare commits

...

108 Commits

Author SHA1 Message Date
Electron Bot
101a2282ab Bump v11.1.0 2020-12-11 13:03:56 -08:00
Jeremy Rose
429400040e fix: restrict sendToFrame to same-process frames by default (#26875) (#26926) 2020-12-11 13:01:31 -08:00
trop[bot]
ca7528a2d0 fix: Upload all *.dll.pdb to symbol server (#26965)
Fixes #26961.

Notes: Add Electron DLLs like libGLESv2.dll to symbol server

Co-authored-by: Biru Mohanathas <birunthan@mohanathas.com>
2020-12-11 12:53:27 -08:00
trop[bot]
d58812b517 fix: Avoid crashing in NativeViewHost::SetParentAccessible on Windows 10 (#26951)
* fix: Avoid crashing in NativeViewHost::SetParentAccessible on Windows

This fixes #26905. The patch was obtained from @deepak1556, who in turn
got it from the Microsoft Teams folks.

I believe the crash started happening due to the changes in
5c6c8e994b%5E!/#F15

This affects Electron 9 and later.

Notes: Fix occasional crash on Windows

* update patches

Co-authored-by: Biru Mohanathas <birunthan@mohanathas.com>
Co-authored-by: Electron Bot <electron@github.com>
2020-12-11 12:51:23 -08:00
trop[bot]
5942c84288 docs: add missing deprecated systemPreferences APIs to breaking-changes (#26936)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2020-12-11 10:59:00 -08:00
trop[bot]
f920463b47 fix: message box missing an "OK" button in GTK (#26916)
Co-authored-by: Mimi <1119186082@qq.com>
2020-12-10 13:06:03 -08:00
Electron Bot
296cba563e Bump v11.0.5 2020-12-10 09:47:04 -08:00
trop[bot]
90a96c0b73 fix: systemPreferences.effectiveAppearance returning systemPreferences.getAppLevelAppearance() (#26878)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2020-12-09 14:58:44 +09:00
Milan Burda
2c325cd654 fix: send IPC_MESSAGES.RENDERER_RELEASE_CALLBACK as internal message (#26808) (#26836) 2020-12-08 13:29:50 +09:00
Electron Bot
c26b78bbc0 chore: bump chromium to 87.0.4280.88 (11-x-y) (#26817)
* chore: bump chromium in DEPS to 87.0.4280.88

* update patches

Co-authored-by: John Kleinschmidt <jkleinsc@github.com>
2020-12-07 16:46:44 -08:00
Alexey Kuzmin
6951c09b61 fix: add a "set" trap to the "screen" module proxy (#26873) 2020-12-07 16:46:05 -08:00
trop[bot]
fe21892974 fix: handle security warnings promise when JS is disabled (#26870)
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2020-12-07 13:03:40 -08:00
Electron Bot
0fd6a8ca83 Bump v11.0.4 2020-12-07 10:06:44 -08:00
Erick Zhao
de12232df5 docs: added fiddle support for code samples (#26766)
Co-authored-by: Antonio <bandantonio@users.noreply.github.com>
2020-12-03 15:54:49 +09:00
trop[bot]
d12674f9f1 docs: fix contentTracing code sample (#26777)
According to the API docs, the property is called included_categories, not include_categories.

Co-authored-by: Jim Fisher <jameshfisher@gmail.com>
2020-12-02 14:29:00 -05:00
Samuel Attard
75cdd02697 build: use all-for-one goma (#26699) (#26770)
* Revert "Revert "build: use one-for-all goma (#26679)" (#26689)"

This reverts commit 38ab829ea6.

* build: ensure file descriptor limit is higher on macOS
2020-12-02 11:18:56 -05:00
trop[bot]
08b7f5a569 fix: draggable views on BrowserViews on Windows (#26774) 2020-12-01 21:35:53 -08:00
trop[bot]
a5077e2586 docs: BrowserWindow extension APIs are deprecated in Electron 9 (#26782)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2020-12-01 21:31:57 -08:00
trop[bot]
4fa9122151 fix: add check in IsMaximized for non-WS_THICKFRAME windows (#26780)
Co-authored-by: mlaurencin <mlaurencin@electronjs.org>
2020-12-01 21:30:59 -08:00
Vadim
56fa037a46 fix: internalModuleReadJSON for unpacked JSON (#26751) 2020-12-01 18:24:22 -06:00
trop[bot]
13a9e15a27 fix: Add default Bluetooth permission strings (#26768) 2020-12-01 15:02:25 -08:00
trop[bot]
badc01c2d8 fix: draggable regions calculation in BrowserWindow/BrowserView (#26754) 2020-12-01 11:29:55 -08:00
Electron Bot
b0862a6e63 Bump v11.0.3 2020-11-23 17:01:12 -08:00
trop[bot]
18cde2ef04 fix: make screen wrapper remote-friendly again (#26660)
This restores accessibility of screen methods via remote.screen.

Fixes #26610.

Signed-off-by: Anders Kaseorg <andersk@mit.edu>

Co-authored-by: Anders Kaseorg <andersk@mit.edu>
2020-11-23 18:27:16 -05:00
Jeremy Rose
e6c94854a0 chore: cherry-pick 47e21abe349a from chromium (#26654)
* chore: cherry-pick 47e21abe349a from chromium

* resolve conflicts
2020-11-23 17:23:57 -05:00
trop[bot]
94d8b7d4c1 fix: reject contentTracing.stopRecording on failure (#26655)
* fix: reject contentTracing.stopRecording on failure

* hacks to account for std::moved promise

Co-authored-by: Jeremy Rose <nornagon@nornagon.net>
2020-11-23 15:36:17 -05:00
John Kleinschmidt
c0769d77e5 build: remove no longer needed arm64 macos patches (#26650) 2020-11-23 12:13:25 -08:00
Jeremy Rose
2a6c3bb7d1 fix: segfault on webContents.fromId(xxx) (#26652) 2020-11-23 11:41:09 -08:00
Milan Burda
d892fde98b fix: <webview> render-process-gone event dispatch (#26578)
Co-authored-by: Milan Burda <miburda@microsoft.com>
2020-11-19 10:29:58 -08:00
Electron Bot
edb6723157 Bump v11.0.2 2020-11-19 10:19:12 -08:00
Samuel Attard
9dda9a894a Revert "Bump v11.0.2"
This reverts commit 4dc98f1347.
2020-11-19 10:17:40 -08:00
Electron Bot
90ab868b50 chore: bump chromium to 87.0.4280.67 (11-x-y) (#26565)
* chore: bump chromium in DEPS to 87.0.4280.66

* chore: bump chromium in DEPS to 87.0.4280.67
2020-11-19 11:25:16 -05:00
Electron Bot
4dc98f1347 Bump v11.0.2 2020-11-18 13:06:12 -08:00
trop[bot]
2189ddb14e fix: LC_ALL env should not be changed (#26551)
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2020-11-18 11:44:04 -08:00
trop[bot]
680569e404 test: support for adding extra module paths (#26543)
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2020-11-18 11:43:53 -08:00
trop[bot]
e119699ae2 revert: disable rosetta as Electron does not run under rosetta
This reverts commit 4829b0f816.

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2020-11-18 11:18:49 -08:00
trop[bot]
63e6f08768 fix: use public APIs in place of private CTFontDescriptorIsSystemUIFont in ui/gfx (#26574)
* fix: use public APIs in place of private CTFontDescriptorIsSystemUIFont in ui/gfx

* Update .patches

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
Co-authored-by: Samuel Attard <sam@electronjs.org>
2020-11-18 11:18:05 -08:00
trop[bot]
b14c57e30c fix: getLoginItemSettings() on windows (#26538)
* find by exe, detect taskmgr enable/disable

* tests

* revert

* oops

Co-authored-by: Jan Hannemann <jan.hannemann@outlook.com>
2020-11-18 11:15:24 +09:00
Electron Bot
8a68a304e0 chore: bump chromium to 87.0.4280.63 (11-x-y) (#26534)
* chore: bump chromium in DEPS to 87.0.4280.63

* update patches
2020-11-17 14:29:42 -05:00
trop[bot]
60cef385d5 fix: webContents interaction with draggable browserviews (#26528)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-11-17 10:16:53 -05:00
Electron Bot
4f281e3d31 Bump v11.0.1 2020-11-17 02:20:52 -08:00
trop[bot]
eb2710e483 fix: Cannot read property 'setDockSide' of undefined (#26514)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-11-16 16:05:51 -05:00
trop[bot]
7a15dca09c fix: do not use crashpad APIs in the MAS build (#26513)
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2020-11-16 11:39:56 -08:00
Electron Bot
387a15f582 Bump v11.0.0 2020-11-16 06:29:41 -08:00
Jeremy Rose
38fab63863 chore: cherry-pick 275865e8c237 from chromium (#26470)
* chore: cherry-pick 275865e8c237 from chromium

* resolve conflict

* update patches

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
Co-authored-by: Electron Bot <electron@github.com>
2020-11-16 09:27:25 -05:00
Milan Burda
1b156c53fd fix: ensure that internal messages are sent from the main process (#26440) 2020-11-16 15:30:47 +09:00
Electron Bot
e4f3f9e1db chore: bump chromium to 87.0.4280.60 (11-x-y) (#26483) 2020-11-13 15:36:26 -08:00
Jeremy Rose
612acc04b0 fix: cherry-pick 8f5a08079948 from chromium (#26469) 2020-11-13 15:14:18 -08:00
Electron Bot
717271095e Bump v11.0.0-beta.23 2020-11-13 13:53:04 -08:00
trop[bot]
76e54ae0c8 feat: add app.runningUnderRosettaTranslation to detect running under rosetta (#26492)
* feat: add app.isRunningUnderRosettaTranslation to detect running under rosetta

* chore: fixup

* chore: make const

* chore: add missing import

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2020-11-13 13:51:05 -08:00
Electron Bot
0c21ce02c1 Bump v11.0.0-beta.22 2020-11-12 07:01:59 -08:00
trop[bot]
01fa45fc50 feat: add 'resized' event to BrowserWindow (#26454)
Also adds 'moved' event to BrowserWindow on Windows.

Co-authored-by: samuelmaddock <samuel.maddock@gmail.com>
2020-11-12 09:47:01 -05:00
trop[bot]
832ce14bda build: fix usage of octokit/rest and make uploading better (#26389)
* build: fix usage of octokit/rest and make uploading better

* Pull in change from #26414

* Update with changes from #26425

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2020-11-11 14:30:58 -05:00
trop[bot]
07318e5146 fix: renderer crash on setImmediate (#26424)
* fix: renderer crash on setImmediate

* spec: add a crash case

* fix: ensure env exists

* Update spec-main/fixtures/crash-cases/setimmediate-renderer-crash/index.js

Co-authored-by: Jeremy Rose <jeremya@chromium.org>

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
Co-authored-by: Jeremy Rose <jeremya@chromium.org>
2020-11-11 10:23:30 -05:00
trop[bot]
79dff5f782 chore(extensions): remove old renderer code (#26441)
Co-authored-by: samuelmaddock <samuel.maddock@gmail.com>
2020-11-11 10:15:27 -05:00
Samuel Attard
9c9e40294e build: auto-push patch file changes (#26235) (#26431)
* build: auto-push patch file changes

* chore: change patch for testing purposes

* build: remove stray log

* build: push as electron bot

* build: suppress all output of the push-patch script

* chore: fix linting
2020-11-10 13:47:51 -08:00
trop[bot]
5b617a7f39 chore: synchronously destroy WebContents on event prevented (#26418)
Co-authored-by: Jeremy Rose <jeremya@chromium.org>
2020-11-10 11:27:32 -05:00
trop[bot]
ff717d4a93 chore: cleanup inline HTML in docs (#26392)
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2020-11-10 10:49:47 -05:00
trop[bot]
51bced4ee3 fix: make draggable regions work when devtools is opened on macOS (#26395)
* fix: make draggable region work when devtools is open

* fix: update draggable regions when resizing

Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2020-11-10 10:46:40 -05:00
Shelley Vohr
b0fd7cf430 fix: honor pageRanges when printing (#25600)
* fix: honor pageRanges when printing

* Update docs/api/web-contents.md

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2020-11-10 10:06:57 -05:00
Electron Bot
a56c1d3f2f Bump v11.0.0-beta.21 2020-11-09 07:02:10 -08:00
John Kleinschmidt
98b6403e3b feat: correctly identify permissions when using setPermissionRequestHandler (#26172) (#26353)
(cherry picked from commit 7f9b21daa0)
2020-11-09 09:58:35 -05:00
trop[bot]
e9c12688e6 refactor: store <webview> attributes as typed Map (#26330)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2020-11-05 15:29:06 -05:00
Electron Bot
8d88d1e2ed chore: bump chromium to 87.0.4280.47 (11-x-y) (#26351)
* chore: bump chromium in DEPS to 87.0.4280.47

* update patches

* Make sure angle has full git info

Co-authored-by: Electron Bot <anonymous@electronjs.org>
Co-authored-by: John Kleinschmidt <jkleinsc@github.com>
2020-11-05 15:11:11 -05:00
Electron Bot
2e730fe48b Bump v11.0.0-beta.20 2020-11-05 07:01:36 -08:00
Electron Bot
88de23b241 chore: bump chromium to 87.0.4280.40 (11-x-y) (#26280)
* chore: bump chromium in DEPS to 87.0.4280.40

* update patches

Co-authored-by: Electron Bot <anonymous@electronjs.org>
2020-11-04 15:35:28 -05:00
trop[bot]
3faa2c2a46 fix: window.open not accepting size values with "px" at the end (#26334)
* fix: use parseInt to parse sizes

* fix: pass radix to parseInt

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>

Co-authored-by: Abhishek Shingane <abhisheks@iitbhilai.ac.in>
Co-authored-by: Cheng Zhao <github@zcbenz.com>
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2020-11-04 10:59:49 -08:00
trop[bot]
cab14277b8 fix: draggable region edge calculation on resize (#26320)
* fix: draggable region edge calculation on resize

* Feedback from review

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-11-04 11:17:14 +09:00
Electron Bot
ce243f8172 Bump v11.0.0-beta.19 2020-11-02 07:01:23 -08:00
Shelley Vohr
da4790d944 build: only check patch diffs in testing builds (#26283)
* build: only check patch diffs in testing builds

* Fixup patch indices
2020-11-02 18:56:13 +09:00
Charles Kerr
4088566a4d fix: nativeTheme.themeSource = 'dark' on windows (#26238)
Manually backports #25373.
2020-11-02 16:20:57 +09:00
Shelley Vohr
ac425c0cf3 fix: draggable regions exclusively on BrowserViews (#26259) 2020-11-02 16:07:04 +09:00
trop[bot]
ccb471e5d5 chore: change some for loops to range-based (#26263)
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2020-10-30 09:58:39 -07:00
Robo
f44880f065 fix: Initialize logging for crashpad (#26250)
* fix: Initialize logging for crashpad

* chore: update mini_chromium

* conditionally access CommandLine because crashpad doesn't initialize one.

https://chromium-review.googlesource.com/c/chromium/src/+/2490880
2020-10-29 16:23:51 -07:00
trop[bot]
7ec001486e fix: hover text only working when VO enabled (#26246)
* fix: hover text only working when VO enabled

* chore: simplify conditional

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-10-29 08:51:45 -07:00
David Sanders
dd3fbae447 chore: use auto to avoid repeating type (#26254) 2020-10-29 08:50:27 -07:00
Electron Bot
e9710f6a77 Bump v11.0.0-beta.18 2020-10-29 08:01:25 -07:00
trop[bot]
699a771288 fix: transparently package bundles as zip archives (#26217)
* refactor: move FileSelectHelper to own file

* fix: zip packages on macOS

* Thread safety, it's good actually

* misc cleanup

* Remove some unused includes

* Better ref management

* Use upstream file_select_helper_mac

* Small fixes

* Put back file_select_helper_mac

* observe RenderWidgetHost

* fix ref-counting and add some guards

* Address review

* Remove refcounting for FileSelectHelper

* Remove unnecessary GetWeakPtr

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
Co-authored-by: deepak1556 <hop2deep@gmail.com>
2020-10-29 10:01:32 -04:00
trop[bot]
f679dd8ad7 fix: build with printing disabled (#26249)
Co-authored-by: deepak1556 <hop2deep@gmail.com>
2020-10-29 02:18:26 -07:00
trop[bot]
9f1b913793 fix: set app locale after user's script is loaded (#26226)
* fix: set app locale after user's script is loaded

* fix: set LC_ALL env on Linux

Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2020-10-28 15:20:10 -04:00
Charles Kerr
9328725e93 perf: improve heap snapshot performance (#26230)
Fixes #24509.

cherry-pick 2e2dc98 from v8
2020-10-28 12:07:48 -07:00
trop[bot]
cea757f59c fix: delay emitting powerMonitor events on windows (#26181)
* fix: delay emitting powerMonitor events

* Update electron_api_power_monitor_win.cc

* Update electron_api_power_monitor_win.cc

* syntax

* Update electron_api_power_monitor_win.cc

* Update electron_api_power_monitor_win.cc

Co-authored-by: Jeremy Rose <nornagon@nornagon.net>
Co-authored-by: Jeremy Rose <jeremya@chromium.org>
2020-10-28 12:39:49 -05:00
trop[bot]
d93cb942fc build: rename the v8 context snapshot on arm64 macOS builds (#26202)
* chore: rename the v8 context snapshot on arm64 macOS builds

* build: update zip manifests

* build: update to upstream patch

* chore: update patches

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2020-10-27 20:11:24 -04:00
trop[bot]
4d280ed483 docs: fix app 'ready' event arguments (#26174)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2020-10-26 20:38:42 -07:00
David Sanders
bb69770267 chore: bump @electron/docs-parser version (#26155) 2020-10-26 11:50:00 -07:00
David Sanders
d4112d38de chore: prefer empty() check for readability (#26157) 2020-10-26 11:48:12 -07:00
Electron Bot
b1eec448f0 Bump v11.0.0-beta.17 2020-10-26 08:01:55 -07:00
trop[bot]
becfe25528 fix: wasm code generation in the renderer (#25829)
* fix: wasm code generation in the renderer

* Fixup patches

* update patches

* update patches

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
Co-authored-by: Electron Bot <anonymous@electronjs.org>
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2020-10-26 18:19:09 +09:00
Shelley Vohr
a461001677 fix: crash in printing on Windows (#26062)
* fix: crash in printing on Windows

* update patches

Co-authored-by: Electron Bot <anonymous@electronjs.org>
2020-10-26 12:11:36 +09:00
Electron Bot
aa15eeed78 Bump v11.0.0-beta.16 2020-10-23 13:10:26 -07:00
Samuel Attard
6daac26f49 Revert "Bump v11.0.0-beta.16"
This reverts commit 2b1004919d.
2020-10-23 13:09:17 -07:00
trop[bot]
3551c81cc5 fix: setSimpleFullScreen shows traffic light in frameless window (#26127)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-10-23 11:06:24 -07:00
Electron Bot
2b1004919d Bump v11.0.0-beta.16 2020-10-23 10:20:48 -07:00
Samuel Attard
d200b9192a revert: "fix: reply notifs sometimes destroyed too early" (#25247) (#26131)
* Revert "fix: reply notifs sometimes destroyed too early (#25086)"

This reverts commit bea6c9e4e1.

* nothing
2020-10-23 10:18:42 -07:00
Samuel Attard
c2e8704683 fix: re-enable the spellchecker when new language list set (#26119) (#26129)
* fix: re-enable the spellchecker when new language list set

Chromium recently added prefs logic to disable the spellchecker if the list of languages is empty, but the logic to re-enable if the languages are provided again lives in another part of Chromium.  This change makes it so our API re-enables the spellchecker correctly when required.

* chore: fix lint
2020-10-23 10:18:30 -07:00
Electron Bot
0b2862b184 chore: bump chromium to 87.0.4280.27 (11-x-y) (#25993)
* chore: bump chromium in DEPS to 87.0.4280.20

* update patches

* test: disable flaky arm tests (#26046)

* tests: disable flaking test on all arm platforms

* tests: disable flaky did-change-theme-color tests on WOA

(cherry picked from commit 4ce7ca6cfb)

* 2478082: Make window cloaking and uncloaking trigger occlusion calculation

https://chromium-review.googlesource.com/c/chromium/src/+/2478082

Fixes visibility issues.

* Revert "2478082: Make window cloaking and uncloaking trigger occlusion calculation"

This reverts commit 5ff8cc8c83.

* ci: disable CalculateNativeWinOcclusion for woa (#26001)

(cherry picked from commit 708cf44d19)

* Update appveyor.yml

disable CalculateNativeWinOcclusion due to visibility issues

* chore: bump chromium in DEPS to 87.0.4280.27

* update patches

Co-authored-by: Electron Bot <anonymous@electronjs.org>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
Co-authored-by: John Kleinschmidt <jkleinsc@github.com>
Co-authored-by: Robo <hop2deep@gmail.com>
2020-10-22 17:01:59 -04:00
trop[bot]
d959222bb8 fix: return early on promise rejection (#26111)
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2020-10-22 13:32:06 -07:00
Jeremy Rose
e5550e5bad chore: backport fix for ARIA TreeGrid rows not being announced by VoiceOver (#26036)
* chore: cherry-pick 2f5b8357dca2 from chromium

* update patches
2020-10-22 12:57:31 -07:00
trop[bot]
8546f98a87 fix: release NSAlert properly (#26099)
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2020-10-22 08:09:21 -07:00
Electron Bot
7a6965087c Bump v11.0.0-beta.15 2020-10-22 08:02:26 -07:00
trop[bot]
2558455be4 fix: crash when printing (#26047)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-10-20 09:08:14 -07:00
trop[bot]
65fdfc1e16 perf: remove GC timer that fired once per minute. (#26051)
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2020-10-20 14:35:51 +09:00
trop[bot]
139e20367f fix: update squirrel.mac to handle bug in Big Sur (#25906)
Fixes #25626

This is not the greatest workaround but at least it works.

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2020-10-20 10:50:22 +09:00
trop[bot]
e84aa04bb5 fix: Save As PDF from PDF Preview (#26012)
* fix: Save As PDF from PDF Preview

* Address review feedback

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-10-20 10:45:34 +09:00
David Sanders
7a06ae575e chore: bump @electron/docs-parser to get fix (#25974) 2020-10-20 10:34:33 +09:00
trop[bot]
460594480f build: fix invocation of cpplint on Windows (#26041)
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2020-10-19 19:17:57 -05:00
trop[bot]
6e676c3695 chore: tweak branch detection in release notes. (#26037)
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2020-10-19 15:36:12 -07:00
Michaela Laurencin
e6fa69bfd2 fix: correct null pointer checks in autoresizing browser views (#25956)
Co-authored-by: mlaurencin <mlaurencin@microsoft.com>
2020-10-19 09:26:13 -07:00
262 changed files with 6179 additions and 1421 deletions

View File

@@ -107,6 +107,7 @@ env-release-build: &env-release-build
STRIP_BINARIES: true
GENERATE_SYMBOLS: true
CHECK_DIST_MANIFEST: '1'
IS_RELEASE: true
env-headless-testing: &env-headless-testing
DISPLAY: ':99.0'
@@ -256,23 +257,34 @@ step-gclient-sync: &step-gclient-sync
"$CIRCLE_REPOSITORY_URL"
ELECTRON_USE_THREE_WAY_MERGE_FOR_PATCHES=1 gclient sync --with_branch_heads --with_tags
# Re-export all the patches to check if there were changes.
python src/electron/script/export_all_patches.py src/electron/patches/config.json
cd src/electron
git update-index --refresh || true
if ! git diff-index --quiet HEAD --; then
# There are changes to the patches. Make a git commit with the updated patches
git add patches
GIT_COMMITTER_NAME="Electron Bot" GIT_COMMITTER_EMAIL="anonymous@electronjs.org" git commit -m "update patches" --author="Electron Bot <anonymous@electronjs.org>"
# Export it
mkdir -p ../../patches
git format-patch -1 --stdout --keep-subject --no-stat --full-index > ../../patches/update-patches.patch
echo
echo "======================================================================"
echo "There were changes to the patches when applying."
echo "Check the CI artifacts for a patch you can apply to fix it."
echo "======================================================================"
exit 1
if [ "$IS_RELEASE" != "true" ]; then
# Re-export all the patches to check if there were changes.
python src/electron/script/export_all_patches.py src/electron/patches/config.json
cd src/electron
git update-index --refresh || true
if ! git diff-index --quiet HEAD --; then
# There are changes to the patches. Make a git commit with the updated patches
git add patches
GIT_COMMITTER_NAME="Electron Bot" GIT_COMMITTER_EMAIL="electron@github.com" git commit -m "update patches" --author="Electron Bot <electron@github.com>"
# Export it
mkdir -p ../../patches
git format-patch -1 --stdout --keep-subject --no-stat --full-index > ../../patches/update-patches.patch
if (node ./script/push-patch.js 2> /dev/null > /dev/null); then
echo
echo "======================================================================"
echo "Changes to the patches when applying, we have auto-pushed the diff to the current branch"
echo "A new CI job will kick off shortly"
echo "======================================================================"
exit 1
else
echo
echo "======================================================================"
echo "There were changes to the patches when applying."
echo "Check the CI artifacts for a patch you can apply to fix it."
echo "======================================================================"
exit 1
fi
fi
fi
fi
@@ -299,10 +311,10 @@ step-setup-goma-for-build: &step-setup-goma-for-build
name: Setup Goma
command: |
echo 'export USE_GOMA=true' >> $BASH_ENV
if [ "`uname`" == "Linux" ]; then
echo 'export NUMBER_OF_NINJA_PROCESSES=300' >> $BASH_ENV
else
echo 'export NUMBER_OF_NINJA_PROCESSES=25' >> $BASH_ENV
echo 'export NUMBER_OF_NINJA_PROCESSES=300' >> $BASH_ENV
if [ "`uname`" == "Darwin" ]; then
echo 'ulimit -n 10000' >> $BASH_ENV
echo 'sudo launchctl limit maxfiles 65536 200000' >> $BASH_ENV
fi
if [ ! -z "$RAW_GOMA_AUTH" ]; then
echo $RAW_GOMA_AUTH > ~/.goma_oauth2_config
@@ -311,7 +323,7 @@ step-setup-goma-for-build: &step-setup-goma-for-build
cd build-tools
npm install
mkdir third_party
node -e "require('./src/utils/goma.js').downloadAndPrepare()"
node -e "require('./src/utils/goma.js').downloadAndPrepare({ gomaOneForAll: true })"
node -e "require('./src/utils/goma.js').ensure()"
echo 'export GN_GOMA_FILE='`node -e "console.log(require('./src/utils/goma.js').gnFilePath)"` >> $BASH_ENV
echo 'export LOCAL_GOMA_DIR='`node -e "console.log(require('./src/utils/goma.js').dir)"` >> $BASH_ENV
@@ -572,6 +584,9 @@ step-electron-dist-build: &step-electron-dist-build
if [ x"$MAS_BUILD" == x"true" ]; then
target_os=mac_mas
fi
if [ "$TARGET_ARCH" == "arm64" ]; then
target_cpu=arm64
fi
elif [ "`uname`" == "Linux" ]; then
target_os=linux
if [ x"$TARGET_ARCH" == x ]; then
@@ -659,10 +674,10 @@ step-electron-publish: &step-electron-publish
cd src/electron
if [ "$UPLOAD_TO_S3" == "1" ]; then
echo 'Uploading Electron release distribution to S3'
script/release/uploaders/upload.py --upload_to_s3
script/release/uploaders/upload.py --verbose --upload_to_s3
else
echo 'Uploading Electron release distribution to Github releases'
script/release/uploaders/upload.py
script/release/uploaders/upload.py --verbose
fi
step-persist-data-for-tests: &step-persist-data-for-tests

View File

@@ -325,7 +325,6 @@ source_set("electron_lib") {
"//base/allocator:buildflags",
"//chrome/app:command_ids",
"//chrome/app/resources:platform_locale_settings",
"//chrome/services/printing/public/mojom",
"//components/certificate_transparency",
"//components/language/core/browser",
"//components/net_log",
@@ -372,6 +371,7 @@ source_set("electron_lib") {
"//third_party/libyuv",
"//third_party/webrtc_overrides:webrtc_component",
"//third_party/widevine/cdm:headers",
"//third_party/zlib/google:zip",
"//ui/base/idle",
"//ui/events:dom_keycode_converter",
"//ui/gl",
@@ -620,7 +620,10 @@ source_set("electron_lib") {
"shell/renderer/printing/print_render_frame_helper_delegate.cc",
"shell/renderer/printing/print_render_frame_helper_delegate.h",
]
deps += [ "//components/printing/common:mojo_interfaces" ]
deps += [
"//chrome/services/printing/public/mojom",
"//components/printing/common:mojo_interfaces",
]
}
if (enable_electron_extensions) {
@@ -658,6 +661,14 @@ source_set("electron_lib") {
"shell/browser/electron_pdf_web_contents_helper_client.h",
]
}
if (is_win && enable_win_dark_mode_window_ui) {
sources += [
"shell/browser/win/dark_mode.cc",
"shell/browser/win/dark_mode.h",
]
libs += [ "uxtheme.lib" ]
}
}
electron_paks("packed_resources") {
@@ -683,10 +694,10 @@ if (is_mac) {
action("fake_v8_context_snapshot_generator") {
script = "build/fake_v8_context_snapshot_generator.py"
args = [
rebase_path("$root_out_dir/v8_context_snapshot.bin"),
rebase_path("$root_out_dir/fake/v8_context_snapshot.bin"),
rebase_path("$root_out_dir/$v8_context_snapshot_filename"),
rebase_path("$root_out_dir/fake/$v8_context_snapshot_filename"),
]
outputs = [ "$root_out_dir/fake/v8_context_snapshot.bin" ]
outputs = [ "$root_out_dir/fake/$v8_context_snapshot_filename" ]
}
bundle_data("electron_framework_resources") {
@@ -700,10 +711,10 @@ if (is_mac) {
public_deps += [ "//v8" ]
if (use_v8_context_snapshot) {
if (use_prebuilt_v8_context_snapshot) {
sources += [ "$root_out_dir/fake/v8_context_snapshot.bin" ]
sources += [ "$root_out_dir/fake/$v8_context_snapshot_filename" ]
public_deps += [ ":fake_v8_context_snapshot_generator" ]
} else {
sources += [ "$root_out_dir/v8_context_snapshot.bin" ]
sources += [ "$root_out_dir/$v8_context_snapshot_filename" ]
public_deps += [ "//tools/v8_context_snapshot" ]
}
} else {

4
DEPS
View File

@@ -14,13 +14,13 @@ gclient_gn_args = [
vars = {
'chromium_version':
'87.0.4280.11',
'87.0.4280.88',
'node_version':
'v12.18.3',
'nan_version':
'2c4ee8a32a299eada3cd6e468bbd0a473bfea96d',
'squirrel.mac_version':
'44468f858ce0d25c27bd5e674abfa104e0119738',
'a3a5b3f03b824441c014893b18f99a103b2603e9',
'boto_version': 'f7574aa6cc2c819430c1f05e9a1a1a666ef8169b',
'pyyaml_version': '3.12',

View File

@@ -1 +1 @@
11.0.0-beta.14
11.1.0

View File

@@ -101,6 +101,11 @@ build_script:
} else {
# update external binaries
python src/electron/script/update-external-binaries.py
# update angle
cd src\third_party\angle
git remote set-url origin https://chromium.googlesource.com/angle/angle.git
git fetch
cd ..\..\..
}
} else {
# file does not exist, gclient sync, then zip
@@ -138,7 +143,7 @@ build_script:
cd build-tools
npm install
mkdir third_party
node -e "require('./src/utils/goma.js').downloadAndPrepare()"
node -e "require('./src/utils/goma.js').downloadAndPrepare({ gomaOneForAll: true })"
$env:GN_GOMA_FILE = node -e "console.log(require('./src/utils/goma.js').gnFilePath)"
$env:LOCAL_GOMA_DIR = node -e "console.log(require('./src/utils/goma.js').dir)"
cd ..
@@ -224,10 +229,10 @@ deploy_script:
if (Test-Path Env:\ELECTRON_RELEASE) {
if (Test-Path Env:\UPLOAD_TO_S3) {
Write-Output "Uploading Electron release distribution to s3"
& python script\release\uploaders\upload.py --upload_to_s3
& python script\release\uploaders\upload.py --verbose --upload_to_s3
} else {
Write-Output "Uploading Electron release distribution to github releases"
& python script\release\uploaders\upload.py
& python script\release\uploaders\upload.py --verbose
}
} elseif (Test-Path Env:\TEST_WOA) {
node script/release/ci-release-build.js --job=electron-woa-testing --ci=VSTS --armTest --appveyorJobId=$env:APPVEYOR_JOB_ID $env:APPVEYOR_REPO_BRANCH

View File

@@ -21,6 +21,7 @@ buildflag_header("buildflags") {
"ENABLE_ELECTRON_EXTENSIONS=$enable_electron_extensions",
"ENABLE_BUILTIN_SPELLCHECKER=$enable_builtin_spellchecker",
"ENABLE_PICTURE_IN_PICTURE=$enable_picture_in_picture",
"ENABLE_WIN_DARK_MODE_WINDOW_UI=$enable_win_dark_mode_window_ui",
"OVERRIDE_LOCATION_PROVIDER=$enable_fake_location_provider",
]
}

View File

@@ -36,4 +36,7 @@ declare_args() {
# Enable Spellchecker support
enable_builtin_spellchecker = true
# Undocumented Windows dark mode API
enable_win_dark_mode_window_ui = false
}

View File

@@ -277,13 +277,15 @@ static_library("chrome") {
}
}
sources += [ "//chrome/browser/hang_monitor/hang_crash_dump.h" ]
if (is_mac) {
sources += [ "//chrome/browser/hang_monitor/hang_crash_dump_mac.cc" ]
} else if (is_win) {
sources += [ "//chrome/browser/hang_monitor/hang_crash_dump_win.cc" ]
} else {
sources += [ "//chrome/browser/hang_monitor/hang_crash_dump.cc" ]
if (!is_mas_build) {
sources += [ "//chrome/browser/hang_monitor/hang_crash_dump.h" ]
if (is_mac) {
sources += [ "//chrome/browser/hang_monitor/hang_crash_dump_mac.cc" ]
} else if (is_win) {
sources += [ "//chrome/browser/hang_monitor/hang_crash_dump_win.cc" ]
} else {
sources += [ "//chrome/browser/hang_monitor/hang_crash_dump.cc" ]
}
}
}

View File

@@ -826,10 +826,9 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessWithTimeout(
to_send.append(current_dir.value());
const std::vector<std::string>& argv = electron::ElectronCommandLine::argv();
for (std::vector<std::string>::const_iterator it = argv.begin();
it != argv.end(); ++it) {
for (const auto& arg : argv) {
to_send.push_back(kTokenDelimiter);
to_send.append(*it);
to_send.append(arg);
}
// Send the message

View File

@@ -122,8 +122,7 @@ void GlobalMenuBarRegistrarX11::OnNameOwnerChanged(GObject* /* ignored */,
GParamSpec* /* ignored */) {
// If the name owner changed, we need to reregister all the live x11::Window
// with the system.
for (std::set<x11::Window>::const_iterator it = live_windows_.begin();
it != live_windows_.end(); ++it) {
RegisterXWindow(*it);
for (const auto& window : live_windows_) {
RegisterXWindow(window);
}
}

View File

@@ -32,7 +32,8 @@ In most cases, you should do everything in the `ready` event handler.
Returns:
* `launchInfo` unknown _macOS_
* `event` Event
* `launchInfo` Record<string, any> _macOS_
Emitted once, when Electron has finished initializing. On macOS, `launchInfo`
holds the `userInfo` of the `NSUserNotification` that was used to open the
@@ -1340,7 +1341,7 @@ systems Application folder. Use in combination with `app.moveToApplicationsFolde
### `app.moveToApplicationsFolder([options])` _macOS_
* `options` Object (optional)
* `conflictHandler` Function<Boolean> (optional) - A handler for potential conflict in move failure.
* `conflictHandler` Function\<Boolean> (optional) - A handler for potential conflict in move failure.
* `conflictType` String - The type of move conflict encountered by the handler; can be `exists` or `existsAndRunning`, where `exists` means that an app of the same name is present in the Applications directory and `existsAndRunning` means both that it exists and that it's presently running.
Returns `Boolean` - Whether the move was successful. Please note that if
@@ -1484,3 +1485,12 @@ which native modules you can use in the renderer process. For more information
on the direction Electron is going with renderer process restarts and usage of
native modules in the renderer process please check out this
[Tracking Issue](https://github.com/electron/electron/issues/18397).
### `app.runningUnderRosettaTranslation` _macOS_ _Readonly_
A `Boolean` which when `true` indicates that the app is currently running
under the [Rosetta Translator Environment](https://en.wikipedia.org/wiki/Rosetta_(software)).
You can use this property to prompt users to download the arm64 version of
your application when they are running the x64 version under Rosetta
incorrectly.

View File

@@ -541,6 +541,12 @@ Note that this is only emitted when the window is being resized manually. Resizi
Emitted after the window has been resized.
#### Event: 'resized' _macOS_ _Windows_
Emitted once when the window has finished being resized.
This is usually emitted when the window has been resized manually. On macOS, resizing the window with `setBounds`/`setSize` and setting the `animate` parameter to `true` will also emit this event once resizing has finished.
#### Event: 'will-move' _macOS_ _Windows_
Returns:
@@ -556,12 +562,12 @@ Note that this is only emitted when the window is being resized manually. Resizi
Emitted when the window is being moved to a new position.
__Note__: On macOS this event is an alias of `moved`.
#### Event: 'moved' _macOS_
#### Event: 'moved' _macOS_ _Windows_
Emitted once when the window is moved to a new position.
__Note__: On macOS this event is an alias of `move`.
#### Event: 'enter-full-screen'
Emitted when the window enters a full-screen state.

View File

@@ -16,7 +16,7 @@ const { app, contentTracing } = require('electron')
app.whenReady().then(() => {
(async () => {
await contentTracing.startRecording({
include_categories: ['*']
included_categories: ['*']
})
console.log('Tracing started')
await new Promise(resolve => setTimeout(resolve, 5000))

View File

@@ -91,7 +91,7 @@ Removes listeners of the specified `channel`.
### `ipcMain.handle(channel, listener)`
* `channel` String
* `listener` Function<Promise<void> | any>
* `listener` Function<Promise\<void> | any>
* `event` IpcMainInvokeEvent
* `...args` any[]
@@ -123,7 +123,7 @@ WebContents is the source of the invoke request.
### `ipcMain.handleOnce(channel, listener)`
* `channel` String
* `listener` Function<Promise<void> | any>
* `listener` Function<Promise\<void> | any>
* `event` IpcMainInvokeEvent
* `...args` any[]

View File

@@ -349,6 +349,7 @@ win.webContents.session.setCertificateVerifyProc((request, callback) => {
* `handler` Function | null
* `webContents` [WebContents](web-contents.md) - WebContents requesting the permission. Please note that if the request comes from a subframe you should use `requestingUrl` to check the request origin.
* `permission` String - The type of requested permission.
* `clipboard-read` - Request access to read from the clipboard.
* `media` - Request access to media devices such as camera, microphone and speakers.
* `mediaKeySystem` - Request access to DRM protected content.
* `geolocation` - Request access to user's current location.
@@ -384,7 +385,7 @@ session.fromPartition('some-partition').setPermissionRequestHandler((webContents
#### `ses.setPermissionCheckHandler(handler)`
* `handler` Function<Boolean> | null
* `handler` Function\<Boolean> | null
* `webContents` [WebContents](web-contents.md) - WebContents checking the permission. Please note that if the request comes from a subframe you should use `requestingUrl` to check the request origin.
* `permission` String - Enum of 'media'.
* `requestingOrigin` String - The origin URL of the permission check

View File

@@ -1,5 +1,6 @@
# IpcMainEvent Object extends `Event`
* `processId` Integer - The internal ID of the renderer process that sent this message
* `frameId` Integer - The ID of the renderer frame that sent this message
* `returnValue` any - Set this to the value to be returned in a synchronous message
* `sender` WebContents - Returns the `webContents` that sent the message

View File

@@ -1,4 +1,5 @@
# IpcMainInvokeEvent Object extends `Event`
* `processId` Integer - The internal ID of the renderer process that sent this message
* `frameId` Integer - The ID of the renderer frame that sent this message
* `sender` WebContents - Returns the `webContents` that sent the message

View File

@@ -42,7 +42,8 @@ returns `null`.
* `id` Integer
Returns `WebContents` - A WebContents instance with the given ID.
Returns `WebContents` | undefined - A WebContents instance with the given ID, or
`undefined` if there is no WebContents associated with the given ID.
## Class: WebContents
@@ -1324,9 +1325,9 @@ Returns [`PrinterInfo[]`](structures/printer-info.md)
* `pagesPerSheet` Number (optional) - The number of pages to print per page sheet.
* `collate` Boolean (optional) - Whether the web page should be collated.
* `copies` Number (optional) - The number of copies of the web page to print.
* `pageRanges` Record<string, number> (optional) - The page range to print.
* `from` Number - the start page.
* `to` Number - the end page.
* `pageRanges` Object[] (optional) - The page range to print. On macOS, only one range is honored.
* `from` Number - Index of the first page to print (0-based).
* `to` Number - Index of the last page to print (inclusive) (0-based).
* `duplexMode` String (optional) - Set the duplex mode of the printed web page. Can be `simplex`, `shortEdge`, or `longEdge`.
* `dpi` Record<string, number> (optional)
* `horizontal` Number (optional) - The horizontal dpi.
@@ -1352,10 +1353,10 @@ Example usage:
const options = {
silent: true,
deviceName: 'My-Printer',
pageRanges: {
pageRanges: [{
from: 0,
to: 1
}
}]
}
win.webContents.print(options, (success, errorType) => {
if (!success) console.log(errorType)
@@ -1373,8 +1374,8 @@ win.webContents.print(options, (success, errorType) => {
default margin, 1 for no margin, and 2 for minimum margin.
* `scaleFactor` Number (optional) - The scale factor of the web page. Can range from 0 to 100.
* `pageRanges` Record<string, number> (optional) - The page range to print.
* `from` Number - zero-based index of the first page to print.
* `to` Number - zero-based index of the last page to print (inclusive).
* `from` Number - Index of the first page to print (0-based).
* `to` Number - Index of the last page to print (inclusive) (0-based).
* `pageSize` String | Size (optional) - Specify page size of the generated PDF. Can be `A3`,
`A4`, `A5`, `Legal`, `Letter`, `Tabloid` or an Object containing `height` and `width` in microns.
* `printBackground` Boolean (optional) - Whether to print CSS backgrounds.
@@ -1621,7 +1622,7 @@ app.whenReady().then(() => {
#### `contents.sendToFrame(frameId, channel, ...args)`
* `frameId` Integer
* `frameId` Integer | [number, number]
* `channel` String
* `...args` any[]

View File

@@ -560,9 +560,9 @@ Stops any `findInPage` request for the `webview` with the provided `action`.
* `pagesPerSheet` Number (optional) - The number of pages to print per page sheet.
* `collate` Boolean (optional) - Whether the web page should be collated.
* `copies` Number (optional) - The number of copies of the web page to print.
* `pageRanges` Record<string, number> (optional) - The page range to print.
* `from` Number - zero-based index of the first page to print.
* `to` Number - zero-based index of the last page to print (inclusive).
* `pageRanges` Object[] (optional) - The page range to print.
* `from` Number - Index of the first page to print (0-based).
* `to` Number - Index of the last page to print (inclusive) (0-based).
* `duplexMode` String (optional) - Set the duplex mode of the printed web page. Can be `simplex`, `shortEdge`, or `longEdge`.
* `dpi` Record<string, number> (optional)
* `horizontal` Number (optional) - The horizontal dpi.
@@ -588,8 +588,8 @@ Prints `webview`'s web page. Same as `webContents.print([options])`.
and `width` in microns.
* `scaleFactor` Number (optional) - The scale factor of the web page. Can range from 0 to 100.
* `pageRanges` Record<string, number> (optional) - The page range to print.
* `from` Number - the first page to print.
* `to` Number - the last page to print (inclusive).
* `from` Number - Index of the first page to print (0-based).
* `to` Number - Index of the last page to print (inclusive) (0-based).
* `pageSize` String | Size (optional) - Specify page size of the generated PDF. Can be `A3`,
`A4`, `A5`, `Legal`, `Letter`, `Tabloid` or an Object containing `height`
* `printBackground` Boolean (optional) - Whether to print CSS backgrounds.

View File

@@ -195,6 +195,45 @@ 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).
### Deprecated: `BrowserWindow` extension APIs
The following extension APIs have been deprecated:
* `BrowserWindow.addExtension(path)`
* `BrowserWindow.addDevToolsExtension(path)`
* `BrowserWindow.removeExtension(name)`
* `BrowserWindow.removeDevToolsExtension(name)`
* `BrowserWindow.getExtensions()`
* `BrowserWindow.getDevToolsExtensions()`
Use the session APIs instead:
* `ses.loadExtension(path)`
* `ses.removeExtension(extension_id)`
* `ses.getAllExtensions()`
```js
// Deprecated in Electron 9
BrowserWindow.addExtension(path)
BrowserWindow.addDevToolsExtension(path)
// Replace with
session.defaultSession.loadExtension(path)
```
```js
// Deprecated in Electron 9
BrowserWindow.removeExtension(name)
BrowserWindow.removeDevToolsExtension(name)
// Replace with
session.defaultSession.removeExtension(extension_id)
```
```js
// Deprecated in Electron 9
BrowserWindow.getExtensions()
BrowserWindow.getDevToolsExtensions()
// Replace with
session.defaultSession.getAllExtensions()
```
### Removed: `<webview>.getWebContents()`
This API, which was deprecated in Electron 8.0, is now removed.
@@ -338,6 +377,52 @@ in Electron 8.x, and cease to exist in Electron 9.x. The layout zoom level
limits are now fixed at a minimum of 0.25 and a maximum of 5.0, as defined
[here](https://chromium.googlesource.com/chromium/src/+/938b37a6d2886bf8335fc7db792f1eb46c65b2ae/third_party/blink/common/page/page_zoom.cc#11).
### Deprecated events in `systemPreferences`
The following `systemPreferences` events have been deprecated:
* `inverted-color-scheme-changed`
* `high-contrast-color-scheme-changed`
Use the new `updated` event on the `nativeTheme` module instead.
```js
// Deprecated
systemPreferences.on('inverted-color-scheme-changed', () => { /* ... */ })
systemPreferences.on('high-contrast-color-scheme-changed', () => { /* ... */ })
// Replace with
nativeTheme.on('updated', () => { /* ... */ })
```
### Deprecated: methods in `systemPreferences`
The following `systemPreferences` methods have been deprecated:
* `systemPreferences.isDarkMode()`
* `systemPreferences.isInvertedColorScheme()`
* `systemPreferences.isHighContrastColorScheme()`
Use the following `nativeTheme` properties instead:
* `nativeTheme.shouldUseDarkColors`
* `nativeTheme.shouldUseInvertedColorScheme`
* `nativeTheme.shouldUseHighContrastColors`
```js
// Deprecated
systemPreferences.isDarkMode()
// Replace with
nativeTheme.shouldUseDarkColors
// Deprecated
systemPreferences.isInvertedColorScheme()
// Replace with
nativeTheme.shouldUseInvertedColorScheme
// Deprecated
systemPreferences.isHighContrastColorScheme()
// Replace with
nativeTheme.shouldUseHighContrastColors
```
## Planned Breaking API Changes (7.0)
### Deprecated: Atom.io Node Headers URL

View File

@@ -177,12 +177,12 @@ $ gn gen out/Testing-x86 --args='... target_cpu = "x86"'
Not all combinations of source and target CPU/OS are supported by Chromium.
<table>
<tr><th>Host</th><th>Target</th><th>Status</th></tr>
<tr><td>Windows x64</td><td>Windows arm64</td><td>Experimental</td>
<tr><td>Windows x64</td><td>Windows x86</td><td>Automatically tested</td></tr>
<tr><td>Linux x64</td><td>Linux x86</td><td>Automatically tested</td></tr>
</table>
| Host | Target | Status |
|-------------|---------------|----------------------|
| Windows x64 | Windows arm64 | Experimental |
| Windows x64 | Windows x86 | Automatically tested |
| Linux x64 | Linux x86 | Automatically tested |
If you test other combinations and find them to work, please update this document :)

View File

@@ -43,8 +43,8 @@ SRV*c:\code\symbols\*https://msdl.microsoft.com/download/symbols;SRV*c:\code\sym
## Using the symbol server in Visual Studio
<img src='https://mdn.mozillademos.org/files/733/symbol-server-vc8express-menu.jpg'>
<img src='https://mdn.mozillademos.org/files/2497/2005_options.gif'>
![Tools -> Options](https://mdn.mozillademos.org/files/733/symbol-server-vc8express-menu.jpg)
![Symbols Settings](https://mdn.mozillademos.org/files/2497/2005_options.gif)
## Troubleshooting: Symbols will not load

View File

@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
</head>
<body>
<h1>Hello World!</h1>
<p>
We are using node <script>document.write(process.versions.node)</script>,
Chrome <script>document.write(process.versions.chrome)</script>,
and Electron <script>document.write(process.versions.electron)</script>.
</p>
<a href="#" id="drag">Drag me</a>
<script src="renderer.js"></script>
</body>
</html>

View File

@@ -0,0 +1,41 @@
const { app, BrowserWindow, ipcMain, nativeImage, NativeImage } = require('electron')
const fs = require('fs');
const http = require('http');
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
}
})
win.loadFile('index.html')
}
const iconName = 'iconForDragAndDrop.png';
const icon = fs.createWriteStream(`${process.cwd()}/${iconName}`);
http.get('http://img.icons8.com/ios/452/drag-and-drop.png', (response) => {
response.pipe(icon);
});
app.whenReady().then(createWindow)
ipcMain.on('ondragstart', (event, filePath) => {
event.sender.startDrag({
file: filePath,
icon: `${process.cwd()}/${iconName}`
})
})
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})

View File

@@ -0,0 +1,9 @@
const { ipcRenderer } = require('electron')
const fs = require('fs')
document.getElementById('drag').ondragstart = (event) => {
const fileName = 'drag-and-drop.md'
fs.writeFileSync(fileName, '# Test drag and drop');
event.preventDefault()
ipcRenderer.send('ondragstart', process.cwd() + `/${fileName}`)
}

View File

@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
</head>
<body>
<h1>Hello World!</h1>
<p>
We are using node <script>document.write(process.versions.node)</script>,
Chrome <script>document.write(process.versions.chrome)</script>,
and Electron <script>document.write(process.versions.electron)</script>.
</p>
</body>
</html>

View File

@@ -0,0 +1,31 @@
const { app, BrowserWindow, globalShortcut } = require('electron')
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
}
})
win.loadFile('index.html')
}
app.whenReady().then(() => {
globalShortcut.register('Alt+CommandOrControl+I', () => {
console.log('Electron loves global shortcuts!')
})
}).then(createWindow)
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})

View File

@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
</head>
<body>
<h1>Hello World!</h1>
We are using node <script>document.write(process.versions.node)</script>,
Chrome <script>document.write(process.versions.chrome)</script>,
and Electron <script>document.write(process.versions.electron)</script>.
</body>
</html>

View File

@@ -0,0 +1,13 @@
const { app, BrowserWindow } = require('electron')
app.whenReady().then(() => {
const win = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true } })
win.loadFile('index.html')
win.webContents.on('before-input-event', (event, input) => {
if (input.control && input.key.toLowerCase() === 'i') {
console.log('Pressed Control+I')
event.preventDefault()
}
})
})

View File

@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
</head>
<body>
<h1>Hello World!</h1>
<p>
We are using node <script>document.write(process.versions.node)</script>,
Chrome <script>document.write(process.versions.chrome)</script>,
and Electron <script>document.write(process.versions.electron)</script>.
</p>
</body>
</html>

View File

@@ -0,0 +1,39 @@
const { app, BrowserWindow, Menu, MenuItem } = require('electron')
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
}
})
win.loadFile('index.html')
}
const menu = new Menu()
menu.append(new MenuItem({
label: 'Electron',
submenu: [{
role: 'help',
accelerator: process.platform === 'darwin' ? 'Alt+Cmd+I' : 'Alt+Shift+I',
click: () => { console.log('Electron rocks!') }
}]
}))
Menu.setApplicationMenu(menu)
app.whenReady().then(createWindow)
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})

View File

@@ -0,0 +1,19 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
<link rel="stylesheet" type="text/css" href="./styles.css">
</head>
<body>
<h1>Hello World!</h1>
<p>Current theme source: <strong id="theme-source">System</strong></p>
<button id="toggle-dark-mode">Toggle Dark Mode</button>
<button id="reset-to-system">Reset to System Theme</button>
<script src="renderer.js"></script>
</body>
</body>
</html>

View File

@@ -0,0 +1,40 @@
const { app, BrowserWindow, ipcMain, nativeTheme } = require('electron')
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
}
})
win.loadFile('index.html')
ipcMain.handle('dark-mode:toggle', () => {
if (nativeTheme.shouldUseDarkColors) {
nativeTheme.themeSource = 'light'
} else {
nativeTheme.themeSource = 'dark'
}
return nativeTheme.shouldUseDarkColors
})
ipcMain.handle('dark-mode:system', () => {
nativeTheme.themeSouce = 'system'
})
}
app.whenReady().then(createWindow)
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})

View File

@@ -0,0 +1,11 @@
const { ipcRenderer } = require('electron')
document.getElementById('toggle-dark-mode').addEventListener('click', async () => {
const isDarkMode = await ipcRenderer.invoke('dark-mode:toggle')
document.getElementById('theme-source').innerHTML = isDarkMode ? 'Dark' : 'Light'
})
document.getElementById('reset-to-system').addEventListener('click', async () => {
await ipcRenderer.invoke('dark-mode:system')
document.getElementById('theme-source').innerHTML = 'System'
})

View File

@@ -0,0 +1,7 @@
@media (prefers-color-scheme: dark) {
body { background: #333; color: white; }
}
@media (prefers-color-scheme: light) {
body { background: #ddd; color: black; }
}

View File

@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
</head>
<body>
<h1>Hello World!</h1>
<p>
We are using node <script>document.write(process.versions.node)</script>,
Chrome <script>document.write(process.versions.chrome)</script>,
and Electron <script>document.write(process.versions.electron)</script>.
</p>
</body>
</html>

View File

@@ -0,0 +1,43 @@
const { app, BrowserWindow, Menu } = require('electron')
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
}
})
win.loadFile('index.html')
}
const dockMenu = Menu.buildFromTemplate([
{
label: 'New Window',
click () { console.log('New Window') }
}, {
label: 'New Window with Settings',
submenu: [
{ label: 'Basic' },
{ label: 'Pro' }
]
},
{ label: 'New Command...' }
])
app.whenReady().then(() => {
app.dock.setMenu(dockMenu)
}).then(createWindow)
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})

View File

@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
</head>
<body>
<h1>Hello World!</h1>
<p>
We are using node <script>document.write(process.versions.node)</script>,
Chrome <script>document.write(process.versions.chrome)</script>,
and Electron <script>document.write(process.versions.electron)</script>.
</p>
</body>
</html>

View File

@@ -0,0 +1,35 @@
const { app, BrowserWindow, Notification } = require('electron')
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
}
})
win.loadFile('index.html')
}
function showNotification () {
const notification = {
title: 'Basic Notification',
body: 'Notification from the Main process'
}
new Notification(notification).show()
}
app.whenReady().then(createWindow).then(showNotification)
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})

View File

@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
</head>
<body>
<h1>Hello World!</h1>
<p>
We are using node <script>document.write(process.versions.node)</script>,
Chrome <script>document.write(process.versions.chrome)</script>,
and Electron <script>document.write(process.versions.electron)</script>.
</p>
<script src="renderer.js"></script>
</body>
</html>

View File

@@ -0,0 +1,27 @@
const { app, BrowserWindow } = require('electron')
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
}
})
win.loadFile('index.html')
}
app.whenReady().then(createWindow)
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})

View File

@@ -0,0 +1,7 @@
const myNotification = new Notification('Title', {
body: 'Notification from the Renderer process'
})
myNotification.onclick = () => {
console.log('Notification clicked')
}

View File

@@ -0,0 +1,15 @@
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
</head>
<body>
<h1>Hello World!</h1>
<p>
We are using node <script>document.write(process.versions.node)</script>,
Chrome <script>document.write(process.versions.chrome)</script>,
and Electron <script>document.write(process.versions.electron)</script>.
</p>
</body>
</html>

View File

@@ -0,0 +1,28 @@
const { app, BrowserWindow } = require('electron')
const fs = require('fs')
app.disableHardwareAcceleration()
let win
app.whenReady().then(() => {
win = new BrowserWindow({ webPreferences: { offscreen: true } })
win.loadURL('https://github.com')
win.webContents.on('paint', (event, dirty, image) => {
fs.writeFileSync('ex.png', image.toPNG())
})
win.webContents.setFrameRate(60)
console.log(`The screenshot has been successfully saved to ${process.cwd()}/ex.png`)
})
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})

View File

@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
</head>
<body>
<h1>Hello World!</h1>
<p>
We are using node <script>document.write(process.versions.node)</script>,
Chrome <script>document.write(process.versions.chrome)</script>,
and Electron <script>document.write(process.versions.electron)</script>.
</p>
<script src="renderer.js"></script>
</body>
</html>

View File

@@ -0,0 +1,24 @@
const { app, BrowserWindow, ipcMain } = require('electron')
let onlineStatusWindow
app.whenReady().then(() => {
onlineStatusWindow = new BrowserWindow({ width: 0, height: 0, show: false, webPreferences: { nodeIntegration: true } })
onlineStatusWindow.loadURL(`file://${__dirname}/index.html`)
})
ipcMain.on('online-status-changed', (event, status) => {
console.log(status)
})
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})

View File

@@ -0,0 +1,7 @@
const { ipcRenderer } = require('electron')
const updateOnlineStatus = () => { ipcRenderer.send('online-status-changed', navigator.onLine ? 'online' : 'offline') }
window.addEventListener('online', updateOnlineStatus)
window.addEventListener('offline', updateOnlineStatus)
updateOnlineStatus()

View File

@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
</head>
<body>
<h1>Hello World!</h1>
<p>
We are using node <script>document.write(process.versions.node)</script>,
Chrome <script>document.write(process.versions.chrome)</script>,
and Electron <script>document.write(process.versions.electron)</script>.
</p>
<script src="renderer.js"></script>
</body>
</html>

View File

@@ -0,0 +1,20 @@
const { app, BrowserWindow } = require('electron')
let onlineStatusWindow
app.whenReady().then(() => {
onlineStatusWindow = new BrowserWindow({ width: 0, height: 0, show: false })
onlineStatusWindow.loadURL(`file://${__dirname}/index.html`)
})
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})

View File

@@ -0,0 +1,6 @@
const alertOnlineStatus = () => { window.alert(navigator.onLine ? 'online' : 'offline') }
window.addEventListener('online', alertOnlineStatus)
window.addEventListener('offline', alertOnlineStatus)
alertOnlineStatus()

View File

@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
</head>
<body>
<h1>Hello World!</h1>
<p>
We are using node <script>document.write(process.versions.node)</script>,
Chrome <script>document.write(process.versions.chrome)</script>,
and Electron <script>document.write(process.versions.electron)</script>.
</p>
</body>
</html>

View File

@@ -0,0 +1,30 @@
const { app, BrowserWindow } = require('electron')
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
}
})
win.loadFile('index.html')
win.setProgressBar(0.5)
}
app.whenReady().then(createWindow)
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})

View File

@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
</head>
<body>
<h1>Hello World!</h1>
<p>
We are using node <script>document.write(process.versions.node)</script>,
Chrome <script>document.write(process.versions.chrome)</script>,
and Electron <script>document.write(process.versions.electron)</script>.
</p>
</body>
</html>

View File

@@ -0,0 +1,34 @@
const { app, BrowserWindow } = require('electron')
const fs = require('fs')
const path = require('path')
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
}
})
win.loadFile('index.html')
}
const fileName = 'recently-used.md'
fs.writeFile(fileName, 'Lorem Ipsum', () => {
app.addRecentDocument(path.join(process.cwd(), `${fileName}`))
})
app.whenReady().then(createWindow)
app.on('window-all-closed', () => {
app.clearRecentDocuments()
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})

View File

@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
</head>
<body>
<h1>Hello World!</h1>
<p>
We are using node <script>document.write(process.versions.node)</script>,
Chrome <script>document.write(process.versions.chrome)</script>,
and Electron <script>document.write(process.versions.electron)</script>.
</p>
</body>
</html>

View File

@@ -0,0 +1,33 @@
const { app, BrowserWindow } = require('electron')
const os = require('os');
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
}
})
win.loadFile('index.html')
}
app.whenReady().then(() => {
const win = new BrowserWindow()
win.setRepresentedFilename(os.homedir())
win.setDocumentEdited(true)
})
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})

View File

@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
</head>
<body>
<h1>Hello World!</h1>
<p>
We are using node <script>document.write(process.versions.node)</script>,
Chrome <script>document.write(process.versions.chrome)</script>,
and Electron <script>document.write(process.versions.electron)</script>.
</p>
</body>
</html>

View File

@@ -0,0 +1,27 @@
const { app, BrowserWindow } = require('electron')
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
}
})
win.loadFile('index.html')
}
app.whenReady().then(createWindow)
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})

View File

@@ -363,8 +363,12 @@ filenames = {
"shell/browser/electron_web_ui_controller_factory.h",
"shell/browser/event_emitter_mixin.cc",
"shell/browser/event_emitter_mixin.h",
"shell/browser/extended_web_contents_observer.h",
"shell/browser/feature_list.cc",
"shell/browser/feature_list.h",
"shell/browser/file_select_helper.cc",
"shell/browser/file_select_helper.h",
"shell/browser/file_select_helper_mac.mm",
"shell/browser/font_defaults.cc",
"shell/browser/font_defaults.h",
"shell/browser/javascript_environment.cc",
@@ -441,6 +445,7 @@ filenames = {
"shell/browser/ui/devtools_manager_delegate.h",
"shell/browser/ui/devtools_ui.cc",
"shell/browser/ui/devtools_ui.h",
"shell/browser/ui/drag_util.cc",
"shell/browser/ui/drag_util.h",
"shell/browser/ui/electron_menu_model.cc",
"shell/browser/ui/electron_menu_model.h",

View File

@@ -686,7 +686,8 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
if (info.size === 0) return ['', false];
if (info.unpacked) {
const realPath = archive.copyFileOut(filePath);
return fs.readFileSync(realPath, { encoding: 'utf8' });
const str = fs.readFileSync(realPath, { encoding: 'utf8' });
return [str, str.length > 0];
}
logASARAccess(asarPath, filePath, info.offset);

View File

@@ -2,19 +2,39 @@ const { createScreen } = process._linkedBinding('electron_common_screen');
let _screen: Electron.Screen;
const createScreenIfNeeded = () => {
if (_screen === undefined) {
_screen = createScreen();
}
};
// We can't call createScreen until after app.on('ready'), but this module
// exposes an instance created by createScreen. In order to avoid
// side-effecting and calling createScreen upon import of this module, instead
// we export a proxy which lazily calls createScreen on first access.
export default new Proxy({}, {
get: (target, prop) => {
if (_screen === undefined) {
_screen = createScreen();
get: (target, property: keyof Electron.Screen) => {
createScreenIfNeeded();
const value = _screen[property];
if (typeof value === 'function') {
return value.bind(_screen);
}
const v = (_screen as any)[prop];
if (typeof v === 'function') {
return v.bind(_screen);
}
return v;
return value;
},
set: (target, property: string, value: unknown) => {
createScreenIfNeeded();
return Reflect.set(_screen, property, value);
},
ownKeys: () => {
createScreenIfNeeded();
return Reflect.ownKeys(_screen);
},
has: (target, property: string) => {
createScreenIfNeeded();
return property in _screen;
},
getOwnPropertyDescriptor: (target, property: string) => {
createScreenIfNeeded();
return Reflect.getOwnPropertyDescriptor(_screen, property);
}
});

View File

@@ -11,7 +11,7 @@ if ('getAppLevelAppearance' in systemPreferences) {
}
if ('getEffectiveAppearance' in systemPreferences) {
const nativeEAGetter = systemPreferences.getAppLevelAppearance;
const nativeEAGetter = systemPreferences.getEffectiveAppearance;
Object.defineProperty(systemPreferences, 'effectiveAppearance', {
get: () => nativeEAGetter.call(systemPreferences)
});

View File

@@ -161,29 +161,29 @@ WebContents.prototype._sendInternalToAll = function (channel, ...args) {
return this._send(internal, sendToAll, channel, args);
};
WebContents.prototype.sendToFrame = function (frameId, channel, ...args) {
WebContents.prototype.sendToFrame = function (frame, channel, ...args) {
if (typeof channel !== 'string') {
throw new Error('Missing required channel argument');
} else if (typeof frameId !== 'number') {
throw new Error('Missing required frameId argument');
} else if (!(typeof frame === 'number' || Array.isArray(frame))) {
throw new Error('Missing required frame argument (must be number or array)');
}
const internal = false;
const sendToAll = false;
return this._sendToFrame(internal, sendToAll, frameId, channel, args);
return this._sendToFrame(internal, sendToAll, frame, channel, args);
};
WebContents.prototype._sendToFrameInternal = function (frameId, channel, ...args) {
WebContents.prototype._sendToFrameInternal = function (frame, channel, ...args) {
if (typeof channel !== 'string') {
throw new Error('Missing required channel argument');
} else if (typeof frameId !== 'number') {
throw new Error('Missing required frameId argument');
} else if (!(typeof frame === 'number' || Array.isArray(frame))) {
throw new Error('Missing required frame argument (must be number or array)');
}
const internal = true;
const sendToAll = false;
return this._sendToFrame(internal, sendToAll, frameId, channel, args);
return this._sendToFrame(internal, sendToAll, frame, channel, args);
};
// Following methods are mapped to webFrame.
@@ -439,8 +439,9 @@ WebContents.prototype.loadFile = function (filePath, options = {}) {
};
const addReplyToEvent = (event: any) => {
const { processId, frameId } = event;
event.reply = (...args: any[]) => {
event.sender.sendToFrame(event.frameId, ...args);
event.sender.sendToFrame([processId, frameId], ...args);
};
};

View File

@@ -19,7 +19,7 @@ const FUNCTION_PROPERTIES = [
];
type RendererFunctionId = [string, number] // [contextId, funcId]
type FinalizerInfo = { id: RendererFunctionId, webContents: electron.WebContents, frameId: number };
type FinalizerInfo = { id: RendererFunctionId, webContents: electron.WebContents, frameId: [number, number] };
type WeakRef<T> = { deref(): T | undefined }
type CallIntoRenderer = (...args: any[]) => void
@@ -31,7 +31,7 @@ const finalizationRegistry = new (globalThis as any).FinalizationRegistry((fi: F
const ref = rendererFunctionCache.get(mapKey);
if (ref !== undefined && ref.deref() === undefined) {
rendererFunctionCache.delete(mapKey);
if (!fi.webContents.isDestroyed()) { fi.webContents.sendToFrame(fi.frameId, 'ELECTRON_RENDERER_RELEASE_CALLBACK', fi.id[0], fi.id[1]); }
if (!fi.webContents.isDestroyed()) { fi.webContents._sendToFrameInternal(fi.frameId, 'ELECTRON_RENDERER_RELEASE_CALLBACK', fi.id[0], fi.id[1]); }
}
});
@@ -43,7 +43,7 @@ function getCachedRendererFunction (id: RendererFunctionId): CallIntoRenderer |
if (deref !== undefined) return deref;
}
}
function setCachedRendererFunction (id: RendererFunctionId, wc: electron.WebContents, frameId: number, value: CallIntoRenderer) {
function setCachedRendererFunction (id: RendererFunctionId, wc: electron.WebContents, frameId: [number, number], value: CallIntoRenderer) {
// eslint-disable-next-line no-undef
const wr = new (globalThis as any).WeakRef(value) as WeakRef<CallIntoRenderer>;
const mapKey = id[0] + '~' + id[1];
@@ -218,7 +218,7 @@ const fakeConstructor = (constructor: Function, name: string) =>
});
// Convert array of meta data from renderer into array of real values.
const unwrapArgs = function (sender: electron.WebContents, frameId: number, contextId: string, args: any[]) {
const unwrapArgs = function (sender: electron.WebContents, frameId: [number, number], contextId: string, args: any[]) {
const metaToValue = function (meta: MetaTypeFromRenderer): any {
switch (meta.type) {
case 'nativeimage':
@@ -263,7 +263,7 @@ const unwrapArgs = function (sender: electron.WebContents, frameId: number, cont
const callIntoRenderer = function (this: any, ...args: any[]) {
let succeed = false;
if (!sender.isDestroyed()) {
succeed = (sender as any)._sendToFrameInternal(frameId, 'ELECTRON_RENDERER_CALLBACK', contextId, meta.id, valueToMeta(sender, contextId, args));
succeed = sender._sendToFrameInternal(frameId, 'ELECTRON_RENDERER_CALLBACK', contextId, meta.id, valueToMeta(sender, contextId, args));
}
if (!succeed) {
removeRemoteListenersAndLogWarning(this, callIntoRenderer);
@@ -421,7 +421,7 @@ handleRemoteCommand('ELECTRON_BROWSER_CURRENT_WEB_CONTENTS', function (event, co
});
handleRemoteCommand('ELECTRON_BROWSER_CONSTRUCTOR', function (event, contextId, id, args) {
args = unwrapArgs(event.sender, event.frameId, contextId, args);
args = unwrapArgs(event.sender, [event.processId, event.frameId], contextId, args);
const constructor = objectsRegistry.get(id);
if (constructor == null) {
@@ -432,7 +432,7 @@ handleRemoteCommand('ELECTRON_BROWSER_CONSTRUCTOR', function (event, contextId,
});
handleRemoteCommand('ELECTRON_BROWSER_FUNCTION_CALL', function (event, contextId, id, args) {
args = unwrapArgs(event.sender, event.frameId, contextId, args);
args = unwrapArgs(event.sender, [event.processId, event.frameId], contextId, args);
const func = objectsRegistry.get(id);
if (func == null) {
@@ -449,7 +449,7 @@ handleRemoteCommand('ELECTRON_BROWSER_FUNCTION_CALL', function (event, contextId
});
handleRemoteCommand('ELECTRON_BROWSER_MEMBER_CONSTRUCTOR', function (event, contextId, id, method, args) {
args = unwrapArgs(event.sender, event.frameId, contextId, args);
args = unwrapArgs(event.sender, [event.processId, event.frameId], contextId, args);
const object = objectsRegistry.get(id);
if (object == null) {
@@ -460,7 +460,7 @@ handleRemoteCommand('ELECTRON_BROWSER_MEMBER_CONSTRUCTOR', function (event, cont
});
handleRemoteCommand('ELECTRON_BROWSER_MEMBER_CALL', function (event, contextId, id, method, args) {
args = unwrapArgs(event.sender, event.frameId, contextId, args);
args = unwrapArgs(event.sender, [event.processId, event.frameId], contextId, args);
const object = objectsRegistry.get(id);
if (object == null) {
@@ -477,7 +477,7 @@ handleRemoteCommand('ELECTRON_BROWSER_MEMBER_CALL', function (event, contextId,
});
handleRemoteCommand('ELECTRON_BROWSER_MEMBER_SET', function (event, contextId, id, name, args) {
args = unwrapArgs(event.sender, event.frameId, contextId, args);
args = unwrapArgs(event.sender, [event.processId, event.frameId], contextId, args);
const obj = objectsRegistry.get(id);
if (obj == null) {

View File

@@ -38,7 +38,7 @@ const keysOfTypeNumber = ['top', 'left', ...Object.keys(keysOfTypeNumberCompileT
type CoercedValue = string | number | boolean;
function coerce (key: string, value: string): CoercedValue {
if (keysOfTypeNumber.includes(key)) {
return Number(value);
return parseInt(value, 10);
}
switch (value) {

View File

@@ -298,7 +298,7 @@ function metaToError (meta: { type: 'error', value: any, members: ObjectMember[]
}
function handleMessage (channel: string, handler: Function) {
ipcRendererInternal.on(channel, (event, passedContextId, id, ...args) => {
ipcRendererInternal.onMessageFromMain(channel, (event, passedContextId, id, ...args) => {
if (passedContextId === contextId) {
handler(id, ...args);
} else {

View File

@@ -1,119 +0,0 @@
import { webFrame } from 'electron';
import * as ipcRendererUtils from '@electron/internal/renderer/ipc-renderer-internal-utils';
const v8Util = process._linkedBinding('electron_common_v8_util');
const IsolatedWorldIDs = {
/**
* Start of extension isolated world IDs, as defined in
* electron_render_frame_observer.h
*/
ISOLATED_WORLD_EXTENSIONS: 1 << 20
};
let isolatedWorldIds = IsolatedWorldIDs.ISOLATED_WORLD_EXTENSIONS;
const extensionWorldId: {[key: string]: number | undefined} = {};
// https://cs.chromium.org/chromium/src/extensions/renderer/script_injection.cc?type=cs&sq=package:chromium&g=0&l=52
const getIsolatedWorldIdForInstance = () => {
// TODO(samuelmaddock): allocate and cleanup IDs
return isolatedWorldIds++;
};
const escapePattern = function (pattern: string) {
return pattern.replace(/[\\^$+?.()|[\]{}]/g, '\\$&');
};
// Check whether pattern matches.
// https://developer.chrome.com/extensions/match_patterns
const matchesPattern = function (pattern: string) {
if (pattern === '<all_urls>') return true;
const regexp = new RegExp(`^${pattern.split('*').map(escapePattern).join('.*')}$`);
const url = `${location.protocol}//${location.host}${location.pathname}`;
return url.match(regexp);
};
// Run the code with chrome API integrated.
const runContentScript = function (this: any, extensionId: string, url: string, code: string) {
// Assign unique world ID to each extension
const worldId = extensionWorldId[extensionId] ||
(extensionWorldId[extensionId] = getIsolatedWorldIdForInstance());
// store extension ID for content script to read in isolated world
v8Util.setHiddenValue(global, `extension-${worldId}`, extensionId);
webFrame.setIsolatedWorldInfo(worldId, {
name: `${extensionId} [${worldId}]`
// TODO(samuelmaddock): read `content_security_policy` from extension manifest
// csp: manifest.content_security_policy,
});
const sources = [{ code, url }];
return webFrame.executeJavaScriptInIsolatedWorld(worldId, sources);
};
const runAllContentScript = function (scripts: Array<Electron.InjectionBase>, extensionId: string) {
for (const { url, code } of scripts) {
runContentScript.call(window, extensionId, url, code);
}
};
const runStylesheet = function (this: any, url: string, code: string) {
webFrame.insertCSS(code);
};
const runAllStylesheet = function (css: Array<Electron.InjectionBase>) {
for (const { url, code } of css) {
runStylesheet.call(window, url, code);
}
};
// Run injected scripts.
// https://developer.chrome.com/extensions/content_scripts
const injectContentScript = function (extensionId: string, script: Electron.ContentScript) {
if (!process.isMainFrame && !script.allFrames) return;
if (!script.matches.some(matchesPattern)) return;
if (script.js) {
const fire = runAllContentScript.bind(window, script.js, extensionId);
if (script.runAt === 'document_start') {
process.once('document-start', fire);
} else if (script.runAt === 'document_end') {
process.once('document-end', fire);
} else {
document.addEventListener('DOMContentLoaded', fire);
}
}
if (script.css) {
const fire = runAllStylesheet.bind(window, script.css);
if (script.runAt === 'document_start') {
process.once('document-start', fire);
} else if (script.runAt === 'document_end') {
process.once('document-end', fire);
} else {
document.addEventListener('DOMContentLoaded', fire);
}
}
};
// Handle the request of chrome.tabs.executeJavaScript.
ipcRendererUtils.handle('CHROME_TABS_EXECUTE_SCRIPT', function (
event: Electron.Event,
extensionId: string,
url: string,
code: string
) {
return runContentScript.call(window, extensionId, url, code);
});
module.exports = (entries: Electron.ContentScriptEntry[]) => {
for (const entry of entries) {
if (entry.contentScripts) {
for (const script of entry.contentScripts) {
injectContentScript(entry.extensionId, script);
}
}
}
};

View File

@@ -1,20 +0,0 @@
export class Event {
private listeners: Function[] = []
addListener (callback: Function) {
this.listeners.push(callback);
}
removeListener (callback: Function) {
const index = this.listeners.indexOf(callback);
if (index !== -1) {
this.listeners.splice(index, 1);
}
}
emit (...args: any[]) {
for (const listener of this.listeners) {
listener(...args);
}
}
}

View File

@@ -1,60 +0,0 @@
// Implementation of chrome.i18n.getMessage
// https://developer.chrome.com/extensions/i18n#method-getMessage
//
// Does not implement predefined messages:
// https://developer.chrome.com/extensions/i18n#overview-predefined
import * as ipcRendererUtils from '@electron/internal/renderer/ipc-renderer-internal-utils';
interface Placeholder {
content: string;
example?: string;
}
const getMessages = (extensionId: number) => {
try {
const data = ipcRendererUtils.invokeSync<string>('CHROME_GET_MESSAGES', extensionId);
return JSON.parse(data) || {};
} catch {
return {};
}
};
const replaceNumberedSubstitutions = (message: string, substitutions: string[]) => {
return message.replace(/\$(\d+)/, (_, number) => {
const index = parseInt(number, 10) - 1;
return substitutions[index] || '';
});
};
const replacePlaceholders = (message: string, placeholders: Record<string, Placeholder>, substitutions: string[] | string) => {
if (typeof substitutions === 'string') substitutions = [substitutions];
if (!Array.isArray(substitutions)) substitutions = [];
if (placeholders) {
Object.keys(placeholders).forEach((name: string) => {
let { content } = placeholders[name];
const substitutionsArray = Array.isArray(substitutions) ? substitutions : [];
content = replaceNumberedSubstitutions(content, substitutionsArray);
message = message.replace(new RegExp(`\\$${name}\\$`, 'gi'), content);
});
}
return replaceNumberedSubstitutions(message, substitutions);
};
const getMessage = (extensionId: number, messageName: string, substitutions: string[]) => {
const messages = getMessages(extensionId);
if (Object.prototype.hasOwnProperty.call(messages, messageName)) {
const { message, placeholders } = messages[messageName];
return replacePlaceholders(message, placeholders, substitutions);
}
};
exports.setup = (extensionId: number) => {
return {
getMessage (messageName: string, substitutions: string[]) {
return getMessage(extensionId, messageName, substitutions);
}
};
};

View File

@@ -1,86 +0,0 @@
import { ipcRendererInternal } from '@electron/internal/renderer/ipc-renderer-internal';
const getStorage = (storageType: string, extensionId: number, callback: Function) => {
if (typeof callback !== 'function') throw new TypeError('No callback provided');
ipcRendererInternal.invoke<string>('CHROME_STORAGE_READ', storageType, extensionId)
.then(data => {
if (data !== null) {
callback(JSON.parse(data));
} else {
// Disabled due to false positive in StandardJS
// eslint-disable-next-line standard/no-callback-literal
callback({});
}
});
};
const setStorage = (storageType: string, extensionId: number, storage: Record<string, any>, callback: Function) => {
const json = JSON.stringify(storage);
ipcRendererInternal.invoke('CHROME_STORAGE_WRITE', storageType, extensionId, json)
.then(() => {
if (callback) callback();
});
};
const getStorageManager = (storageType: string, extensionId: number) => {
return {
get (keys: string[], callback: Function) {
getStorage(storageType, extensionId, (storage: Record<string, any>) => {
if (keys == null) return callback(storage);
let defaults: Record<string, any> = {};
switch (typeof keys) {
case 'string':
keys = [keys];
break;
case 'object':
if (!Array.isArray(keys)) {
defaults = keys;
keys = Object.keys(keys);
}
break;
}
// Disabled due to false positive in StandardJS
// eslint-disable-next-line standard/no-callback-literal
if (keys.length === 0) return callback({});
const items: Record<string, any> = {};
keys.forEach((key: string) => {
let value = storage[key];
if (value == null) value = defaults[key];
items[key] = value;
});
callback(items);
});
},
set (items: Record<string, any>, callback: Function) {
getStorage(storageType, extensionId, (storage: Record<string, any>) => {
Object.keys(items).forEach(name => { storage[name] = items[name]; });
setStorage(storageType, extensionId, storage, callback);
});
},
remove (keys: string[], callback: Function) {
getStorage(storageType, extensionId, (storage: Record<string, any>) => {
if (!Array.isArray(keys)) keys = [keys];
keys.forEach((key: string) => {
delete storage[key];
});
setStorage(storageType, extensionId, storage, callback);
});
},
clear (callback: Function) {
setStorage(storageType, extensionId, {}, callback);
}
};
};
export const setup = (extensionId: number) => ({
sync: getStorageManager('sync', extensionId),
local: getStorageManager('local', extensionId)
});

View File

@@ -1,19 +0,0 @@
import { Event } from '@electron/internal/renderer/extensions/event';
import { ipcRendererInternal } from '@electron/internal/renderer/ipc-renderer-internal';
class WebNavigation {
private onBeforeNavigate = new Event()
private onCompleted = new Event()
constructor () {
ipcRendererInternal.on('CHROME_WEBNAVIGATION_ONBEFORENAVIGATE', (event: Electron.IpcRendererEvent, details: any) => {
this.onBeforeNavigate.emit(details);
});
ipcRendererInternal.on('CHROME_WEBNAVIGATION_ONCOMPLETED', (event: Electron.IpcRendererEvent, details: any) => {
this.onCompleted.emit(details);
});
}
}
export const setup = () => new WebNavigation();

View File

@@ -3,7 +3,7 @@ import { ipcRendererInternal } from '@electron/internal/renderer/ipc-renderer-in
type IPCHandler = (event: Electron.IpcRendererEvent, ...args: any[]) => any
export const handle = function <T extends IPCHandler> (channel: string, handler: T) {
ipcRendererInternal.on(channel, async (event, requestId, ...args) => {
ipcRendererInternal.onMessageFromMain(channel, async (event, requestId, ...args) => {
const replyChannel = `${channel}_RESPONSE_${requestId}`;
try {
event.sender.send(replyChannel, null, await handler(event, ...args));

View File

@@ -29,4 +29,27 @@ ipcRendererInternal.invoke = async function<T> (channel: string, ...args: any[])
return result;
};
ipcRendererInternal.onMessageFromMain = function (channel: string, listener: (event: Electron.IpcRendererEvent, ...args: any[]) => void) {
return ipcRendererInternal.on(channel, (event, ...args) => {
if (event.senderId !== 0) {
console.error(`Message ${channel} sent by unexpected WebContents (${event.senderId})`);
return;
}
listener(event, ...args);
});
};
ipcRendererInternal.onceMessageFromMain = function (channel: string, listener: (event: Electron.IpcRendererEvent, ...args: any[]) => void) {
return ipcRendererInternal.on(channel, function wrapper (event, ...args) {
if (event.senderId !== 0) {
console.error(`Message ${channel} sent by unexpected WebContents (${event.senderId})`);
return;
}
ipcRendererInternal.removeListener(channel, wrapper);
listener(event, ...args);
});
};
export { ipcRendererInternal };

View File

@@ -179,7 +179,7 @@ const warnAboutInsecureCSP = function () {
console.warn('%cElectron Security Warning (Insecure Content-Security-Policy)',
'font-weight: bold;', warning);
});
}).catch(() => {});
};
/**

View File

@@ -27,6 +27,7 @@ const WEB_VIEW_EVENTS: Record<string, Array<string>> = {
'focus-change': ['focus', 'guestInstanceId'],
close: [],
crashed: [],
'render-process-gone': ['details'],
'plugin-crashed': ['name', 'version'],
destroyed: [],
'page-title-updated': ['title', 'explicitSet'],
@@ -66,18 +67,18 @@ const dispatchEvent = function (
};
export function registerEvents (webView: WebViewImpl, viewInstanceId: number) {
ipcRendererInternal.on(`ELECTRON_GUEST_VIEW_INTERNAL_DESTROY_GUEST-${viewInstanceId}`, function () {
ipcRendererInternal.onMessageFromMain(`ELECTRON_GUEST_VIEW_INTERNAL_DESTROY_GUEST-${viewInstanceId}`, function () {
webView.guestInstanceId = undefined;
webView.reset();
const domEvent = new Event('destroyed');
webView.dispatchEvent(domEvent);
});
ipcRendererInternal.on(`ELECTRON_GUEST_VIEW_INTERNAL_DISPATCH_EVENT-${viewInstanceId}`, function (event, eventName, ...args) {
ipcRendererInternal.onMessageFromMain(`ELECTRON_GUEST_VIEW_INTERNAL_DISPATCH_EVENT-${viewInstanceId}`, function (event, eventName, ...args) {
dispatchEvent(webView, eventName, eventName, ...args);
});
ipcRendererInternal.on(`ELECTRON_GUEST_VIEW_INTERNAL_IPC_MESSAGE-${viewInstanceId}`, function (event, channel, ...args) {
ipcRendererInternal.onMessageFromMain(`ELECTRON_GUEST_VIEW_INTERNAL_IPC_MESSAGE-${viewInstanceId}`, function (event, channel, ...args) {
const domEvent = new Event('ipc-message') as IpcMessageEvent;
domEvent.channel = channel;
domEvent.args = args;

View File

@@ -17,7 +17,7 @@ interface MutationHandler {
// Attribute objects.
// Default implementation of a WebView attribute.
class WebViewAttribute implements MutationHandler {
export class WebViewAttribute implements MutationHandler {
public value: any;
public ignoreMutation = false;
@@ -78,7 +78,7 @@ class BooleanAttribute extends WebViewAttribute {
}
// Attribute representing the state of the storage partition.
class PartitionAttribute extends WebViewAttribute {
export class PartitionAttribute extends WebViewAttribute {
public validPartitionId = true
constructor (public webViewImpl: WebViewImpl) {
@@ -102,7 +102,7 @@ class PartitionAttribute extends WebViewAttribute {
}
// Attribute that handles the location and navigation of the webview.
class SrcAttribute extends WebViewAttribute {
export class SrcAttribute extends WebViewAttribute {
public observer!: MutationObserver;
constructor (public webViewImpl: WebViewImpl) {
@@ -168,7 +168,7 @@ class SrcAttribute extends WebViewAttribute {
}
public parse () {
if (!this.webViewImpl.elementAttached || !this.webViewImpl.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_PARTITION].validPartitionId || !this.getValue()) {
if (!this.webViewImpl.elementAttached || !(this.webViewImpl.attributes.get(WEB_VIEW_CONSTANTS.ATTRIBUTE_PARTITION) as PartitionAttribute).validPartitionId || !this.getValue()) {
return;
}
if (this.webViewImpl.guestInstanceId == null) {
@@ -182,12 +182,12 @@ class SrcAttribute extends WebViewAttribute {
// Navigate to |this.src|.
const opts: Record<string, string> = {};
const httpreferrer = this.webViewImpl.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_HTTPREFERRER].getValue();
const httpreferrer = this.webViewImpl.attributes.get(WEB_VIEW_CONSTANTS.ATTRIBUTE_HTTPREFERRER)!.getValue();
if (httpreferrer) {
opts.httpReferrer = httpreferrer;
}
const useragent = this.webViewImpl.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_USERAGENT].getValue();
const useragent = this.webViewImpl.attributes.get(WEB_VIEW_CONSTANTS.ATTRIBUTE_USERAGENT)!.getValue();
if (useragent) {
opts.userAgent = useragent;
}
@@ -274,19 +274,18 @@ class EnableRemoteModuleAttribute extends WebViewAttribute {
// Sets up all of the webview attributes.
WebViewImpl.prototype.setupWebViewAttributes = function () {
this.attributes = {};
this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_PARTITION] = new PartitionAttribute(this);
this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_SRC] = new SrcAttribute(this);
this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_HTTPREFERRER] = new HttpReferrerAttribute(this);
this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_USERAGENT] = new UserAgentAttribute(this);
this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_NODEINTEGRATION] = new BooleanAttribute(WEB_VIEW_CONSTANTS.ATTRIBUTE_NODEINTEGRATION, this);
this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_NODEINTEGRATIONINSUBFRAMES] = new BooleanAttribute(WEB_VIEW_CONSTANTS.ATTRIBUTE_NODEINTEGRATIONINSUBFRAMES, this);
this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_PLUGINS] = new BooleanAttribute(WEB_VIEW_CONSTANTS.ATTRIBUTE_PLUGINS, this);
this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_DISABLEWEBSECURITY] = new BooleanAttribute(WEB_VIEW_CONSTANTS.ATTRIBUTE_DISABLEWEBSECURITY, this);
this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_ALLOWPOPUPS] = new BooleanAttribute(WEB_VIEW_CONSTANTS.ATTRIBUTE_ALLOWPOPUPS, this);
this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_ENABLEREMOTEMODULE] = new EnableRemoteModuleAttribute(this);
this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_PRELOAD] = new PreloadAttribute(this);
this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_BLINKFEATURES] = new BlinkFeaturesAttribute(this);
this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_DISABLEBLINKFEATURES] = new DisableBlinkFeaturesAttribute(this);
this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_WEBPREFERENCES] = new WebPreferencesAttribute(this);
this.attributes.set(WEB_VIEW_CONSTANTS.ATTRIBUTE_PARTITION, new PartitionAttribute(this));
this.attributes.set(WEB_VIEW_CONSTANTS.ATTRIBUTE_SRC, new SrcAttribute(this));
this.attributes.set(WEB_VIEW_CONSTANTS.ATTRIBUTE_HTTPREFERRER, new HttpReferrerAttribute(this));
this.attributes.set(WEB_VIEW_CONSTANTS.ATTRIBUTE_USERAGENT, new UserAgentAttribute(this));
this.attributes.set(WEB_VIEW_CONSTANTS.ATTRIBUTE_NODEINTEGRATION, new BooleanAttribute(WEB_VIEW_CONSTANTS.ATTRIBUTE_NODEINTEGRATION, this));
this.attributes.set(WEB_VIEW_CONSTANTS.ATTRIBUTE_NODEINTEGRATIONINSUBFRAMES, new BooleanAttribute(WEB_VIEW_CONSTANTS.ATTRIBUTE_NODEINTEGRATIONINSUBFRAMES, this));
this.attributes.set(WEB_VIEW_CONSTANTS.ATTRIBUTE_PLUGINS, new BooleanAttribute(WEB_VIEW_CONSTANTS.ATTRIBUTE_PLUGINS, this));
this.attributes.set(WEB_VIEW_CONSTANTS.ATTRIBUTE_DISABLEWEBSECURITY, new BooleanAttribute(WEB_VIEW_CONSTANTS.ATTRIBUTE_DISABLEWEBSECURITY, this));
this.attributes.set(WEB_VIEW_CONSTANTS.ATTRIBUTE_ALLOWPOPUPS, new BooleanAttribute(WEB_VIEW_CONSTANTS.ATTRIBUTE_ALLOWPOPUPS, this));
this.attributes.set(WEB_VIEW_CONSTANTS.ATTRIBUTE_ENABLEREMOTEMODULE, new EnableRemoteModuleAttribute(this));
this.attributes.set(WEB_VIEW_CONSTANTS.ATTRIBUTE_PRELOAD, new PreloadAttribute(this));
this.attributes.set(WEB_VIEW_CONSTANTS.ATTRIBUTE_BLINKFEATURES, new BlinkFeaturesAttribute(this));
this.attributes.set(WEB_VIEW_CONSTANTS.ATTRIBUTE_DISABLEBLINKFEATURES, new DisableBlinkFeaturesAttribute(this));
this.attributes.set(WEB_VIEW_CONSTANTS.ATTRIBUTE_WEBPREFERENCES, new WebPreferencesAttribute(this));
};

View File

@@ -16,9 +16,6 @@ export const enum WEB_VIEW_CONSTANTS {
ATTRIBUTE_DISABLEBLINKFEATURES = 'disableblinkfeatures',
ATTRIBUTE_WEBPREFERENCES = 'webpreferences',
// Internal attribute.
ATTRIBUTE_INTERNALINSTANCEID = 'internalinstanceid',
// Error messages.
ERROR_MSG_ALREADY_NAVIGATED = 'The object has already navigated, so its partition cannot be changed.',
ERROR_MSG_CANNOT_INJECT_SCRIPT = '<webview> = ' + 'Script cannot be injected into content until the page has loaded.',

View File

@@ -10,6 +10,7 @@
import { WEB_VIEW_CONSTANTS } from '@electron/internal/renderer/web-view/web-view-constants';
import { WebViewImpl as IWebViewImpl, webViewImplModule } from '@electron/internal/renderer/web-view/web-view-impl';
import type { SrcAttribute } from '@electron/internal/renderer/web-view/web-view-attributes';
// Return a WebViewElement class that is defined in this context.
const defineWebViewElement = (v8Util: NodeJS.V8UtilBinding, webViewImpl: typeof webViewImplModule) => {
@@ -49,7 +50,7 @@ const defineWebViewElement = (v8Util: NodeJS.V8UtilBinding, webViewImpl: typeof
if (!internal.elementAttached) {
guestViewInternal.registerEvents(internal, internal.viewInstanceId);
internal.elementAttached = true;
internal.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_SRC].parse();
(internal.attributes.get(WEB_VIEW_CONSTANTS.ATTRIBUTE_SRC) as SrcAttribute).parse();
}
}

View File

@@ -5,6 +5,7 @@ import * as ipcRendererUtils from '@electron/internal/renderer/ipc-renderer-inte
import * as guestViewInternal from '@electron/internal/renderer/web-view/guest-view-internal';
import { WEB_VIEW_CONSTANTS } from '@electron/internal/renderer/web-view/web-view-constants';
import { syncMethods, asyncMethods, properties } from '@electron/internal/common/web-view-methods';
import type { WebViewAttribute, PartitionAttribute } from '@electron/internal/renderer/web-view/web-view-attributes';
import { deserialize } from '@electron/internal/common/type-utils';
const { webFrame } = electron;
@@ -33,7 +34,7 @@ export class WebViewImpl {
public internalElement: HTMLIFrameElement
// Replaced in web-view-attributes
public attributes: Record<string, any> = {}
public attributes = new Map<string, WebViewAttribute>();
public setupWebViewAttributes (): void {}
constructor (public webviewNode: HTMLElement) {
@@ -76,7 +77,7 @@ export class WebViewImpl {
}
this.beforeFirstNavigation = true;
this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_PARTITION].validPartitionId = true;
(this.attributes.get(WEB_VIEW_CONSTANTS.ATTRIBUTE_PARTITION) as PartitionAttribute).validPartitionId = true;
// Since attachment swaps a local frame for a remote frame, we need our
// internal iframe element to be local again before we can reattach.
@@ -95,12 +96,12 @@ export class WebViewImpl {
// attribute, if necessary. See BrowserPlugin::UpdateDOMAttribute for more
// details.
handleWebviewAttributeMutation (attributeName: string, oldValue: any, newValue: any) {
if (!this.attributes[attributeName] || this.attributes[attributeName].ignoreMutation) {
if (!this.attributes.has(attributeName) || this.attributes.get(attributeName)!.ignoreMutation) {
return;
}
// Let the changed attribute handle its own mutation
this.attributes[attributeName].handleMutation(oldValue, newValue);
this.attributes.get(attributeName)!.handleMutation(oldValue, newValue);
}
onElementResize () {
@@ -149,7 +150,7 @@ export class WebViewImpl {
// Touching the src attribute triggers a navigation. To avoid
// triggering a page reload on every guest-initiated navigation,
// we do not handle this mutation.
this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_SRC].setValueIgnoreMutation(newValue);
this.attributes.get(WEB_VIEW_CONSTANTS.ATTRIBUTE_SRC)!.setValueIgnoreMutation(newValue);
}
}
@@ -163,7 +164,7 @@ export class WebViewImpl {
}
onAttach (storagePartitionId: number) {
return this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_PARTITION].setValue(storagePartitionId);
return this.attributes.get(WEB_VIEW_CONSTANTS.ATTRIBUTE_PARTITION)!.setValue(storagePartitionId);
}
buildParams () {
@@ -172,10 +173,8 @@ export class WebViewImpl {
userAgentOverride: this.userAgentOverride
};
for (const attributeName in this.attributes) {
if (Object.prototype.hasOwnProperty.call(this.attributes, attributeName)) {
params[attributeName] = this.attributes[attributeName].getValue();
}
for (const [attributeName, attribute] of this.attributes) {
params[attributeName] = attribute.getValue();
}
return params;

View File

@@ -181,7 +181,7 @@ class BrowserWindowProxy {
this.guestId = guestId;
this._location = new LocationProxy(guestId);
ipcRendererInternal.once(`ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_CLOSED_${guestId}`, () => {
ipcRendererInternal.onceMessageFromMain(`ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_CLOSED_${guestId}`, () => {
removeProxy(guestId);
this.closed = true;
});
@@ -281,7 +281,7 @@ export const windowSetup = (
if (contextIsolationEnabled) internalContextBridge.overrideGlobalValueFromIsolatedWorld(['prompt'], window.prompt);
if (!usesNativeWindowOpen || openerId != null) {
ipcRendererInternal.on('ELECTRON_GUEST_WINDOW_POSTMESSAGE', function (
ipcRendererInternal.onMessageFromMain('ELECTRON_GUEST_WINDOW_POSTMESSAGE', function (
_event, sourceId: number, message: any, sourceOrigin: string
) {
// Manually dispatch event instead of using postMessage because we also need to
@@ -336,7 +336,7 @@ export const windowSetup = (
let cachedVisibilityState = isHiddenPage ? 'hidden' : 'visible';
// Subscribe to visibilityState changes.
ipcRendererInternal.on('ELECTRON_GUEST_INSTANCE_VISIBILITY_CHANGE', function (_event, visibilityState: VisibilityState) {
ipcRendererInternal.onMessageFromMain('ELECTRON_GUEST_INSTANCE_VISIBILITY_CHANGE', function (_event, visibilityState: VisibilityState) {
if (cachedVisibilityState !== visibilityState) {
cachedVisibilityState = visibilityState;
document.dispatchEvent(new Event('visibilitychange'));

View File

@@ -1,11 +1,12 @@
{
"name": "electron",
"version": "11.0.0-beta.14",
"version": "11.1.0",
"repository": "https://github.com/electron/electron",
"description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
"devDependencies": {
"@electron/docs-parser": "^0.9.1",
"@electron/docs-parser": "^0.10.0",
"@electron/typescript-definitions": "^8.7.5",
"@octokit/auth-app": "^2.10.0",
"@octokit/rest": "^18.0.3",
"@primer/octicons": "^10.0.0",
"@types/basic-auth": "^1.1.3",

View File

@@ -73,7 +73,6 @@ add_trustedauthclient_to_urlloaderfactory.patch
feat_allow_disabling_blink_scheduler_throttling_per_renderview.patch
accessible_pane_view.patch
fix_use_the_new_mediaplaypause_key_listener_for_internal_chrome.patch
use_electron_resources_in_pdf_util.patch
hack_plugin_response_interceptor_to_point_to_electron.patch
fix_route_mouse_event_navigations_through_the_web_contents_delegate.patch
feat_add_support_for_overriding_the_base_spellchecker_download_url.patch
@@ -93,9 +92,18 @@ crash_allow_disabling_compression_on_linux.patch
allow_setting_secondary_label_via_simplemenumodel.patch
fix_swap_global_proxies_before_initializing_the_windows_proxies.patch
feat_add_streaming-protocol_registry_to_multibuffer_data_source.patch
use_electron_resources_in_icon_reader_service.patch
fix_patch_out_profile_refs_in_accessibility_ui.patch
remove_some_deps_that_do_not_work_on_arm64.patch
fix_check_issecureeventinputenabled_in_constructor_before_setting.patch
skip_atk_toolchain_check.patch
worker_feat_add_hook_to_notify_script_ready.patch
cherry-pick-2f5b8357dca2.patch
fix_use_electron_generated_resources.patch
chore_expose_v8_initialization_isolate_callbacks.patch
crashpad-initialize-logging.patch
fix_properly_honor_printing_page_ranges.patch
cherry-pick-8f5a08079948.patch
cherry-pick-275865e8c237.patch
use_public_apis_to_determine_if_a_font_is_a_system_font_in_mas_build.patch
cherry-pick-47e21abe349a.patch
fix_setparentacessibile_crash_win.patch

View File

@@ -23,10 +23,10 @@ index f63b17435218d0d67bba044da67c1c80015fc996..d0fe24182f2cb48a1333054ce44b6a7f
int32_t world_id) {}
virtual void DidClearWindowObject() {}
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 3b2626c3ef9dab2aedddd09d24901e892605cf01..ca83a9317d0a0136de39aa9af467580e9268cd30 100644
index 72a3bd4837f37bb1bab1f5ca48e90c41a297337f..23ff9cc13aaa97d395983dceb2a27158b2d679a5 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -5032,6 +5032,12 @@ void RenderFrameImpl::DidCreateScriptContext(v8::Local<v8::Context> context,
@@ -5036,6 +5036,12 @@ void RenderFrameImpl::DidCreateScriptContext(v8::Local<v8::Context> context,
observer.DidCreateScriptContext(context, world_id);
}

View File

@@ -14,10 +14,10 @@ when there is code doing that.
This patch reverts the change to fix the crash in Electron.
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc
index c00d6f81db121f57aa6fc0443a9c27daa4973024..8b8121a9291781515d2cea6a832ad0c29b0e846e 100644
index f532469a54a40ef56350063e2472cbf77705d69f..98b5007d5a41cb7b8f71bdd03ccb88d56d2e039e 100644
--- a/third_party/blink/renderer/core/frame/local_frame.cc
+++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -580,10 +580,6 @@ void LocalFrame::DetachImpl(FrameDetachType type) {
@@ -581,10 +581,6 @@ void LocalFrame::DetachImpl(FrameDetachType type) {
}
DCHECK(!view_ || !view_->IsAttached());
@@ -28,7 +28,7 @@ index c00d6f81db121f57aa6fc0443a9c27daa4973024..8b8121a9291781515d2cea6a832ad0c2
if (!Client())
return;
@@ -600,6 +596,10 @@ void LocalFrame::DetachImpl(FrameDetachType type) {
@@ -601,6 +597,10 @@ void LocalFrame::DetachImpl(FrameDetachType type) {
// Notify WindowProxyManager that the frame is closing, since its cleanup ends
// up calling back to LocalFrameClient via WindowProxy.
GetWindowProxyManager()->ClearForClose();

View File

@@ -7,7 +7,7 @@ This exposes a method for obtaining a reference to an isolated world, which is
otherwise not available in the Blink API.
diff --git a/third_party/blink/public/web/web_local_frame.h b/third_party/blink/public/web/web_local_frame.h
index 8dc04d131c188e4b14cd09ab90b5b44a213ddbe3..0db04331e317bbcab1c5d98f55ae76f9e0d48ebd 100644
index 0e8a64cdd2b38058b967b39260e6f5ff4e45147c..166ea5f681eee30f299242d826d97c17f8c6a5a8 100644
--- a/third_party/blink/public/web/web_local_frame.h
+++ b/third_party/blink/public/web/web_local_frame.h
@@ -365,6 +365,8 @@ class WebLocalFrame : public WebFrame {
@@ -38,7 +38,7 @@ index 1bb42b8fc49d420767a2dbe4893d8594b7eda6d1..3f47067c3a4be48155771f0c1d25f614
return BindingSecurity::ShouldAllowAccessToFrame(
CurrentDOMWindow(V8PerIsolateData::MainThreadIsolate()),
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.h b/third_party/blink/renderer/core/frame/web_local_frame_impl.h
index 61e0033bf150bb7f3e28a24e7ac300563447bfa7..415483e3436ee9cf05059ff5195d91e09fac57d4 100644
index 5ff4f6a6d7e6b992c1ae702acd88116d19444986..ef068180f5a9e0f537a2c646212aab9fe4b9c874 100644
--- a/third_party/blink/renderer/core/frame/web_local_frame_impl.h
+++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.h
@@ -169,6 +169,8 @@ class CORE_EXPORT WebLocalFrameImpl final

View File

@@ -9,10 +9,10 @@ potentially prevent a window from being created.
TODO(loc): this patch is currently broken.
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
index 0c57f1004ffab022df99670a13bfc2fadc514437..a0bc43f68cda2d4fe77f9348d0c4402eeb6313c7 100644
index 8aa3723aa317ccd1591196a4929582b61c0d3b5f..b820655013e58a55698450f703dd7230f1d1d250 100644
--- a/content/browser/renderer_host/render_frame_host_impl.cc
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -4911,6 +4911,7 @@ void RenderFrameHostImpl::CreateNewWindow(
@@ -4959,6 +4959,7 @@ void RenderFrameHostImpl::CreateNewWindow(
last_committed_origin_, params->window_container_type,
params->target_url, params->referrer.To<Referrer>(),
params->frame_name, params->disposition, *params->features,
@@ -21,10 +21,10 @@ index 0c57f1004ffab022df99670a13bfc2fadc514437..a0bc43f68cda2d4fe77f9348d0c4402e
&no_javascript_access);
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index c3a2e5c241e36ea1417ea37580d872f0154f714b..06fbfdc22bd7cc11117783fd37bc4562ff490b64 100644
index 26bd3968521cc2713d6350a0fa9265124c7efb00..5234e86d8f10533c4f8c6992a328d521c1850cea 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -3697,9 +3697,9 @@ RenderFrameHostDelegate* WebContentsImpl::CreateNewWindow(
@@ -3712,9 +3712,9 @@ RenderFrameHostDelegate* WebContentsImpl::CreateNewWindow(
}
if (delegate_) {
@@ -66,7 +66,7 @@ index da3aceed75b10087a86bcb8427c241fe647cdcfe..cafd45df059293bc1cf31e1d7b798e67
bool opener_suppressed,
bool* no_javascript_access) {
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
index 27b7e117b531bb370ea948e56b33d1a07eef11c6..9953cc472c04c2dc6ae0f70b64ea2b8d6ac86a05 100644
index 811bc7be6b174e0695beac6ee604ca19e9402739..3b93afa004fb4d56ade2ab16147b42f26e90e3db 100644
--- a/content/public/browser/content_browser_client.h
+++ b/content/public/browser/content_browser_client.h
@@ -153,6 +153,7 @@ class NetworkService;
@@ -77,7 +77,7 @@ index 27b7e117b531bb370ea948e56b33d1a07eef11c6..9953cc472c04c2dc6ae0f70b64ea2b8d
} // namespace network
namespace sandbox {
@@ -868,6 +869,8 @@ class CONTENT_EXPORT ContentBrowserClient {
@@ -876,6 +877,8 @@ class CONTENT_EXPORT ContentBrowserClient {
const std::string& frame_name,
WindowOpenDisposition disposition,
const blink::mojom::WindowFeatures& features,

View File

@@ -0,0 +1,413 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Martin Robinson <mrobinson@igalia.com>
Date: Tue, 20 Oct 2020 09:00:52 +0000
Subject: Mac: Target a11y actions on certain containers to focused or
activedescendant children
When an action is triggered on a container with selectable children and
that container has a focused or activedescendant child, retarget the
action to that child. This fixes an issue where when the VoiceOver
cursor is on a tree with a focused child, triggered context menus would
use the tree as the target element.
menu on a tree instead of a focused child.
Bug: 1114892
Change-Id: Ibe580beed93aeaac54d1dabaee28443b290fd0e2
AX-Relnotes: Fix an issue where VoiceOver would trigger a context
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2466281
Commit-Queue: Martin Robinson <mrobinson@igalia.com>
Reviewed-by: Scott Violet <sky@chromium.org>
Reviewed-by: Dominic Mazzoni <dmazzoni@chromium.org>
Reviewed-by: Nektarios Paisios <nektar@chromium.org>
Cr-Commit-Position: refs/heads/master@{#818831}
diff --git a/content/browser/accessibility/browser_accessibility_cocoa.h b/content/browser/accessibility/browser_accessibility_cocoa.h
index 770c0cb6a4dad8cbf35900311a23a8296407d81d..0ffc8d768299cc5e7f37878fb656c12b028fead9 100644
--- a/content/browser/accessibility/browser_accessibility_cocoa.h
+++ b/content/browser/accessibility/browser_accessibility_cocoa.h
@@ -117,6 +117,14 @@ id AXTextMarkerRangeFrom(id anchor_textmarker, id focus_textmarker);
- (bool)findRowIndex:(BrowserAccessibilityCocoa*)toFind
withCurrentIndex:(int*)currentIndex;
+// Choose the appropriate accessibility object to receive an action depending
+// on the characteristics of this accessibility node.
+- (content::BrowserAccessibility*)actionTarget;
+
+// Return the active descendant for this accessibility object or null if there
+// is no active descendant defined or in the case of an error.
+- (content::BrowserAccessibility*)activeDescendant;
+
// Internally-used property.
@property(nonatomic, readonly) NSPoint origin;
diff --git a/content/browser/accessibility/browser_accessibility_cocoa.mm b/content/browser/accessibility/browser_accessibility_cocoa.mm
index 17aa494d6473866721a8cc5f4c5c646af9307d93..71f927cd35a27dd5f656907dc177fbfe7577d3f0 100644
--- a/content/browser/accessibility/browser_accessibility_cocoa.mm
+++ b/content/browser/accessibility/browser_accessibility_cocoa.mm
@@ -1744,14 +1744,7 @@ - (id)owns {
// supported with VoiceOver.
//
- int activeDescendantId;
- if (!_owner->GetIntAttribute(ax::mojom::IntAttribute::kActivedescendantId,
- &activeDescendantId))
- return nil;
-
- BrowserAccessibilityManager* manager = _owner->manager();
- BrowserAccessibility* activeDescendant =
- manager->GetFromID(activeDescendantId);
+ BrowserAccessibility* activeDescendant = [self activeDescendant];
if (!activeDescendant)
return nil;
@@ -3729,16 +3722,18 @@ - (void)accessibilityPerformAction:(NSString*)action {
return;
// TODO(dmazzoni): Support more actions.
- BrowserAccessibilityManager* manager = _owner->manager();
+ BrowserAccessibility* actionTarget = [self actionTarget];
+ BrowserAccessibilityManager* manager = actionTarget->manager();
if ([action isEqualToString:NSAccessibilityPressAction]) {
- manager->DoDefaultAction(*_owner);
- if (_owner->GetData().GetRestriction() != ax::mojom::Restriction::kNone ||
+ manager->DoDefaultAction(*actionTarget);
+ if (actionTarget->GetData().GetRestriction() !=
+ ax::mojom::Restriction::kNone ||
![self isCheckable])
return;
// Hack: preemptively set the checked state to what it should become,
// otherwise VoiceOver will very likely report the old, incorrect state to
// the user as it requests the value too quickly.
- ui::AXNode* node = _owner->node();
+ ui::AXNode* node = actionTarget->node();
if (!node)
return;
AXNodeData data(node->TakeData()); // Temporarily take data.
@@ -3756,13 +3751,13 @@ - (void)accessibilityPerformAction:(NSString*)action {
}
node->SetData(data); // Set the data back in the node.
} else if ([action isEqualToString:NSAccessibilityShowMenuAction]) {
- manager->ShowContextMenu(*_owner);
+ manager->ShowContextMenu(*actionTarget);
} else if ([action isEqualToString:NSAccessibilityScrollToVisibleAction]) {
- manager->ScrollToMakeVisible(*_owner, gfx::Rect());
+ manager->ScrollToMakeVisible(*actionTarget, gfx::Rect());
} else if ([action isEqualToString:NSAccessibilityIncrementAction]) {
- manager->Increment(*_owner);
+ manager->Increment(*actionTarget);
} else if ([action isEqualToString:NSAccessibilityDecrementAction]) {
- manager->Decrement(*_owner);
+ manager->Decrement(*actionTarget);
}
}
@@ -3871,4 +3866,32 @@ - (BOOL)accessibilityNotifiesWhenDestroyed {
return YES;
}
+// Choose the appropriate accessibility object to receive an action depending
+// on the characteristics of this accessibility node.
+- (BrowserAccessibility*)actionTarget {
+ // When an action is triggered on a container with selectable children and
+ // one of those children is an active descendant or focused, retarget the
+ // action to that child. See https://crbug.com/1114892.
+ if (!ui::IsContainerWithSelectableChildren(_owner->node()->data().role))
+ return _owner;
+
+ if (BrowserAccessibility* activeDescendant = [self activeDescendant])
+ return activeDescendant;
+
+ BrowserAccessibility* focused = _owner->manager()->GetFocus();
+ if (focused && focused->IsDescendantOf(_owner))
+ return focused;
+
+ return _owner;
+}
+
+// Return the active descendant for this accessibility object or null if there
+// is no active descendant defined or in the case of an error.
+- (BrowserAccessibility*)activeDescendant {
+ int activeDescendantId;
+ if (!_owner->GetIntAttribute(ax::mojom::IntAttribute::kActivedescendantId,
+ &activeDescendantId))
+ return nullptr;
+ return _owner->manager()->GetFromID(activeDescendantId);
+}
@end
diff --git a/content/browser/accessibility/browser_accessibility_cocoa_browsertest.mm b/content/browser/accessibility/browser_accessibility_cocoa_browsertest.mm
index 17801b9774813df79e4b944cb0a73535eb4c07c2..6eb2c484ddc479d9cfa566df0b103782264d3af8 100644
--- a/content/browser/accessibility/browser_accessibility_cocoa_browsertest.mm
+++ b/content/browser/accessibility/browser_accessibility_cocoa_browsertest.mm
@@ -44,6 +44,35 @@
return web_contents->GetRootBrowserAccessibilityManager();
}
+ // Trigger a context menu for the provided element without showing it. Returns
+ // the coordinates where the context menu was invoked (calculated based on
+ // the provided element). These coordinates are relative to the RenderView
+ // origin.
+ gfx::Point TriggerContextMenuAndGetMenuLocation(
+ NSAccessibilityElement* element,
+ ContextMenuFilter* filter) {
+ // accessibilityPerformAction is deprecated, but it's still used internally
+ // by AppKit.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ [element accessibilityPerformAction:NSAccessibilityShowMenuAction];
+ filter->Wait();
+
+ UntrustworthyContextMenuParams context_menu_params = filter->get_params();
+ return gfx::Point(context_menu_params.x, context_menu_params.y);
+#pragma clang diagnostic pop
+ }
+
+ void FocusAccessibilityElementAndWaitForFocusChange(
+ NSAccessibilityElement* element) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ [element accessibilitySetValue:@(1)
+ forAttribute:NSAccessibilityFocusedAttribute];
+#pragma clang diagnostic pop
+ WaitForAccessibilityFocusChange();
+ }
+
private:
BrowserAccessibility* FindNodeInSubtree(BrowserAccessibility& node,
ax::mojom::Role role) {
@@ -466,4 +495,165 @@ GURL url(R"HTML(data:text/html,
EXPECT_NSEQ(@"AXRow", [row_nodes[1] role]);
EXPECT_NSEQ(@"row2", [row_nodes[1] descriptionForAccessibility]);
}
+
+IN_PROC_BROWSER_TEST_F(BrowserAccessibilityCocoaBrowserTest,
+ TestTreeContextMenuEvent) {
+ AccessibilityNotificationWaiter waiter(shell()->web_contents(),
+ ui::kAXModeComplete,
+ ax::mojom::Event::kLoadComplete);
+
+ GURL url(R"HTML(data:text/html,
+ <div alt="tree" role="tree">
+ <div tabindex="1" role="treeitem">1</div>
+ <div tabindex="2" role="treeitem">2</div>
+ </div>)HTML");
+
+ EXPECT_TRUE(NavigateToURL(shell(), url));
+ waiter.WaitForNotification();
+
+ BrowserAccessibility* tree = FindNode(ax::mojom::Role::kTree);
+ base::scoped_nsobject<BrowserAccessibilityCocoa> cocoa_tree(
+ [ToBrowserAccessibilityCocoa(tree) retain]);
+
+ NSArray* tree_children = [cocoa_tree children];
+ EXPECT_NSEQ(@"AXRow", [tree_children[0] role]);
+ EXPECT_NSEQ(@"AXRow", [tree_children[1] role]);
+
+ content::RenderProcessHost* render_process_host =
+ shell()->web_contents()->GetMainFrame()->GetProcess();
+ auto menu_filter = base::MakeRefCounted<ContextMenuFilter>(
+ ContextMenuFilter::ShowBehavior::kPreventShow);
+ render_process_host->AddFilter(menu_filter.get());
+
+ gfx::Point tree_point =
+ TriggerContextMenuAndGetMenuLocation(cocoa_tree, menu_filter.get());
+
+ menu_filter->Reset();
+ gfx::Point item_1_point =
+ TriggerContextMenuAndGetMenuLocation(tree_children[1], menu_filter.get());
+ ASSERT_NE(tree_point, item_1_point);
+
+ // Now focus the second child and trigger a context menu on the tree.
+ EXPECT_TRUE(
+ content::ExecuteScript(shell()->web_contents(),
+ "document.body.children[0].children[1].focus();"));
+ WaitForAccessibilityFocusChange();
+
+ // Triggering a context menu on the tree should now trigger the menu
+ // on the focused child.
+ menu_filter->Reset();
+ gfx::Point new_point =
+ TriggerContextMenuAndGetMenuLocation(cocoa_tree, menu_filter.get());
+ ASSERT_EQ(new_point, item_1_point);
+}
+
+IN_PROC_BROWSER_TEST_F(BrowserAccessibilityCocoaBrowserTest,
+ TestEventRetargetingFocus) {
+ AccessibilityNotificationWaiter waiter(shell()->web_contents(),
+ ui::kAXModeComplete,
+ ax::mojom::Event::kLoadComplete);
+
+ GURL url(R"HTML(data:text/html,
+ <div role="tree">
+ <div tabindex="1" role="treeitem">1</div>
+ <div tabindex="2" role="treeitem">2</div>
+ </div>
+ <div role="treegrid">
+ <div tabindex="1" role="treeitem">1</div>
+ <div tabindex="2" role="treeitem">2</div>
+ </div>
+ <div role="tablist">
+ <div tabindex="1" role="tab">1</div>
+ <div tabindex="2" role="tab">2</div>
+ </div>
+ <div role="table">
+ <div tabindex="1" role="row">1</div>
+ <div tabindex="2" role="row">2</div>
+ </div>
+ <div role="banner">
+ <div tabindex="1" role="link">1</div>
+ <div tabindex="2" role="link">2</div>
+ </div>)HTML");
+
+ EXPECT_TRUE(NavigateToURL(shell(), url));
+ waiter.WaitForNotification();
+
+ std::pair<ax::mojom::Role, bool> tests[] = {
+ std::make_pair(ax::mojom::Role::kTree, true),
+ std::make_pair(ax::mojom::Role::kTreeGrid, true),
+ std::make_pair(ax::mojom::Role::kTabList, true),
+ std::make_pair(ax::mojom::Role::kTable, false),
+ std::make_pair(ax::mojom::Role::kBanner, false),
+ };
+
+ for (auto& test : tests) {
+ base::scoped_nsobject<BrowserAccessibilityCocoa> parent(
+ [ToBrowserAccessibilityCocoa(FindNode(test.first)) retain]);
+ BrowserAccessibilityCocoa* child = [parent children][1];
+
+ EXPECT_NE(nullptr, parent.get());
+ EXPECT_EQ([child owner], [child actionTarget]);
+ EXPECT_EQ([parent owner], [parent actionTarget]);
+
+ FocusAccessibilityElementAndWaitForFocusChange(child);
+ ASSERT_EQ(test.second, [parent actionTarget] == [child owner]);
+ }
+}
+
+IN_PROC_BROWSER_TEST_F(BrowserAccessibilityCocoaBrowserTest,
+ TestEventRetargetingActiveDescendant) {
+ AccessibilityNotificationWaiter waiter(shell()->web_contents(),
+ ui::kAXModeComplete,
+ ax::mojom::Event::kLoadComplete);
+
+ GURL url(R"HTML(data:text/html,
+ <div role="tree" aria-activedescendant="tree-child">
+ <div tabindex="1" role="treeitem">1</div>
+ <div id="tree-child" tabindex="2" role="treeitem">2</div>
+ </div>
+ <div role="treegrid" aria-activedescendant="treegrid-child">
+ <div tabindex="1" role="treeitem">1</div>
+ <div id="treegrid-child" tabindex="2" role="treeitem">2</div>
+ </div>
+ <div role="tablist" aria-activedescendant="tablist-child">
+ <div tabindex="1" role="tab">1</div>
+ <div id="tablist-child" tabindex="2" role="tab">2</div>
+ </div>
+ <div role="table" aria-activedescendant="table-child">
+ <div tabindex="1" role="row">1</div>
+ <div id="table-child" tabindex="2" role="row">2</div>
+ </div>
+ <div role="banner" aria-activedescendant="banner-child">
+ <div tabindex="1" role="link">1</div>
+ <div id="banner-child" tabindex="2" role="link">2</div>
+ </div>)HTML");
+
+ EXPECT_TRUE(NavigateToURL(shell(), url));
+ waiter.WaitForNotification();
+
+ std::pair<ax::mojom::Role, bool> tests[] = {
+ std::make_pair(ax::mojom::Role::kTree, true),
+ std::make_pair(ax::mojom::Role::kTreeGrid, true),
+ std::make_pair(ax::mojom::Role::kTabList, true),
+ std::make_pair(ax::mojom::Role::kTable, false),
+ std::make_pair(ax::mojom::Role::kBanner, false),
+ };
+
+ for (auto& test : tests) {
+ base::scoped_nsobject<BrowserAccessibilityCocoa> parent(
+ [ToBrowserAccessibilityCocoa(FindNode(test.first)) retain]);
+ BrowserAccessibilityCocoa* first_child = [parent children][0];
+ BrowserAccessibilityCocoa* second_child = [parent children][1];
+
+ EXPECT_NE(nullptr, parent.get());
+ EXPECT_EQ([second_child owner], [second_child actionTarget]);
+ EXPECT_EQ(test.second, [second_child owner] == [parent actionTarget]);
+
+ // aria-activedescendant should take priority of focus for determining
+ // if an object is the action target.
+ FocusAccessibilityElementAndWaitForFocusChange(first_child);
+ EXPECT_EQ(test.second, [second_child owner] == [parent actionTarget]);
+ }
+}
+
} // namespace content
diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc
index 47161f98b2fcdacece578cde50141860d2ab0a40..a8f988b8465c420224979d805baf454483e49134 100644
--- a/content/public/test/browser_test_utils.cc
+++ b/content/public/test/browser_test_utils.cc
@@ -3220,10 +3220,11 @@ void VerifyStaleContentOnFrameEviction(
#endif // defined(USE_AURA)
-ContextMenuFilter::ContextMenuFilter()
+ContextMenuFilter::ContextMenuFilter(ShowBehavior behavior)
: BrowserMessageFilter(FrameMsgStart),
run_loop_(std::make_unique<base::RunLoop>()),
- quit_closure_(run_loop_->QuitClosure()) {}
+ quit_closure_(run_loop_->QuitClosure()),
+ show_behavior_(behavior) {}
bool ContextMenuFilter::OnMessageReceived(const IPC::Message& message) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -3234,6 +3235,9 @@ bool ContextMenuFilter::OnMessageReceived(const IPC::Message& message) {
GetUIThreadTaskRunner({})->PostTask(
FROM_HERE,
base::BindOnce(&ContextMenuFilter::OnContextMenu, this, menu_params));
+ // Returning true here blocks the default action for this message, which
+ // means that the menu will not be shown.
+ return show_behavior_ == ShowBehavior::kPreventShow;
}
return false;
}
@@ -3244,6 +3248,12 @@ void ContextMenuFilter::Wait() {
run_loop_ = nullptr;
}
+void ContextMenuFilter::Reset() {
+ ASSERT_EQ(run_loop_, nullptr);
+ run_loop_ = std::make_unique<base::RunLoop>();
+ quit_closure_ = run_loop_->QuitClosure();
+}
+
ContextMenuFilter::~ContextMenuFilter() = default;
void ContextMenuFilter::OnContextMenu(
diff --git a/content/public/test/browser_test_utils.h b/content/public/test/browser_test_utils.h
index f68d423999ff711b46b7fe9d718163158e1d5223..3568bcceee9867db634306d36e3281d32450ea0a 100644
--- a/content/public/test/browser_test_utils.h
+++ b/content/public/test/browser_test_utils.h
@@ -1688,10 +1688,15 @@ void VerifyStaleContentOnFrameEviction(
// sent by the renderer.
class ContextMenuFilter : public content::BrowserMessageFilter {
public:
- ContextMenuFilter();
+ // Whether or not the ContextMenu should be prevented from performing
+ // its default action, preventing the context menu from showing.
+ enum ShowBehavior { kShow, kPreventShow };
+
+ explicit ContextMenuFilter(ShowBehavior behavior = ShowBehavior::kShow);
bool OnMessageReceived(const IPC::Message& message) override;
void Wait();
+ void Reset();
content::UntrustworthyContextMenuParams get_params() { return last_params_; }
@@ -1703,6 +1708,7 @@ class ContextMenuFilter : public content::BrowserMessageFilter {
std::unique_ptr<base::RunLoop> run_loop_;
base::OnceClosure quit_closure_;
content::UntrustworthyContextMenuParams last_params_;
+ const ShowBehavior show_behavior_;
DISALLOW_COPY_AND_ASSIGN(ContextMenuFilter);
};

View File

@@ -0,0 +1,330 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Martin Robinson <mrobinson@igalia.com>
Date: Mon, 12 Oct 2020 08:50:01 +0000
Subject: Expose AXIndex for accessibility TreeGrid and Tree rows on Mac
VoiceOver requires each row to have in index in order to announce it. We
expose this property for rows which either have role=row or
role=treeitem.
AX-Relnotes: Fix an issue where ARIA TreeGrid and Tree rows were not announced.
Bug: 1115267
Change-Id: Ia8917044a510b2467aa2480dff54fe226b90c391
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2426569
Auto-Submit: Martin Robinson <mrobinson@igalia.com>
Commit-Queue: Martin Robinson <mrobinson@igalia.com>
Reviewed-by: Dominic Mazzoni <dmazzoni@chromium.org>
Reviewed-by: Abigail Klein <abigailbklein@google.com>
Cr-Commit-Position: refs/heads/master@{#816089}
diff --git a/content/browser/accessibility/browser_accessibility_cocoa.h b/content/browser/accessibility/browser_accessibility_cocoa.h
index 318af1ec3a11ee53a1146909f76c9cea7f78be1e..770c0cb6a4dad8cbf35900311a23a8296407d81d 100644
--- a/content/browser/accessibility/browser_accessibility_cocoa.h
+++ b/content/browser/accessibility/browser_accessibility_cocoa.h
@@ -112,6 +112,11 @@ id AXTextMarkerRangeFrom(id anchor_textmarker, id focus_textmarker);
- (NSString*)valueForRange:(NSRange)range;
- (NSAttributedString*)attributedValueForRange:(NSRange)range;
+// Find the index of the given row among the descendants of this object
+// or return nil if this row is not found.
+- (bool)findRowIndex:(BrowserAccessibilityCocoa*)toFind
+ withCurrentIndex:(int*)currentIndex;
+
// Internally-used property.
@property(nonatomic, readonly) NSPoint origin;
@@ -150,6 +155,7 @@ id AXTextMarkerRangeFrom(id anchor_textmarker, id focus_textmarker);
@property(nonatomic, readonly, getter=isIgnored) BOOL ignored;
// Index of a row, column, or tree item.
@property(nonatomic, readonly) NSNumber* index;
+@property(nonatomic, readonly) NSNumber* treeItemRowIndex;
#ifndef MAS_BUILD
@property(nonatomic, readonly) NSNumber* insertionPointLineNumber;
#endif
diff --git a/content/browser/accessibility/browser_accessibility_cocoa.mm b/content/browser/accessibility/browser_accessibility_cocoa.mm
index 96b6fa030c2a36ab5c4217ad19f0bfe4d5212bb8..3abd9933ab325bda6cb486a41fd6c8b246aa8e71 100644
--- a/content/browser/accessibility/browser_accessibility_cocoa.mm
+++ b/content/browser/accessibility/browser_accessibility_cocoa.mm
@@ -1497,7 +1497,10 @@ - (id)highestEditableAncestor {
- (NSNumber*)index {
if (![self instanceActive])
return nil;
- if ([self internalRole] == ax::mojom::Role::kColumn) {
+
+ if ([self internalRole] == ax::mojom::Role::kTreeItem) {
+ return [self treeItemRowIndex];
+ } else if ([self internalRole] == ax::mojom::Role::kColumn) {
DCHECK(_owner->node());
base::Optional<int> col_index = *_owner->node()->GetTableColColIndex();
if (col_index)
@@ -1512,6 +1515,55 @@ - (NSNumber*)index {
return nil;
}
+- (NSNumber*)treeItemRowIndex {
+ if (![self instanceActive])
+ return nil;
+
+ DCHECK([self internalRole] == ax::mojom::Role::kTreeItem);
+ DCHECK([[self role] isEqualToString:NSAccessibilityRowRole]);
+
+ // First find an ancestor that establishes this tree or treegrid. We
+ // will search in this ancestor to calculate our row index.
+ BrowserAccessibility* container = [self owner]->PlatformGetParent();
+ while (container && container->GetRole() != ax::mojom::Role::kTree &&
+ container->GetRole() != ax::mojom::Role::kTreeGrid) {
+ container = container->PlatformGetParent();
+ }
+ if (!container)
+ return nil;
+
+ const BrowserAccessibilityCocoa* cocoaContainer =
+ ToBrowserAccessibilityCocoa(container);
+ int currentIndex = 0;
+ if ([cocoaContainer findRowIndex:self withCurrentIndex:&currentIndex]) {
+ return @(currentIndex);
+ }
+
+ return nil;
+}
+
+- (bool)findRowIndex:(BrowserAccessibilityCocoa*)toFind
+ withCurrentIndex:(int*)currentIndex {
+ if (![self instanceActive])
+ return false;
+
+ DCHECK([[toFind role] isEqualToString:NSAccessibilityRowRole]);
+ for (BrowserAccessibilityCocoa* childToCheck in [self children]) {
+ if ([toFind isEqual:childToCheck]) {
+ return true;
+ }
+
+ if ([[childToCheck role] isEqualToString:NSAccessibilityRowRole]) {
+ ++(*currentIndex);
+ }
+
+ if ([childToCheck findRowIndex:toFind withCurrentIndex:currentIndex]) {
+ return true;
+ }
+ }
+
+ return false;
+}
#ifndef MAS_BUILD
- (NSNumber*)insertionPointLineNumber {
@@ -3441,12 +3493,15 @@ - (NSArray*)accessibilityAttributeNames {
container = container->PlatformGetParent();
if ([subrole isEqualToString:NSAccessibilityOutlineRowSubrole] ||
(container && container->GetRole() == ax::mojom::Role::kTreeGrid)) {
+ // clang-format off
[ret addObjectsFromArray:@[
- NSAccessibilityDisclosingAttribute,
+ NSAccessibilityIndexAttribute,
NSAccessibilityDisclosedByRowAttribute,
- NSAccessibilityDisclosureLevelAttribute,
- NSAccessibilityDisclosedRowsAttribute
+ NSAccessibilityDisclosedRowsAttribute,
+ NSAccessibilityDisclosingAttribute,
+ NSAccessibilityDisclosureLevelAttribute
]];
+ // clang-format on
} else {
[ret addObjectsFromArray:@[ NSAccessibilityIndexAttribute ]];
}
diff --git a/content/test/data/accessibility/aria/aria-level-expected-mac.txt b/content/test/data/accessibility/aria/aria-level-expected-mac.txt
index 2977dc82f7c894b8496158fb51dc2665939d0d9d..19b7c2b3f131a41f9e49dc4a8db875efe53e3cdb 100644
--- a/content/test/data/accessibility/aria/aria-level-expected-mac.txt
+++ b/content/test/data/accessibility/aria/aria-level-expected-mac.txt
@@ -14,21 +14,21 @@ AXWebArea
++AXHeading AXTitle='Level 5' AXValue=5
++++AXStaticText AXValue='Level 5'
++AXOutline
-++++AXRow AXSubrole=AXOutlineRow AXDisclosing=1 AXDisclosureLevel=0 AXTitle='Tree item at level 1'
+++++AXRow AXSubrole=AXOutlineRow AXDisclosing=1 AXDisclosureLevel=0 AXIndex=0 AXTitle='Tree item at level 1'
++++++AXStaticText AXValue='Tree item at level 1'
++++++AXGroup
-++++++++AXRow AXSubrole=AXOutlineRow AXDisclosing=0 AXDisclosureLevel=1 AXTitle='Tree item at level 2'
+++++++++AXRow AXSubrole=AXOutlineRow AXDisclosing=0 AXDisclosureLevel=1 AXIndex=1 AXTitle='Tree item at level 2'
++++++++++AXStaticText AXValue='Tree item at level 2'
-++++AXRow AXSubrole=AXOutlineRow AXDisclosing=0 AXDisclosureLevel=2 AXTitle='Tree item at level 3'
+++++AXRow AXSubrole=AXOutlineRow AXDisclosing=0 AXDisclosureLevel=2 AXIndex=2 AXTitle='Tree item at level 3'
++++++AXStaticText AXValue='Tree item at level 3'
++AXTable
-++++AXRow AXDisclosureLevel=0
+++++AXRow AXDisclosureLevel=0 AXIndex=0
++++++AXCell
++++++++AXStaticText AXValue='Cell at level 1'
-++++AXRow AXDisclosureLevel=1
+++++AXRow AXDisclosureLevel=1 AXIndex=1
++++++AXCell
++++++++AXStaticText AXValue='Cell at level 2'
-++++AXColumn
+++++AXColumn AXIndex=0
++++++AXCell
++++++++AXStaticText AXValue='Cell at level 1'
++++++AXCell
diff --git a/content/test/data/accessibility/aria/aria-level.html b/content/test/data/accessibility/aria/aria-level.html
index 9c499edadbfb8dfa3c07d5cf1d9e5f48349a48a5..b7aabab3a3232985c597cb2362184c0a436e8475 100644
--- a/content/test/data/accessibility/aria/aria-level.html
+++ b/content/test/data/accessibility/aria/aria-level.html
@@ -3,6 +3,7 @@
@MAC-ALLOW:AXSubrole=AXOutlineRow
@MAC-ALLOW:AXDisclosing*
@MAC-ALLOW:AXDisclosureLevel*
+@MAC-ALLOW:AXIndex*
@WIN-ALLOW:level:*
@WIN-ALLOW:EXPANDED
@WIN-DENY:name=''
diff --git a/content/test/data/accessibility/aria/aria-tree-discontinuous-expected-mac.txt b/content/test/data/accessibility/aria/aria-tree-discontinuous-expected-mac.txt
index 3f2259665df8fbc291a848e5ada5ee02c37eb8cd..48afda07b5d020f0972a9aaf9ccffcfb76fd3857 100644
--- a/content/test/data/accessibility/aria/aria-tree-discontinuous-expected-mac.txt
+++ b/content/test/data/accessibility/aria/aria-tree-discontinuous-expected-mac.txt
@@ -1,7 +1,7 @@
AXWebArea
++AXOutline AXARIASetSize=2
-++++AXRow AXARIAPosInSet=1 AXARIASetSize=2 AXTitle='card content'
+++++AXRow AXARIAPosInSet=1 AXARIASetSize=2 AXIndex=0 AXTitle='card content'
++++++AXStaticText AXValue='card content'
++++AXGroup
-++++AXRow AXARIAPosInSet=2 AXARIASetSize=2 AXTitle='card content'
+++++AXRow AXARIAPosInSet=2 AXARIASetSize=2 AXIndex=1 AXTitle='card content'
++++++AXStaticText AXValue='card content'
diff --git a/content/test/data/accessibility/aria/aria-tree-discontinuous.html b/content/test/data/accessibility/aria/aria-tree-discontinuous.html
index c0ef927e92216957f9369afedb07c068c0970025..f14ce533208511655e6c86f934661e1adec083ba 100644
--- a/content/test/data/accessibility/aria/aria-tree-discontinuous.html
+++ b/content/test/data/accessibility/aria/aria-tree-discontinuous.html
@@ -1,6 +1,7 @@
<!--
@MAC-ALLOW:AXARIASetSize
@MAC-ALLOW:AXARIAPosInSet
+@MAC-ALLOW:AXIndex
@WIN-ALLOW:setsize*
@WIN-ALLOW:posinset*
@UIA-WIN-ALLOW:SizeOfSet*
diff --git a/content/test/data/accessibility/aria/aria-tree-expected-mac.txt b/content/test/data/accessibility/aria/aria-tree-expected-mac.txt
index 5d40b45374b4cc3685eff0146d34e3f814216af8..2580c407cf97626dff52f6e883b5ee8c1c753dc8 100644
--- a/content/test/data/accessibility/aria/aria-tree-expected-mac.txt
+++ b/content/test/data/accessibility/aria/aria-tree-expected-mac.txt
@@ -1,22 +1,22 @@
AXWebArea
++AXOutline AXARIASetSize=2
-++++AXRow AXARIAPosInSet=1 AXARIASetSize=2 AXTitle='Animals' AXValue=2
+++++AXRow AXARIAPosInSet=1 AXARIASetSize=2 AXIndex=0 AXTitle='Animals' AXValue=2
++++++AXLink AXDescription='Animals'
++++++++AXStaticText AXValue='Animals'
++++++AXGroup AXARIASetSize=2
-++++++++AXRow AXARIAPosInSet=1 AXARIASetSize=2 AXTitle='Domesticated'
+++++++++AXRow AXARIAPosInSet=1 AXARIASetSize=2 AXIndex=1 AXTitle='Domesticated'
++++++++++AXLink AXDescription='Domesticated'
++++++++++++AXStaticText AXValue='Domesticated'
++++++++++AXGroup AXARIASetSize=2
-++++++++++++AXRow AXARIAPosInSet=1 AXARIASetSize=2 AXTitle='Dog' AXValue=1
+++++++++++++AXRow AXARIAPosInSet=1 AXARIASetSize=2 AXIndex=2 AXTitle='Dog' AXValue=1
++++++++++++++AXLink AXDescription='Dog'
++++++++++++++++AXStaticText AXValue='Dog'
-++++++++++++AXRow AXARIAPosInSet=2 AXARIASetSize=2 AXTitle='Cat' AXValue=0
+++++++++++++AXRow AXARIAPosInSet=2 AXARIASetSize=2 AXIndex=3 AXTitle='Cat' AXValue=0
++++++++++++++AXLink AXDescription='Cat'
++++++++++++++++AXStaticText AXValue='Cat'
-++++++++AXRow AXARIAPosInSet=2 AXARIASetSize=2 AXTitle='Wild'
+++++++++AXRow AXARIAPosInSet=2 AXARIASetSize=2 AXIndex=4 AXTitle='Wild'
++++++++++AXLink AXDescription='Wild'
++++++++++++AXStaticText AXValue='Wild'
-++++AXRow AXARIAPosInSet=2 AXARIASetSize=2 AXTitle='Plants'
+++++AXRow AXARIAPosInSet=2 AXARIASetSize=2 AXIndex=5 AXTitle='Plants'
++++++AXLink AXDescription='Plants'
++++++++AXStaticText AXValue='Plants'
diff --git a/content/test/data/accessibility/aria/aria-tree.html b/content/test/data/accessibility/aria/aria-tree.html
index f2974e876b83e48d277a54d2bcf92319dcc89cfe..7b984675b97b09cb629d81d6835b5616c7b8873f 100644
--- a/content/test/data/accessibility/aria/aria-tree.html
+++ b/content/test/data/accessibility/aria/aria-tree.html
@@ -1,4 +1,5 @@
<!--
+@MAC-ALLOW:AXIndex
@MAC-ALLOW:AXARIASetSize
@MAC-ALLOW:AXARIAPosInSet
@WIN-ALLOW:setsize*
diff --git a/content/test/data/accessibility/aria/aria-treegrid-expected-mac.txt b/content/test/data/accessibility/aria/aria-treegrid-expected-mac.txt
index 3c28472ddfe697d88e3fba3fe0fcff5853e0d1d5..d4d0a70fd610994b19641ddd69a31bb56574a55e 100644
--- a/content/test/data/accessibility/aria/aria-treegrid-expected-mac.txt
+++ b/content/test/data/accessibility/aria/aria-treegrid-expected-mac.txt
@@ -1,12 +1,12 @@
AXWebArea
++AXTable
-++++AXRow AXDisclosureLevel=0
+++++AXRow AXDisclosureLevel=0 AXIndex=0
++++++AXCell
++++++++AXStaticText AXValue='Cell at level 1'
-++++AXRow AXDisclosureLevel=1
+++++AXRow AXDisclosureLevel=1 AXIndex=1
++++++AXCell
++++++++AXStaticText AXValue='Cell at level 2'
-++++AXColumn
+++++AXColumn AXIndex=0
++++++AXCell
++++++++AXStaticText AXValue='Cell at level 1'
++++++AXCell
@@ -14,10 +14,10 @@ AXWebArea
++++AXGroup
++AXTable
++++AXGroup
-++++++AXRow AXDisclosureLevel=0
+++++++AXRow AXDisclosureLevel=0 AXIndex=0
++++++++AXCell
++++++++++AXStaticText AXValue='Cell at level 1'
-++++AXColumn
+++++AXColumn AXIndex=0
++++++AXCell
++++++++AXStaticText AXValue='Cell at level 1'
++++AXGroup
diff --git a/content/test/data/accessibility/aria/aria-treegrid.html b/content/test/data/accessibility/aria/aria-treegrid.html
index f8aefe163b900596152999b845bd856b44a05df2..01b74aa99db9304248e94273bbc3d73a170d8539 100644
--- a/content/test/data/accessibility/aria/aria-treegrid.html
+++ b/content/test/data/accessibility/aria/aria-treegrid.html
@@ -1,5 +1,6 @@
<!--
@BLINK-ALLOW:hierarchicalLevel*
+@MAC-ALLOW:AXIndex
@MAC-ALLOW:AXRole=*
@MAC-ALLOW:AXDisclosureLevel*
@WIN-ALLOW:xml-roles:*
diff --git a/content/test/data/accessibility/aria/aria-treeitem-nested-in-lists-expected-mac.txt b/content/test/data/accessibility/aria/aria-treeitem-nested-in-lists-expected-mac.txt
index 0b7abc24fd7b3acec0a44244c7f975075282e887..523458d38299a7599060c1fda8a8c301acc4304f 100644
--- a/content/test/data/accessibility/aria/aria-treeitem-nested-in-lists-expected-mac.txt
+++ b/content/test/data/accessibility/aria/aria-treeitem-nested-in-lists-expected-mac.txt
@@ -1,17 +1,17 @@
AXWebArea AXRoleDescription='HTML content'
++AXOutline AXARIASetSize=5 AXRoleDescription='outline'
++++AXGroup AXRoleDescription='group'
-++++++AXRow AXARIAPosInSet=2 AXARIASetSize=5 AXRoleDescription='row' AXTitle='treeitem 2 of 5, level 1'
+++++++AXRow AXARIAPosInSet=2 AXARIASetSize=5 AXIndex=0 AXRoleDescription='row' AXTitle='treeitem 2 of 5, level 1'
++++++++AXStaticText AXRoleDescription='text' AXValue='treeitem 2 of 5, level 1'
++++AXGroup AXRoleDescription='group'
-++++++AXRow AXARIAPosInSet=3 AXARIASetSize=5 AXRoleDescription='row' AXTitle='treeitem 3 of 5, level 1'
+++++++AXRow AXARIAPosInSet=3 AXARIASetSize=5 AXIndex=1 AXRoleDescription='row' AXTitle='treeitem 3 of 5, level 1'
++++++++AXStaticText AXRoleDescription='text' AXValue='treeitem 3 of 5, level 1'
++++AXGroup AXRoleDescription='group'
-++++++AXRow AXARIAPosInSet=1 AXARIASetSize=2 AXRoleDescription='row' AXTitle='treeitem 1 of 2, level 2'
+++++++AXRow AXARIAPosInSet=1 AXARIASetSize=2 AXIndex=2 AXRoleDescription='row' AXTitle='treeitem 1 of 2, level 2'
++++++++AXStaticText AXRoleDescription='text' AXValue='treeitem 1 of 2, level 2'
++++AXGroup AXRoleDescription='group'
-++++++AXRow AXARIAPosInSet=1 AXARIASetSize=1 AXRoleDescription='row' AXTitle='treeitem 1 of 1, level 3'
+++++++AXRow AXARIAPosInSet=1 AXARIASetSize=1 AXIndex=3 AXRoleDescription='row' AXTitle='treeitem 1 of 1, level 3'
++++++++AXStaticText AXRoleDescription='text' AXValue='treeitem 1 of 1, level 3'
++++AXGroup AXRoleDescription='group'
-++++++AXRow AXARIAPosInSet=2 AXARIASetSize=2 AXRoleDescription='row' AXTitle='treeitem 2 of 2, level 2'
+++++++AXRow AXARIAPosInSet=2 AXARIASetSize=2 AXIndex=4 AXRoleDescription='row' AXTitle='treeitem 2 of 2, level 2'
++++++++AXStaticText AXRoleDescription='text' AXValue='treeitem 2 of 2, level 2'
diff --git a/content/test/data/accessibility/aria/aria-treeitem-nested-in-lists.html b/content/test/data/accessibility/aria/aria-treeitem-nested-in-lists.html
index f3794bbad09a43a279fef12b5bc4f63e1c70341f..8294fb11adb63a801117e4439c8b43c48dc8ce59 100644
--- a/content/test/data/accessibility/aria/aria-treeitem-nested-in-lists.html
+++ b/content/test/data/accessibility/aria/aria-treeitem-nested-in-lists.html
@@ -4,6 +4,7 @@
@MAC-ALLOW:AXARIAPosInSet*
@MAC-DENY:AXARIASetSize=0
@MAC-DENY:AXARIAPosInSet=0
+@MAC-ALLOW:AXIndex
@WIN-ALLOW:xml-roles*
@WIN-ALLOW:level*
@WIN-ALLOW:setsize*

View File

@@ -0,0 +1,723 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Martin Robinson <mrobinson@igalia.com>
Date: Thu, 19 Nov 2020 21:28:45 +0000
Subject: Improve AXTextStateChangeType in
NSAccessibilitySelectedTextChangedNotification
When setting the AXTextStateChangeType key in the user info data
structure for the notification, use AXTextStateChangeTypeSelectionMove
when we detect a focus change. This causes VoiceOver to properly
announce the label and type of form entries when their contents are
selected due to focus changes.
type are now announced.
Bug: 1127421
Change-Id: I42d66ad60fbcba7c8c34396fdbc3f6e0c739d1a2
AX-Relnotes: When focus changes moves to form inputs, the input label and
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2512913
Commit-Queue: Martin Robinson <mrobinson@igalia.com>
Reviewed-by: Nektarios Paisios <nektar@chromium.org>
Cr-Commit-Position: refs/heads/master@{#829380}
diff --git a/content/browser/accessibility/accessibility_event_recorder_mac.mm b/content/browser/accessibility/accessibility_event_recorder_mac.mm
index fcb93bab1c94f792dc9868e895a0e562d1fd8449..1e415ee8f849b67c098e49572c9d4e890ed44d04 100644
--- a/content/browser/accessibility/accessibility_event_recorder_mac.mm
+++ b/content/browser/accessibility/accessibility_event_recorder_mac.mm
@@ -6,6 +6,7 @@
#import <Cocoa/Cocoa.h>
+#include <algorithm>
#include <string>
#include "base/logging.h"
@@ -15,6 +16,7 @@
#include "base/strings/sys_string_conversions.h"
#include "content/browser/accessibility/accessibility_tools_utils_mac.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
+#include "ui/accessibility/platform/ax_private_webkit_constants_mac.h"
namespace content {
@@ -28,7 +30,11 @@
~AccessibilityEventRecorderMac() override;
// Callback executed every time we receive an event notification.
- void EventReceived(AXUIElementRef element, CFStringRef notification);
+ void EventReceived(AXUIElementRef element,
+ CFStringRef notification,
+ CFDictionaryRef user_info);
+ static std::string SerializeTextSelectionChangedProperties(
+ CFDictionaryRef user_info);
private:
// Add one notification to the list of notifications monitored by our
@@ -54,10 +60,11 @@
static void EventReceivedThunk(AXObserverRef observer_ref,
AXUIElementRef element,
CFStringRef notification,
+ CFDictionaryRef user_info,
void* refcon) {
AccessibilityEventRecorderMac* this_ptr =
static_cast<AccessibilityEventRecorderMac*>(refcon);
- this_ptr->EventReceived(element, notification);
+ this_ptr->EventReceived(element, notification, user_info);
}
// static
@@ -95,8 +102,9 @@ static void EventReceivedThunk(AXObserverRef observer_ref,
base::ProcessId pid,
AXUIElementRef node)
: AccessibilityEventRecorder(manager), observer_run_loop_source_(NULL) {
- if (kAXErrorSuccess != AXObserverCreate(pid, EventReceivedThunk,
- observer_ref_.InitializeInto())) {
+ if (kAXErrorSuccess !=
+ AXObserverCreateWithInfoCallback(pid, EventReceivedThunk,
+ observer_ref_.InitializeInto())) {
LOG(FATAL) << "Failed to create AXObserverRef";
}
@@ -157,7 +165,8 @@ static void EventReceivedThunk(AXObserverRef observer_ref,
}
void AccessibilityEventRecorderMac::EventReceived(AXUIElementRef element,
- CFStringRef notification) {
+ CFStringRef notification,
+ CFDictionaryRef user_info) {
std::string notification_str = base::SysCFStringRefToUTF8(notification);
std::string role = GetAXAttributeValue(element, NSAccessibilityRoleAttribute);
if (role.empty())
@@ -180,7 +189,49 @@ static void EventReceivedThunk(AXObserverRef observer_ref,
if (!value.empty())
log += base::StringPrintf(" AXValue=\"%s\"", value.c_str());
+ if (notification_str ==
+ base::SysNSStringToUTF8(NSAccessibilitySelectedTextChangedNotification))
+ log += " " + SerializeTextSelectionChangedProperties(user_info);
+
OnEvent(log);
}
+std::string
+AccessibilityEventRecorderMac::SerializeTextSelectionChangedProperties(
+ CFDictionaryRef user_info) {
+ std::vector<std::string> serialized_info;
+ CFDictionaryApplyFunction(
+ user_info,
+ [](const void* raw_key, const void* raw_value, void* context) {
+ auto* key = static_cast<NSString*>(raw_key);
+ auto* value = static_cast<NSObject*>(raw_value);
+ auto* serialized_info = static_cast<std::vector<std::string>*>(context);
+ std::string value_string;
+ if ([key isEqual:ui::NSAccessibilityTextStateChangeTypeKey]) {
+ value_string = ToString(static_cast<ui::AXTextStateChangeType>(
+ [static_cast<NSNumber*>(value) intValue]));
+ } else if ([key isEqual:ui::NSAccessibilityTextSelectionDirection]) {
+ value_string = ToString(static_cast<ui::AXTextSelectionDirection>(
+ [static_cast<NSNumber*>(value) intValue]));
+ } else if ([key isEqual:ui::NSAccessibilityTextSelectionGranularity]) {
+ value_string = ToString(static_cast<ui::AXTextSelectionGranularity>(
+ [static_cast<NSNumber*>(value) intValue]));
+ } else if ([key isEqual:ui::NSAccessibilityTextEditType]) {
+ value_string = ToString(static_cast<ui::AXTextEditType>(
+ [static_cast<NSNumber*>(value) intValue]));
+ } else {
+ return;
+ }
+ serialized_info->push_back(base::SysNSStringToUTF8(key) + "=" +
+ value_string);
+ },
+ &serialized_info);
+
+ // Always sort the info so that we don't depend on CFDictionary for
+ // consistent output ordering.
+ std::sort(serialized_info.begin(), serialized_info.end());
+
+ return base::JoinString(serialized_info, " ");
+}
+
} // namespace content
diff --git a/content/browser/accessibility/browser_accessibility_manager_mac.h b/content/browser/accessibility/browser_accessibility_manager_mac.h
index b4043f56341e72bcf75ef71c56cb8cf9fc442579..925bfe1ea191ab846805fdbff1b0314e779b1c9e 100644
--- a/content/browser/accessibility/browser_accessibility_manager_mac.h
+++ b/content/browser/accessibility/browser_accessibility_manager_mac.h
@@ -54,7 +54,8 @@ class CONTENT_EXPORT BrowserAccessibilityManagerMac
const std::vector<Change>& changes) override;
// Returns an autoreleased object.
- NSDictionary* GetUserInfoForSelectedTextChangedNotification();
+ NSDictionary* GetUserInfoForSelectedTextChangedNotification(
+ bool focus_changed);
// Returns an autoreleased object.
NSDictionary* GetUserInfoForValueChangedNotification(
diff --git a/content/browser/accessibility/browser_accessibility_manager_mac.mm b/content/browser/accessibility/browser_accessibility_manager_mac.mm
index 68b8ccd88fb4ad6e4793a54869d5424f2a860d8a..4232959e30ab758bff58aa8e4457b6cdd3c7745b 100644
--- a/content/browser/accessibility/browser_accessibility_manager_mac.mm
+++ b/content/browser/accessibility/browser_accessibility_manager_mac.mm
@@ -19,91 +19,13 @@
#include "content/public/browser/web_contents.h"
#include "ui/accelerated_widget_mac/accelerated_widget_mac.h"
#include "ui/accessibility/ax_role_properties.h"
+#include "ui/accessibility/platform/ax_private_webkit_constants_mac.h"
namespace {
// Use same value as in Safari's WebKit.
const int kLiveRegionChangeIntervalMS = 20;
-// Declare undocumented accessibility constants and enums only present in
-// WebKit.
-
-enum AXTextStateChangeType {
- AXTextStateChangeTypeUnknown,
- AXTextStateChangeTypeEdit,
- AXTextStateChangeTypeSelectionMove,
- AXTextStateChangeTypeSelectionExtend
-};
-
-enum AXTextSelectionDirection {
- AXTextSelectionDirectionUnknown,
- AXTextSelectionDirectionBeginning,
- AXTextSelectionDirectionEnd,
- AXTextSelectionDirectionPrevious,
- AXTextSelectionDirectionNext,
- AXTextSelectionDirectionDiscontiguous
-};
-
-enum AXTextSelectionGranularity {
- AXTextSelectionGranularityUnknown,
- AXTextSelectionGranularityCharacter,
- AXTextSelectionGranularityWord,
- AXTextSelectionGranularityLine,
- AXTextSelectionGranularitySentence,
- AXTextSelectionGranularityParagraph,
- AXTextSelectionGranularityPage,
- AXTextSelectionGranularityDocument,
- AXTextSelectionGranularityAll
-};
-
-enum AXTextEditType {
- AXTextEditTypeUnknown,
- AXTextEditTypeDelete,
- AXTextEditTypeInsert,
- AXTextEditTypeTyping,
- AXTextEditTypeDictation,
- AXTextEditTypeCut,
- AXTextEditTypePaste,
- AXTextEditTypeAttributesChange
-};
-
-// Native mac notifications fired.
-NSString* const NSAccessibilityAutocorrectionOccurredNotification =
- @"AXAutocorrectionOccurred";
-NSString* const NSAccessibilityLoadCompleteNotification = @"AXLoadComplete";
-NSString* const NSAccessibilityInvalidStatusChangedNotification =
- @"AXInvalidStatusChanged";
-NSString* const NSAccessibilityLiveRegionCreatedNotification =
- @"AXLiveRegionCreated";
-NSString* const NSAccessibilityLiveRegionChangedNotification =
- @"AXLiveRegionChanged";
-NSString* const NSAccessibilityExpandedChanged = @"AXExpandedChanged";
-NSString* const NSAccessibilityMenuItemSelectedNotification =
- @"AXMenuItemSelected";
-
-// The following native mac notifications are not fired:
-// AXLayoutComplete: Voiceover does not use this, it is considered too spammy.
-
-// Attributes used for NSAccessibilitySelectedTextChangedNotification and
-// NSAccessibilityValueChangedNotification.
-NSString* const NSAccessibilityTextStateChangeTypeKey =
- @"AXTextStateChangeType";
-NSString* const NSAccessibilityTextStateSyncKey = @"AXTextStateSync";
-NSString* const NSAccessibilityTextSelectionDirection =
- @"AXTextSelectionDirection";
-NSString* const NSAccessibilityTextSelectionGranularity =
- @"AXTextSelectionGranularity";
-NSString* const NSAccessibilityTextSelectionChangedFocus =
- @"AXTextSelectionChangedFocus";
-NSString* const NSAccessibilityTextChangeElement = @"AXTextChangeElement";
-NSString* const NSAccessibilityTextEditType = @"AXTextEditType";
-NSString* const NSAccessibilityTextChangeValue = @"AXTextChangeValue";
-NSString* const NSAccessibilityChangeValueStartMarker =
- @"AXTextChangeValueStartMarker";
-NSString* const NSAccessibilityTextChangeValueLength =
- @"AXTextChangeValueLength";
-NSString* const NSAccessibilityTextChangeValues = @"AXTextChangeValues";
-
} // namespace
namespace content {
@@ -164,7 +86,7 @@
NSString* mac_notification = nullptr;
switch (event_type) {
case ax::mojom::Event::kAutocorrectionOccured:
- mac_notification = NSAccessibilityAutocorrectionOccurredNotification;
+ mac_notification = ui::NSAccessibilityAutocorrectionOccurredNotification;
break;
default:
return;
@@ -203,6 +125,8 @@ void PostAnnouncementNotification(NSString* announcement) {
auto native_node = ToBrowserAccessibilityCocoa(node);
DCHECK(native_node);
+ bool focus_changed = GetFocus() != GetLastFocusedNode();
+
// Refer to |AXObjectCache::postPlatformNotification| in WebKit source code.
NSString* mac_notification = nullptr;
switch (event_type) {
@@ -232,7 +156,7 @@ void PostAnnouncementNotification(NSString* announcement) {
// |NSAccessibilityLoadCompleteNotification| should only be fired on the
// top document and when the document is not Chrome's new tab page.
if (IsRootTree() && !IsChromeNewTabPage()) {
- mac_notification = NSAccessibilityLoadCompleteNotification;
+ mac_notification = ui::NSAccessibilityLoadCompleteNotification;
} else {
// Voiceover moves focus to the web content when it receives an
// AXLoadComplete event. On Chrome's new tab page, focus should stay
@@ -242,7 +166,7 @@ void PostAnnouncementNotification(NSString* announcement) {
}
break;
case ui::AXEventGenerator::Event::INVALID_STATUS_CHANGED:
- mac_notification = NSAccessibilityInvalidStatusChangedNotification;
+ mac_notification = ui::NSAccessibilityInvalidStatusChangedNotification;
break;
case ui::AXEventGenerator::Event::SELECTED_CHILDREN_CHANGED:
if (ui::IsTableLike(node->GetRole())) {
@@ -289,7 +213,7 @@ void PostAnnouncementNotification(NSString* announcement) {
// API has been present on versions of OS X since 10.7 but doesn't
// appear to be needed by Voiceover before version 10.11.
NSDictionary* user_info =
- GetUserInfoForSelectedTextChangedNotification();
+ GetUserInfoForSelectedTextChangedNotification(focus_changed);
BrowserAccessibilityManager* root_manager = GetRootManager();
if (!root_manager)
@@ -342,11 +266,11 @@ void PostAnnouncementNotification(NSString* announcement) {
}
break;
case ui::AXEventGenerator::Event::LIVE_REGION_CREATED:
- mac_notification = NSAccessibilityLiveRegionCreatedNotification;
+ mac_notification = ui::NSAccessibilityLiveRegionCreatedNotification;
break;
case ui::AXEventGenerator::Event::ALERT:
NSAccessibilityPostNotification(
- native_node, NSAccessibilityLiveRegionCreatedNotification);
+ native_node, ui::NSAccessibilityLiveRegionCreatedNotification);
// Voiceover requires a live region changed notification to actually
// announce the live region.
FireGeneratedEvent(ui::AXEventGenerator::Event::LIVE_REGION_CHANGED,
@@ -359,7 +283,7 @@ void PostAnnouncementNotification(NSString* announcement) {
if (never_suppress_or_delay_events_for_testing_) {
NSAccessibilityPostNotification(
- native_node, NSAccessibilityLiveRegionChangedNotification);
+ native_node, ui::NSAccessibilityLiveRegionChangedNotification);
return;
}
@@ -383,7 +307,7 @@ void PostAnnouncementNotification(NSString* announcement) {
[](base::scoped_nsobject<BrowserAccessibilityCocoa> node) {
if (node && [node instanceActive]) {
NSAccessibilityPostNotification(
- node, NSAccessibilityLiveRegionChangedNotification);
+ node, ui::NSAccessibilityLiveRegionChangedNotification);
}
},
std::move(retained_node)),
@@ -398,7 +322,7 @@ void PostAnnouncementNotification(NSString* announcement) {
node->GetRole() == ax::mojom::Role::kTreeItem) {
mac_notification = NSAccessibilityRowExpandedNotification;
} else {
- mac_notification = NSAccessibilityExpandedChanged;
+ mac_notification = ui::NSAccessibilityExpandedChanged;
}
break;
case ui::AXEventGenerator::Event::COLLAPSED:
@@ -406,11 +330,11 @@ void PostAnnouncementNotification(NSString* announcement) {
node->GetRole() == ax::mojom::Role::kTreeItem) {
mac_notification = NSAccessibilityRowCollapsedNotification;
} else {
- mac_notification = NSAccessibilityExpandedChanged;
+ mac_notification = ui::NSAccessibilityExpandedChanged;
}
break;
case ui::AXEventGenerator::Event::MENU_ITEM_SELECTED:
- mac_notification = NSAccessibilityMenuItemSelectedNotification;
+ mac_notification = ui::NSAccessibilityMenuItemSelectedNotification;
break;
case ui::AXEventGenerator::Event::ACCESS_KEY_CHANGED:
case ui::AXEventGenerator::Event::ATK_TEXT_OBJECT_ATTRIBUTE_CHANGED:
@@ -514,18 +438,32 @@ void PostAnnouncementNotification(NSString* announcement) {
}
}
-NSDictionary* BrowserAccessibilityManagerMac::
- GetUserInfoForSelectedTextChangedNotification() {
+NSDictionary*
+BrowserAccessibilityManagerMac::GetUserInfoForSelectedTextChangedNotification(
+ bool focus_changed) {
NSMutableDictionary* user_info =
[[[NSMutableDictionary alloc] init] autorelease];
- [user_info setObject:@YES forKey:NSAccessibilityTextStateSyncKey];
- [user_info setObject:@(AXTextStateChangeTypeUnknown)
- forKey:NSAccessibilityTextStateChangeTypeKey];
- [user_info setObject:@(AXTextSelectionDirectionUnknown)
- forKey:NSAccessibilityTextSelectionDirection];
- [user_info setObject:@(AXTextSelectionGranularityUnknown)
- forKey:NSAccessibilityTextSelectionGranularity];
- [user_info setObject:@YES forKey:NSAccessibilityTextSelectionChangedFocus];
+ [user_info setObject:@YES forKey:ui::NSAccessibilityTextStateSyncKey];
+ [user_info setObject:@(ui::AXTextSelectionDirectionUnknown)
+ forKey:ui::NSAccessibilityTextSelectionDirection];
+ [user_info setObject:@(ui::AXTextSelectionGranularityUnknown)
+ forKey:ui::NSAccessibilityTextSelectionGranularity];
+ [user_info setObject:@YES
+ forKey:ui::NSAccessibilityTextSelectionChangedFocus];
+
+ // Try to detect when the text selection changes due to a focus change.
+ // This is necessary so that VoiceOver also anounces information about the
+ // element that contains this selection.
+ // TODO(mrobinson): Determine definitively what the type of this text
+ // selection change is. This requires passing this information here from
+ // blink.
+ if (focus_changed) {
+ [user_info setObject:@(ui::AXTextStateChangeTypeSelectionMove)
+ forKey:ui::NSAccessibilityTextStateChangeTypeKey];
+ } else {
+ [user_info setObject:@(ui::AXTextStateChangeTypeUnknown)
+ forKey:ui::NSAccessibilityTextStateChangeTypeKey];
+ }
int32_t focus_id = ax_tree()->GetUnignoredSelection().focus_object_id;
BrowserAccessibility* focus_object = GetFromID(focus_id);
@@ -534,7 +472,7 @@ void PostAnnouncementNotification(NSString* announcement) {
auto native_focus_object = ToBrowserAccessibilityCocoa(focus_object);
if (native_focus_object && [native_focus_object instanceActive]) {
[user_info setObject:native_focus_object
- forKey:NSAccessibilityTextChangeElement];
+ forKey:ui::NSAccessibilityTextChangeElement];
#ifndef MAS_BUILD
id selected_text = [native_focus_object selectedTextMarkerRange];
@@ -565,38 +503,39 @@ void PostAnnouncementNotification(NSString* announcement) {
if (!deleted_text.empty()) {
NSMutableDictionary* change =
[NSMutableDictionary dictionaryWithDictionary:@{
- NSAccessibilityTextEditType : @(AXTextEditTypeDelete),
- NSAccessibilityTextChangeValueLength : @(deleted_text.length()),
- NSAccessibilityTextChangeValue :
+ ui::NSAccessibilityTextEditType : @(ui::AXTextEditTypeDelete),
+ ui::NSAccessibilityTextChangeValueLength : @(deleted_text.length()),
+ ui::NSAccessibilityTextChangeValue :
base::SysUTF16ToNSString(deleted_text)
}];
if (edit_text_marker) {
- change[NSAccessibilityChangeValueStartMarker] = edit_text_marker;
+ change[ui::NSAccessibilityChangeValueStartMarker] = edit_text_marker;
}
[changes addObject:change];
}
if (!inserted_text.empty()) {
// TODO(nektar): Figure out if this is a paste, insertion or typing.
// Changes to Blink would be required. A heuristic is currently used.
- auto edit_type = inserted_text.length() > 1 ? @(AXTextEditTypeInsert)
- : @(AXTextEditTypeTyping);
+ auto edit_type = inserted_text.length() > 1 ? @(ui::AXTextEditTypeInsert)
+ : @(ui::AXTextEditTypeTyping);
NSMutableDictionary* change =
[NSMutableDictionary dictionaryWithDictionary:@{
- NSAccessibilityTextEditType : edit_type,
- NSAccessibilityTextChangeValueLength : @(inserted_text.length()),
- NSAccessibilityTextChangeValue :
+ ui::NSAccessibilityTextEditType : edit_type,
+ ui::NSAccessibilityTextChangeValueLength : @(inserted_text.length()),
+ ui::NSAccessibilityTextChangeValue :
base::SysUTF16ToNSString(inserted_text)
}];
if (edit_text_marker) {
- change[NSAccessibilityChangeValueStartMarker] = edit_text_marker;
+ change[ui::NSAccessibilityChangeValueStartMarker] = edit_text_marker;
}
[changes addObject:change];
}
return @{
- NSAccessibilityTextStateChangeTypeKey : @(AXTextStateChangeTypeEdit),
- NSAccessibilityTextChangeValues : changes,
- NSAccessibilityTextChangeElement : native_node
+ ui::
+ NSAccessibilityTextStateChangeTypeKey : @(ui::AXTextStateChangeTypeEdit),
+ ui::NSAccessibilityTextChangeValues : changes,
+ ui::NSAccessibilityTextChangeElement : native_node
};
}
diff --git a/content/test/data/accessibility/event/aria-combo-box-focus-expected-mac.txt b/content/test/data/accessibility/event/aria-combo-box-focus-expected-mac.txt
index ad5e2bf2c8029185c51eecc94cac1dbe7608c99e..67e07a89f77f7c61a57eb51cecea211df5227341 100644
--- a/content/test/data/accessibility/event/aria-combo-box-focus-expected-mac.txt
+++ b/content/test/data/accessibility/event/aria-combo-box-focus-expected-mac.txt
@@ -1,3 +1,3 @@
AXFocusedUIElementChanged on AXStaticText AXValue="Apple not selected"
-AXSelectedTextChanged on AXStaticText AXValue="Apple not selected"
-AXSelectedTextChanged on AXWebArea
\ No newline at end of file
+AXSelectedTextChanged on AXStaticText AXValue="Apple not selected" AXTextSelectionDirection=AXTextSelectionDirectionUnknown AXTextSelectionGranularity=AXTextSelectionGranularityUnknown AXTextStateChangeType=AXTextStateChangeTypeSelectionMove
+AXSelectedTextChanged on AXWebArea AXTextSelectionDirection=AXTextSelectionDirectionUnknown AXTextSelectionGranularity=AXTextSelectionGranularityUnknown AXTextStateChangeType=AXTextStateChangeTypeSelectionMove
diff --git a/content/test/data/accessibility/event/caret-browsing-disabled-expected-mac.txt b/content/test/data/accessibility/event/caret-browsing-disabled-expected-mac.txt
index ec0b74d984ade9928705242f9b0682a743e20fb2..87447c5a4b14efde5b64b1d340a3fa2fb6574b80 100644
--- a/content/test/data/accessibility/event/caret-browsing-disabled-expected-mac.txt
+++ b/content/test/data/accessibility/event/caret-browsing-disabled-expected-mac.txt
@@ -1,5 +1,5 @@
-AXSelectedTextChanged on AXWebArea
-AXSelectedTextChanged on AXWebArea
+AXSelectedTextChanged on AXWebArea AXTextSelectionDirection=AXTextSelectionDirectionUnknown AXTextSelectionGranularity=AXTextSelectionGranularityUnknown AXTextStateChangeType=AXTextStateChangeTypeUnknown
+AXSelectedTextChanged on AXWebArea AXTextSelectionDirection=AXTextSelectionDirectionUnknown AXTextSelectionGranularity=AXTextSelectionGranularityUnknown AXTextStateChangeType=AXTextStateChangeTypeUnknown
=== Start Continuation ===
-AXSelectedTextChanged on AXWebArea
-AXSelectedTextChanged on AXWebArea
+AXSelectedTextChanged on AXWebArea AXTextSelectionDirection=AXTextSelectionDirectionUnknown AXTextSelectionGranularity=AXTextSelectionGranularityUnknown AXTextStateChangeType=AXTextStateChangeTypeUnknown
+AXSelectedTextChanged on AXWebArea AXTextSelectionDirection=AXTextSelectionDirectionUnknown AXTextSelectionGranularity=AXTextSelectionGranularityUnknown AXTextStateChangeType=AXTextStateChangeTypeUnknown
diff --git a/content/test/data/accessibility/event/caret-browsing-enabled-expected-mac.txt b/content/test/data/accessibility/event/caret-browsing-enabled-expected-mac.txt
index ec0b74d984ade9928705242f9b0682a743e20fb2..87447c5a4b14efde5b64b1d340a3fa2fb6574b80 100644
--- a/content/test/data/accessibility/event/caret-browsing-enabled-expected-mac.txt
+++ b/content/test/data/accessibility/event/caret-browsing-enabled-expected-mac.txt
@@ -1,5 +1,5 @@
-AXSelectedTextChanged on AXWebArea
-AXSelectedTextChanged on AXWebArea
+AXSelectedTextChanged on AXWebArea AXTextSelectionDirection=AXTextSelectionDirectionUnknown AXTextSelectionGranularity=AXTextSelectionGranularityUnknown AXTextStateChangeType=AXTextStateChangeTypeUnknown
+AXSelectedTextChanged on AXWebArea AXTextSelectionDirection=AXTextSelectionDirectionUnknown AXTextSelectionGranularity=AXTextSelectionGranularityUnknown AXTextStateChangeType=AXTextStateChangeTypeUnknown
=== Start Continuation ===
-AXSelectedTextChanged on AXWebArea
-AXSelectedTextChanged on AXWebArea
+AXSelectedTextChanged on AXWebArea AXTextSelectionDirection=AXTextSelectionDirectionUnknown AXTextSelectionGranularity=AXTextSelectionGranularityUnknown AXTextStateChangeType=AXTextStateChangeTypeUnknown
+AXSelectedTextChanged on AXWebArea AXTextSelectionDirection=AXTextSelectionDirectionUnknown AXTextSelectionGranularity=AXTextSelectionGranularityUnknown AXTextStateChangeType=AXTextStateChangeTypeUnknown
diff --git a/content/test/data/accessibility/event/text-selection-changed-expected-mac.txt b/content/test/data/accessibility/event/text-selection-changed-expected-mac.txt
new file mode 100644
index 0000000000000000000000000000000000000000..9213c873393d595bba8796cdb0e2325d3ee37ee9
--- /dev/null
+++ b/content/test/data/accessibility/event/text-selection-changed-expected-mac.txt
@@ -0,0 +1,10 @@
+AXSelectedTextChanged on AXWebArea AXTextSelectionDirection=AXTextSelectionDirectionUnknown AXTextSelectionGranularity=AXTextSelectionGranularityUnknown AXTextStateChangeType=AXTextStateChangeTypeUnknown
+AXSelectedTextChanged on AXWebArea AXTextSelectionDirection=AXTextSelectionDirectionUnknown AXTextSelectionGranularity=AXTextSelectionGranularityUnknown AXTextStateChangeType=AXTextStateChangeTypeUnknown
+=== Start Continuation ===
+AXFocusedUIElementChanged on AXTextField AXDescription="input" AXValue="input"
+AXSelectedTextChanged on AXTextField AXDescription="input" AXValue="input" AXTextSelectionDirection=AXTextSelectionDirectionUnknown AXTextSelectionGranularity=AXTextSelectionGranularityUnknown AXTextStateChangeType=AXTextStateChangeTypeSelectionMove
+AXSelectedTextChanged on AXWebArea AXTextSelectionDirection=AXTextSelectionDirectionUnknown AXTextSelectionGranularity=AXTextSelectionGranularityUnknown AXTextStateChangeType=AXTextStateChangeTypeSelectionMove
+=== Start Continuation ===
+AXFocusedUIElementChanged on AXTextArea AXDescription="textarea"
+AXSelectedTextChanged on AXTextArea AXDescription="textarea" AXTextSelectionDirection=AXTextSelectionDirectionUnknown AXTextSelectionGranularity=AXTextSelectionGranularityUnknown AXTextStateChangeType=AXTextStateChangeTypeSelectionMove
+AXSelectedTextChanged on AXWebArea AXTextSelectionDirection=AXTextSelectionDirectionUnknown AXTextSelectionGranularity=AXTextSelectionGranularityUnknown AXTextStateChangeType=AXTextStateChangeTypeSelectionMove
diff --git a/ui/accessibility/platform/BUILD.gn b/ui/accessibility/platform/BUILD.gn
index 2f015b939bb6835f2ff817ce6c960157eaf32342..eafddade0f7fa8ab8d008bf4888fc9ecef85463d 100644
--- a/ui/accessibility/platform/BUILD.gn
+++ b/ui/accessibility/platform/BUILD.gn
@@ -110,6 +110,8 @@ source_set("platform") {
"ax_event_intent_mac.mm",
"ax_platform_node_mac.h",
"ax_platform_node_mac.mm",
+ "ax_private_webkit_constants_mac.h",
+ "ax_private_webkit_constants_mac.mm",
]
frameworks = [
diff --git a/ui/accessibility/platform/ax_private_webkit_constants_mac.h b/ui/accessibility/platform/ax_private_webkit_constants_mac.h
new file mode 100644
index 0000000000000000000000000000000000000000..5f1776a3aeac89b70d6d852b8e5209a1208271ae
--- /dev/null
+++ b/ui/accessibility/platform/ax_private_webkit_constants_mac.h
@@ -0,0 +1,96 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_ACCESSIBILITY_PLATFORM_AX_PRIVATE_WEBKIT_CONSTANTS_MAC_H_
+#define UI_ACCESSIBILITY_PLATFORM_AX_PRIVATE_WEBKIT_CONSTANTS_MAC_H_
+
+#import <Cocoa/Cocoa.h>
+#include "ui/accessibility/ax_export.h"
+
+namespace ui {
+
+enum AXTextStateChangeType {
+ AXTextStateChangeTypeUnknown,
+ AXTextStateChangeTypeEdit,
+ AXTextStateChangeTypeSelectionMove,
+ AXTextStateChangeTypeSelectionExtend
+};
+
+enum AXTextSelectionDirection {
+ AXTextSelectionDirectionUnknown,
+ AXTextSelectionDirectionBeginning,
+ AXTextSelectionDirectionEnd,
+ AXTextSelectionDirectionPrevious,
+ AXTextSelectionDirectionNext,
+ AXTextSelectionDirectionDiscontiguous
+};
+
+enum AXTextSelectionGranularity {
+ AXTextSelectionGranularityUnknown,
+ AXTextSelectionGranularityCharacter,
+ AXTextSelectionGranularityWord,
+ AXTextSelectionGranularityLine,
+ AXTextSelectionGranularitySentence,
+ AXTextSelectionGranularityParagraph,
+ AXTextSelectionGranularityPage,
+ AXTextSelectionGranularityDocument,
+ AXTextSelectionGranularityAll
+};
+
+enum AXTextEditType {
+ AXTextEditTypeUnknown,
+ AXTextEditTypeDelete,
+ AXTextEditTypeInsert,
+ AXTextEditTypeTyping,
+ AXTextEditTypeDictation,
+ AXTextEditTypeCut,
+ AXTextEditTypePaste,
+ AXTextEditTypeAttributesChange
+};
+
+// Native mac notifications fired.
+NSString* const NSAccessibilityAutocorrectionOccurredNotification =
+ @"AXAutocorrectionOccurred";
+NSString* const NSAccessibilityLoadCompleteNotification = @"AXLoadComplete";
+NSString* const NSAccessibilityInvalidStatusChangedNotification =
+ @"AXInvalidStatusChanged";
+NSString* const NSAccessibilityLiveRegionCreatedNotification =
+ @"AXLiveRegionCreated";
+NSString* const NSAccessibilityLiveRegionChangedNotification =
+ @"AXLiveRegionChanged";
+NSString* const NSAccessibilityExpandedChanged = @"AXExpandedChanged";
+NSString* const NSAccessibilityMenuItemSelectedNotification =
+ @"AXMenuItemSelected";
+
+// The following native mac notifications are not fired:
+// AXLayoutComplete: Voiceover does not use this, it is considered too spammy.
+
+// Attributes used for NSAccessibilitySelectedTextChangedNotification and
+// NSAccessibilityValueChangedNotification.
+NSString* const NSAccessibilityTextStateChangeTypeKey =
+ @"AXTextStateChangeType";
+NSString* const NSAccessibilityTextStateSyncKey = @"AXTextStateSync";
+NSString* const NSAccessibilityTextSelectionDirection =
+ @"AXTextSelectionDirection";
+NSString* const NSAccessibilityTextSelectionGranularity =
+ @"AXTextSelectionGranularity";
+NSString* const NSAccessibilityTextSelectionChangedFocus =
+ @"AXTextSelectionChangedFocus";
+NSString* const NSAccessibilityTextChangeElement = @"AXTextChangeElement";
+NSString* const NSAccessibilityTextEditType = @"AXTextEditType";
+NSString* const NSAccessibilityTextChangeValue = @"AXTextChangeValue";
+NSString* const NSAccessibilityChangeValueStartMarker =
+ @"AXTextChangeValueStartMarker";
+NSString* const NSAccessibilityTextChangeValueLength =
+ @"AXTextChangeValueLength";
+NSString* const NSAccessibilityTextChangeValues = @"AXTextChangeValues";
+
+AX_EXPORT const char* ToString(AXTextStateChangeType);
+AX_EXPORT const char* ToString(AXTextSelectionDirection);
+AX_EXPORT const char* ToString(AXTextSelectionGranularity);
+AX_EXPORT const char* ToString(AXTextEditType);
+
+} // namespace ui
+
+#endif // UI_ACCESSIBILITY_PLATFORM_AX_PRIVATE_WEBKIT_CONSTANTS_MAC_H_
diff --git a/ui/accessibility/platform/ax_private_webkit_constants_mac.mm b/ui/accessibility/platform/ax_private_webkit_constants_mac.mm
new file mode 100644
index 0000000000000000000000000000000000000000..7de31a487dd6e0e6a4af2f4fa62e463f41a0d96a
--- /dev/null
+++ b/ui/accessibility/platform/ax_private_webkit_constants_mac.mm
@@ -0,0 +1,91 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/accessibility/platform/ax_private_webkit_constants_mac.h"
+
+namespace ui {
+
+const char* ToString(AXTextStateChangeType type) {
+ switch (type) {
+ case AXTextStateChangeTypeUnknown:
+ return "AXTextStateChangeTypeUnknown";
+ case AXTextStateChangeTypeEdit:
+ return "AXTextStateChangeTypeEdit";
+ case AXTextStateChangeTypeSelectionMove:
+ return "AXTextStateChangeTypeSelectionMove";
+ case AXTextStateChangeTypeSelectionExtend:
+ return "AXTextStateChangeTypeSelectionExtend";
+ }
+
+ return "";
+}
+
+const char* ToString(AXTextSelectionDirection direction) {
+ switch (direction) {
+ case AXTextSelectionDirectionUnknown:
+ return "AXTextSelectionDirectionUnknown";
+ case AXTextSelectionDirectionBeginning:
+ return "AXTextSelectionDirectionBeginning";
+ case AXTextSelectionDirectionEnd:
+ return "AXTextSelectionDirectionEnd";
+ case AXTextSelectionDirectionPrevious:
+ return "AXTextSelectionDirectionPrevious";
+ case AXTextSelectionDirectionNext:
+ return "AXTextSelectionDirectionNext";
+ case AXTextSelectionDirectionDiscontiguous:
+ return "AXTextSelectionDirectionDiscontiguous";
+ }
+
+ return "";
+}
+
+const char* ToString(AXTextSelectionGranularity granularity) {
+ switch (granularity) {
+ case AXTextSelectionGranularityUnknown:
+ return "AXTextSelectionGranularityUnknown";
+ case AXTextSelectionGranularityCharacter:
+ return "AXTextSelectionGranularityCharacter";
+ case AXTextSelectionGranularityWord:
+ return "AXTextSelectionGranularityWord";
+ case AXTextSelectionGranularityLine:
+ return "AXTextSelectionGranularityLine";
+ case AXTextSelectionGranularitySentence:
+ return "AXTextSelectionGranularitySentence";
+ case AXTextSelectionGranularityParagraph:
+ return "AXTextSelectionGranularityParagraph";
+ case AXTextSelectionGranularityPage:
+ return "AXTextSelectionGranularityPage";
+ case AXTextSelectionGranularityDocument:
+ return "AXTextSelectionGranularityDocument";
+ case AXTextSelectionGranularityAll:
+ return "AXTextSelectionGranularityAll";
+ }
+
+ return "";
+}
+
+const char* ToString(AXTextEditType type) {
+ switch (type) {
+ case AXTextEditTypeUnknown:
+ return "AXTextEditTypeUnknown";
+ case AXTextEditTypeDelete:
+ return "AXTextEditTypeDelete";
+ case AXTextEditTypeInsert:
+ return "AXTextEditTypeInsert";
+ case AXTextEditTypeTyping:
+ return "AXTextEditTypeTyping";
+ case AXTextEditTypeDictation:
+ return "AXTextEditTypeDictation";
+ case AXTextEditTypeCut:
+ return "AXTextEditTypeCut";
+ case AXTextEditTypePaste:
+ return "AXTextEditTypePaste";
+ case AXTextEditTypeAttributesChange:
+ return "AXTextEditTypeAttributesChange";
+ }
+
+ return "";
+}
+
+} // namespace ui

View File

@@ -0,0 +1,115 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Martin Robinson <mrobinson@igalia.com>
Date: Mon, 26 Oct 2020 23:12:55 +0000
Subject: Expose a11y popup menu type via the name "AXPopupValue" on Mac
This value was exposed via the name "AXHasPopupValue", while WebKit
exposes this value via "AXPopupValue." Fix the attribute name, which in
turn fixes an issue with how popup buttons are announced in VoiceOver.
Bug: 1129678
Change-Id: Iede26b2fd6ddb9d7717fcb47fd1dd1cce5b74075
AX-Relnotes: Fix an issue with the announcement of popup buttons in VoiceOver.
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2489985
Commit-Queue: Aaron Leventhal <aleventhal@chromium.org>
Reviewed-by: Aaron Leventhal <aleventhal@chromium.org>
Cr-Commit-Position: refs/heads/master@{#820964}
diff --git a/content/browser/accessibility/browser_accessibility_cocoa.mm b/content/browser/accessibility/browser_accessibility_cocoa.mm
index 3abd9933ab325bda6cb486a41fd6c8b246aa8e71..17aa494d6473866721a8cc5f4c5c646af9307d93 100644
--- a/content/browser/accessibility/browser_accessibility_cocoa.mm
+++ b/content/browser/accessibility/browser_accessibility_cocoa.mm
@@ -92,7 +92,7 @@
@"AXFocusableAncestor";
NSString* const NSAccessibilityGrabbedAttribute = @"AXGrabbed";
NSString* const NSAccessibilityHasPopupAttribute = @"AXHasPopup";
-NSString* const NSAccessibilityHasPopupValueAttribute = @"AXHasPopupValue";
+NSString* const NSAccessibilityPopupValueAttribute = @"AXPopupValue";
NSString* const NSAccessibilityHighestEditableAncestorAttribute =
@"AXHighestEditableAncestor";
NSString* const NSAccessibilityInvalidAttribute = @"AXInvalid";
@@ -836,7 +836,7 @@ + (void)initialize {
{NSAccessibilityGrabbedAttribute, @"grabbed"},
{NSAccessibilityHeaderAttribute, @"header"},
{NSAccessibilityHasPopupAttribute, @"hasPopup"},
- {NSAccessibilityHasPopupValueAttribute, @"hasPopupValue"},
+ {NSAccessibilityPopupValueAttribute, @"popupValue"},
{NSAccessibilityHelpAttribute, @"help"},
{NSAccessibilityHighestEditableAncestorAttribute,
@"highestEditableAncestor"},
@@ -1411,7 +1411,7 @@ - (NSNumber*)hasPopup {
return @(_owner->HasIntAttribute(ax::mojom::IntAttribute::kHasPopup));
}
-- (NSString*)hasPopupValue {
+- (NSString*)popupValue {
if (![self instanceActive])
return nil;
int hasPopup = _owner->GetIntAttribute(ax::mojom::IntAttribute::kHasPopup);
@@ -3586,7 +3586,7 @@ - (NSArray*)accessibilityAttributeNames {
if (_owner->HasIntAttribute(ax::mojom::IntAttribute::kHasPopup)) {
[ret addObjectsFromArray:@[
- NSAccessibilityHasPopupAttribute, NSAccessibilityHasPopupValueAttribute
+ NSAccessibilityHasPopupAttribute, NSAccessibilityPopupValueAttribute
]];
}
diff --git a/content/test/data/accessibility/aria/aria-haspopup-expected-mac.txt b/content/test/data/accessibility/aria/aria-haspopup-expected-mac.txt
index e988b9fe7d061fa3aa6930ababa4f32c095bd8a3..de0f31f2065490d6085027e2800706a3926bcf5b 100644
--- a/content/test/data/accessibility/aria/aria-haspopup-expected-mac.txt
+++ b/content/test/data/accessibility/aria/aria-haspopup-expected-mac.txt
@@ -1,10 +1,10 @@
AXWebArea
-++AXPopUpButton AXHasPopup=1 AXHasPopupValue='menu'
+++AXPopUpButton AXHasPopup=1 AXPopupValue='menu'
++AXPopUpButton
-++AXPopUpButton AXHasPopup=1 AXHasPopupValue='menu'
-++AXPopUpButton AXHasPopup=1 AXHasPopupValue='listbox'
-++AXPopUpButton AXHasPopup=1 AXHasPopupValue='grid'
-++AXPopUpButton AXHasPopup=1 AXHasPopupValue='dialog'
-++AXPopUpButton AXHasPopup=1 AXHasPopupValue='menu'
-++AXPopUpButton AXHasPopup=1 AXHasPopupValue='listbox'
-++AXPopUpButton AXHasPopup=1 AXHasPopupValue='listbox'
+++AXPopUpButton AXHasPopup=1 AXPopupValue='menu'
+++AXPopUpButton AXHasPopup=1 AXPopupValue='listbox'
+++AXPopUpButton AXHasPopup=1 AXPopupValue='grid'
+++AXPopUpButton AXHasPopup=1 AXPopupValue='dialog'
+++AXPopUpButton AXHasPopup=1 AXPopupValue='menu'
+++AXPopUpButton AXHasPopup=1 AXPopupValue='listbox'
+++AXPopUpButton AXHasPopup=1 AXPopupValue='listbox'
diff --git a/content/test/data/accessibility/aria/aria-haspopup.html b/content/test/data/accessibility/aria/aria-haspopup.html
index 026397c4e9ad805f5facfc499cc986cd0763aef3..7d982745e89b8346bf71eee90110fe6a96648629 100644
--- a/content/test/data/accessibility/aria/aria-haspopup.html
+++ b/content/test/data/accessibility/aria/aria-haspopup.html
@@ -3,7 +3,7 @@
@MAC-ALLOW:AXShowMenu*
@MAC-ALLOW:AXPress*
@MAC-ALLOW:AXHasPopup
-@MAC-ALLOW:AXHasPopupValue
+@MAC-ALLOW:AXPopupValue
@WIN-ALLOW:EXPANDED*
@WIN-ALLOW:HASPOPUP*
@WIN-ALLOW:haspopup*
diff --git a/content/test/data/accessibility/html/input-suggestions-source-element-expected-mac.txt b/content/test/data/accessibility/html/input-suggestions-source-element-expected-mac.txt
index 4b0bde650deed34edead37ffabd3eda2d7a82b49..38ca751991f564f9a24ba131652014f161d4b996 100644
--- a/content/test/data/accessibility/html/input-suggestions-source-element-expected-mac.txt
+++ b/content/test/data/accessibility/html/input-suggestions-source-element-expected-mac.txt
@@ -1,3 +1,3 @@
AXWebArea AXRoleDescription='HTML content'
++AXGroup AXRoleDescription='group'
-++++AXComboBox AXAutocompleteValue='list' AXHasPopup=1 AXHasPopupValue='listbox' AXRoleDescription='combo box'
+++++AXComboBox AXAutocompleteValue='list' AXHasPopup=1 AXPopupValue='listbox' AXRoleDescription='combo box'
diff --git a/content/test/data/accessibility/html/input-suggestions-source-element.html b/content/test/data/accessibility/html/input-suggestions-source-element.html
index 039ac5855e1122b34dad0c1fae42f798791b7890..d024f17de3d3b04029c532e616140e20afa87549 100644
--- a/content/test/data/accessibility/html/input-suggestions-source-element.html
+++ b/content/test/data/accessibility/html/input-suggestions-source-element.html
@@ -1,7 +1,7 @@
<!--
@MAC-ALLOW:AXRoleDescription
@MAC-ALLOW:AXHasPopup
-@MAC-ALLOW:AXHasPopupValue
+@MAC-ALLOW:AXPopupValue
@WIN-ALLOW:haspopup*
@AURALINUX-ALLOW:haspopup*
@AURALINUX-ALLOW:supports-autocompletion

View File

@@ -0,0 +1,37 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shelley Vohr <shelley.vohr@gmail.com>
Date: Mon, 5 Oct 2020 13:43:59 -0700
Subject: chore: expose v8 initialization isolate callbacks
This commit is necessary in order to ensure consistent behavior from
v8 Isolate callbacks in contexts which Node.js does not control. If
we're running with contextIsolation enabled, we should be falling back
to Blink's logic. This will be upstreamed in some form.
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc b/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc
index 85ac9d5d95856470707d320d382743673cd1451a..398095d8890cee3f8838170a86ccb48010ff74a0 100644
--- a/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc
+++ b/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc
@@ -438,7 +438,7 @@ CodeGenerationCheckCallbackInMainThread(v8::Local<v8::Context> context,
return {true, std::move(stringified_source)};
}
-static bool WasmCodeGenerationCheckCallbackInMainThread(
+bool V8Initializer::WasmCodeGenerationCheckCallbackInMainThread(
v8::Local<v8::Context> context,
v8::Local<v8::String> source) {
if (ExecutionContext* execution_context = ToExecutionContext(context)) {
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_initializer.h b/third_party/blink/renderer/bindings/core/v8/v8_initializer.h
index e7cbc5db7d15aa0fcfb37ba261673b973827296a..6b93aa449a005e06862a99ea0c9b751ffff2d6ec 100644
--- a/third_party/blink/renderer/bindings/core/v8/v8_initializer.h
+++ b/third_party/blink/renderer/bindings/core/v8/v8_initializer.h
@@ -67,6 +67,9 @@ class CORE_EXPORT V8Initializer {
v8::Local<v8::Value>);
static void MessageHandlerInWorker(v8::Local<v8::Message>,
v8::Local<v8::Value>);
+ static bool WasmCodeGenerationCheckCallbackInMainThread(
+ v8::Local<v8::Context> context,
+ v8::Local<v8::String> source);
};
} // namespace blink

View File

@@ -7,10 +7,10 @@ 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 e462f7d8bef19577547cacc76fc794ab6fa17dcf..5fae70dc1c035596099eedf49b9eb27f0fd21e07 100644
index 62ddc2d8548bcac4d55bbc7283426c426fecf254..b0eb803cd132390d492b82600d8629e2c43cc72e 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -5944,6 +5944,7 @@ static_library("browser") {
@@ -5960,6 +5960,7 @@ static_library("browser") {
deps += [
"//components/spellcheck/browser",
"//components/spellcheck/common",

View File

@@ -75,10 +75,10 @@ index aaa9ad1d58d7f584cbf391e0cb0a61a0d25d5c69..5b02834b5ecaf4bcb7e051d9ee98cd5e
// 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
diff --git a/components/crash/core/app/crashpad_mac.mm b/components/crash/core/app/crashpad_mac.mm
index aa7c3302f2e3fc7129381b355ed4fa1bc386f8cb..d7dd05118f3c90f5ab570f59685c43bd180885e5 100644
index eb675321436a53e82432144d43f258bed6e938e2..ae2032a12eac7c789d790e53857d11ba3e03d510 100644
--- a/components/crash/core/app/crashpad_mac.mm
+++ b/components/crash/core/app/crashpad_mac.mm
@@ -71,6 +71,8 @@
@@ -77,6 +77,8 @@
} // @autoreleasepool
return process_annotations;
}();
@@ -87,7 +87,7 @@ index aa7c3302f2e3fc7129381b355ed4fa1bc386f8cb..d7dd05118f3c90f5ab570f59685c43bd
return annotations;
}
@@ -141,6 +143,13 @@ void DumpProcessWithoutCrashing(task_t task_port) {
@@ -147,6 +149,13 @@ void DumpProcessWithoutCrashing(task_t task_port) {
std::vector<std::string> arguments;

View File

@@ -0,0 +1,146 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Joshua Peraza <jperaza@chromium.org>
Date: Wed, 21 Oct 2020 11:10:25 -0700
Subject: Initialize logging for crashpad
Although logging to files is not yet supported by mini_chromium, it is
the default behavior for OS_WIN in chromium. This change should
cause crashpad to log via OutputDebugString() on Windows, instead of
debug.log files. Future work (crbug.com/crashpad/26) should arrange for
logs to be uploaded with reports, embedded in associated minidumps or as
file attachments.
Bug: chromium:711159
Change-Id: I0f9004f7de94dd29d555cc7d23c48a63da6b4bba
Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/2425108
Reviewed-by: Mark Mentovai <mark@chromium.org>
diff --git a/base/logging.cc b/base/logging.cc
index b5cf2c4933d0cbb89f2f1b410c5c249a0b8647f0..698dca03914934b294457d05d89722a27cdebb56 100644
--- a/base/logging.cc
+++ b/base/logging.cc
@@ -369,21 +369,23 @@ bool BaseInitLoggingImpl(const LoggingSettings& settings) {
g_log_format = settings.log_format;
#endif
- base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
- // Don't bother initializing |g_vlog_info| unless we use one of the
- // vlog switches.
- if (command_line->HasSwitch(switches::kV) ||
- command_line->HasSwitch(switches::kVModule)) {
- // NOTE: If |g_vlog_info| has already been initialized, it might be in use
- // by another thread. Don't delete the old VLogInfo, just create a second
- // one. We keep track of both to avoid memory leak warnings.
- CHECK(!g_vlog_info_prev);
- g_vlog_info_prev = g_vlog_info;
-
- g_vlog_info =
- new VlogInfo(command_line->GetSwitchValueASCII(switches::kV),
- command_line->GetSwitchValueASCII(switches::kVModule),
- &g_min_log_level);
+ if (base::CommandLine::InitializedForCurrentProcess()) {
+ base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+ // Don't bother initializing |g_vlog_info| unless we use one of the
+ // vlog switches.
+ if (command_line->HasSwitch(switches::kV) ||
+ command_line->HasSwitch(switches::kVModule)) {
+ // NOTE: If |g_vlog_info| has already been initialized, it might be in use
+ // by another thread. Don't delete the old VLogInfo, just create a second
+ // one. We keep track of both to avoid memory leak warnings.
+ CHECK(!g_vlog_info_prev);
+ g_vlog_info_prev = g_vlog_info;
+
+ g_vlog_info =
+ new VlogInfo(command_line->GetSwitchValueASCII(switches::kV),
+ command_line->GetSwitchValueASCII(switches::kVModule),
+ &g_min_log_level);
+ }
}
g_logging_destination = settings.logging_dest;
@@ -394,7 +396,10 @@ bool BaseInitLoggingImpl(const LoggingSettings& settings) {
config.min_severity = FX_LOG_INFO;
config.console_fd = -1;
config.log_service_channel = ZX_HANDLE_INVALID;
- std::string log_tag = command_line->GetProgram().BaseName().AsUTF8Unsafe();
+ std::string log_tag = base::CommandLine::ForCurrentProcess()
+ ->GetProgram()
+ .BaseName()
+ .AsUTF8Unsafe();
const char* log_tag_data = log_tag.data();
config.tags = &log_tag_data;
config.num_tags = 1;
diff --git a/third_party/crashpad/crashpad/DEPS b/third_party/crashpad/crashpad/DEPS
index 83995e0cdea91522c272415330c57af764d23163..7e83327aac2582e81a38720086a52832de58a37a 100644
--- a/third_party/crashpad/crashpad/DEPS
+++ b/third_party/crashpad/crashpad/DEPS
@@ -42,7 +42,7 @@ deps = {
'7bde79cc274d06451bf65ae82c012a5d3e476b5a',
'crashpad/third_party/mini_chromium/mini_chromium':
Var('chromium_git') + '/chromium/mini_chromium@' +
- '76a9bb7475f6217eaf108789246379d3972b4e6a',
+ '5fc64bfbf1c000161445c586de45e40464ff2314',
'crashpad/third_party/libfuzzer/src':
Var('chromium_git') + '/chromium/llvm-project/compiler-rt/lib/fuzzer.git@' +
'fda403cf93ecb8792cb1d061564d89a6553ca020',
diff --git a/third_party/crashpad/crashpad/handler/handler_main.cc b/third_party/crashpad/crashpad/handler/handler_main.cc
index 33649291e253a7a9bd281b892bab415ff1950b6a..a3ba9bb17e221e8330b09eae572d116bd29e4ba4 100644
--- a/third_party/crashpad/crashpad/handler/handler_main.cc
+++ b/third_party/crashpad/crashpad/handler/handler_main.cc
@@ -504,16 +504,26 @@ class ScopedStoppable {
DISALLOW_COPY_AND_ASSIGN(ScopedStoppable);
};
+void InitCrashpadLogging() {
+ logging::LoggingSettings settings;
+#if defined(OS_CHROMEOS)
+ settings.logging_dest = logging::LOG_TO_FILE;
+ settings.log_file_path = "/var/log/chrome/chrome";
+#elif defined(OS_WIN)
+ settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
+#else
+ settings.logging_dest =
+ logging::LOG_TO_SYSTEM_DEBUG_LOG | logging::LOG_TO_STDERR;
+#endif
+ logging::InitLogging(settings);
+}
+
} // namespace
int HandlerMain(int argc,
char* argv[],
const UserStreamDataSources* user_stream_sources) {
-#if defined(OS_CHROMEOS)
- if (freopen("/var/log/chrome/chrome", "a", stderr) == nullptr) {
- PLOG(ERROR) << "Failed to redirect stderr to /var/log/chrome/chrome";
- }
-#endif
+ InitCrashpadLogging();
InstallCrashHandler();
CallMetricsRecordNormalExit metrics_record_normal_exit;
diff --git a/third_party/crashpad/crashpad/test/gtest_main.cc b/third_party/crashpad/crashpad/test/gtest_main.cc
index 67cfa0d72d7eb469775201f3a9df906f27c302a9..c67b8e24bb940935d5da88428ed3058a135f5a57 100644
--- a/third_party/crashpad/crashpad/test/gtest_main.cc
+++ b/third_party/crashpad/crashpad/test/gtest_main.cc
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#include "base/logging.h"
#include "build/build_config.h"
#include "gtest/gtest.h"
#include "test/main_arguments.h"
@@ -99,6 +100,12 @@ int main(int argc, char* argv[]) {
#endif // CRASHPAD_IS_IN_CHROMIUM
+ // base::TestSuite initializes logging when using Chromium's test launcher.
+ logging::LoggingSettings settings;
+ settings.logging_dest =
+ logging::LOG_TO_STDERR | logging::LOG_TO_SYSTEM_DEBUG_LOG;
+ logging::InitLogging(settings);
+
#if defined(CRASHPAD_TEST_LAUNCHER_GOOGLEMOCK)
testing::InitGoogleMock(&argc, argv);
#elif defined(CRASHPAD_TEST_LAUNCHER_GOOGLETEST)

View File

@@ -17,10 +17,10 @@ only one or two specific checks fail. Then it's better to simply comment out the
failing checks and allow the rest of the target to have them enabled.
diff --git a/content/browser/renderer_host/navigation_controller_impl.cc b/content/browser/renderer_host/navigation_controller_impl.cc
index 18f5da7bc5953282e72933fffd7e37bbf77bfb31..b164f15fa7506caf82f0f5f450d90dbbd88a116e 100644
index 29fed88f36ecaf0c022d2a5a2f3ed7db66e2c96c..e1aadf680851d23cc2ce6023b20f496ee97c22da 100644
--- a/content/browser/renderer_host/navigation_controller_impl.cc
+++ b/content/browser/renderer_host/navigation_controller_impl.cc
@@ -1275,8 +1275,10 @@ NavigationType NavigationControllerImpl::ClassifyNavigation(
@@ -1276,8 +1276,10 @@ NavigationType NavigationControllerImpl::ClassifyNavigation(
return NAVIGATION_TYPE_NEW_SUBFRAME;
}
@@ -33,7 +33,7 @@ index 18f5da7bc5953282e72933fffd7e37bbf77bfb31..b164f15fa7506caf82f0f5f450d90dbb
if (rfh->GetParent()) {
// All manual subframes would be did_create_new_entry and handled above, so
@@ -1551,7 +1553,10 @@ void NavigationControllerImpl::RendererDidNavigateToNewPage(
@@ -1552,7 +1554,10 @@ void NavigationControllerImpl::RendererDidNavigateToNewPage(
new_entry->GetFavicon() = GetLastCommittedEntry()->GetFavicon();
}
@@ -46,10 +46,10 @@ index 18f5da7bc5953282e72933fffd7e37bbf77bfb31..b164f15fa7506caf82f0f5f450d90dbb
// navigation. Now we know that the renderer has updated its state accordingly
// and it is safe to also clear the browser side history.
diff --git a/ui/base/clipboard/clipboard_win.cc b/ui/base/clipboard/clipboard_win.cc
index 8d0e981720bb4a0ec4c42f389275fd375c1b1e43..9473f4f7819667d7cc4bfa514955b4e65d69c1c9 100644
index 260858079f2f511cb6eb513c37eec8a0d38b55a0..39f2cef515c4a1724aeb6f3660730221f251e51e 100644
--- a/ui/base/clipboard/clipboard_win.cc
+++ b/ui/base/clipboard/clipboard_win.cc
@@ -850,10 +850,10 @@ SkBitmap ClipboardWin::ReadImageInternal(ClipboardBuffer buffer) const {
@@ -817,10 +817,10 @@ SkBitmap ClipboardWin::ReadImageInternal(ClipboardBuffer buffer) const {
void ClipboardWin::WriteToClipboard(ClipboardFormatType format, HANDLE handle) {
UINT cf_format = format.ToFormatEtc().cfFormat;

View File

@@ -20,10 +20,10 @@ to deal with color spaces. That is being tracked at
https://crbug.com/634542 and https://crbug.com/711107.
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index c0bdb8cf65f6162911135e11ef58943e7d20716f..b26cd1a4572bdd0c0dfbf343c64c9fde21054304 100644
index bb7ff971823db702991a3167b5b0ac1b3dd4a6c9..e5afad68300bdd6ac109b3c9b94d3c200d164456 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -1760,6 +1760,10 @@ void LayerTreeHostImpl::SetIsLikelyToRequireADraw(
@@ -1762,6 +1762,10 @@ void LayerTreeHostImpl::SetIsLikelyToRequireADraw(
gfx::ColorSpace LayerTreeHostImpl::GetRasterColorSpace(
gfx::ContentColorUsage content_color_usage) const {
@@ -35,10 +35,10 @@ index c0bdb8cf65f6162911135e11ef58943e7d20716f..b26cd1a4572bdd0c0dfbf343c64c9fde
// If we are likely to software composite the resource, we use sRGB because
diff --git a/cc/trees/layer_tree_settings.h b/cc/trees/layer_tree_settings.h
index 64fe3c1c3f60758c25f9bc88daedf35633508aa7..a2e9ebb3dc31b4e8665376ffb1f805c6093bce5c 100644
index e5a58655788be3bd1c86e238e34bbadf8012bc48..2a2de85e89a8a0f803b7c987620a259b26281d8d 100644
--- a/cc/trees/layer_tree_settings.h
+++ b/cc/trees/layer_tree_settings.h
@@ -98,6 +98,8 @@ class CC_EXPORT LayerTreeSettings {
@@ -99,6 +99,8 @@ class CC_EXPORT LayerTreeSettings {
bool use_rgba_4444 = false;
bool unpremultiply_and_dither_low_bit_depth_tiles = false;
@@ -229,7 +229,7 @@ index e5179c0e4971bc593860b1e5b606fec651e6756b..fc7c09d19c60d498885d3e4f1a4a4ac9
+
+#undef PATCH_CS
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc
index de4eadaf7be8be95fc0ad454d66c8ec397cfc20a..d4c451ea992490befb34b3690a98d968bb50b899 100644
index d7439d851d6c027a20bf09a258603939b5c19f1e..72162a468f63543c508a3d34e357be1dfcdeba51 100644
--- a/content/browser/gpu/gpu_process_host.cc
+++ b/content/browser/gpu/gpu_process_host.cc
@@ -221,6 +221,7 @@ GpuTerminationStatus ConvertToGpuTerminationStatus(
@@ -327,7 +327,7 @@ index 95e818f1406eb1a73a746b73a608137ab5c6e894..6e1d3b3b1add4eda90560856b6915d46
// is what the renderer uses if its not threaded.
settings.enable_checker_imaging =
diff --git a/ui/gfx/mac/io_surface.cc b/ui/gfx/mac/io_surface.cc
index 3e80dc40c83bd4eb96f9029643c4a0856253494e..8e19a78f106daf4185ee69970832ea1237d3d03b 100644
index ec83bd814a0d5d6802b349d08b22013a0d99e015..043e769e7db9773de2054dcc66f13f062823f58f 100644
--- a/ui/gfx/mac/io_surface.cc
+++ b/ui/gfx/mac/io_surface.cc
@@ -18,6 +18,7 @@
@@ -353,7 +353,7 @@ index 3e80dc40c83bd4eb96f9029643c4a0856253494e..8e19a78f106daf4185ee69970832ea12
// Allow but ignore invalid color spaces.
if (!color_space.IsValid())
return true;
@@ -265,6 +274,15 @@ IOSurfaceRef CreateIOSurface(const gfx::Size& size,
@@ -286,6 +295,15 @@ IOSurfaceRef CreateIOSurface(const gfx::Size& size,
DCHECK_EQ(kIOReturnSuccess, r);
}

View File

@@ -6,10 +6,10 @@ Subject: disable_hidden.patch
Electron uses this to disable background throttling for hidden windows.
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
index 529a5b71b9987be21bfb1494b420ef88bbd17f7a..19d7421e1de9680a8b1364f010e19cc95ef7325a 100644
index 1ff402be7362bd1dd64f3ffb88081f6cfac328d8..aa00ff974485d3093f05b0cdaeb6c8ed865015e3 100644
--- a/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -692,6 +692,9 @@ void RenderWidgetHostImpl::WasHidden() {
@@ -693,6 +693,9 @@ void RenderWidgetHostImpl::WasHidden() {
if (is_hidden_)
return;
@@ -20,7 +20,7 @@ index 529a5b71b9987be21bfb1494b420ef88bbd17f7a..19d7421e1de9680a8b1364f010e19cc9
blink::mojom::PointerLockResult::kWrongDocument);
diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h
index 9d7d10136a683620d6fb67246aae51df982930d0..c119dd8916fe2fbde97ce91cce6f788fc62f3534 100644
index 9f02961f7ef63d672b918439bb84121ea22e2931..66fd1cbec90c1ecc1f0f1a9722367a58d66c64fd 100644
--- a/content/browser/renderer_host/render_widget_host_impl.h
+++ b/content/browser/renderer_host/render_widget_host_impl.h
@@ -173,6 +173,9 @@ class CONTENT_EXPORT RenderWidgetHostImpl

View File

@@ -33,7 +33,7 @@ index 0ccfe130f00ec3b6c75cd8ee04d5a2777e1fd00c..653829457d58bf92057cc36aa8a28970
DISALLOW_COPY_AND_ASSIGN(StaticHttpUserAgentSettings);
};
diff --git a/services/network/network_context.cc b/services/network/network_context.cc
index f67b3159bb13d4892e656c18b5120c4901666344..7661dfc65295cdea2ee554a086c68cea4d8c4e9e 100644
index 3dc5c6d6027be44c1e799bb8e0b509a03bae963a..b2d9b7a74f71b3127f51ea2c4f4ed0caaa2bff05 100644
--- a/services/network/network_context.cc
+++ b/services/network/network_context.cc
@@ -1082,6 +1082,13 @@ void NetworkContext::SetNetworkConditions(

View File

@@ -62,7 +62,7 @@ index e2ca7dd198390ebc923facd690904faeb8300e62..f2f53775abb0ba2954cbb3ec431d84c3
};
diff --git a/ui/native_theme/native_theme_win.cc b/ui/native_theme/native_theme_win.cc
index eaf817b4b5400fa4d2b6af7c86ac69aabf030a38..0f702be38f8e015c4e61677db5cf566259650dc6 100644
index fd075a6f8a1357e7456a97d37af339848635a102..54fa642f614acd221ceaeee0938506e6fea41b1a 100644
--- a/ui/native_theme/native_theme_win.cc
+++ b/ui/native_theme/native_theme_win.cc
@@ -737,6 +737,8 @@ bool NativeThemeWin::ShouldUseDarkColors() const {

View File

@@ -7,10 +7,10 @@ Subject:
Disable usage of pthread_fchdir_np and pthread_chdir_np in MAS builds.
diff --git a/base/process/launch_mac.cc b/base/process/launch_mac.cc
index 2841b7735430ca3fb03fff7a737b393a8d168747..e356bfe7fdfc11b3b1df429337cf460037788dd8 100644
index c074f0d73eab1993b580f317c42480688e6669e6..2a86b0c6897efd10c483d0816b3f7a54f1e13d2a 100644
--- a/base/process/launch_mac.cc
+++ b/base/process/launch_mac.cc
@@ -26,8 +26,10 @@ extern "C" {
@@ -27,8 +27,10 @@ extern "C" {
// descriptor. libpthread only exposes a syscall wrapper starting in
// macOS 10.12, but the system call dates back to macOS 10.5. On older OSes,
// the syscall is issued directly.
@@ -21,7 +21,7 @@ index 2841b7735430ca3fb03fff7a737b393a8d168747..e356bfe7fdfc11b3b1df429337cf4600
int responsibility_spawnattrs_setdisclaim(posix_spawnattr_t attrs, int disclaim)
API_AVAILABLE(macosx(10.14));
@@ -102,21 +104,29 @@ class PosixSpawnFileActions {
@@ -103,21 +105,29 @@ class PosixSpawnFileActions {
};
int ChangeCurrentThreadDirectory(const char* path) {
@@ -51,7 +51,7 @@ index 2841b7735430ca3fb03fff7a737b393a8d168747..e356bfe7fdfc11b3b1df429337cf4600
}
struct GetAppOutputOptions {
@@ -232,11 +242,13 @@ Process LaunchProcess(const std::vector<std::string>& argv,
@@ -233,11 +243,13 @@ Process LaunchProcess(const std::vector<std::string>& argv,
file_actions.Inherit(STDERR_FILENO);
}

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