Compare commits

..

52 Commits

Author SHA1 Message Date
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
154 changed files with 3381 additions and 1009 deletions

View File

@@ -265,16 +265,25 @@ step-gclient-sync: &step-gclient-sync
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>"
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
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 (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
@@ -302,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
@@ -314,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
@@ -665,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

2
DEPS
View File

@@ -14,7 +14,7 @@ gclient_gn_args = [
vars = {
'chromium_version':
'87.0.4280.40',
'87.0.4280.67',
'node_version':
'v12.18.3',
'nan_version':

View File

@@ -1 +1 @@
11.0.0-beta.20
11.0.4

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

@@ -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

@@ -1341,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
@@ -1485,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

@@ -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.

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.

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

@@ -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

@@ -16,5 +16,23 @@ export default new Proxy({}, {
return v.bind(_screen);
}
return v;
},
ownKeys: () => {
if (_screen === undefined) {
_screen = createScreen();
}
return Reflect.ownKeys(_screen);
},
has: (target, prop: string) => {
if (_screen === undefined) {
_screen = createScreen();
}
return prop in _screen;
},
getOwnPropertyDescriptor: (target, prop: string) => {
if (_screen === undefined) {
_screen = createScreen();
}
return Reflect.getOwnPropertyDescriptor(_screen, prop);
}
});

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

@@ -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.20",
"version": "11.0.4",
"repository": "https://github.com/electron/electron",
"description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
"devDependencies": {
"@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

@@ -100,5 +100,9 @@ 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
rename_the_v8_context_snapshot_on_arm64_macos_builds.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

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 e811aec4853c1ba0dacdcad758a5bc834643d7e3..5eb2dcde4d2033015677681ceeba7da9b9fe32df 100644
index 72a3bd4837f37bb1bab1f5ca48e90c41a297337f..23ff9cc13aaa97d395983dceb2a27158b2d679a5 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -5034,6 +5034,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

@@ -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 497033d3d5257daffe4aca2ebdd1fd71513db73f..7412bf8f9a9e07975917514e7f4c13253112138a 100644
index 45ce62954b5527b3906c7ec8c06c41cf2dd4d111..bc55d9109d5c34e9f2b4a19424926e7f43ad5d4e 100644
--- a/content/browser/renderer_host/render_frame_host_impl.cc
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -4945,6 +4945,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 497033d3d5257daffe4aca2ebdd1fd71513db73f..7412bf8f9a9e07975917514e7f4c1325
&no_javascript_access);
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index a39f43b61afc70296470a9ed616d7e8a423780aa..b113c265dcf5b8e3c7533085f1b8409fa13bcfa0 100644
index 2640a8c6371083804da42565f65fb41cf1a57607..6aa0c4db0cf1a3644a20d0fe0c7e292f3d4bbd6f 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -3703,9 +3703,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,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

@@ -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 b41fce646b16e51ccfdcc6fef68d2f29195a24f2..f76896877ae828a6fa7901507a62491188b5cd2d 100644
index 62ddc2d8548bcac4d55bbc7283426c426fecf254..b0eb803cd132390d492b82600d8629e2c43cc72e 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -5955,6 +5955,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

@@ -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();
}

View File

@@ -35,10 +35,10 @@ index bb7ff971823db702991a3167b5b0ac1b3dd4a6c9..e5afad68300bdd6ac109b3c9b94d3c20
// 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

@@ -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);
}

View File

@@ -0,0 +1,128 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shelley Vohr <shelley.vohr@gmail.com>
Date: Wed, 23 Sep 2020 11:16:12 -0700
Subject: fix: properly honor printing page ranges
The print ranges in Chromium's print job settings were not being properly
plumbed through to PMPrintSettings on mcOS. This fixes that by setting
them should they exist.
diff --git a/printing/printing_context_mac.h b/printing/printing_context_mac.h
index 909aaf6ce803fed32eb1c64c0abcf272731762da..ba431655fe5894c7d9b04464ea36307a145ac198 100644
--- a/printing/printing_context_mac.h
+++ b/printing/printing_context_mac.h
@@ -82,6 +82,10 @@ class PRINTING_EXPORT PrintingContextMac : public PrintingContext {
// Returns true if the orientation was set.
bool SetOrientationIsLandscape(bool landscape);
+ // Set the page range in native print info object.
+ // Returns true if the range was set.
+ bool SetPrintRangeInPrintSettings(const PageRanges& ranges);
+
// Sets duplex mode in PMPrintSettings.
// Returns true if duplex mode is set.
bool SetDuplexModeInPrintSettings(mojom::DuplexMode mode);
diff --git a/printing/printing_context_mac.mm b/printing/printing_context_mac.mm
index 51c8ff31497fd03842ac9e7da4eab8a5919ec898..53e11ca26e82f2eac18a3465cabde2605b061319 100644
--- a/printing/printing_context_mac.mm
+++ b/printing/printing_context_mac.mm
@@ -188,7 +188,8 @@ PMPaper MatchPaper(CFArrayRef paper_list,
!SetCopiesInPrintSettings(settings_->copies()) ||
!SetCollateInPrintSettings(settings_->collate()) ||
!SetDuplexModeInPrintSettings(settings_->duplex_mode()) ||
- !SetOutputColor(static_cast<int>(settings_->color()))) {
+ !SetOutputColor(static_cast<int>(settings_->color())) ||
+ !SetPrintRangeInPrintSettings(settings_->ranges())) {
return OnError();
}
}
@@ -341,6 +342,22 @@ PMPaper MatchPaper(CFArrayRef paper_list,
return PMSetCopies(print_settings, copies, false) == noErr;
}
+bool PrintingContextMac::SetPrintRangeInPrintSettings(const PageRanges& ranges) {
+ // Default is already NSPrintAllPages - we can safely bail.
+ if (ranges.empty())
+ return true;
+
+ auto* print_settings =
+ static_cast<PMPrintSettings>([print_info_.get() PMPrintSettings]);
+
+ // macOS does not allow multiple ranges, so pluck the first.
+ auto range = ranges.front();
+ bool set_first_page = PMSetFirstPage(print_settings, range.from + 1, false) == noErr;
+ bool set_last_page = PMSetLastPage(print_settings, range.to + 1, false) == noErr;
+
+ return set_first_page && set_last_page;
+}
+
bool PrintingContextMac::SetCollateInPrintSettings(bool collate) {
PMPrintSettings print_settings =
static_cast<PMPrintSettings>([print_info_.get() PMPrintSettings]);
diff --git a/printing/printing_context_system_dialog_win.cc b/printing/printing_context_system_dialog_win.cc
index d3c8677f30d72efc49b28f293260c74c7b8d8b4e..f6e66aaa58ab1881d64dcbb320ae8b5ac7631b28 100644
--- a/printing/printing_context_system_dialog_win.cc
+++ b/printing/printing_context_system_dialog_win.cc
@@ -52,14 +52,28 @@ void PrintingContextSystemDialogWin::AskUserForSettings(
PRINTPAGERANGE ranges[32];
dialog_options.nStartPage = START_PAGE_GENERAL;
if (max_pages) {
- // Default initialize to print all the pages.
memset(ranges, 0, sizeof(ranges));
- ranges[0].nFromPage = 1;
- ranges[0].nToPage = max_pages;
- dialog_options.nPageRanges = 1;
- dialog_options.nMaxPageRanges = base::size(ranges);
+
+ auto page_ranges = settings_->ranges();
+ if (!page_ranges.empty()) {
+ for (size_t i = 0; i < page_ranges.size(); i++) {
+ auto range = page_ranges[i];
+ ranges[i].nFromPage = range.from + 1;
+ ranges[i].nToPage = range.to + 1;
+ }
+ dialog_options.nPageRanges = page_ranges.size();
+
+ // Ensure the Pages radio button is selected.
+ dialog_options.Flags |= PD_PAGENUMS;
+ } else {
+ ranges[0].nFromPage = 1;
+ ranges[0].nToPage = max_pages;
+ dialog_options.nPageRanges = 1;
+ }
+
dialog_options.nMinPage = 1;
dialog_options.nMaxPage = max_pages;
+ dialog_options.nMaxPageRanges = base::size(ranges);
dialog_options.lpPageRanges = ranges;
} else {
// No need to bother, we don't know how many pages are available.
diff --git a/ui/gtk/printing/print_dialog_gtk.cc b/ui/gtk/printing/print_dialog_gtk.cc
index f2ed36e1258f4f3ef1bfce972e215e3d5d7335b6..5b38bf1369a68546f0aeea8948abba995c65e7f7 100644
--- a/ui/gtk/printing/print_dialog_gtk.cc
+++ b/ui/gtk/printing/print_dialog_gtk.cc
@@ -239,6 +239,24 @@ void PrintDialogGtk::UpdateSettings(
gtk_print_settings_set_n_copies(gtk_settings_, settings->copies());
gtk_print_settings_set_collate(gtk_settings_, settings->collate());
+
+ auto print_ranges = settings->ranges();
+ if (!print_ranges.empty()) {
+ // Tell the system that we only intend to print a subset of pages.
+ gtk_print_settings_set_print_pages(gtk_settings_, GTK_PRINT_PAGES_RANGES);
+
+ GtkPageRange* ranges;
+ ranges = g_new(GtkPageRange, print_ranges.size());
+ for (size_t i = 0; i < print_ranges.size(); i++) {
+ auto range = print_ranges[i];
+ ranges[i].start = range.from;
+ ranges[i].end = range.to;
+ }
+
+ gtk_print_settings_set_page_ranges(gtk_settings_, ranges, 1);
+ g_free(ranges);
+ }
+
if (settings->dpi_horizontal() > 0 && settings->dpi_vertical() > 0) {
gtk_print_settings_set_resolution_xy(
gtk_settings_, settings->dpi_horizontal(), settings->dpi_vertical());

View File

@@ -13,10 +13,10 @@ This patch can be removed once app.allowRendererProcessReuse is forced
to true as then Chromiums assumptions around processes become correct.
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index b113c265dcf5b8e3c7533085f1b8409fa13bcfa0..b80aab0f3b4a1389e6dd740d23df8f1beb051deb 100644
index 6aa0c4db0cf1a3644a20d0fe0c7e292f3d4bbd6f..c480e16575df51cede26c83ed9455af9cb207f8c 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -3075,11 +3075,13 @@ bool WebContentsImpl::HandleMouseEvent(const blink::WebMouseEvent& event) {
@@ -3076,11 +3076,13 @@ bool WebContentsImpl::HandleMouseEvent(const blink::WebMouseEvent& event) {
WebContentsImpl* outermost = GetOutermostWebContents();
if (event.button == blink::WebPointerProperties::Button::kBack &&
outermost->controller_.CanGoBack()) {

View File

@@ -42,10 +42,10 @@ index 75a58c7f56ef990e340ef271aa2d057f3541c47d..ab2679680111cfdc260c8d8dafbfae00
// another SiteInstance for the same site.
void RegisterSiteInstance(SiteInstanceImpl* site_instance);
diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc
index ab58967aba4143d5a39f51d7bbeed0568e2fa012..102c72335f0b3e7116c982784a3b0a26d780a618 100644
index e4942faa3fbf90c2819620d3f091aea59299522d..60b2b213d6429fa7cff783370cbbeff26a97a859 100644
--- a/content/browser/renderer_host/navigation_request.cc
+++ b/content/browser/renderer_host/navigation_request.cc
@@ -1396,6 +1396,21 @@ void NavigationRequest::BeginNavigation() {
@@ -1397,6 +1397,21 @@ void NavigationRequest::BeginNavigation() {
// it immediately.
EnterChildTraceEvent("ResponseStarted", this);
@@ -67,7 +67,7 @@ index ab58967aba4143d5a39f51d7bbeed0568e2fa012..102c72335f0b3e7116c982784a3b0a26
// Select an appropriate RenderFrameHost.
render_frame_host_ =
frame_tree_node_->render_manager()->GetFrameHostForNavigation(this);
@@ -5066,6 +5081,7 @@ void NavigationRequest::CheckStateTransition(NavigationState state) const {
@@ -5067,6 +5082,7 @@ void NavigationRequest::CheckStateTransition(NavigationState state) const {
{WILL_START_REQUEST, {
WILL_REDIRECT_REQUEST,
WILL_PROCESS_RESPONSE,
@@ -75,7 +75,7 @@ index ab58967aba4143d5a39f51d7bbeed0568e2fa012..102c72335f0b3e7116c982784a3b0a26
READY_TO_COMMIT,
DID_COMMIT,
CANCELING,
@@ -5079,10 +5095,14 @@ void NavigationRequest::CheckStateTransition(NavigationState state) const {
@@ -5080,10 +5096,14 @@ void NavigationRequest::CheckStateTransition(NavigationState state) const {
WILL_FAIL_REQUEST,
}},
{WILL_PROCESS_RESPONSE, {
@@ -91,7 +91,7 @@ index ab58967aba4143d5a39f51d7bbeed0568e2fa012..102c72335f0b3e7116c982784a3b0a26
NOT_STARTED,
DID_COMMIT,
diff --git a/content/browser/renderer_host/navigation_request.h b/content/browser/renderer_host/navigation_request.h
index 8ed463f9f7255bdd74471d3d06c17044c68bc953..c31a9e5a4a14e2c3f745b297ebe7355383c2b8bb 100644
index cc726282fd93048177174d91e01b7c4a3ad9fdcd..2685a56b7b1582e66d90fbc07e04462b68c59a0f 100644
--- a/content/browser/renderer_host/navigation_request.h
+++ b/content/browser/renderer_host/navigation_request.h
@@ -129,6 +129,10 @@ class CONTENT_EXPORT NavigationRequest
@@ -255,7 +255,7 @@ index cafd45df059293bc1cf31e1d7b798e67578f3e9d..c196b783fe0a43bfee98253afe8461a0
const MainFunctionParams& parameters) {
return nullptr;
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
index 9953cc472c04c2dc6ae0f70b64ea2b8d6ac86a05..5200555594d41f52bcf208b55c346323d7017b81 100644
index 3b93afa004fb4d56ade2ab16147b42f26e90e3db..9156388fda045775145302f2c7fd810b0f61bd84 100644
--- a/content/public/browser/content_browser_client.h
+++ b/content/public/browser/content_browser_client.h
@@ -253,8 +253,45 @@ class CONTENT_EXPORT ContentBrowserClient {

View File

@@ -38,10 +38,10 @@ index f23af2d9738f3aa76e3a49301e1c3216ee4a64b4..ede178acabc63c3c33d6ce93efd5632b
v8::Isolate* isolate() { return isolate_; }
diff --git a/gin/v8_initializer.cc b/gin/v8_initializer.cc
index 9ba60a7f928a24b4829dafdf9a7362ad58bd7c64..51fe2fa000e47ced3661ba581c52dceba93447fe 100644
index 4174fd98f3a1d9ed6c9a4b57651e8122a2d37770..07d970b84b770b06019dc1de441cf108d67b1782 100644
--- a/gin/v8_initializer.cc
+++ b/gin/v8_initializer.cc
@@ -191,12 +191,14 @@ enum LoadV8FileResult {
@@ -198,12 +198,14 @@ enum LoadV8FileResult {
} // namespace
// static

View File

@@ -12,7 +12,7 @@ rendering and there is no signal from browser process on this event
to identify it.
diff --git a/content/browser/gpu/gpu_data_manager_impl.cc b/content/browser/gpu/gpu_data_manager_impl.cc
index 694f63ecd2de241fd1a8b7b529bbd4d1bea78337..cc9679eb86f85239f5612d8db8200db5392f5bc5 100644
index 1f36d0320040b318c8f8611253ddffb2749e3dc3..15bcff79b7d416366b1d1dc187c966466a2eacb7 100644
--- a/content/browser/gpu/gpu_data_manager_impl.cc
+++ b/content/browser/gpu/gpu_data_manager_impl.cc
@@ -229,6 +229,11 @@ void GpuDataManagerImpl::TerminateInfoCollectionGpuProcess() {
@@ -28,7 +28,7 @@ index 694f63ecd2de241fd1a8b7b529bbd4d1bea78337..cc9679eb86f85239f5612d8db8200db5
void GpuDataManagerImpl::UpdateGpuFeatureInfo(
diff --git a/content/browser/gpu/gpu_data_manager_impl.h b/content/browser/gpu/gpu_data_manager_impl.h
index 7030549c94196877b690e8f683dda212534176ec..e9b216f65394e36525533768e087cd367d7bfaae 100644
index ef04f1bf4a009c3e6c4fe0cb2d3393ca9bbcef16..1640de1fbcbbf6904b9aaac7b8f6a58feda8ead6 100644
--- a/content/browser/gpu/gpu_data_manager_impl.h
+++ b/content/browser/gpu/gpu_data_manager_impl.h
@@ -97,6 +97,7 @@ class CONTENT_EXPORT GpuDataManagerImpl : public GpuDataManager,
@@ -56,7 +56,7 @@ index 879e233fa550b3aad94b64fb1ac603cbae782922..cecf9738c6e33c766fcadea8c71b6656
void GpuDataManagerImplPrivate::UpdateGpuFeatureInfo(
diff --git a/content/browser/gpu/gpu_data_manager_impl_private.h b/content/browser/gpu/gpu_data_manager_impl_private.h
index 27b517d56af0c687c15b7e2d2db37798b63df3e8..aa92f8b6e12c762cdb81090d072c76742ac9489c 100644
index 73b6c034e382e52dbcb951ee8d783575f01fe451..5d1d8a6bc719c4c9c71e6bce40c50cdfbedf4634 100644
--- a/content/browser/gpu/gpu_data_manager_impl_private.h
+++ b/content/browser/gpu/gpu_data_manager_impl_private.h
@@ -75,6 +75,7 @@ class CONTENT_EXPORT GpuDataManagerImplPrivate {

View File

@@ -43,10 +43,10 @@ index 19d7421e1de9680a8b1364f010e19cc95ef7325a..b213e28a6a475d003892117c0a64c70b
void RenderWidgetHostImpl::OnCursorVisibilityStateChanged(bool is_visible) {
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 2e32ddda8980ed760e46e73e01c69c548e77b7b6..2927f0b9ce03a0567a460698903d17d62fc42c95 100644
index 2894425cecf01849928cffeb3b5a565741f303f1..53aa670f317249da6a39dee60ec3a9f02baa5e61 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -4270,6 +4270,12 @@ bool WebContentsImpl::OnUpdateDragCursor() {
@@ -4279,6 +4279,12 @@ bool WebContentsImpl::OnUpdateDragCursor() {
browser_plugin_embedder_->OnUpdateDragCursor();
}

View File

@@ -1,214 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Attard <samuel.r.attard@gmail.com>
Date: Wed, 21 Oct 2020 13:13:00 -0700
Subject: rename the v8 context snapshot on arm64 macOS builds
This is done so that the arm64 and x64 v8 context snapshots can
live side by side in a universal app build of a Chromium based
application. All other files can be Mach-O universal binaries
generated using "lipo" but these snapshot files have to be uniquely
named so that both can exist in the Resources folder at the same time
and the correct one is chosen at runtime.
Bug: 1142017
Change-Id: I8449b72ba3a36e7ce69b9d9ec7768bd80ecc3e3a
diff --git a/android_webview/BUILD.gn b/android_webview/BUILD.gn
index 169a790b48dd6a76b59bc17c94871e23499bd6fb..3dbca6cfba89ffbbddb23832a090c4ca5a2323b6 100644
--- a/android_webview/BUILD.gn
+++ b/android_webview/BUILD.gn
@@ -790,7 +790,7 @@ if (android_64bit_target_cpu) {
"32-bit targets shouldn't have secondary abi")
arch_suffix = "32"
if (use_v8_context_snapshot) {
- renaming_sources = [ "$_secondary_abi_out_dir/v8_context_snapshot.bin" ]
+ renaming_sources = [ "$_secondary_abi_out_dir/$v8_context_snapshot_filename" ]
renaming_destinations = [ "v8_context_snapshot_$arch_suffix.bin" ]
} else {
renaming_sources = [ "$_secondary_abi_out_dir/snapshot_blob.bin" ]
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn
index 56f5ff4c628daa7f42f4c84c9a4b98f3f250a2b0..15f7a164662b9e90fa43eb893d743182e05b48fa 100644
--- a/chrome/BUILD.gn
+++ b/chrome/BUILD.gn
@@ -772,7 +772,7 @@ if (is_win) {
if (v8_use_external_startup_data) {
public_deps += [ "//v8" ]
if (use_v8_context_snapshot) {
- sources += [ "$root_out_dir/v8_context_snapshot.bin" ]
+ sources += [ "$root_out_dir/$v8_context_snapshot_filename" ]
public_deps += [ "//tools/v8_context_snapshot" ]
} else {
sources += [ "$root_out_dir/snapshot_blob.bin" ]
diff --git a/chrome/installer/mini_installer/BUILD.gn b/chrome/installer/mini_installer/BUILD.gn
index 7c7af8c0d9487abcd82ecd9d2d5b1ab4b737148b..df39ea145cc6b05775db7fbfb680fce892b8941a 100644
--- a/chrome/installer/mini_installer/BUILD.gn
+++ b/chrome/installer/mini_installer/BUILD.gn
@@ -228,7 +228,7 @@ template("generate_mini_installer") {
if (v8_use_external_startup_data) {
deps += [ "//v8" ]
if (use_v8_context_snapshot) {
- inputs += [ "$root_out_dir/v8_context_snapshot.bin" ]
+ inputs += [ "$root_out_dir/$v8_context_snapshot_filename" ]
deps += [ "//tools/v8_context_snapshot" ]
} else {
inputs += [ "$root_out_dir/snapshot_blob.bin" ]
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index fcf6229f4d530c56b7c65fe6898c00a8a566dc1a..b3115bab5c08106072e28a9f01304f688d51f72b 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -43,6 +43,7 @@ source_set("browser") {
configs += [
"//build/config:precompiled_headers",
"//content:content_implementation",
+ "//tools/v8_context_snapshot:use_v8_context_snapshot",
"//v8:external_startup_data",
]
defines = []
diff --git a/content/browser/v8_snapshot_files.cc b/content/browser/v8_snapshot_files.cc
index d557c41a38e17c61e1b91d3daa47ea17e13a6a9e..43c93e3f50290d2aef230083a4bcebf307ef0c6e 100644
--- a/content/browser/v8_snapshot_files.cc
+++ b/content/browser/v8_snapshot_files.cc
@@ -13,7 +13,7 @@ std::map<std::string, base::FilePath> GetV8SnapshotFilesToPreload() {
#if defined(OS_LINUX) || defined(OS_CHROMEOS)
#if defined(USE_V8_CONTEXT_SNAPSHOT)
return {{kV8ContextSnapshotDataDescriptor,
- base::FilePath(FILE_PATH_LITERAL("v8_context_snapshot.bin"))}};
+ base::FilePath(FILE_PATH_LITERAL(V8_CONTEXT_SNAPSHOT_FILENAME))}};
#else
return {{kV8SnapshotDataDescriptor,
base::FilePath(FILE_PATH_LITERAL("snapshot_blob.bin"))}};
diff --git a/content/shell/BUILD.gn b/content/shell/BUILD.gn
index 578e4341247e112440b13080b45ac5e854635bd2..74c1e0f29db065985920756ae057e255d76e51c2 100644
--- a/content/shell/BUILD.gn
+++ b/content/shell/BUILD.gn
@@ -547,7 +547,7 @@ if (is_mac) {
if (v8_use_external_startup_data) {
public_deps += [ "//v8" ]
if (use_v8_context_snapshot) {
- sources += [ "$root_out_dir/v8_context_snapshot.bin" ]
+ sources += [ "$root_out_dir/$v8_context_snapshot_filename" ]
public_deps += [ "//tools/v8_context_snapshot" ]
} else {
sources += [ "$root_out_dir/snapshot_blob.bin" ]
diff --git a/gin/BUILD.gn b/gin/BUILD.gn
index 9ec6eb1b898bc87d066bdc75867ff624f7ef1f50..dfc59c17382f8463e82185032d977a1868c71985 100644
--- a/gin/BUILD.gn
+++ b/gin/BUILD.gn
@@ -85,7 +85,10 @@ component("gin") {
frameworks = [ "CoreFoundation.framework" ]
}
- configs += [ "//v8:external_startup_data" ]
+ configs += [
+ "//tools/v8_context_snapshot:use_v8_context_snapshot",
+ "//v8:external_startup_data",
+ ]
}
executable("gin_shell") {
diff --git a/gin/v8_initializer.cc b/gin/v8_initializer.cc
index 51fe2fa000e47ced3661ba581c52dceba93447fe..07d970b84b770b06019dc1de441cf108d67b1782 100644
--- a/gin/v8_initializer.cc
+++ b/gin/v8_initializer.cc
@@ -76,7 +76,9 @@ const char kSnapshotFileName32[] = "snapshot_blob_32.bin";
#endif
#else // defined(OS_ANDROID)
-const char kV8ContextSnapshotFileName[] = "v8_context_snapshot.bin";
+#if defined(USE_V8_CONTEXT_SNAPSHOT)
+const char kV8ContextSnapshotFileName[] = V8_CONTEXT_SNAPSHOT_FILENAME;
+#endif
const char kSnapshotFileName[] = "snapshot_blob.bin";
#endif // defined(OS_ANDROID)
@@ -86,7 +88,12 @@ const char* GetSnapshotFileName(
case V8Initializer::V8SnapshotFileType::kDefault:
return kSnapshotFileName;
case V8Initializer::V8SnapshotFileType::kWithAdditionalContext:
+#if defined(USE_V8_CONTEXT_SNAPSHOT)
return kV8ContextSnapshotFileName;
+#else
+ NOTREACHED();
+ return nullptr;
+#endif
}
NOTREACHED();
return nullptr;
diff --git a/headless/BUILD.gn b/headless/BUILD.gn
index aeab3dc3ad08688b7a7af191b43e20845da72091..d2ab76aed326d246c8f8d550ff709b84b56e45d3 100644
--- a/headless/BUILD.gn
+++ b/headless/BUILD.gn
@@ -471,7 +471,7 @@ component("headless_non_renderer") {
if (v8_use_external_startup_data) {
public_deps += [ "//v8" ]
if (use_v8_context_snapshot) {
- data += [ "$root_out_dir/v8_context_snapshot.bin" ]
+ data += [ "$root_out_dir/$v8_context_snapshot_filename" ]
data_deps += [ "//tools/v8_context_snapshot" ]
} else {
data += [ "$root_out_dir/snapshot_blob.bin" ]
diff --git a/tools/v8_context_snapshot/BUILD.gn b/tools/v8_context_snapshot/BUILD.gn
index 2f20f684d89021dcd0e64421a0553a3e4a66334d..7662cc8ee83e39709eee6e0919c85370fedbb983 100644
--- a/tools/v8_context_snapshot/BUILD.gn
+++ b/tools/v8_context_snapshot/BUILD.gn
@@ -21,14 +21,17 @@ group("v8_context_snapshot") {
if (use_v8_context_snapshot) {
public_deps = [ ":generate_v8_context_snapshot" ]
if (!is_android) {
- data = [ "$root_out_dir/v8_context_snapshot.bin" ]
+ data = [ "$root_out_dir/$v8_context_snapshot_filename" ]
}
}
}
config("use_v8_context_snapshot") {
if (use_v8_context_snapshot) {
- defines = [ "USE_V8_CONTEXT_SNAPSHOT" ]
+ defines = [
+ "USE_V8_CONTEXT_SNAPSHOT",
+ "V8_CONTEXT_SNAPSHOT_FILENAME=\"$v8_context_snapshot_filename\"",
+ ]
}
}
@@ -36,7 +39,7 @@ if (use_v8_context_snapshot) {
if (is_android && enable_java_templates) {
android_assets("v8_context_snapshot_assets") {
deps = [ ":v8_context_snapshot" ]
- renaming_sources = [ "$root_out_dir/v8_context_snapshot.bin" ]
+ renaming_sources = [ "$root_out_dir/$v8_context_snapshot_filename" ]
if (current_cpu == "arm" || current_cpu == "x86" ||
current_cpu == "mipsel") {
renaming_destinations = [ "v8_context_snapshot_32.bin" ]
@@ -49,7 +52,7 @@ if (use_v8_context_snapshot) {
action("generate_v8_context_snapshot") {
script = "//build/gn_run_binary.py"
- output_file = "$root_out_dir/v8_context_snapshot.bin"
+ output_file = "$root_out_dir/$v8_context_snapshot_filename"
output_path = rebase_path(output_file, root_build_dir)
args = [
diff --git a/tools/v8_context_snapshot/v8_context_snapshot.gni b/tools/v8_context_snapshot/v8_context_snapshot.gni
index 6a6f477ad3f543680cd6485bdf6b0e82d567012c..7f485e135cef8e3f0c01ede28b4cfe76067bc624 100644
--- a/tools/v8_context_snapshot/v8_context_snapshot.gni
+++ b/tools/v8_context_snapshot/v8_context_snapshot.gni
@@ -18,6 +18,18 @@ declare_args() {
!is_chromeos && !is_android && !is_chromecast && !is_fuchsia &&
!(host_os == "mac" && current_cpu == "x86") &&
(v8_target_cpu == target_cpu || is_msan) && !(is_win && host_os != "win")
+
+ # We use a different filename for arm64 macOS builds so that the arm64 and
+ # x64 snapshots can live side-by-side in a universal macOS app.
+ if (is_mac) {
+ if (v8_target_cpu == "x64") {
+ v8_context_snapshot_filename = "v8_context_snapshot.x86_64.bin"
+ } else if (v8_target_cpu == "arm64") {
+ v8_context_snapshot_filename = "v8_context_snapshot.arm64.bin"
+ }
+ } else {
+ v8_context_snapshot_filename = "v8_context_snapshot.bin"
+ }
}
# We cannot use V8 context snapshot, if V8 doesn't use snapshot files.

View File

@@ -10,10 +10,10 @@ kinds of utility windows. Similarly for `disableAutoHideCursor`.
Additionally, disables usage of some private APIs in MAS builds.
diff --git a/content/app_shim_remote_cocoa/render_widget_host_view_cocoa.mm b/content/app_shim_remote_cocoa/render_widget_host_view_cocoa.mm
index eae6d8c330a523e85c7997e59091be0ce42031dc..3f23af8dca0d8a1fa149877cde1a553360610eba 100644
index eae6d8c330a523e85c7997e59091be0ce42031dc..d90f13139cfc9291c76824a6529e2931176d1079 100644
--- a/content/app_shim_remote_cocoa/render_widget_host_view_cocoa.mm
+++ b/content/app_shim_remote_cocoa/render_widget_host_view_cocoa.mm
@@ -154,6 +154,11 @@ void ExtractUnderlines(NSAttributedString* string,
@@ -154,6 +154,15 @@ void ExtractUnderlines(NSAttributedString* string,
} // namespace
@@ -21,11 +21,15 @@ index eae6d8c330a523e85c7997e59091be0ce42031dc..3f23af8dca0d8a1fa149877cde1a5533
+- (BOOL)acceptsFirstMouse;
+- (BOOL)disableAutoHideCursor;
+@end
+
+@interface NSView (ElectronCustomMethods)
+- (BOOL)shouldIgnoreMouseEvent;
+@end
+
// These are not documented, so use only after checking -respondsToSelector:.
@interface NSApplication (UndocumentedSpeechMethods)
- (void)speakString:(NSString*)string;
@@ -573,6 +578,9 @@ - (BOOL)acceptsMouseEventsWhenInactive {
@@ -573,6 +582,9 @@ - (BOOL)acceptsMouseEventsWhenInactive {
}
- (BOOL)acceptsFirstMouse:(NSEvent*)theEvent {
@@ -35,7 +39,18 @@ index eae6d8c330a523e85c7997e59091be0ce42031dc..3f23af8dca0d8a1fa149877cde1a5533
return [self acceptsMouseEventsWhenInactive];
}
@@ -996,6 +1004,10 @@ - (void)keyEvent:(NSEvent*)theEvent wasKeyEquivalent:(BOOL)equiv {
@@ -648,6 +660,10 @@ - (BOOL)shouldIgnoreMouseEvent:(NSEvent*)theEvent {
// its parent view.
BOOL hitSelf = NO;
while (view) {
+ if ([view respondsToSelector:@selector(shouldIgnoreMouseEvent)] && ![view shouldIgnoreMouseEvent]) {
+ return NO;
+ }
+
if (view == self)
hitSelf = YES;
if ([view isKindOfClass:[self class]] && ![view isEqual:self] &&
@@ -996,6 +1012,10 @@ - (void)keyEvent:(NSEvent*)theEvent wasKeyEquivalent:(BOOL)equiv {
eventType == NSKeyDown &&
!(modifierFlags & NSCommandKeyMask);
@@ -46,7 +61,7 @@ index eae6d8c330a523e85c7997e59091be0ce42031dc..3f23af8dca0d8a1fa149877cde1a5533
// We only handle key down events and just simply forward other events.
if (eventType != NSKeyDown) {
_hostHelper->ForwardKeyboardEvent(event, latency_info);
@@ -1772,9 +1784,11 @@ - (NSAccessibilityRole)accessibilityRole {
@@ -1772,9 +1792,11 @@ - (NSAccessibilityRole)accessibilityRole {
// Since this implementation doesn't have to wait any IPC calls, this doesn't
// make any key-typing jank. --hbono 7/23/09
//
@@ -58,7 +73,7 @@ index eae6d8c330a523e85c7997e59091be0ce42031dc..3f23af8dca0d8a1fa149877cde1a5533
- (NSArray*)validAttributesForMarkedText {
// This code is just copied from WebKit except renaming variables.
@@ -1783,7 +1797,10 @@ - (NSArray*)validAttributesForMarkedText {
@@ -1783,7 +1805,10 @@ - (NSArray*)validAttributesForMarkedText {
initWithObjects:NSUnderlineStyleAttributeName,
NSUnderlineColorAttributeName,
NSMarkedClauseSegmentAttributeName,

View File

@@ -52,10 +52,10 @@ Some alternatives to this patch:
None of these options seems like a substantial maintainability win over this patch to me (@nornagon).
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn
index bfaf61fe2622812724617267bfe099bb9608dfff..56f5ff4c628daa7f42f4c84c9a4b98f3f250a2b0 100644
index 7913e9c6bd0a275543b2183761134826aa14a5c8..1a4a98c25b39b5879c19f999dfd680141500ef09 100644
--- a/chrome/BUILD.gn
+++ b/chrome/BUILD.gn
@@ -1434,7 +1434,7 @@ if (is_chrome_branded && !is_android) {
@@ -1437,7 +1437,7 @@ if (is_chrome_branded && !is_android) {
}
}
@@ -64,7 +64,7 @@ index bfaf61fe2622812724617267bfe099bb9608dfff..56f5ff4c628daa7f42f4c84c9a4b98f3
chrome_paks("packed_resources") {
if (is_mac) {
output_dir = "$root_gen_dir/repack"
@@ -1454,6 +1454,12 @@ if (!is_android) {
@@ -1457,6 +1457,12 @@ if (!is_android) {
}
}

View File

@@ -92,10 +92,10 @@ index 541fb915a2096a6ea56860662fff9f1dec9929cf..e4637fc393bafcdeac62cd4257f42451
// |url|. If the function returns a valid |new_url|, the request must be
// updated to use it. The |force_ignore_site_for_cookies| output parameter
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 5eb2dcde4d2033015677681ceeba7da9b9fe32df..6b3177a36bcd47192c967562d72bee02fb9ebc81 100644
index 23ff9cc13aaa97d395983dceb2a27158b2d679a5..d6ca9930c8c8caacac4e3d7f8a65189349589464 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -5797,6 +5797,23 @@ void RenderFrameImpl::BeginNavigation(
@@ -5799,6 +5799,23 @@ void RenderFrameImpl::BeginNavigation(
// we can do a per-frame check here rather than a process-wide check.
bool should_fork = HasWebUIScheme(url) || HasWebUIScheme(old_url) ||
(enabled_bindings_ & kWebUIBindingsPolicyMask);

View File

@@ -0,0 +1,37 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Attard <samuel.r.attard@gmail.com>
Date: Tue, 17 Nov 2020 16:59:28 -0800
Subject: use public APIs to determine if a font is a system font in MAS build
CTFontDescriptorIsSystemUIFont is a private API, we're using an _interesting_ technique in the MAS build to determine if the font is a system font by checking if it's kCTFontPriorityAttribute is set to system priority.
diff --git a/ui/gfx/platform_font_mac.mm b/ui/gfx/platform_font_mac.mm
index fc6047806e3511f60b58a669fdf628e1a48eb05b..bcc29ac87cfc965eb4c3f06d959605d2cb259770 100644
--- a/ui/gfx/platform_font_mac.mm
+++ b/ui/gfx/platform_font_mac.mm
@@ -25,9 +25,11 @@
using Weight = Font::Weight;
+#if !defined(MAS_BUILD)
extern "C" {
bool CTFontDescriptorIsSystemUIFont(CTFontDescriptorRef);
}
+#endif
namespace {
@@ -269,7 +271,13 @@ NSInteger ToNSFontManagerWeight(Weight weight) {
// TODO(avi, etienneb): Figure out this font stuff.
base::ScopedCFTypeRef<CTFontDescriptorRef> descriptor(
CTFontCopyFontDescriptor(font));
+#if defined(MAS_BUILD)
+ CFNumberRef priority = (CFNumberRef)CTFontDescriptorCopyAttribute(descriptor.get(), (CFStringRef)kCTFontPriorityAttribute);
+ SInt64 v;
+ if (CFNumberGetValue(priority, kCFNumberSInt64Type, &v) && v == kCTFontPrioritySystem) {
+#else
if (CTFontDescriptorIsSystemUIFont(descriptor.get())) {
+#endif
// Assume it's the standard system font. The fact that this much is known is
// enough.
return PlatformFontMac::SystemFontType::kGeneral;

View File

@@ -7,10 +7,10 @@ v8_context_snapshot_generator is a build time executable.
The patch adds the config.
diff --git a/tools/v8_context_snapshot/BUILD.gn b/tools/v8_context_snapshot/BUILD.gn
index 7728ccccee97e747d476500baf0ae46a52b66ae3..2f20f684d89021dcd0e64421a0553a3e4a66334d 100644
index c238e7e3837e0ee521374045b28340a8fc223a7d..7662cc8ee83e39709eee6e0919c85370fedbb983 100644
--- a/tools/v8_context_snapshot/BUILD.gn
+++ b/tools/v8_context_snapshot/BUILD.gn
@@ -112,6 +112,7 @@ if (use_v8_context_snapshot) {
@@ -115,6 +115,7 @@ if (use_v8_context_snapshot) {
configs += [
"//v8:external_startup_data",
":disable_icf",

View File

@@ -9,10 +9,10 @@ is needed for OSR.
Originally landed in https://github.com/electron/libchromiumcontent/pull/226.
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index b80aab0f3b4a1389e6dd740d23df8f1beb051deb..2e32ddda8980ed760e46e73e01c69c548e77b7b6 100644
index c480e16575df51cede26c83ed9455af9cb207f8c..2894425cecf01849928cffeb3b5a565741f303f1 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -2770,6 +2770,12 @@ void WebContentsImpl::Init(const WebContents::CreateParams& params) {
@@ -2771,6 +2771,12 @@ void WebContentsImpl::Init(const WebContents::CreateParams& params) {
std::string unique_name;
frame_tree_.root()->SetFrameName(params.main_frame_name, unique_name);
@@ -25,7 +25,7 @@ index b80aab0f3b4a1389e6dd740d23df8f1beb051deb..2e32ddda8980ed760e46e73e01c69c54
WebContentsViewDelegate* delegate =
GetContentClient()->browser()->GetWebContentsViewDelegate(this);
@@ -2780,6 +2786,7 @@ void WebContentsImpl::Init(const WebContents::CreateParams& params) {
@@ -2781,6 +2787,7 @@ void WebContentsImpl::Init(const WebContents::CreateParams& params) {
view_.reset(CreateWebContentsView(this, delegate,
&render_view_host_delegate_view_));
}

View File

@@ -7,7 +7,5 @@ workaround_an_undefined_symbol_error.patch
do_not_export_private_v8_symbols_on_windows.patch
revert_cleanup_switch_offset_of_to_offsetof_where_possible.patch
fix_build_deprecated_attirbute_for_older_msvc_versions.patch
chore_add_v8_apple_silicon_patches.patch
fix_use_proper_page_size_for_mac_arm64.patch
fix_correct_calling_convention_for_windows_on_arm.patch
perf_make_getpositioninfoslow_faster.patch

View File

@@ -9,10 +9,10 @@ necessary for native modules to load.
Also, some fixes relating to mksnapshot on ARM.
diff --git a/BUILD.gn b/BUILD.gn
index 704ed28caa59eb6159baa2be4f6f94d62db74c16..8bdb2718008eed2a04a916253850a76b5eff8c96 100644
index 94b598bc9a2882c1a47fad6d2c47068b472ecb6c..128271ee0305baef31001894a163beff98bcdd6a 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -411,7 +411,7 @@ config("internal_config") {
@@ -410,7 +410,7 @@ config("internal_config") {
":v8_header_features",
]
@@ -21,7 +21,7 @@ index 704ed28caa59eb6159baa2be4f6f94d62db74c16..8bdb2718008eed2a04a916253850a76b
defines += [ "BUILDING_V8_SHARED" ]
}
}
@@ -4478,7 +4478,7 @@ if (current_toolchain == v8_generator_toolchain) {
@@ -4477,7 +4477,7 @@ if (current_toolchain == v8_generator_toolchain) {
"src/interpreter/bytecodes.h",
]
@@ -30,7 +30,7 @@ index 704ed28caa59eb6159baa2be4f6f94d62db74c16..8bdb2718008eed2a04a916253850a76b
deps = [
":v8_libbase",
@@ -4515,6 +4515,8 @@ if (current_toolchain == v8_snapshot_toolchain) {
@@ -4514,6 +4514,8 @@ if (current_toolchain == v8_snapshot_toolchain) {
configs = [ ":internal_config" ]

View File

@@ -1,134 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Attard <marshallofsound@electronjs.org>
Date: Mon, 6 Jul 2020 20:47:43 -0700
Subject: chore: add v8 apple silicon patches
Once these are available upstream we can remove this patch.
diff --git a/src/codegen/arm64/macro-assembler-arm64.cc b/src/codegen/arm64/macro-assembler-arm64.cc
index fef1758aaa81a85009461839ec9aa816e7d196a6..c0f7a1cf5fd4787896b06bce911aabf17b290e88 100644
--- a/src/codegen/arm64/macro-assembler-arm64.cc
+++ b/src/codegen/arm64/macro-assembler-arm64.cc
@@ -2975,6 +2975,35 @@ void TurboAssembler::PrintfNoPreserve(const char* format,
int arg_count = kPrintfMaxArgCount;
+#if V8_OS_MACOSX && !USE_SIMULATOR
+ CPURegList tmp_list = kCallerSaved;
+ tmp_list.Remove(x0); // Used to pass the format string.
+ tmp_list.Remove(arg0, arg1, arg2, arg3);
+
+ // Override the MacroAssembler's scratch register list. The lists will be
+ // reset automatically at the end of the UseScratchRegisterScope.
+ UseScratchRegisterScope temps(this);
+ TmpList()->set_list(tmp_list.list());
+
+ VRegister temp_D = temps.AcquireD();
+
+ // https://developer.apple.com/library/archive/documentation/Xcode/Conceptual/iPhoneOSABIReference/Articles/ARM64FunctionCallingConventions.html#//apple_ref/doc/uid/TP40013702-SW1
+ Claim(kPrintfMaxArgCount, 8);
+ int64_t offset = 0;
+ for (unsigned i = 0; i < kPrintfMaxArgCount; i++) {
+ CPURegister arg = args[i];
+ if (arg.IsNone()) {
+ break;
+ }
+ if (arg.IsS()) {
+ fcvt(temp_D, arg.S());
+ arg = temp_D;
+ }
+ // FIXME: Use stp.
+ str(arg, MemOperand(sp, offset, Offset));
+ offset += 8;
+ }
+#else
// The PCS varargs registers for printf. Note that x0 is used for the printf
// format string.
static const CPURegList kPCSVarargs =
@@ -3085,7 +3114,7 @@ void TurboAssembler::PrintfNoPreserve(const char* format,
}
#endif
}
-
+#endif
// Load the format string into x0, as per the procedure-call standard.
//
// To make the code as portable as possible, the format string is encoded
@@ -3107,6 +3136,10 @@ void TurboAssembler::PrintfNoPreserve(const char* format,
}
CallPrintf(arg_count, pcs);
+
+#if V8_OS_MACOSX && !USE_SIMULATOR
+ Drop(kPrintfMaxArgCount, 8);
+#endif
}
void TurboAssembler::CallPrintf(int arg_count, const CPURegister* args) {
diff --git a/src/compiler/backend/arm64/instruction-selector-arm64.cc b/src/compiler/backend/arm64/instruction-selector-arm64.cc
index fac7f9c1d1146b36b57aa70565fc86a1604887c8..6c13a0747009e38fd574ba94d38b6654fdd70edf 100644
--- a/src/compiler/backend/arm64/instruction-selector-arm64.cc
+++ b/src/compiler/backend/arm64/instruction-selector-arm64.cc
@@ -1898,6 +1898,7 @@ void InstructionSelector::EmitPrepareArguments(
// Poke the arguments into the stack.
while (slot >= 0) {
+ // FIXME: In the Apple ARM64 ABI parameters should be packed on the stack.
PushParameter input0 = (*arguments)[slot];
PushParameter input1 = slot > 0 ? (*arguments)[slot - 1] : PushParameter();
// Emit a poke-pair if consecutive parameters have the same type.
diff --git a/src/flags/flag-definitions.h b/src/flags/flag-definitions.h
index ab689283e970a79bc02dbeee7a4a74720265fcd7..12e54765d316f97297ad0a999ca32c5d07872580 100644
--- a/src/flags/flag-definitions.h
+++ b/src/flags/flag-definitions.h
@@ -763,7 +763,12 @@ DEFINE_INT(wasm_num_compilation_tasks, 128,
"maximum number of parallel compilation tasks for wasm")
DEFINE_DEBUG_BOOL(trace_wasm_native_heap, false,
"trace wasm native heap events")
-DEFINE_BOOL(wasm_write_protect_code_memory, false,
+#if V8_OS_MACOSX && V8_TARGET_ARCH_ARM64
+#define V8_DEFAULT_WASM_WRITE_PROTECT_CODE_MEMORY true
+#else
+#define V8_DEFAULT_WASM_WRITE_PROTECT_CODE_MEMORY false
+#endif
+DEFINE_BOOL(wasm_write_protect_code_memory, V8_DEFAULT_WASM_WRITE_PROTECT_CODE_MEMORY,
"write protect code memory on the wasm native heap")
DEFINE_DEBUG_BOOL(trace_wasm_serialization, false,
"trace serialization/deserialization")
diff --git a/src/wasm/function-compiler.cc b/src/wasm/function-compiler.cc
index 8b41a90992f58c535df285e7fa569b51ae31f85d..1ff813abf44d25e8f2fd84b236623b74913684fb 100644
--- a/src/wasm/function-compiler.cc
+++ b/src/wasm/function-compiler.cc
@@ -258,6 +258,7 @@ void WasmCompilationUnit::CompileWasmFunction(Isolate* isolate,
isolate->counters(), detected);
if (result.succeeded()) {
WasmCodeRefScope code_ref_scope;
+ NativeModuleModificationScope native_module_modification_scope(native_module);
native_module->PublishCode(
native_module->AddCompiledCode(std::move(result)));
} else {
diff --git a/src/wasm/wasm-code-manager.h b/src/wasm/wasm-code-manager.h
index 5e8ed5475bb064cb657069242ce7517de7f5f8e2..5652bb407da3646e55c42492b3e9facec4556367 100644
--- a/src/wasm/wasm-code-manager.h
+++ b/src/wasm/wasm-code-manager.h
@@ -886,7 +886,7 @@ class V8_EXPORT_PRIVATE WasmCodeManager final {
// and even if we did, the resulting set of pages may be fragmented.
// Currently, we try and keep the number of syscalls low.
// - similar argument for debug time.
-class NativeModuleModificationScope final {
+class V8_EXPORT_PRIVATE NativeModuleModificationScope final {
public:
explicit NativeModuleModificationScope(NativeModule* native_module);
~NativeModuleModificationScope();
diff --git a/src/wasm/wasm-objects.cc b/src/wasm/wasm-objects.cc
index cf78ab5ff3286d6c07527a323eac4213255fe825..b89433d445f46110ba6cacfc6ec930d31171fd1f 100644
--- a/src/wasm/wasm-objects.cc
+++ b/src/wasm/wasm-objects.cc
@@ -1512,6 +1512,7 @@ void WasmInstanceObject::ImportWasmJSFunctionIntoTable(
wasm::WasmCompilationResult result = compiler::CompileWasmImportCallWrapper(
isolate->wasm_engine(), &env, kind, sig, false,
shared.internal_formal_parameter_count());
+ wasm::NativeModuleModificationScope native_module_modification_scope(native_module);
std::unique_ptr<wasm::WasmCode> wasm_code = native_module->AddCode(
result.func_index, result.code_desc, result.frame_slot_count,
result.tagged_parameter_slots,

View File

@@ -12,10 +12,10 @@ This patch can be safely removed if, when it is removed, `node.lib` does not
contain any standard C++ library exports (e.g. `std::ostringstream`).
diff --git a/BUILD.gn b/BUILD.gn
index da035d3afac94617d163197156dc2871be6c4be3..07fd11838469c4296f50d21a5f7941570293cd58 100644
index 6197ec36eb4c2ee3047334be243633ad5e866506..80ad800fa986e616896b782701fe9eb0ba2a0baa 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -411,6 +411,10 @@ config("internal_config") {
@@ -410,6 +410,10 @@ config("internal_config") {
":v8_header_features",
]

View File

@@ -6,10 +6,10 @@ Subject: expose_mksnapshot.patch
Needed in order to target mksnapshot for mksnapshot zip.
diff --git a/BUILD.gn b/BUILD.gn
index 8bdb2718008eed2a04a916253850a76b5eff8c96..da035d3afac94617d163197156dc2871be6c4be3 100644
index 128271ee0305baef31001894a163beff98bcdd6a..6197ec36eb4c2ee3047334be243633ad5e866506 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -4489,7 +4489,6 @@ if (current_toolchain == v8_generator_toolchain) {
@@ -4488,7 +4488,6 @@ if (current_toolchain == v8_generator_toolchain) {
if (current_toolchain == v8_snapshot_toolchain) {
v8_executable("mksnapshot") {

View File

@@ -1,43 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: John Kleinschmidt <jkleinsc@github.com>
Date: Wed, 8 Jul 2020 10:46:13 -0400
Subject: fix: use proper page size for mac arm64
This fix temporarily sets page size to 16k for mac arm64 so that mksnapshot can run on x64
and generate a mac arm64 snapshot
diff --git a/src/base/platform/platform-posix.cc b/src/base/platform/platform-posix.cc
index 89173b593a6ce887c0f3cea082f2d31e17f8f5db..f233d83286dd82559ee3573b7adc525adf7ce377 100644
--- a/src/base/platform/platform-posix.cc
+++ b/src/base/platform/platform-posix.cc
@@ -167,9 +167,19 @@ void* Allocate(void* hint, size_t size, OS::MemoryPermission access,
PageType page_type) {
int prot = GetProtectionFromMemoryPermission(access);
int flags = GetFlagsForMemoryPermission(access, page_type);
+#if defined(__APPLE__) && V8_TARGET_ARCH_ARM64 && defined(__x86_64__)
+ // XXX: This logic is simple and leaky as it is only used for mksnapshot.
+ size_t alignment = 16384;
+ void* result = mmap(hint, size + alignment, prot, flags, kMmapFd,
+ kMmapFdOffset);
+ if (result == MAP_FAILED) return nullptr;
+ return reinterpret_cast<void*>(
+ RoundUp(reinterpret_cast<uintptr_t>(result), alignment));
+#else
void* result = mmap(hint, size, prot, flags, kMmapFd, kMmapFdOffset);
if (result == MAP_FAILED) return nullptr;
return result;
+#endif
}
#endif // !V8_OS_FUCHSIA
@@ -226,7 +236,9 @@ void OS::Initialize(bool hard_abort, const char* const gc_fake_mmap) {
}
int OS::ActivationFrameAlignment() {
-#if V8_TARGET_ARCH_ARM
+#if defined(__APPLE__) && V8_TARGET_ARCH_ARM
+ return 4;
+#elif V8_TARGET_ARCH_ARM
// On EABI ARM targets this is required for fp correctness in the
// runtime system.
return 8;

41
script/push-patch.js Normal file
View File

@@ -0,0 +1,41 @@
const { createAppAuth } = require('@octokit/auth-app');
const cp = require('child_process');
if (!process.env.CIRCLE_BRANCH) {
console.error('Not building for a specific branch, can\'t autopush a patch');
process.exit(1);
}
if (process.env.CIRCLE_PR_NUMBER) {
console.error('Building for a forked PR, can\'t autopush a patch');
process.exit(1);
}
const auth = createAppAuth({
appId: process.env.PATCH_UP_APP_ID,
privateKey: Buffer.from(process.env.PATCH_UP_PRIVATE_KEY, 'base64').toString('utf8'),
installationId: process.env.PATCH_UP_INSTALLATION_ID,
clientId: process.env.PATCH_UP_CLIENT_ID,
clientSecret: process.env.PATCH_UP_CLIENT_SECRET
});
async function main () {
const installationAuth = await auth({ type: 'installation' });
const remoteURL = `https://x-access-token:${installationAuth.token}@github.com/electron/electron.git`;
// NEVER LOG THE OUTPUT OF THIS COMMAND
// GIT LEAKS THE ACCESS CREDENTIALS IN CONSOLE LOGS
const { status } = cp.spawnSync('git', ['push', '--set-upstream', remoteURL], {
stdio: 'ignore'
});
if (status !== 0) {
console.error('Failed to push to target branch');
process.exit(1);
}
}
if (process.mainModule === module) {
main().catch((err) => {
console.error(err);
process.exit(1);
});
}

View File

@@ -51,7 +51,7 @@ function uploadToGitHub () {
console.log(`Error uploading ${fileName} to GitHub, will retry. Error was:`, err);
retry++;
octokit.repos.listAssetsForRelease({
octokit.repos.listReleaseAssets({
owner: 'electron',
repo: targetRepo,
release_id: releaseId,

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