Compare commits

...

52 Commits

Author SHA1 Message Date
Electron Bot
3d2afa45c3 Bump v11.0.0-nightly.20200812 2020-08-12 07:32:30 -07:00
Electron Bot
4080b04911 Bump v11.0.0-nightly.20200811 2020-08-11 07:37:50 -07:00
Electron Bot
b09c828dd3 Revert "Bump v11.0.0-nightly.20200811"
This reverts commit f3363bde26.
2020-08-11 07:36:50 -07:00
Electron Bot
f3363bde26 Bump v11.0.0-nightly.20200811 2020-08-11 07:36:24 -07:00
Electron Bot
f136bf406f Revert "Bump v11.0.0-nightly.20200811"
This reverts commit 77ee3da77c.
2020-08-11 07:35:30 -07:00
Electron Bot
77ee3da77c Bump v11.0.0-nightly.20200811 2020-08-11 07:34:51 -07:00
GitHubPang
47f88b65b7 docs: fix typo in api/ipc-renderer (#24901) 2020-08-11 07:31:38 -07:00
Olawanle Joel
d7909b507f docs: fixed minor typos (#24912)
I was going through the entire documentation and decided to fix this to the best of my knowledge.
2020-08-11 07:30:45 -07:00
Teo Koon Peng
14aba3f0de fix: export libuv symbols (#24659)
* fix: export libuv symbols

* add test for linux and windows

* mac linker flags

* assuming same foo.so path for macos

* use --whole-archive flag for mac as well

* use force_load for mac

* refactor: use napi c api directly

Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2020-08-11 19:17:18 +09:00
Shelley Vohr
7ded768743 fix: pdf viewer template strings (#24913) 2020-08-10 22:46:58 -07:00
Samuel Attard
47d451ae52 fix: ts-node node is not a thing 2020-08-10 20:25:29 -07:00
Charles Kerr
7e84d3a2c1 build: in release notes script, do not assume electron dirname (#24927) 2020-08-10 16:56:54 -07:00
Samuel Attard
29a7b8f805 fix: add deps on the new devtools highlighter (#24921) 2020-08-10 16:54:05 -07:00
Shelley Vohr
16c32d2eb2 build: handle unhandled promise rejection in notes (#24923)
Handle any potential Git processes without throwing unhandled rejection errors.
2020-08-10 10:18:08 -07:00
Samuel Attard
047650b564 chore: update patches (#24919) 2020-08-10 08:23:21 -07:00
Shelley Vohr
8311078a96 fix: don't try to init mmap on missing asar (#24890) 2020-08-10 08:22:49 -07:00
Electron Bot
a9eaebb7f4 Bump v11.0.0-nightly.20200810 2020-08-10 07:32:34 -07:00
Samuel Attard
01c9113e2b build: fix path to git attributes for for patch export (#24896) 2020-08-10 07:10:15 -07:00
Jeremy Rose
481b19bee6 fix: send guid with linux crashes (#24881) 2020-08-07 15:30:49 -07:00
Samuel Attard
433956ce4f build: remove the tools folder (#24880) 2020-08-07 14:13:09 -07:00
Samuel Attard
b0ea1e14e1 build: type check the script folder during lint (#24892) 2020-08-07 13:49:07 -07:00
Samuel Attard
4d50f3f62c build: convert some scripts to TS (#24891) 2020-08-07 13:48:46 -07:00
Electron Bot
2028492356 Bump v11.0.0-nightly.20200807 2020-08-07 12:02:05 -07:00
Samuel Attard
3fa250d6da Revert "Bump v11.0.0-nightly.20200807"
This reverts commit cbdfeb1979.
2020-08-07 12:00:29 -07:00
Samuel Attard
854b74809a build: upload the file stream not a JSON blob for the read stream (#24889) 2020-08-07 12:00:12 -07:00
Electron Bot
cbdfeb1979 Bump v11.0.0-nightly.20200807 2020-08-07 07:32:05 -07:00
Cheng Zhao
2224d94c75 fix: add handle scope in SelectClientCertificate (#24868) 2020-08-06 20:50:41 -07:00
Electron Bot
b6f8cd39e5 Bump v11.0.0-nightly.20200806 2020-08-06 14:58:30 -07:00
Electron Bot
075a7adcc0 Revert "Bump v11.0.0-nightly.20200806"
This reverts commit 14256ee697.
2020-08-06 14:57:37 -07:00
Electron Bot
14256ee697 Bump v11.0.0-nightly.20200806 2020-08-06 13:20:37 -07:00
Samuel Attard
aaa971ff19 Revert "Bump v11.0.0-nightly.20200806"
This reverts commit 5bf423b646.
2020-08-06 13:15:48 -07:00
Electron Bot
5bf423b646 Bump v11.0.0-nightly.20200806 2020-08-06 10:40:35 -07:00
Samuel Attard
4f4c383ec5 build: only do the lower case symbol copy on case sensitive file systems (#24876) 2020-08-06 10:39:24 -07:00
Samuel Attard
5ed8afbdb6 Revert "Bump v11.0.0-nightly.20200806"
This reverts commit 4523c90dcd.
2020-08-06 10:36:41 -07:00
Cheng Zhao
5f447e4b4f fix: do not render inactive titlebar as active on Windows (#24847) 2020-08-06 09:05:23 -07:00
Electron Bot
4523c90dcd Bump v11.0.0-nightly.20200806 2020-08-06 07:31:55 -07:00
Shelley Vohr
6cb23e1d36 fix: use non-symbols in isURLInstance check (#24831) 2020-08-05 15:05:36 -07:00
Samuel Attard
a2c82f2342 build: ensure symbol files are named lowercase on disk so that boto can find them (#24856) 2020-08-05 14:03:50 -07:00
Shelley Vohr
9274117e12 build: quash octokit deprecation warning (#24790) 2020-08-05 11:59:52 -04:00
Electron Bot
99874fd71f Bump v11.0.0-nightly.20200805 2020-08-05 07:31:04 -07:00
Shelley Vohr
06c47c650a fix: duplicate suspend/resume events (#24818) 2020-08-04 20:08:45 -07:00
Jeremy Rose
30cd9cdf2a docs: remove reference to remote from faq (#24816) 2020-08-04 12:08:44 -07:00
Jeremy Rose
9c234f3f3f docs: remove references to 'remote' from app-arch tutorial (#24815) 2020-08-04 12:08:35 -07:00
Jeremy Rose
01a2e23194 refactor: mmap asar files (#24470) 2020-08-04 11:48:04 -07:00
Electron Bot
15ee34a1f2 Bump v11.0.0-nightly.20200804 2020-08-04 07:32:55 -07:00
Eryk Rakowski
f53aac97f5 fix(extensions): bypass cors in requests made from background pages (#24483) 2020-08-03 16:56:18 -07:00
Jeremy Rose
1350dc46ed refactor: ginify Archive (#24799) 2020-08-03 14:26:27 -07:00
Shelley Vohr
6fd302f745 chore: remove overwritten Node.js patch (#24775)
* chore: remove overwritten Node.js patch

* update patches

Co-authored-by: Electron Bot <anonymous@electronjs.org>
2020-08-03 08:49:31 -07:00
Electron Bot
e5c721eafc Bump v11.0.0-nightly.20200803 2020-08-03 07:32:11 -07:00
Electron Bot
a342ab7ce7 Bump v11.0.0-nightly.20200731 2020-07-31 07:31:51 -07:00
Samuel Attard
c3258d6c4e fix: provide AXTextChangeValueStartMarker for macOS a11y value change notifications (#24801) 2020-07-30 21:01:26 -07:00
Jeremy Rose
b5cd9ce0b3 refactor: ginify WebContents (#24651) 2020-07-30 09:17:57 -07:00
88 changed files with 1155 additions and 578 deletions

View File

@@ -1037,6 +1037,11 @@ steps-lint: &steps-lint
cd src/electron
node script/yarn install --frozen-lockfile
node script/yarn lint
- run:
name: Run Script Typechecker
command: |
cd src/electron
node script/yarn tsc -p tsconfig.script.json
steps-checkout-and-save-cache: &steps-checkout-and-save-cache
steps:

View File

@@ -170,7 +170,7 @@ action("electron_js2c") {
inputs = sources + [ "//third_party/electron_node/tools/js2c.py" ]
outputs = [ "$root_gen_dir/electron_natives.cc" ]
script = "tools/js2c.py"
script = "build/js2c.py"
args = [ rebase_path("//third_party/electron_node") ] +
rebase_path(outputs, root_build_dir) +
rebase_path(sources, root_build_dir)
@@ -360,6 +360,7 @@ source_set("electron_lib") {
"//services/viz/privileged/mojom/compositing",
"//skia",
"//third_party/blink/public:blink",
"//third_party/blink/public:blink_devtools_inspector_resources",
"//third_party/boringssl",
"//third_party/electron_node:node_lib",
"//third_party/inspector_protocol:crdtp",
@@ -813,6 +814,9 @@ if (is_mac) {
"-Wl,-install_name,@rpath/$output_name.framework/$output_name",
"-rpath",
"@loader_path/Libraries",
# Required for exporting all symbols of libuv.
"-Wl,-force_load,obj/third_party/electron_node/deps/uv/libuv.a",
]
if (is_component_build) {
ldflags += [
@@ -1144,7 +1148,14 @@ if (is_mac) {
]
}
if (is_linux) {
ldflags = [ "-pie" ]
ldflags = [
"-pie",
# Required for exporting all symbols of libuv.
"-Wl,--whole-archive",
"obj/third_party/electron_node/deps/uv/libuv.a",
"-Wl,--no-whole-archive",
]
if (!is_component_build && is_component_ffmpeg) {
configs += [ "//build/config/gcc:rpath_for_built_shared_libraries" ]

View File

@@ -1 +1 @@
11.0.0-nightly.20200730
11.0.0-nightly.20200812

View File

@@ -108,7 +108,7 @@ ipcMain.handle('some-name', async (event, someArgument) => {
If you need to transfer a [`MessagePort`][] to the main process, use [`ipcRenderer.postMessage`](#ipcrendererpostmessagechannel-message-transfer).
If you do not need a respons to the message, consider using [`ipcRenderer.send`](#ipcrenderersendchannel-args).
If you do not need a response to the message, consider using [`ipcRenderer.send`](#ipcrenderersendchannel-args).
### `ipcRenderer.sendSync(channel, ...args)`

View File

@@ -1,4 +1,4 @@
# KeyboardEvent Object extends `Event`
# KeyboardEvent Object
* `ctrlKey` Boolean (optional) - whether the Control key was used in an accelerator to trigger the Event
* `metaKey` Boolean (optional) - whether a meta key was used in an accelerator to trigger the Event

View File

@@ -43,26 +43,14 @@ use HTML5 APIs which are already available in browsers. Good candidates are
[Storage API][storage], [`localStorage`][local-storage],
[`sessionStorage`][session-storage], and [IndexedDB][indexed-db].
Or you can use the IPC system, which is specific to Electron, to store objects
in the main process as a global variable, and then to access them from the
renderers through the `remote` property of `electron` module:
```javascript
// In the main process.
global.sharedObject = {
someProperty: 'default value'
}
```
```javascript
// In page 1.
require('electron').remote.getGlobal('sharedObject').someProperty = 'new value'
```
```javascript
// In page 2.
console.log(require('electron').remote.getGlobal('sharedObject').someProperty)
```
Alternatively, you can use the IPC primitives that are provided by Electron. To
share data between the main and renderer processes, you can use the
[`ipcMain`](api/ipc-main.md) and [`ipcRenderer`](api/ipc-renderer.md) modules.
To communicate directly between web pages, you can send a
[`MessagePort`][message-port] from one to the other, possibly via the main process
using [`ipcRenderer.postMessage()`](api/ipc-renderer.md#ipcrendererpostmessagechannel-message-transfer).
Subsequent communication over message ports is direct and does not detour through
the main process.
## My app's tray disappeared after a few minutes.
@@ -171,5 +159,6 @@ Notice that just setting the background in the CSS does not have the desired eff
[local-storage]: https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage
[session-storage]: https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage
[indexed-db]: https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API
[message-port]: https://developer.mozilla.org/en-US/docs/Web/API/MessagePort
[browser-window]: api/browser-window.md
[subpixel rendering example]: images/subpixel-rendering-screenshot.gif

View File

@@ -38,11 +38,11 @@ process of the web page must communicate with the main process to request that
the main process perform those operations.
> #### Aside: Communication Between Processes
> In Electron, we have several ways to communicate between the main process
and renderer processes, such as [`ipcRenderer`](../api/ipc-renderer.md) and
[`ipcMain`](../api/ipc-main.md) modules for sending messages, and the
[remote](../api/remote.md) module for RPC style communication. There is also
an FAQ entry on [how to share data between web pages][share-data].
> In Electron, communicating between the main process and renderer processes,
> is done through the [`ipcRenderer`](../api/ipc-renderer.md) and
> [`ipcMain`](../api/ipc-main.md) modules. There is also an FAQ entry on [how
> to share data between web pages][share-data].
## Using Electron APIs
@@ -71,20 +71,26 @@ const win = new BrowserWindow()
```
Since communication between the processes is possible, a renderer process
can call upon the main process to perform tasks. Electron comes with a
module called `remote` that exposes APIs usually only available on the
main process. In order to create a `BrowserWindow` from a renderer process,
we'd use the remote as a middle-man:
can call upon the main process to perform tasks through IPC.
```javascript
// This will work in a renderer process, but be `undefined` in the
// main process:
const { remote } = require('electron')
const { BrowserWindow } = remote
// In the main process:
const { ipcMain } = require('electron')
const win = new BrowserWindow()
ipcMain.handle('perform-action', (event, ...args) => {
// ... do something on behalf of the renderer ...
})
// In the renderer process:
const { ipcRenderer } = require('electron')
ipcRenderer.invoke('perform-action', ...args)
```
Note that code in the renderer may not be trustworthy, so it's important
to carefully validate in the main process requests that come from renderers,
especially if they host third-party content.
## Using Node.js APIs
Electron exposes full access to Node.js both in the main and the renderer

View File

@@ -13,11 +13,11 @@ to automate the `Info.plist` changes during app build time.
## Automatically updating the native interfaces
"Native Interfaces" include the file picker, window border, dialogs, context menus and more; basically,
"Native Interfaces" include the file picker, window border, dialogs, context menus, and more; basically,
anything where the UI comes from macOS and not your app. As of Electron 7.0.0, the default behavior
is to opt in to this automatic theming from the OS. If you wish to opt out and are using Electron
is to opt into this automatic theming from the OS. If you wish to opt-out and are using Electron
&gt; 8.0.0, you must set the `NSRequiresAquaSystemAppearance` key in the `Info.plist` file to `true`.
Please note that Electron 8.0.0 and above will not let your opt out of this theming, due to the use
Please note that Electron 8.0.0 and above will not let your opt-out of this theming, due to the use
of the macOS 10.14 SDK.
## Automatically updating your own interfaces

View File

@@ -55,6 +55,7 @@ template("electron_extra_paks") {
output = "${invoker.output_dir}/resources.pak"
sources = [
"$root_gen_dir/chrome/dev_ui_browser_resources.pak",
"$root_gen_dir/chrome/print_preview_pdf_resources.pak",
"$root_gen_dir/components/components_resources.pak",
"$root_gen_dir/content/browser/resources/media/media_internals_resources.pak",
"$root_gen_dir/content/browser/tracing/tracing_resources.pak",
@@ -64,11 +65,13 @@ template("electron_extra_paks") {
"$root_gen_dir/mojo/public/js/mojo_bindings_resources.pak",
"$root_gen_dir/net/net_resources.pak",
"$root_gen_dir/third_party/blink/public/resources/blink_resources.pak",
"$root_gen_dir/third_party/blink/public/resources/inspector_overlay_resources.pak",
"$root_gen_dir/ui/resources/webui_resources.pak",
"$target_gen_dir/electron_resources.pak",
]
deps = [
"//chrome/browser:dev_ui_browser_resources",
"//chrome/browser/resources:print_preview_pdf_resources",
"//components/resources",
"//content:content_resources",
"//content:dev_ui_content_resources",
@@ -78,6 +81,7 @@ template("electron_extra_paks") {
"//electron:resources",
"//mojo/public/js:resources",
"//net:net_resources",
"//third_party/blink/public:devtools_inspector_resources",
"//third_party/blink/public:resources",
"//ui/resources",
]

View File

@@ -529,17 +529,15 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
return fs.readFile(realPath, options, callback);
}
const buffer = Buffer.alloc(info.size);
const fd = archive.getFd();
if (!(fd >= 0)) {
const error = createError(AsarError.NOT_FOUND, { asarPath, filePath });
nextTick(callback, [error]);
return;
}
logASARAccess(asarPath, filePath, info.offset);
fs.read(fd, buffer, 0, info.size, info.offset, (error: Error) => {
callback(error, encoding ? buffer.toString(encoding) : buffer);
archive.read(info.offset, info.size).then((buf) => {
const buffer = Buffer.from(buf);
callback(null, encoding ? buffer.toString(encoding) : buffer);
}, (err) => {
const error: AsarErrorObject = new Error(`EINVAL, ${err.message} while reading ${filePath} in ${asarPath}`);
error.code = 'EINVAL';
error.errno = -22;
callback(error);
});
};
@@ -572,13 +570,19 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
}
const { encoding } = options;
const buffer = Buffer.alloc(info.size);
const fd = archive.getFd();
if (!(fd >= 0)) throw createError(AsarError.NOT_FOUND, { asarPath, filePath });
logASARAccess(asarPath, filePath, info.offset);
fs.readSync(fd, buffer, 0, info.size, info.offset);
return (encoding) ? buffer.toString(encoding) : buffer;
let arrayBuffer: ArrayBuffer;
try {
arrayBuffer = archive.readSync(info.offset, info.size);
} catch (err) {
const error: AsarErrorObject = new Error(`EINVAL, ${err.message} while reading ${filePath} in ${asarPath}`);
error.code = 'EINVAL';
error.errno = -22;
throw error;
}
const buffer = Buffer.from(arrayBuffer);
return encoding ? buffer.toString(encoding) : buffer;
};
const { readdir } = fs;
@@ -685,12 +689,17 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
return fs.readFileSync(realPath, { encoding: 'utf8' });
}
const buffer = Buffer.alloc(info.size);
const fd = archive.getFd();
if (!(fd >= 0)) return [];
logASARAccess(asarPath, filePath, info.offset);
fs.readSync(fd, buffer, 0, info.size, info.offset);
let arrayBuffer: ArrayBuffer;
try {
arrayBuffer = archive.readSync(info.offset, info.size);
} catch (err) {
const error: AsarErrorObject = new Error(`EINVAL, ${err.message} while reading ${filePath} in ${asarPath}`);
error.code = 'EINVAL';
error.errno = -22;
throw error;
}
const buffer = Buffer.from(arrayBuffer);
const str = buffer.toString('utf8');
return [str, str.length > 0];
};

View File

@@ -9,7 +9,6 @@ import { ipcMainInternal } from '@electron/internal/browser/ipc-main-internal';
import * as ipcMainUtils from '@electron/internal/browser/ipc-main-internal-utils';
import { parseFeatures } from '@electron/internal/common/parse-features-string';
import { MessagePortMain } from '@electron/internal/browser/message-port-main';
import { EventEmitter } from 'events';
// session is not used here, the purpose is to make sure session is initalized
// before the webContents module.
@@ -124,8 +123,6 @@ const defaultPrintingSetting = {
const binding = process._linkedBinding('electron_browser_web_contents');
const { WebContents } = binding as { WebContents: { prototype: Electron.WebContentsInternal } };
Object.setPrototypeOf(WebContents.prototype, EventEmitter.prototype);
WebContents.prototype.send = function (channel, ...args) {
if (typeof channel !== 'string') {
throw new Error('Missing required channel argument');

View File

@@ -1,12 +1,12 @@
{
"name": "electron",
"version": "11.0.0-nightly.20200730",
"version": "11.0.0-nightly.20200812",
"repository": "https://github.com/electron/electron",
"description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
"devDependencies": {
"@electron/docs-parser": "^0.9.1",
"@electron/typescript-definitions": "^8.7.4",
"@octokit/rest": "^16.3.2",
"@octokit/rest": "^18.0.3",
"@primer/octicons": "^10.0.0",
"@types/basic-auth": "^1.1.3",
"@types/busboy": "^0.2.3",
@@ -108,7 +108,7 @@
"node script/lint.js --js --fix --only --"
],
"*.{js,ts,d.ts}": [
"node script/gen-filenames.js"
"ts-node script/gen-filenames.ts"
],
"*.{cc,mm,c,h}": [
"python script/run-clang-format.py -r -c --fix"
@@ -124,13 +124,13 @@
"node script/lint.js --py --fix --only --"
],
"docs/api/**/*.md": [
"node script/gen-filenames.js",
"ts-node script/gen-filenames.ts",
"python script/check-trailing-whitespace.py --fix",
"git add filenames.auto.gni"
],
"{*.patch,.patches}": [
"node script/lint.js --patches --only --",
"node script/check-patch-diff.js"
"ts-node script/check-patch-diff.ts"
],
"DEPS": [
"node script/gen-hunspell-filenames.js"

View File

@@ -105,3 +105,4 @@ fix_missing_weakptr_check_in_preconnectmanager.patch
revert_swiftshader_roll_in_deps.patch
worker_feat_add_hook_to_notify_script_ready.patch
mac_work_around_xcode_12b3_sdk_bug.patch
fix_provide_axtextchangevaluestartmarker_a11y_value_change.patch

View File

@@ -74,7 +74,7 @@ index 6052fd13ff3d63cf8a4b019b058efb61aad39c3b..42eac7a7b656096c1d2039e340037ac8
}
return VKEY_UNKNOWN;
}
@@ -193,7 +199,10 @@ CGEventRef MediaKeysListenerImpl::EventTapCallback(CGEventTapProxy proxy,
@@ -193,7 +199,10 @@ static CGEventRef EventTapCallback(CGEventTapProxy proxy,
int key_code = (data1 & 0xFFFF0000) >> 16;
if (key_code != NX_KEYTYPE_PLAY && key_code != NX_KEYTYPE_NEXT &&
key_code != NX_KEYTYPE_PREVIOUS && key_code != NX_KEYTYPE_FAST &&

View File

@@ -78,7 +78,7 @@ diff --git a/components/crash/core/app/crashpad_mac.mm b/components/crash/core/a
index 0b594d053d7c7f2a8eae9a15e62daacab52ffa64..96210530f699a2331f57415beddc20ed19b9cb4b 100644
--- a/components/crash/core/app/crashpad_mac.mm
+++ b/components/crash/core/app/crashpad_mac.mm
@@ -67,6 +67,8 @@ std::map<std::string, std::string> GetProcessSimpleAnnotations() {
@@ -67,6 +67,8 @@
} // @autoreleasepool
return process_annotations;
}();
@@ -87,7 +87,7 @@ index 0b594d053d7c7f2a8eae9a15e62daacab52ffa64..96210530f699a2331f57415beddc20ed
return annotations;
}
@@ -137,6 +139,13 @@ base::FilePath PlatformCrashpadInitialization(
@@ -137,6 +139,13 @@ void DumpProcessWithoutCrashing(task_t task_port) {
std::vector<std::string> arguments;

View File

@@ -9,7 +9,7 @@ diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/cont
index b5e4f8fb0e914078ae40d034e1b785f77607bbea..e8a6199632a3110ae5d0238dfe3568df9224f353 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -478,7 +478,11 @@ void RenderWidgetHostViewMac::WasOccluded() {
@@ -478,7 +478,11 @@
return;
host()->WasHidden();

View File

@@ -0,0 +1,168 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Attard <samuel.r.attard@gmail.com>
Date: Thu, 30 Jul 2020 16:02:55 -0700
Subject: fix: provide AXTextChangeValueStartMarker a11y value change
notifications
This will be upstreamed and can be removed once it has landed there.
Upstream attempt: https://chromium-review.googlesource.com/c/chromium/src/+/2330812
diff --git a/content/browser/accessibility/browser_accessibility_cocoa.h b/content/browser/accessibility/browser_accessibility_cocoa.h
index f56a191cb01fbcf91f60abc312ee5277bf857929..fa5429e2da1124fc1c2ff4fb6fed7aeb4dabdbea 100644
--- a/content/browser/accessibility/browser_accessibility_cocoa.h
+++ b/content/browser/accessibility/browser_accessibility_cocoa.h
@@ -19,13 +19,14 @@ namespace content {
// support character echo and other announcements during editing.
struct AXTextEdit {
AXTextEdit() = default;
- AXTextEdit(base::string16 inserted_text, base::string16 deleted_text)
- : inserted_text(inserted_text), deleted_text(deleted_text) {}
+ AXTextEdit(base::string16 inserted_text, base::string16 deleted_text, id edit_text_marker)
+ : inserted_text(inserted_text), deleted_text(deleted_text), edit_text_marker(edit_text_marker) {}
bool IsEmpty() const { return inserted_text.empty() && deleted_text.empty(); }
base::string16 inserted_text;
base::string16 deleted_text;
+ id edit_text_marker;
};
// Returns true if the given object is AXTextMarker object.
diff --git a/content/browser/accessibility/browser_accessibility_cocoa.mm b/content/browser/accessibility/browser_accessibility_cocoa.mm
index 090c8fdc3b374ed937d3e04ccd5d91772acc7d9d..8a96c55b638b33f390372c2a30228dabad08665a 100644
--- a/content/browser/accessibility/browser_accessibility_cocoa.mm
+++ b/content/browser/accessibility/browser_accessibility_cocoa.mm
@@ -1882,7 +1882,11 @@ - (BOOL)shouldExposeTitleUIElement {
base::string16 deletedText = oldValue.substr(i, oldValue.length() - i - j);
base::string16 insertedText = newValue.substr(i, newValue.length() - i - j);
- return content::AXTextEdit(insertedText, deletedText);
+#ifndef MAS_BUILD
+ return content::AXTextEdit(insertedText, deletedText, CreateTextMarker(_owner->CreatePositionAt(i)));
+#else
+ return content::AXTextEdit(insertedText, deletedText, nil);
+#endif
}
- (BOOL)instanceActive {
@@ -2257,7 +2261,7 @@ - (NSValue*)selectedTextRange {
- (id)selectedTextMarkerRange {
if (![self instanceActive])
return nil;
- return CreateTextMarkerRange(GetSelectedRange(*_owner));
+ return CreateTextMarkerRange(GetSelectedRange(*_owner).AsBackwardRange());
}
#endif
diff --git a/content/browser/accessibility/browser_accessibility_manager_mac.h b/content/browser/accessibility/browser_accessibility_manager_mac.h
index 8fb447a74cb6e818c221131aba5f57c5f8b8094d..b930963467642738db3ec0109b4a6681ade03b2c 100644
--- a/content/browser/accessibility/browser_accessibility_manager_mac.h
+++ b/content/browser/accessibility/browser_accessibility_manager_mac.h
@@ -60,7 +60,8 @@ class CONTENT_EXPORT BrowserAccessibilityManagerMac
NSDictionary* GetUserInfoForValueChangedNotification(
const BrowserAccessibilityCocoa* native_node,
const base::string16& deleted_text,
- const base::string16& inserted_text) const;
+ const base::string16& inserted_text,
+ id edit_text_marker) const;
void AnnounceActiveDescendant(BrowserAccessibility* node) const;
diff --git a/content/browser/accessibility/browser_accessibility_manager_mac.mm b/content/browser/accessibility/browser_accessibility_manager_mac.mm
index 5972939a070908521e82845b084d2d3b9f9a73f8..fda1d2f9fdccbff035d05f0dfc39238a8a667522 100644
--- a/content/browser/accessibility/browser_accessibility_manager_mac.mm
+++ b/content/browser/accessibility/browser_accessibility_manager_mac.mm
@@ -94,6 +94,7 @@
NSString* const NSAccessibilityTextChangeElement = @"AXTextChangeElement";
NSString* const NSAccessibilityTextEditType = @"AXTextEditType";
NSString* const NSAccessibilityTextChangeValue = @"AXTextChangeValue";
+NSString* const NSAccessibilityChangeValueStartMarker = @"AXTextChangeValueStartMarker";
NSString* const NSAccessibilityTextChangeValueLength =
@"AXTextChangeValueLength";
NSString* const NSAccessibilityTextChangeValues = @"AXTextChangeValues";
@@ -313,16 +314,18 @@ void PostAnnouncementNotification(NSString* announcement) {
if (base::mac::IsAtLeastOS10_11() && !text_edits_.empty()) {
base::string16 deleted_text;
base::string16 inserted_text;
- int32_t id = node->GetId();
- const auto iterator = text_edits_.find(id);
+ int32_t id_ = node->GetId();
+ id edit_text_marker = nil;
+ const auto iterator = text_edits_.find(id_);
if (iterator != text_edits_.end()) {
AXTextEdit text_edit = iterator->second;
deleted_text = text_edit.deleted_text;
inserted_text = text_edit.inserted_text;
+ edit_text_marker = text_edit.edit_text_marker;
}
NSDictionary* user_info = GetUserInfoForValueChangedNotification(
- native_node, deleted_text, inserted_text);
+ native_node, deleted_text, inserted_text, edit_text_marker);
BrowserAccessibility* root = GetRoot();
if (!root)
@@ -546,27 +549,34 @@ void PostAnnouncementNotification(NSString* announcement) {
BrowserAccessibilityManagerMac::GetUserInfoForValueChangedNotification(
const BrowserAccessibilityCocoa* native_node,
const base::string16& deleted_text,
- const base::string16& inserted_text) const {
+ const base::string16& inserted_text,
+ id edit_text_marker) const {
DCHECK(native_node);
if (deleted_text.empty() && inserted_text.empty())
return nil;
NSMutableArray* changes = [[[NSMutableArray alloc] init] autorelease];
if (!deleted_text.empty()) {
- [changes addObject:@{
- NSAccessibilityTextEditType : @(AXTextEditTypeDelete),
- NSAccessibilityTextChangeValueLength : @(deleted_text.length()),
- NSAccessibilityTextChangeValue : base::SysUTF16ToNSString(deleted_text)
- }];
+ NSMutableDictionary* change = [[[NSMutableDictionary alloc] initWithCapacity:4] autorelease];
+ change[NSAccessibilityTextEditType] = @(AXTextEditTypeDelete);
+ change[NSAccessibilityTextChangeValueLength] = @(deleted_text.length());
+ change[NSAccessibilityTextChangeValue] = base::SysUTF16ToNSString(deleted_text);
+ if (edit_text_marker) {
+ change[NSAccessibilityChangeValueStartMarker] = edit_text_marker;
+ }
+ [changes addObject:change];
}
if (!inserted_text.empty()) {
// TODO(nektar): Figure out if this is a paste operation instead of typing.
// Changes to Blink would be required.
- [changes addObject:@{
- NSAccessibilityTextEditType : @(AXTextEditTypeTyping),
- NSAccessibilityTextChangeValueLength : @(inserted_text.length()),
- NSAccessibilityTextChangeValue : base::SysUTF16ToNSString(inserted_text)
- }];
+ NSMutableDictionary* change = [[[NSMutableDictionary alloc] initWithCapacity:4] autorelease];
+ change[NSAccessibilityTextEditType] = @(AXTextEditTypeTyping);
+ change[NSAccessibilityTextChangeValueLength] = @(inserted_text.length());
+ change[NSAccessibilityTextChangeValue] = base::SysUTF16ToNSString(inserted_text);
+ if (edit_text_marker) {
+ change[NSAccessibilityChangeValueStartMarker] = edit_text_marker;
+ }
+ [changes addObject:change];
}
return @{
diff --git a/ui/accessibility/ax_range.h b/ui/accessibility/ax_range.h
index 62db9d3c0ff251e40dd5016901e40a3083cb786f..2d263e1c7eaf806a76eba6ee79919ef87d3eb04b 100644
--- a/ui/accessibility/ax_range.h
+++ b/ui/accessibility/ax_range.h
@@ -131,6 +131,12 @@ class AXRange {
: AXRange(anchor_->Clone(), focus_->Clone());
}
+ AXRange AsBackwardRange() const {
+ return (CompareEndpoints(anchor(), focus()).value_or(0) < 0)
+ ? AXRange(focus_->Clone(), anchor_->Clone())
+ : AXRange(anchor_->Clone(), focus_->Clone());
+ }
+
bool IsCollapsed() const { return !IsNull() && *anchor_ == *focus_; }
// We define a "leaf text range" as an AXRange whose endpoints are leaf text

View File

@@ -12,7 +12,7 @@ diff --git a/chrome/browser/extensions/global_shortcut_listener_mac.mm b/chrome/
index befe726af9c10b1563a7fc0bb77cc55f65943d5c..bac51f33f35f96fe4ecc764cf5ca887176642f74 100644
--- a/chrome/browser/extensions/global_shortcut_listener_mac.mm
+++ b/chrome/browser/extensions/global_shortcut_listener_mac.mm
@@ -39,7 +39,7 @@ GlobalShortcutListenerMac::GlobalShortcutListenerMac()
@@ -39,7 +39,7 @@
// global MediaKeysListener to receive media keys.
if (!content::MediaKeysListenerManager::IsMediaKeysListenerManagerEnabled()) {
media_keys_listener_ = ui::MediaKeysListener::Create(

View File

@@ -9,7 +9,7 @@ diff --git a/base/mac/foundation_util.mm b/base/mac/foundation_util.mm
index be12912dcd0ef0cf046ee2d4033a18ecfdf1e992..d2af322a9d5751105e2c8fe023aad9a91027bf05 100644
--- a/base/mac/foundation_util.mm
+++ b/base/mac/foundation_util.mm
@@ -28,12 +28,6 @@ CFTypeID SecKeyGetTypeID();
@@ -28,12 +28,6 @@
#if !defined(OS_IOS)
CFTypeID SecACLGetTypeID();
CFTypeID SecTrustedApplicationGetTypeID();
@@ -22,7 +22,7 @@ index be12912dcd0ef0cf046ee2d4033a18ecfdf1e992..d2af322a9d5751105e2c8fe023aad9a9
#endif
} // extern "C"
@@ -326,8 +320,7 @@ NSFont* CFToNSCast(CTFontRef cf_val) {
@@ -326,8 +320,7 @@ void SetBaseBundleID(const char* new_base_bundle_id) {
const_cast<NSFont*>(reinterpret_cast<const NSFont*>(cf_val));
DCHECK(!cf_val ||
CTFontGetTypeID() == CFGetTypeID(cf_val) ||
@@ -32,7 +32,7 @@ index be12912dcd0ef0cf046ee2d4033a18ecfdf1e992..d2af322a9d5751105e2c8fe023aad9a9
return ns_val;
}
@@ -398,9 +391,6 @@ CFCast<CTFontRef>(const CFTypeRef& cf_val) {
@@ -398,9 +391,6 @@ CTFontRef NSToCFCast(NSFont* ns_val) {
return (CTFontRef)(cf_val);
}

View File

@@ -18,7 +18,7 @@ index 94afefcee81b87c05bf9b1199d90d3d4b5ea84a6..2ec7f04c71824b47de1ddbf1f0e8625d
extern "C" {
// Kill ring calls. Would be better to use NSKillRing.h, but that's not
@@ -39,38 +40,53 @@ NSString* _NSYankFromKillRing();
@@ -39,38 +40,53 @@
void _NSNewKillRingSequence();
void _NSSetKillRingToYankedState();
}
@@ -92,7 +92,7 @@ index 8f4ae94bc1d8188d041654c50511f3346eee79de..fa06f47abbff3dcda937bf0b794f616e
namespace blink {
@@ -95,10 +97,12 @@ bool ThemePainterMac::PaintTextField(const Node* node,
@@ -95,10 +97,12 @@ void _NSDrawCarbonThemeListBox(NSRect frame,
// behavior change while remaining a fragile solution.
// https://bugs.chromium.org/p/chromium/issues/detail?id=658085#c3
if (!use_ns_text_field_cell) {
@@ -105,7 +105,7 @@ index 8f4ae94bc1d8188d041654c50511f3346eee79de..fa06f47abbff3dcda937bf0b794f616e
return false;
}
@@ -186,10 +190,12 @@ bool ThemePainterMac::PaintTextArea(const Node* node,
@@ -186,10 +190,12 @@ void _NSDrawCarbonThemeListBox(NSRect frame,
const IntRect& r) {
ScopedColorSchemeAppearance appearance(style.UsedColorScheme());
LocalCurrentGraphicsContext local_context(paint_info.context, r);

View File

@@ -18,7 +18,7 @@ index 69580888047c4ac6abb68873315bcafb78dda706..aa347913a75084f669bf7d89fbcc919b
@interface NSWindow (PrivateBrowserNativeWidgetAPI)
+ (Class)frameViewClassForStyleMask:(NSUInteger)windowStyle;
@end
@@ -63,6 +64,8 @@
@@ -63,6 +64,8 @@ - (NSRect)_draggableFrame NS_DEPRECATED_MAC(10_10, 10_11) {
@end
@@ -27,7 +27,7 @@ index 69580888047c4ac6abb68873315bcafb78dda706..aa347913a75084f669bf7d89fbcc919b
@implementation BrowserNativeWidgetWindow
// Prevent detached tabs from glitching when the window is partially offscreen.
@@ -84,6 +87,7 @@
@@ -84,6 +87,7 @@ - (NSRect)constrainFrameRect:(NSRect)rect toScreen:(NSScreen*)screen {
// NSWindow (PrivateAPI) overrides.
@@ -35,7 +35,7 @@ index 69580888047c4ac6abb68873315bcafb78dda706..aa347913a75084f669bf7d89fbcc919b
+ (Class)frameViewClassForStyleMask:(NSUInteger)windowStyle {
// - NSThemeFrame and its subclasses will be nil if it's missing at runtime.
if ([BrowserWindowFrame class])
@@ -98,6 +102,8 @@
@@ -98,6 +102,8 @@ - (BOOL)_usesCustomDrawing {
return NO;
}
@@ -57,7 +57,7 @@ index 8416c7c6e052dafb2aad61c0bd3224c36e945d23..cd356beda023ab2409b16d58ca38c70b
@interface NSWindow (PrivateAPI)
+ (Class)frameViewClassForStyleMask:(NSUInteger)windowStyle;
@end
@@ -18,8 +20,12 @@
@@ -18,8 +20,12 @@ - (CGFloat)_titlebarHeight {
}
@end
@@ -70,7 +70,7 @@ index 8416c7c6e052dafb2aad61c0bd3224c36e945d23..cd356beda023ab2409b16d58ca38c70b
+ (Class)frameViewClassForStyleMask:(NSUInteger)windowStyle {
if ([NativeWidgetMacFramelessNSWindowFrame class]) {
return [NativeWidgetMacFramelessNSWindowFrame class];
@@ -27,4 +33,6 @@
@@ -27,4 +33,6 @@ + (Class)frameViewClassForStyleMask:(NSUInteger)windowStyle {
return [super frameViewClassForStyleMask:windowStyle];
}
@@ -111,7 +111,7 @@ index 757c72d98de11f611309f4f5af8d0d9aab639181..a6319a0760308df6bac6b39ad3500ad7
- (BOOL)hasKeyAppearance;
- (long long)_resizeDirectionForMouseLocation:(CGPoint)location;
- (BOOL)_isConsideredOpenForPersistentState;
@@ -58,6 +60,8 @@
@@ -58,6 +60,8 @@ - (void)cr_mouseDownOnFrameView:(NSEvent*)event {
}
@end
@@ -120,7 +120,7 @@ index 757c72d98de11f611309f4f5af8d0d9aab639181..a6319a0760308df6bac6b39ad3500ad7
@implementation NativeWidgetMacNSWindowTitledFrame
- (void)mouseDown:(NSEvent*)event {
if (base::mac::IsAtMostOS10_11() && self.window.isMovable)
@@ -84,6 +88,8 @@
@@ -84,6 +88,8 @@ - (BOOL)usesCustomDrawing {
}
@end
@@ -129,7 +129,7 @@ index 757c72d98de11f611309f4f5af8d0d9aab639181..a6319a0760308df6bac6b39ad3500ad7
@implementation NativeWidgetMacNSWindow {
@private
base::scoped_nsobject<CommandDispatcher> _commandDispatcher;
@@ -165,6 +171,8 @@
@@ -165,6 +171,8 @@ - (BOOL)hasViewsMenuActive {
// NSWindow overrides.
@@ -138,7 +138,7 @@ index 757c72d98de11f611309f4f5af8d0d9aab639181..a6319a0760308df6bac6b39ad3500ad7
+ (Class)frameViewClassForStyleMask:(NSWindowStyleMask)windowStyle {
if (windowStyle & NSWindowStyleMaskTitled) {
if (Class customFrame = [NativeWidgetMacNSWindowTitledFrame class])
@@ -176,6 +184,8 @@
@@ -176,6 +184,8 @@ + (Class)frameViewClassForStyleMask:(NSWindowStyleMask)windowStyle {
return [super frameViewClassForStyleMask:windowStyle];
}

View File

@@ -17,7 +17,7 @@ diff --git a/components/remote_cocoa/app_shim/application_bridge.mm b/components
index 9ddda9116e7284cbccde8a51e23ad7560dd06367..e846091ad99b0154636489e53491209ff3cbfaaa 100644
--- a/components/remote_cocoa/app_shim/application_bridge.mm
+++ b/components/remote_cocoa/app_shim/application_bridge.mm
@@ -49,6 +49,7 @@ class NativeWidgetBridgeOwner : public NativeWidgetNSWindowHostHelper {
@@ -49,6 +49,7 @@
// NativeWidgetNSWindowHostHelper:
id GetNativeViewAccessible() override {
@@ -25,7 +25,7 @@ index 9ddda9116e7284cbccde8a51e23ad7560dd06367..e846091ad99b0154636489e53491209f
if (!remote_accessibility_element_) {
int64_t browser_pid = 0;
std::vector<uint8_t> element_token;
@@ -59,6 +60,9 @@ class NativeWidgetBridgeOwner : public NativeWidgetNSWindowHostHelper {
@@ -59,6 +60,9 @@ id GetNativeViewAccessible() override {
ui::RemoteAccessibility::GetRemoteElementFromToken(element_token);
}
return remote_accessibility_element_.get();
@@ -35,7 +35,7 @@ index 9ddda9116e7284cbccde8a51e23ad7560dd06367..e846091ad99b0154636489e53491209f
}
void DispatchKeyEvent(ui::KeyEvent* event) override {
bool event_handled = false;
@@ -96,8 +100,10 @@ class NativeWidgetBridgeOwner : public NativeWidgetNSWindowHostHelper {
@@ -96,8 +100,10 @@ void GetWordAt(const gfx::Point& location_in_content,
mojo::AssociatedRemote<mojom::TextInputHost> text_input_host_remote_;
std::unique_ptr<NativeWidgetNSWindowBridge> bridge_;
@@ -50,7 +50,7 @@ diff --git a/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.mm
index 2ee45cb069ec5d78d9c7a3f61fdd1d444a590f41..badc4323b910f8e3957583e05af303472cb204f6 100644
--- a/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.mm
+++ b/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.mm
@@ -543,10 +543,12 @@ void NativeWidgetNSWindowBridge::CreateContentView(uint64_t ns_view_id,
@@ -543,10 +543,12 @@ NSUInteger CountBridgedWindows(NSArray* child_windows) {
// this should be treated as an error and caught early.
CHECK(bridged_view_);
@@ -67,7 +67,7 @@ diff --git a/content/app_shim_remote_cocoa/ns_view_bridge_factory_impl.mm b/cont
index c3a9fbf0f9d2b80c1de42a22ad094a286f0b559b..02493d4b62c98a3aebd3e460c459218a4dc4ea8e 100644
--- a/content/app_shim_remote_cocoa/ns_view_bridge_factory_impl.mm
+++ b/content/app_shim_remote_cocoa/ns_view_bridge_factory_impl.mm
@@ -70,8 +70,10 @@ class RenderWidgetHostNSViewBridgeOwner
@@ -70,8 +70,10 @@ id GetFocusedBrowserAccessibilityElement() override {
return nil;
}
void SetAccessibilityWindow(NSWindow* window) override {
@@ -78,7 +78,7 @@ index c3a9fbf0f9d2b80c1de42a22ad094a286f0b559b..02493d4b62c98a3aebd3e460c459218a
}
void ForwardKeyboardEvent(const content::NativeWebKeyboardEvent& key_event,
@@ -133,8 +135,10 @@ class RenderWidgetHostNSViewBridgeOwner
@@ -133,8 +135,10 @@ void SmartMagnify(const blink::WebGestureEvent& web_event) override {
mojo::AssociatedRemote<mojom::RenderWidgetHostNSViewHost> host_;
std::unique_ptr<RenderWidgetHostNSViewBridge> bridge_;
@@ -120,7 +120,7 @@ diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/cont
index ed223cdb6ea7a0f6130547b7988982bb44aa157d..b5e4f8fb0e914078ae40d034e1b785f77607bbea 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -233,8 +233,10 @@ RenderWidgetHostViewMac::~RenderWidgetHostViewMac() {
@@ -233,8 +233,10 @@
void RenderWidgetHostViewMac::MigrateNSViewBridge(
remote_cocoa::mojom::Application* remote_cocoa_application,
uint64_t parent_ns_view_id) {
@@ -131,7 +131,7 @@ index ed223cdb6ea7a0f6130547b7988982bb44aa157d..b5e4f8fb0e914078ae40d034e1b785f7
// Disconnect from the previous bridge (this will have the effect of
// destroying the associated bridge), and close the receiver (to allow it
@@ -1377,8 +1379,10 @@ RenderWidgetHostViewMac::AccessibilityGetNativeViewAccessible() {
@@ -1377,8 +1379,10 @@ void CombineTextNodesAndMakeCallback(SpeechCallback callback,
gfx::NativeViewAccessible
RenderWidgetHostViewMac::AccessibilityGetNativeViewAccessibleForWindow() {
@@ -142,7 +142,7 @@ index ed223cdb6ea7a0f6130547b7988982bb44aa157d..b5e4f8fb0e914078ae40d034e1b785f7
return [GetInProcessNSView() window];
}
@@ -1410,9 +1414,11 @@ id RenderWidgetHostViewMac::GetFocusedBrowserAccessibilityElement() {
@@ -1410,9 +1414,11 @@ void CombineTextNodesAndMakeCallback(SpeechCallback callback,
}
void RenderWidgetHostViewMac::SetAccessibilityWindow(NSWindow* window) {
@@ -154,7 +154,7 @@ index ed223cdb6ea7a0f6130547b7988982bb44aa157d..b5e4f8fb0e914078ae40d034e1b785f7
}
bool RenderWidgetHostViewMac::SyncIsWidgetForMainFrame(
@@ -1899,12 +1905,14 @@ void RenderWidgetHostViewMac::StopSpeaking() {
@@ -1899,12 +1905,14 @@ void CombineTextNodesAndMakeCallback(SpeechCallback callback,
void RenderWidgetHostViewMac::SetRemoteAccessibilityWindowToken(
const std::vector<uint8_t>& window_token) {
@@ -239,7 +239,7 @@ diff --git a/ui/views/cocoa/native_widget_mac_ns_window_host.mm b/ui/views/cocoa
index 2256c365af5b1af79458fdcb0cb9d44c9ff641fd..f4949b071a177452b0074a2436669e9846558d1a 100644
--- a/ui/views/cocoa/native_widget_mac_ns_window_host.mm
+++ b/ui/views/cocoa/native_widget_mac_ns_window_host.mm
@@ -282,14 +282,22 @@ gfx::NativeViewAccessible
@@ -282,14 +282,22 @@ void HandleAccelerator(const ui::Accelerator& accelerator,
NativeWidgetMacNSWindowHost::GetNativeViewAccessibleForNSView() const {
if (in_process_ns_window_bridge_)
return in_process_ns_window_bridge_->ns_view();
@@ -262,7 +262,7 @@ index 2256c365af5b1af79458fdcb0cb9d44c9ff641fd..f4949b071a177452b0074a2436669e98
}
remote_cocoa::mojom::NativeWidgetNSWindow*
@@ -1118,6 +1126,7 @@ void NativeWidgetMacNSWindowHost::OnFocusWindowToolbar() {
@@ -1118,6 +1126,7 @@ void HandleAccelerator(const ui::Accelerator& accelerator,
void NativeWidgetMacNSWindowHost::SetRemoteAccessibilityTokens(
const std::vector<uint8_t>& window_token,
const std::vector<uint8_t>& view_token) {
@@ -270,7 +270,7 @@ index 2256c365af5b1af79458fdcb0cb9d44c9ff641fd..f4949b071a177452b0074a2436669e98
remote_window_accessible_ =
ui::RemoteAccessibility::GetRemoteElementFromToken(window_token);
remote_view_accessible_ =
@@ -1125,14 +1134,17 @@ void NativeWidgetMacNSWindowHost::SetRemoteAccessibilityTokens(
@@ -1125,14 +1134,17 @@ void HandleAccelerator(const ui::Accelerator& accelerator,
[remote_view_accessible_ setWindowUIElement:remote_window_accessible_.get()];
[remote_view_accessible_
setTopLevelUIElement:remote_window_accessible_.get()];

View File

@@ -44,7 +44,7 @@ diff --git a/gpu/ipc/service/image_transport_surface_overlay_mac.mm b/gpu/ipc/se
index 67e0efb23c717c3194f27695215a8bd20dbbb957..cf02fab328d9fe7a6e9f53c712a7c1c871b8b304 100644
--- a/gpu/ipc/service/image_transport_surface_overlay_mac.mm
+++ b/gpu/ipc/service/image_transport_surface_overlay_mac.mm
@@ -51,7 +51,7 @@ ImageTransportSurfaceOverlayMacBase<BaseClass>::
@@ -51,7 +51,7 @@
ca_layer_tree_coordinator_.reset(new ui::CALayerTreeCoordinator(
use_remote_layer_api_, allow_av_sample_buffer_display_layer));
@@ -53,7 +53,7 @@ index 67e0efb23c717c3194f27695215a8bd20dbbb957..cf02fab328d9fe7a6e9f53c712a7c1c8
// Create the CAContext to send this to the GPU process, and the layer for
// the context.
if (use_remote_layer_api_) {
@@ -60,6 +60,7 @@ ImageTransportSurfaceOverlayMacBase<BaseClass>::
@@ -60,6 +60,7 @@
options:@{}] retain]);
[ca_context_ setLayer:ca_layer_tree_coordinator_->GetCALayerForDisplay()];
}
@@ -61,7 +61,7 @@ index 67e0efb23c717c3194f27695215a8bd20dbbb957..cf02fab328d9fe7a6e9f53c712a7c1c8
}
template <typename BaseClass>
@@ -140,7 +141,9 @@ ImageTransportSurfaceOverlayMacBase<BaseClass>::SwapBuffersInternal(
@@ -140,7 +141,9 @@
"GLImpl", static_cast<int>(gl::GetGLImplementation()),
"width", pixel_size_.width());
if (use_remote_layer_api_) {
@@ -75,7 +75,7 @@ diff --git a/ui/accelerated_widget_mac/display_ca_layer_tree.mm b/ui/accelerated
index 0db8f3e223e3cb8e289af63a50104fb6823ed46a..d7969cf08317731bf8e1c8545a07734412593e37 100644
--- a/ui/accelerated_widget_mac/display_ca_layer_tree.mm
+++ b/ui/accelerated_widget_mac/display_ca_layer_tree.mm
@@ -98,6 +98,7 @@ void DisplayCALayerTree::UpdateCALayerTree(
@@ -98,6 +98,7 @@ - (void)setContentsChanged;
}
void DisplayCALayerTree::GotCALayerFrame(uint32_t ca_context_id) {
@@ -83,7 +83,7 @@ index 0db8f3e223e3cb8e289af63a50104fb6823ed46a..d7969cf08317731bf8e1c8545a077344
// Early-out if the remote layer has not changed.
if ([remote_layer_ contextId] == ca_context_id)
return;
@@ -122,6 +123,9 @@ void DisplayCALayerTree::GotCALayerFrame(uint32_t ca_context_id) {
@@ -122,6 +123,9 @@ - (void)setContentsChanged;
[io_surface_layer_ removeFromSuperlayer];
io_surface_layer_.reset();
}

View File

@@ -10,7 +10,7 @@ diff --git a/content/browser/accessibility/accessibility_tree_formatter_mac.mm b
index 6074fd6fb7da7c0e927fa81e8095729349520417..d6e93ab7cea23fe9592110967a1c9cfa0481551d 100644
--- a/content/browser/accessibility/accessibility_tree_formatter_mac.mm
+++ b/content/browser/accessibility/accessibility_tree_formatter_mac.mm
@@ -341,11 +341,13 @@ AccessibilityTreeFormatterMac::ParamByPropertyNode(
@@ -341,11 +341,13 @@ id PropertyNodeToTextMarkerRange(const PropertyNode&,
param = PropertyNodeToRange(property_node);
} else if (property_name == "AXIndexForChildUIElement") { // UIElement
param = PropertyNodeToUIElement(property_node, line_indexes_map);
@@ -24,7 +24,7 @@ index 6074fd6fb7da7c0e927fa81e8095729349520417..d6e93ab7cea23fe9592110967a1c9cfa
}
return param;
@@ -433,6 +435,7 @@ AccessibilityTreeFormatterMac::PropertyNodeToUIElement(
@@ -433,6 +435,7 @@ id PropertyNodeToTextMarkerRange(const PropertyNode&,
return uielement;
}
@@ -32,7 +32,7 @@ index 6074fd6fb7da7c0e927fa81e8095729349520417..d6e93ab7cea23fe9592110967a1c9cfa
id AccessibilityTreeFormatterMac::DictNodeToTextMarker(
const PropertyNode& dictnode,
const LineIndexesMap& line_indexes_map) const {
@@ -512,6 +515,7 @@ id AccessibilityTreeFormatterMac::PropertyNodeToTextMarkerRange(
@@ -512,6 +515,7 @@ id PropertyNodeToTextMarkerRange(const PropertyNode&,
return content::AXTextMarkerRangeFrom(anchor_textmarker, focus_textmarker);
}
@@ -40,7 +40,7 @@ index 6074fd6fb7da7c0e927fa81e8095729349520417..d6e93ab7cea23fe9592110967a1c9cfa
base::Value AccessibilityTreeFormatterMac::PopulateSize(
const BrowserAccessibilityCocoa* cocoa_node) const {
@@ -573,7 +577,7 @@ base::Value AccessibilityTreeFormatterMac::PopulateObject(
@@ -573,7 +577,7 @@ id PropertyNodeToTextMarkerRange(const PropertyNode&,
0 == strcmp([value objCType], @encode(NSRange))) {
return PopulateRange([value rangeValue]);
}
@@ -49,7 +49,7 @@ index 6074fd6fb7da7c0e927fa81e8095729349520417..d6e93ab7cea23fe9592110967a1c9cfa
// AXTextMarker
if (content::IsAXTextMarker(value)) {
return PopulateTextPosition(content::AXTextMarkerToPosition(value).get(),
@@ -584,7 +588,7 @@ base::Value AccessibilityTreeFormatterMac::PopulateObject(
@@ -584,7 +588,7 @@ id PropertyNodeToTextMarkerRange(const PropertyNode&,
if (content::IsAXTextMarkerRange(value)) {
return PopulateTextMarkerRange(value, line_indexes_map);
}
@@ -58,7 +58,7 @@ index 6074fd6fb7da7c0e927fa81e8095729349520417..d6e93ab7cea23fe9592110967a1c9cfa
// Accessible object
if ([value isKindOfClass:[BrowserAccessibilityCocoa class]]) {
return base::Value(NodeToLineIndex(value, line_indexes_map));
@@ -635,7 +639,7 @@ base::Value AccessibilityTreeFormatterMac::PopulateTextPosition(
@@ -635,7 +639,7 @@ id PropertyNodeToTextMarkerRange(const PropertyNode&,
kConstValuePrefix + affinity);
return set;
}
@@ -67,7 +67,7 @@ index 6074fd6fb7da7c0e927fa81e8095729349520417..d6e93ab7cea23fe9592110967a1c9cfa
base::Value AccessibilityTreeFormatterMac::PopulateTextMarkerRange(
id object,
const LineIndexesMap& line_indexes_map) const {
@@ -650,7 +654,7 @@ base::Value AccessibilityTreeFormatterMac::PopulateTextMarkerRange(
@@ -650,7 +654,7 @@ id PropertyNodeToTextMarkerRange(const PropertyNode&,
dict.SetPath("focus", PopulateTextPosition(range.focus(), line_indexes_map));
return dict;
}
@@ -123,7 +123,7 @@ diff --git a/content/browser/accessibility/browser_accessibility_cocoa.mm b/cont
index 474ae88c323e9a10bd8486482507f0d749214963..090c8fdc3b374ed937d3e04ccd5d91772acc7d9d 100644
--- a/content/browser/accessibility/browser_accessibility_cocoa.mm
+++ b/content/browser/accessibility/browser_accessibility_cocoa.mm
@@ -208,6 +208,7 @@ NSString* const
@@ -208,6 +208,7 @@
NSString* const NSAccessibilityLengthForTextMarkerRangeParameterizedAttribute =
@"AXLengthForTextMarkerRange";
@@ -131,7 +131,7 @@ index 474ae88c323e9a10bd8486482507f0d749214963..090c8fdc3b374ed937d3e04ccd5d9177
// Private attributes that can be used for testing text markers, e.g. in dump
// tree tests.
NSString* const
@@ -219,6 +220,7 @@ NSString* const
@@ -219,6 +220,7 @@
NSString* const
NSAccessibilityTextMarkerNodeDebugDescriptionParameterizedAttribute =
@"AXTextMarkerNodeDebugDescription";
@@ -139,7 +139,7 @@ index 474ae88c323e9a10bd8486482507f0d749214963..090c8fdc3b374ed937d3e04ccd5d9177
// Other private attributes.
NSString* const NSAccessibilitySelectTextWithCriteriaParameterizedAttribute =
@@ -242,6 +244,7 @@ NSDictionary* attributeToMethodNameMap = nil;
@@ -242,6 +244,7 @@
// VoiceOver uses -1 to mean "no limit" for AXResultsLimit.
const int kAXResultsLimitNoLimit = -1;
@@ -147,7 +147,7 @@ index 474ae88c323e9a10bd8486482507f0d749214963..090c8fdc3b374ed937d3e04ccd5d9177
extern "C" {
// The following are private accessibility APIs required for cursor navigation
@@ -470,6 +473,7 @@ NSAttributedString* GetAttributedTextForTextMarkerRange(id marker_range) {
@@ -470,6 +473,7 @@ void AddMisspelledTextAttributes(const AXPlatformRange& ax_range,
AddMisspelledTextAttributes(ax_range, attributed_text);
return attributed_text;
}
@@ -155,7 +155,7 @@ index 474ae88c323e9a10bd8486482507f0d749214963..090c8fdc3b374ed937d3e04ccd5d9177
// Returns an autoreleased copy of the AXNodeData's attribute.
NSString* NSStringForStringAttribute(BrowserAccessibility* browserAccessibility,
@@ -727,6 +731,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
@@ -727,6 +731,7 @@ bool IsSelectedStateRelevant(BrowserAccessibility* item) {
#define NSAccessibilityLanguageAttribute @"AXLanguage"
#endif
@@ -163,7 +163,7 @@ index 474ae88c323e9a10bd8486482507f0d749214963..090c8fdc3b374ed937d3e04ccd5d9177
bool content::IsAXTextMarker(id object) {
if (object == nil)
return false;
@@ -770,6 +775,7 @@ id content::AXTextMarkerRangeFrom(id anchor_textmarker, id focus_textmarker) {
@@ -770,6 +775,7 @@ bool IsSelectedStateRelevant(BrowserAccessibility* item) {
kCFAllocatorDefault, anchor_textmarker, focus_textmarker);
return [static_cast<id>(cf_marker_range) autorelease];
}
@@ -171,7 +171,7 @@ index 474ae88c323e9a10bd8486482507f0d749214963..090c8fdc3b374ed937d3e04ccd5d9177
@implementation BrowserAccessibilityCocoa
@@ -807,7 +813,9 @@ id content::AXTextMarkerRangeFrom(id anchor_textmarker, id focus_textmarker) {
@@ -807,7 +813,9 @@ + (void)initialize {
{NSAccessibilityEditableAncestorAttribute, @"editableAncestor"},
{NSAccessibilityElementBusyAttribute, @"elementBusy"},
{NSAccessibilityEnabledAttribute, @"enabled"},
@@ -181,7 +181,7 @@ index 474ae88c323e9a10bd8486482507f0d749214963..090c8fdc3b374ed937d3e04ccd5d9177
{NSAccessibilityExpandedAttribute, @"expanded"},
{NSAccessibilityFocusableAncestorAttribute, @"focusableAncestor"},
{NSAccessibilityFocusedAttribute, @"focused"},
@@ -819,8 +827,10 @@ id content::AXTextMarkerRangeFrom(id anchor_textmarker, id focus_textmarker) {
@@ -819,8 +827,10 @@ + (void)initialize {
{NSAccessibilityHighestEditableAncestorAttribute,
@"highestEditableAncestor"},
{NSAccessibilityIndexAttribute, @"index"},
@@ -192,7 +192,7 @@ index 474ae88c323e9a10bd8486482507f0d749214963..090c8fdc3b374ed937d3e04ccd5d9177
{NSAccessibilityInvalidAttribute, @"invalid"},
{NSAccessibilityIsMultiSelectableAttribute, @"isMultiSelectable"},
{NSAccessibilityLanguageAttribute, @"language"},
@@ -842,13 +852,17 @@ id content::AXTextMarkerRangeFrom(id anchor_textmarker, id focus_textmarker) {
@@ -842,13 +852,17 @@ + (void)initialize {
{NSAccessibilityRowsAttribute, @"rows"},
// TODO(aboxhall): expose
// NSAccessibilityServesAsTitleForUIElementsAttribute
@@ -210,7 +210,7 @@ index 474ae88c323e9a10bd8486482507f0d749214963..090c8fdc3b374ed937d3e04ccd5d9177
{NSAccessibilitySizeAttribute, @"size"},
{NSAccessibilitySortDirectionAttribute, @"sortDirection"},
{NSAccessibilitySubroleAttribute, @"subrole"},
@@ -1336,6 +1350,7 @@ id content::AXTextMarkerRangeFrom(id anchor_textmarker, id focus_textmarker) {
@@ -1336,6 +1350,7 @@ - (NSNumber*)enabled {
ax::mojom::Restriction::kDisabled];
}
@@ -218,7 +218,7 @@ index 474ae88c323e9a10bd8486482507f0d749214963..090c8fdc3b374ed937d3e04ccd5d9177
// Returns a text marker that points to the last character in the document that
// can be selected with VoiceOver.
- (id)endTextMarker {
@@ -1346,6 +1361,7 @@ id content::AXTextMarkerRangeFrom(id anchor_textmarker, id focus_textmarker) {
@@ -1346,6 +1361,7 @@ - (id)endTextMarker {
BrowserAccessibilityPositionInstance position = root->CreatePositionAt(0);
return CreateTextMarker(position->CreatePositionAtEndOfAnchor());
}
@@ -226,7 +226,7 @@ index 474ae88c323e9a10bd8486482507f0d749214963..090c8fdc3b374ed937d3e04ccd5d9177
- (NSNumber*)expanded {
if (![self instanceActive])
@@ -1495,6 +1511,8 @@ id content::AXTextMarkerRangeFrom(id anchor_textmarker, id focus_textmarker) {
@@ -1495,6 +1511,8 @@ - (NSNumber*)index {
return nil;
}
@@ -235,7 +235,7 @@ index 474ae88c323e9a10bd8486482507f0d749214963..090c8fdc3b374ed937d3e04ccd5d9177
- (NSNumber*)insertionPointLineNumber {
if (![self instanceActive])
return nil;
@@ -1517,6 +1535,7 @@ id content::AXTextMarkerRangeFrom(id anchor_textmarker, id focus_textmarker) {
@@ -1517,6 +1535,7 @@ - (NSNumber*)insertionPointLineNumber {
caretPosition->AsTextPosition()->text_offset());
return @(std::distance(lineBreaks.begin(), iterator));
}
@@ -243,7 +243,7 @@ index 474ae88c323e9a10bd8486482507f0d749214963..090c8fdc3b374ed937d3e04ccd5d9177
// Returns whether or not this node should be ignored in the
// accessibility tree.
@@ -2193,6 +2212,7 @@ id content::AXTextMarkerRangeFrom(id anchor_textmarker, id focus_textmarker) {
@@ -2193,6 +2212,7 @@ - (NSArray*)selectedChildren {
return ret;
}
@@ -251,7 +251,7 @@ index 474ae88c323e9a10bd8486482507f0d749214963..090c8fdc3b374ed937d3e04ccd5d9177
- (NSString*)selectedText {
if (![self instanceActive])
return nil;
@@ -2204,11 +2224,13 @@ id content::AXTextMarkerRangeFrom(id anchor_textmarker, id focus_textmarker) {
@@ -2204,11 +2224,13 @@ - (NSString*)selectedText {
return nil;
return base::SysUTF16ToNSString(range.GetText());
}
@@ -265,7 +265,7 @@ index 474ae88c323e9a10bd8486482507f0d749214963..090c8fdc3b374ed937d3e04ccd5d9177
- (NSValue*)selectedTextRange {
if (![self instanceActive])
return nil;
@@ -2229,12 +2251,15 @@ id content::AXTextMarkerRangeFrom(id anchor_textmarker, id focus_textmarker) {
@@ -2229,12 +2251,15 @@ - (NSValue*)selectedTextRange {
int selLength = range.GetText().length();
return [NSValue valueWithRange:NSMakeRange(selStart, selLength)];
}
@@ -281,7 +281,7 @@ index 474ae88c323e9a10bd8486482507f0d749214963..090c8fdc3b374ed937d3e04ccd5d9177
- (NSValue*)size {
if (![self instanceActive])
@@ -2267,6 +2292,7 @@ id content::AXTextMarkerRangeFrom(id anchor_textmarker, id focus_textmarker) {
@@ -2267,6 +2292,7 @@ - (NSString*)sortDirection {
return nil;
}
@@ -289,7 +289,7 @@ index 474ae88c323e9a10bd8486482507f0d749214963..090c8fdc3b374ed937d3e04ccd5d9177
// Returns a text marker that points to the first character in the document that
// can be selected with VoiceOver.
- (id)startTextMarker {
@@ -2277,6 +2303,7 @@ id content::AXTextMarkerRangeFrom(id anchor_textmarker, id focus_textmarker) {
@@ -2277,6 +2303,7 @@ - (id)startTextMarker {
BrowserAccessibilityPositionInstance position = root->CreatePositionAt(0);
return CreateTextMarker(position->CreatePositionAtStartOfAnchor());
}
@@ -297,7 +297,7 @@ index 474ae88c323e9a10bd8486482507f0d749214963..090c8fdc3b374ed937d3e04ccd5d9177
// Returns a subrole based upon the role.
- (NSString*)subrole {
@@ -2599,11 +2626,13 @@ id content::AXTextMarkerRangeFrom(id anchor_textmarker, id focus_textmarker) {
@@ -2599,11 +2626,13 @@ - (NSAttributedString*)attributedValueForRange:(NSRange)range {
NSMutableAttributedString* attributedInnerText =
[[[NSMutableAttributedString alloc]
initWithString:base::SysUTF16ToNSString(innerText)] autorelease];
@@ -311,7 +311,7 @@ index 474ae88c323e9a10bd8486482507f0d749214963..090c8fdc3b374ed937d3e04ccd5d9177
return [attributedInnerText attributedSubstringFromRange:range];
}
@@ -2707,9 +2736,8 @@ id content::AXTextMarkerRangeFrom(id anchor_textmarker, id focus_textmarker) {
@@ -2707,9 +2736,8 @@ - (id)accessibilityAttributeValue:(NSString*)attribute
return ToBrowserAccessibilityCocoa(cell);
}
@@ -323,7 +323,7 @@ index 474ae88c323e9a10bd8486482507f0d749214963..090c8fdc3b374ed937d3e04ccd5d9177
BrowserAccessibilityPositionInstance position =
CreatePositionFromTextMarker(parameter);
if (!position->IsNullPosition())
@@ -3022,6 +3050,7 @@ id content::AXTextMarkerRangeFrom(id anchor_textmarker, id focus_textmarker) {
@@ -3022,6 +3050,7 @@ AXPlatformRange range(std::move(lineStartPosition),
return CreateTextMarker(root->CreatePositionAt(index));
}
@@ -331,7 +331,7 @@ index 474ae88c323e9a10bd8486482507f0d749214963..090c8fdc3b374ed937d3e04ccd5d9177
if ([attribute isEqualToString:
NSAccessibilityBoundsForRangeParameterizedAttribute]) {
@@ -3057,6 +3086,7 @@ id content::AXTextMarkerRangeFrom(id anchor_textmarker, id focus_textmarker) {
@@ -3057,6 +3086,7 @@ AXPlatformRange range(std::move(lineStartPosition),
return nil;
}
@@ -339,7 +339,7 @@ index 474ae88c323e9a10bd8486482507f0d749214963..090c8fdc3b374ed937d3e04ccd5d9177
if ([attribute
isEqualToString:
NSAccessibilityLineTextMarkerRangeForTextMarkerParameterizedAttribute]) {
@@ -3171,6 +3201,7 @@ id content::AXTextMarkerRangeFrom(id anchor_textmarker, id focus_textmarker) {
@@ -3171,6 +3201,7 @@ AXPlatformRange range(std::move(lineStartPosition),
return @(child->GetIndexInParent());
}
@@ -351,7 +351,7 @@ diff --git a/content/browser/accessibility/browser_accessibility_manager_mac.mm
index aaf53dd214037f103ea7399d0702b1e2ffff1b56..5972939a070908521e82845b084d2d3b9f9a73f8 100644
--- a/content/browser/accessibility/browser_accessibility_manager_mac.mm
+++ b/content/browser/accessibility/browser_accessibility_manager_mac.mm
@@ -527,6 +527,7 @@ NSDictionary* BrowserAccessibilityManagerMac::
@@ -527,6 +527,7 @@ void PostAnnouncementNotification(NSString* announcement) {
[user_info setObject:native_focus_object
forKey:NSAccessibilityTextChangeElement];
@@ -359,7 +359,7 @@ index aaf53dd214037f103ea7399d0702b1e2ffff1b56..5972939a070908521e82845b084d2d3b
id selected_text = [native_focus_object selectedTextMarkerRange];
if (selected_text) {
NSString* const NSAccessibilitySelectedTextMarkerRangeAttribute =
@@ -534,6 +535,7 @@ NSDictionary* BrowserAccessibilityManagerMac::
@@ -534,6 +535,7 @@ void PostAnnouncementNotification(NSString* announcement) {
[user_info setObject:selected_text
forKey:NSAccessibilitySelectedTextMarkerRangeAttribute];
}
@@ -383,7 +383,7 @@ index 28ca1646af0b0cce40d27baec71cbe65adc334fa..bae65c1f485bc02eb9ef2ebf7018af4a
namespace content {
@@ -22,6 +24,7 @@ namespace {
@@ -22,6 +24,7 @@
// verifies there are no existing open connections), and then indicates that
// Chrome should continue execution without access to launchservicesd.
void DisableSystemServices() {
@@ -411,7 +411,7 @@ index 3aec8bc1fe1a619f2c4ec42ef438ae49fe0f5812..76dc23dfa26beb3b92bd87eb60fe3868
extern "C" {
// Undocumented IOBluetooth Preference API [1]. Used by `blueutil` [2] and
// `Karabiner` [3] to programmatically control the Bluetooth state. Calling the
@@ -49,6 +50,7 @@ extern "C" {
@@ -49,6 +50,7 @@
// [4] https://support.apple.com/kb/PH25091
void IOBluetoothPreferenceSetControllerPowerState(int state);
}
@@ -419,7 +419,7 @@ index 3aec8bc1fe1a619f2c4ec42ef438ae49fe0f5812..76dc23dfa26beb3b92bd87eb60fe3868
namespace {
@@ -118,8 +120,10 @@ BluetoothAdapterMac::BluetoothAdapterMac()
@@ -118,8 +120,10 @@ CBCentralManagerState GetCBManagerState(CBCentralManager* manager) {
controller_state_function_(
base::BindRepeating(&BluetoothAdapterMac::GetHostControllerState,
base::Unretained(this))),
@@ -430,7 +430,7 @@ index 3aec8bc1fe1a619f2c4ec42ef438ae49fe0f5812..76dc23dfa26beb3b92bd87eb60fe3868
should_update_name_(true),
classic_discovery_manager_(
BluetoothDiscoveryManagerMac::CreateClassic(this)),
@@ -306,8 +310,12 @@ base::WeakPtr<BluetoothAdapter> BluetoothAdapterMac::GetWeakPtr() {
@@ -306,8 +310,12 @@ CBCentralManagerState GetCBManagerState(CBCentralManager* manager) {
}
bool BluetoothAdapterMac::SetPoweredImpl(bool powered) {

View File

@@ -25,7 +25,7 @@ index bd3c6c1724bee8f06544a2aece0ae5e45c145e4d..d84160a3ce7d08e64053b4634f490669
// These are not documented, so use only after checking -respondsToSelector:.
@interface NSApplication (UndocumentedSpeechMethods)
- (void)speakString:(NSString*)string;
@@ -645,6 +650,9 @@ void ExtractUnderlines(NSAttributedString* string,
@@ -645,6 +650,9 @@ - (BOOL)acceptsMouseEventsWhenInactive {
}
- (BOOL)acceptsFirstMouse:(NSEvent*)theEvent {
@@ -35,7 +35,7 @@ index bd3c6c1724bee8f06544a2aece0ae5e45c145e4d..d84160a3ce7d08e64053b4634f490669
return [self acceptsMouseEventsWhenInactive];
}
@@ -1078,6 +1086,10 @@ void ExtractUnderlines(NSAttributedString* string,
@@ -1078,6 +1086,10 @@ - (void)keyEvent:(NSEvent*)theEvent wasKeyEquivalent:(BOOL)equiv {
eventType == NSKeyDown &&
!(modifierFlags & NSCommandKeyMask);
@@ -46,7 +46,7 @@ index bd3c6c1724bee8f06544a2aece0ae5e45c145e4d..d84160a3ce7d08e64053b4634f490669
// We only handle key down events and just simply forward other events.
if (eventType != NSKeyDown) {
_hostHelper->ForwardKeyboardEvent(event, latency_info);
@@ -1854,9 +1866,11 @@ void ExtractUnderlines(NSAttributedString* string,
@@ -1854,9 +1866,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 +58,7 @@ index bd3c6c1724bee8f06544a2aece0ae5e45c145e4d..d84160a3ce7d08e64053b4634f490669
- (NSArray*)validAttributesForMarkedText {
// This code is just copied from WebKit except renaming variables.
@@ -1865,7 +1879,10 @@ extern NSString* NSTextInputReplacementRangeAttributeName;
@@ -1865,7 +1879,10 @@ - (NSArray*)validAttributesForMarkedText {
initWithObjects:NSUnderlineStyleAttributeName,
NSUnderlineColorAttributeName,
NSMarkedClauseSegmentAttributeName,

View File

@@ -26,7 +26,7 @@ diff --git a/content/browser/web_contents/web_drag_dest_mac.mm b/content/browser
index a964f38b830f62bf694646033e1c24e0cf4557c5..61e69fdebaca038d09b5ebab71fd20e2e13188f0 100644
--- a/content/browser/web_contents/web_drag_dest_mac.mm
+++ b/content/browser/web_contents/web_drag_dest_mac.mm
@@ -384,9 +384,7 @@ void DropCompletionCallback(
@@ -384,9 +384,7 @@ - (void)setDragStartTrackersForProcess:(int)processID {
}
- (bool)isValidDragTarget:(content::RenderWidgetHostImpl*)targetRWH {

View File

@@ -13,7 +13,6 @@ feat_add_flags_for_low-level_hooks_and_exceptions.patch
fix_expose_tracing_agent_and_use_tracing_tracingcontroller_instead.patch
pass_all_globals_through_require.patch
call_process_log_from_fallback_stream_on_windows.patch
fixme_use_redefined_version_of_internalmodulestat.patch
fixme_remove_async_id_assertion_check.patch
fixme_comment_trace_event_macro.patch
fix_key_gen_apis_are_not_available_in_boringssl.patch
@@ -41,3 +40,4 @@ update_tests_after_increasing_typed_array_size.patch
darwin_work_around_clock_jumping_back_in_time.patch
fix_do_not_register_the_esm_loader_in_renderer_processes.patch
fix_allow_preventing_setpromiserejectcallback.patch
lib_use_non-symbols_in_isurlinstance_check.patch

View File

@@ -1,23 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shelley Vohr <shelley.vohr@gmail.com>
Date: Wed, 21 Aug 2019 11:06:16 -0700
Subject: FIXME: use redefined version of internalModuleStat
Instantiate redefined version of the internalModuleStat function
(see lib/common/asar.js in the electron/electron repo). For some reason
this has to be done after the upgrade to the Node.js v8.7.0. in the very beginning of the file holds a reference
to a native Node.js implementation of the function.
diff --git a/lib/internal/modules/cjs/loader.js b/lib/internal/modules/cjs/loader.js
index 0ef46569924354ea3ef59f3220637e30b316a761..44271058a26dc05b693e07aad9a22037dd9a5d1f 100644
--- a/lib/internal/modules/cjs/loader.js
+++ b/lib/internal/modules/cjs/loader.js
@@ -142,6 +142,8 @@ function enrichCJSError(err) {
}
function stat(filename) {
+ // FIXME(codebytere): determine why this needs to be done and remove
+ const internalModuleStat = process.binding('fs').internalModuleStat;
filename = path.toNamespacedPath(filename);
if (statCache !== null) {
const result = statCache.get(filename);

View File

@@ -0,0 +1,30 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shelley Vohr <shelley.vohr@gmail.com>
Date: Tue, 4 Aug 2020 09:17:06 -0700
Subject: lib: use non-symbols in isURLInstance check
This slightly changes the conditional used to determine whether or
not something is a URL instance. Since Node.js adds symbols to the URL
not specified by the WHATWG, those symbols are not present in other
implementations (like Blink's) and therefore can cause false negatives.
This fixes that by slightly changing the check to properties present
in all URL instances as specified in the WHATWG spec.
Upstreamed at: https://github.com/nodejs/node/pull/34622.
diff --git a/lib/internal/url.js b/lib/internal/url.js
index 78f5b32745a0436337233e8a4b57b89263effad6..ace274501f2c1f6bb06f600abb850e737c988338 100644
--- a/lib/internal/url.js
+++ b/lib/internal/url.js
@@ -1394,8 +1394,8 @@ function pathToFileURL(filepath) {
}
function isURLInstance(fileURLOrPath) {
- return fileURLOrPath != null && fileURLOrPath[searchParams] &&
- fileURLOrPath[searchParams][searchParams];
+ return fileURLOrPath != null && fileURLOrPath['href'] &&
+ fileURLOrPath['origin'];
}
function toPathIfFileURL(fileURLOrPath) {

View File

@@ -22,7 +22,7 @@ index c872941b974216d94863bcbf0e597b9c09ca50e2..4e7c3c10255a0eae4d5333f88e51cf71
process.config = JSONParse(internalBinding('native_module').config);
diff --git a/lib/internal/modules/cjs/loader.js b/lib/internal/modules/cjs/loader.js
index 44271058a26dc05b693e07aad9a22037dd9a5d1f..7d08fb05e9a0abeb82d416891968b23002dc3685 100644
index 0ef46569924354ea3ef59f3220637e30b316a761..7d08fb05e9a0abeb82d416891968b23002dc3685 100644
--- a/lib/internal/modules/cjs/loader.js
+++ b/lib/internal/modules/cjs/loader.js
@@ -55,7 +55,7 @@ const assert = require('internal/assert');
@@ -34,14 +34,7 @@ index 44271058a26dc05b693e07aad9a22037dd9a5d1f..7d08fb05e9a0abeb82d416891968b230
const packageJsonReader = require('internal/modules/package_json_reader');
const { safeGetenv } = internalBinding('credentials');
const {
@@ -142,14 +142,12 @@ function enrichCJSError(err) {
}
function stat(filename) {
- // FIXME(codebytere): determine why this needs to be done and remove
- const internalModuleStat = process.binding('fs').internalModuleStat;
filename = path.toNamespacedPath(filename);
if (statCache !== null) {
@@ -147,7 +147,7 @@ function stat(filename) {
const result = statCache.get(filename);
if (result !== undefined) return result;
}

View File

@@ -9,7 +9,7 @@ diff --git a/Squirrel/SQRLZipArchiver.m b/Squirrel/SQRLZipArchiver.m
index 478509cdd528db4fcfa340c6f93fa58a446957e6..7c279bf73c368453bff4f922d76908c06dc378cd 100644
--- a/Squirrel/SQRLZipArchiver.m
+++ b/Squirrel/SQRLZipArchiver.m
@@ -134,7 +134,7 @@ const NSInteger SQRLZipArchiverShellTaskFailed = 1;
@@ -134,7 +134,7 @@ - (RACSignal *)launchWithArguments:(NSArray *)arguments {
return [RACSignal
zip:@[ self.taskTerminated, self.standardErrorData ]
reduce:^(NSNumber *exitStatus, NSData *errorData) {

View File

@@ -1,6 +1,5 @@
const { spawnSync } = require('child_process');
const path = require('path');
const { inspect } = require('util');
import { spawnSync } from 'child_process';
import * as path from 'path';
const srcPath = path.resolve(__dirname, '..', '..', '..');
const patchExportFnPath = path.resolve(__dirname, 'export_all_patches.py');

View File

@@ -1,6 +1,6 @@
const cp = require('child_process');
const fs = require('fs');
const path = require('path');
import * as cp from 'child_process';
import * as fs from 'fs';
import * as path from 'path';
const certificatePath = process.argv[2];
const outPath = process.argv[3];

View File

@@ -40,7 +40,7 @@ DevToolsSecurity -enable
# security import "$dir"/public.key -k $KEY_CHAIN
# Generate Trust Settings
node "$(dirname $0)"/gen-trust.js "$dir"/certificate.cer "$dir"/trust.xml
npx ts-node "$(dirname $0)"/gen-trust.ts "$dir"/certificate.cer "$dir"/trust.xml
# Import Trust Settings
sudo security trust-settings-import -d "$dir/trust.xml"

View File

@@ -1,5 +1,6 @@
const args = require('minimist')(process.argv.slice(2));
const octokit = require('@octokit/rest')();
const { Octokit } = require('@octokit/rest');
const octokit = new Octokit();
const path = require('path');
const SOURCE_ROOT = path.normalize(path.dirname(__dirname));

View File

@@ -1,7 +1,7 @@
const cp = require('child_process');
const fs = require('fs-extra');
const os = require('os');
const path = require('path');
import * as cp from 'child_process';
import * as fs from 'fs-extra';
import * as os from 'os';
import * as path from 'path';
const rootPath = path.resolve(__dirname, '..');
const gniPath = path.resolve(__dirname, '../filenames.auto.gni');
@@ -43,7 +43,7 @@ const main = async () => {
}
];
await Promise.all(webpackTargets.map(async webpackTarget => {
const webpackTargetsWithDeps = await Promise.all(webpackTargets.map(async webpackTarget => {
const tmpDir = await fs.mkdtemp(path.resolve(os.tmpdir(), 'electron-filenames-'));
const child = cp.spawn('node', [
'build/webpack/get-outputs.js',
@@ -66,20 +66,24 @@ const main = async () => {
resolve();
}));
webpackTarget.dependencies = JSON.parse(output)
// Remove whitespace
.map(line => line.trim())
// Get the relative path
.map(line => path.relative(rootPath, line).replace(/\\/g, '/'))
// Only care about files in //electron
.filter(line => !line.startsWith('..'))
// Only care about our own files
.filter(line => !line.startsWith('node_modules'))
// All webpack builds depend on the tsconfig and package json files
.concat(['tsconfig.json', 'tsconfig.electron.json', 'package.json', ...typingFiles])
// Make the generated list easier to read
.sort();
const webpackTargetWithDeps = {
...webpackTarget,
dependencies: (JSON.parse(output) as string[])
// Remove whitespace
.map(line => line.trim())
// Get the relative path
.map(line => path.relative(rootPath, line).replace(/\\/g, '/'))
// Only care about files in //electron
.filter(line => !line.startsWith('..'))
// Only care about our own files
.filter(line => !line.startsWith('node_modules'))
// All webpack builds depend on the tsconfig and package json files
.concat(['tsconfig.json', 'tsconfig.electron.json', 'package.json', ...typingFiles])
// Make the generated list easier to read
.sort()
};
await fs.remove(tmpDir);
return webpackTargetWithDeps;
}));
fs.writeFileSync(
@@ -90,7 +94,7 @@ auto_filenames = {
${allDocs.map(doc => ` "${doc}",`).join('\n')}
]
${webpackTargets.map(target => ` ${target.name} = [
${webpackTargetsWithDeps.map(target => ` ${target.name} = [
${target.dependencies.map(dep => ` "${dep}",`).join('\n')}
]`).join('\n\n')}
}

View File

@@ -190,7 +190,7 @@ def format_patch(repo, since):
'-C',
repo,
'-c',
'core.attributesfile=' + os.path.join(os.path.dirname(os.path.realpath(__file__)), '.electron.attributes'),
'core.attributesfile=' + os.path.join(os.path.dirname(os.path.realpath(__file__)), 'electron.gitattributes'),
# Ensure it is not possible to match anything
# Disabled for now as we have consistent chunk headers
# '-c',

View File

@@ -1,6 +1,7 @@
if (!process.env.CI) require('dotenv-safe').load();
const octokit = require('@octokit/rest')({
const { Octokit } = require('@octokit/rest');
const octokit = new Octokit({
auth: process.env.ELECTRON_GITHUB_TOKEN
});

View File

@@ -11,6 +11,7 @@ const notesGenerator = require('./notes.js');
const semverify = version => version.replace(/^origin\//, '').replace(/[xy]/g, '0').replace(/-/g, '.');
const runGit = async (args) => {
console.info(`Running: git ${args.join(' ')}`);
const response = await GitProcess.exec(args, ELECTRON_DIR);
if (response.exitCode !== 0) {
throw new Error(response.stderr.trim());
@@ -19,15 +20,20 @@ const runGit = async (args) => {
};
const tagIsSupported = tag => tag && !tag.includes('nightly') && !tag.includes('unsupported');
const tagIsBeta = tag => tag.includes('beta');
const tagIsBeta = tag => tag && tag.includes('beta');
const tagIsStable = tag => tagIsSupported(tag) && !tagIsBeta(tag);
const getTagsOf = async (point) => {
return (await runGit(['tag', '--merged', point]))
.split('\n')
.map(tag => tag.trim())
.filter(tag => semver.valid(tag))
.sort(semver.compare);
try {
const tags = await runGit(['tag', '--merged', point]);
return tags.split('\n')
.map(tag => tag.trim())
.filter(tag => semver.valid(tag))
.sort(semver.compare);
} catch (err) {
console.error(`Failed to fetch tags for point ${point}`);
throw err;
}
};
const getTagsOnBranch = async (point) => {
@@ -41,21 +47,31 @@ const getTagsOnBranch = async (point) => {
};
const getBranchOf = async (point) => {
const branches = (await runGit(['branch', '-a', '--contains', point]))
.split('\n')
.map(branch => branch.trim())
.filter(branch => !!branch);
const current = branches.find(branch => branch.startsWith('* '));
return current ? current.slice(2) : branches.shift();
try {
const branches = (await runGit(['branch', '-a', '--contains', point]))
.split('\n')
.map(branch => branch.trim())
.filter(branch => !!branch);
const current = branches.find(branch => branch.startsWith('* '));
return current ? current.slice(2) : branches.shift();
} catch (err) {
console.error(`Failed to fetch branch for ${point}: `, err);
throw err;
}
};
const getAllBranches = async () => {
return (await runGit(['branch', '--remote']))
.split('\n')
.map(branch => branch.trim())
.filter(branch => !!branch)
.filter(branch => branch !== 'origin/HEAD -> origin/master')
.sort();
try {
const branches = await runGit(['branch', '--remote']);
return branches.split('\n')
.map(branch => branch.trim())
.filter(branch => !!branch)
.filter(branch => branch !== 'origin/HEAD -> origin/master')
.sort();
} catch (err) {
console.error('Failed to fetch all branches');
throw err;
}
};
const getStabilizationBranches = async () => {

View File

@@ -6,11 +6,12 @@ const fs = require('fs');
const path = require('path');
const { GitProcess } = require('dugite');
const octokit = require('@octokit/rest')({
const { Octokit } = require('@octokit/rest');
const octokit = new Octokit({
auth: process.env.ELECTRON_GITHUB_TOKEN
});
const { SRC_DIR } = require('../../lib/utils');
const { ELECTRON_DIR } = require('../../lib/utils');
const MAX_FAIL_COUNT = 3;
const CHECK_INTERVAL = 5000;
@@ -386,13 +387,12 @@ const getNotes = async (fromRef, toRef, newVersion) => {
}
const pool = new Pool();
const electronDir = path.resolve(SRC_DIR, 'electron');
const toBranch = await getBranchNameOfRef(toRef, electronDir);
const toBranch = await getBranchNameOfRef(toRef, ELECTRON_DIR);
console.log(`Generating release notes between ${fromRef} and ${toRef} for version ${newVersion} in branch ${toBranch}`);
// get the electron/electron commits
const electron = { owner: 'electron', repo: 'electron', dir: electronDir };
const electron = { owner: 'electron', repo: 'electron', dir: ELECTRON_DIR };
await addRepoToPool(pool, electron, fromRef, toRef);
// remove any old commits

View File

@@ -5,9 +5,7 @@ const args = require('minimist')(process.argv.slice(2), {
boolean: ['automaticRelease', 'notesOnly', 'stable']
});
const ciReleaseBuild = require('./ci-release-build');
const octokit = require('@octokit/rest')({
auth: process.env.ELECTRON_GITHUB_TOKEN
});
const { Octokit } = require('@octokit/rest');
const { execSync } = require('child_process');
const { GitProcess } = require('dugite');
@@ -18,6 +16,10 @@ const { getCurrentBranch, ELECTRON_DIR } = require('../lib/utils.js');
const bumpType = args._[0];
const targetRepo = bumpType === 'nightly' ? 'nightlies' : 'electron';
const octokit = new Octokit({
auth: process.env.ELECTRON_GITHUB_TOKEN
});
require('colors');
const pass = '✓'.green;
const fail = '✗'.red;
@@ -211,4 +213,8 @@ async function prepareRelease (isBeta, notesOnly) {
}
}
prepareRelease(!args.stable, args.notesOnly);
prepareRelease(!args.stable, args.notesOnly)
.catch((err) => {
console.error(err);
process.exit(1);
});

View File

@@ -6,8 +6,10 @@ const { getCurrentBranch, ELECTRON_DIR } = require('../lib/utils');
const request = require('request');
const semver = require('semver');
const rootPackageJson = require('../../package.json');
const octokit = require('@octokit/rest')({
headers: { 'User-Agent': 'electron-npm-publisher' }
const { Octokit } = require('@octokit/rest');
const octokit = new Octokit({
userAgent: 'electron-npm-publisher'
});
if (!process.env.ELECTRON_NPM_OTP) {

View File

@@ -9,8 +9,9 @@ const path = require('path');
const { execSync } = require('child_process');
const { GitProcess } = require('dugite');
const { getCurrentBranch, ELECTRON_DIR } = require('../lib/utils.js');
const { Octokit } = require('@octokit/rest');
const octokit = require('@octokit/rest')({
const octokit = new Octokit({
auth: process.env.ELECTRON_GITHUB_TOKEN
});

View File

@@ -21,6 +21,7 @@ const path = require('path');
const sumchecker = require('sumchecker');
const temp = require('temp').track();
const { URL } = require('url');
const { Octokit } = require('@octokit/rest');
require('colors');
const pass = '✓'.green;
@@ -28,7 +29,7 @@ const fail = '✗'.red;
const { ELECTRON_DIR } = require('../lib/utils');
const octokit = require('@octokit/rest')({
const octokit = new Octokit({
auth: process.env.ELECTRON_GITHUB_TOKEN
});
@@ -251,7 +252,7 @@ async function uploadShasumFile (filePath, fileName, releaseId) {
'content-type': 'text/plain',
'content-length': fs.statSync(filePath).size
},
file: fs.createReadStream(filePath),
data: fs.createReadStream(filePath),
name: fileName
}).catch(err => {
console.log(`${fail} Error uploading ${filePath} to GitHub:`, err);

View File

@@ -2,8 +2,14 @@
import glob
import os
import shutil
import subprocess
import sys
import tempfile
def is_fs_case_sensitive():
with tempfile.NamedTemporaryFile(prefix='TmP') as tmp_file:
return(not os.path.exists(tmp_file.name.lower()))
sys.path.append(
os.path.abspath(os.path.dirname(os.path.abspath(__file__)) + "/../.."))
@@ -49,7 +55,19 @@ def main():
# The symbol server needs lowercase paths, it will fail otherwise
# So lowercase all the file paths here
if is_fs_case_sensitive():
for f in files:
lower_f = f.lower()
if lower_f != f:
if os.path.exists(lower_f):
shutil.rmtree(lower_f)
lower_dir = os.path.dirname(lower_f)
if not os.path.exists(lower_dir):
os.makedirs(lower_dir)
shutil.copy2(f, lower_f)
files = [f.lower() for f in files]
for f in files:
assert os.path.exists(f)
bucket, access_key, secret_key = s3_config()
upload_symbols(bucket, access_key, secret_key, files)

View File

@@ -2,7 +2,8 @@ if (!process.env.CI) require('dotenv-safe').load();
const fs = require('fs');
const octokit = require('@octokit/rest')({
const { Octokit } = require('@octokit/rest');
const octokit = new Octokit({
auth: process.env.ELECTRON_GITHUB_TOKEN
});
@@ -40,7 +41,7 @@ function uploadToGitHub () {
octokit.repos.uploadReleaseAsset({
url: uploadUrl,
headers: getHeaders(filePath, fileName),
file: fs.createReadStream(filePath),
data: fs.createReadStream(filePath),
name: fileName
}).then(() => {
console.log(`Successfully uploaded ${fileName} to GitHub.`);

17
script/run-if-exists.js Normal file
View File

@@ -0,0 +1,17 @@
const cp = require('child_process');
const fs = require('fs');
const checkPath = process.argv[2];
const command = process.argv.slice(3);
if (fs.existsSync(checkPath)) {
const child = cp.spawn(
`${command[0]}${process.platform === 'win32' ? '.cmd' : ''}`,
command.slice(1),
{
stdio: 'inherit',
cwd: checkPath
}
);
child.on('exit', code => process.exit(code));
}

View File

@@ -806,6 +806,7 @@ base::OnceClosure App::SelectClientCertificate(
std::make_shared<net::ClientCertIdentityList>(std::move(identities));
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
v8::HandleScope handle_scope(isolate);
bool prevent_default =
Emit("select-client-certificate",
WebContents::FromOrCreate(isolate, web_contents),

View File

@@ -78,7 +78,7 @@ BrowserWindow::BrowserWindow(gin::Arguments* args,
Observe(api_web_contents_->web_contents());
// Keep a copy of the options for later use.
gin_helper::Dictionary(isolate, web_contents->GetWrapper())
gin_helper::Dictionary(isolate, web_contents.ToV8().As<v8::Object>())
.Set("browserWindowOptions", options);
// Associate with BrowserWindow.

View File

@@ -40,7 +40,11 @@
#endif
#if defined(OS_LINUX)
#include "base/containers/span.h"
#include "base/files/file_util.h"
#include "base/guid.h"
#include "components/crash/core/app/breakpad_linux.h"
#include "components/crash/core/common/crash_keys.h"
#include "v8/include/v8-wasm-trap-handler-posix.h"
#include "v8/include/v8.h"
#endif
@@ -81,6 +85,40 @@ bool IsCrashReporterEnabled() {
const std::map<std::string, std::string>& GetGlobalCrashKeys() {
return GetGlobalCrashKeysMutable();
}
base::FilePath GetClientIdPath() {
base::FilePath path;
base::PathService::Get(electron::DIR_CRASH_DUMPS, &path);
return path.Append("client_id");
}
std::string ReadClientId() {
base::ThreadRestrictions::ScopedAllowIO allow_io;
std::string client_id;
// "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".length == 36
if (!base::ReadFileToStringWithMaxSize(GetClientIdPath(), &client_id, 36) ||
client_id.size() != 36)
return std::string();
return client_id;
}
void WriteClientId(const std::string& client_id) {
DCHECK_EQ(client_id.size(), 36u);
base::ThreadRestrictions::ScopedAllowIO allow_io;
base::WriteFile(GetClientIdPath(), client_id);
}
std::string GetClientId() {
static base::NoDestructor<std::string> client_id;
if (!client_id->empty())
return *client_id;
*client_id = ReadClientId();
if (client_id->empty()) {
*client_id = base::GenerateGUID();
WriteClientId(*client_id);
}
return *client_id;
}
#endif
void Start(const std::string& submit_url,
@@ -107,6 +145,7 @@ void Start(const std::string& submit_url,
? "node"
: command_line->GetSwitchValueASCII(::switches::kProcessType);
#if defined(OS_LINUX)
::crash_keys::SetMetricsClientIdFromGUID(GetClientId());
auto& global_crash_keys = GetGlobalCrashKeysMutable();
for (const auto& pair : global_extra) {
global_crash_keys[pair.first] = pair.second;

View File

@@ -19,6 +19,7 @@ bool IsCrashReporterEnabled();
#if defined(OS_LINUX)
const std::map<std::string, std::string>& GetGlobalCrashKeys();
std::string GetClientId();
#endif
// JS bindings API; exposed publicly because it's also called from node_main.cc

View File

@@ -24,29 +24,27 @@
if ((self = [super init])) {
NSDistributedNotificationCenter* distCenter =
[NSDistributedNotificationCenter defaultCenter];
// A notification that the screen was locked.
[distCenter addObserver:self
selector:@selector(onScreenLocked:)
name:@"com.apple.screenIsLocked"
object:nil];
// A notification that the screen was unlocked by the user.
[distCenter addObserver:self
selector:@selector(onScreenUnlocked:)
name:@"com.apple.screenIsUnlocked"
object:nil];
// A notification that the workspace posts before the machine goes to sleep.
[[[NSWorkspace sharedWorkspace] notificationCenter]
addObserver:self
selector:@selector(isSuspending:)
name:NSWorkspaceWillSleepNotification
object:nil];
[distCenter addObserver:self
selector:@selector(isSuspending:)
name:NSWorkspaceWillSleepNotification
object:nil];
// A notification that the workspace posts when the machine wakes from
// sleep.
[[[NSWorkspace sharedWorkspace] notificationCenter]
addObserver:self
selector:@selector(isResuming:)
name:NSWorkspaceDidWakeNotification
object:nil];
[distCenter addObserver:self
selector:@selector(isResuming:)
name:NSWorkspaceDidWakeNotification
object:nil];
}
return self;
}

View File

@@ -12,6 +12,7 @@
#include <utility>
#include <vector>
#include "base/containers/id_map.h"
#include "base/no_destructor.h"
#include "base/optional.h"
#include "base/strings/utf_string_conversions.h"
@@ -332,6 +333,11 @@ namespace api {
namespace {
base::IDMap<WebContents*>& GetAllWebContents() {
static base::NoDestructor<base::IDMap<WebContents*>> s_all_web_contents;
return *s_all_web_contents;
}
// Called when CapturePage is done.
void OnCapturePageDone(gin_helper::Promise<gfx::Image> promise,
const SkBitmap& bitmap) {
@@ -389,12 +395,21 @@ base::string16 GetDefaultPrinterAsync() {
}
#endif
struct UserDataLink : public base::SupportsUserData::Data {
explicit UserDataLink(base::WeakPtr<WebContents> contents)
: web_contents(contents) {}
base::WeakPtr<WebContents> web_contents;
};
const void* kElectronApiWebContentsKey = &kElectronApiWebContentsKey;
} // namespace
WebContents::WebContents(v8::Isolate* isolate,
content::WebContents* web_contents)
: content::WebContentsObserver(web_contents),
type_(Type::REMOTE),
id_(GetAllWebContents().Add(this)),
weak_factory_(this) {
auto session = Session::CreateFrom(isolate, GetBrowserContext());
session_.Reset(isolate, session.ToV8());
@@ -402,8 +417,8 @@ WebContents::WebContents(v8::Isolate* isolate,
web_contents->SetUserAgentOverride(blink::UserAgentOverride::UserAgentOnly(
GetBrowserContext()->GetUserAgent()),
false);
Init(isolate);
AttachAsUserData(web_contents);
web_contents->SetUserData(kElectronApiWebContentsKey,
std::make_unique<UserDataLink>(GetWeakPtr()));
InitZoomController(web_contents, gin::Dictionary::CreateEmpty(isolate));
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
extensions::ElectronExtensionWebContentsObserver::CreateForWebContents(
@@ -421,6 +436,7 @@ WebContents::WebContents(v8::Isolate* isolate,
Type type)
: content::WebContentsObserver(web_contents.get()),
type_(type),
id_(GetAllWebContents().Add(this)),
weak_factory_(this) {
DCHECK(type != Type::REMOTE)
<< "Can't take ownership of a remote WebContents";
@@ -432,7 +448,7 @@ WebContents::WebContents(v8::Isolate* isolate,
WebContents::WebContents(v8::Isolate* isolate,
const gin_helper::Dictionary& options)
: weak_factory_(this) {
: id_(GetAllWebContents().Add(this)), weak_factory_(this) {
// Read options.
options.Get("backgroundThrottling", &background_throttling_);
@@ -610,11 +626,12 @@ void WebContents::InitWithSessionAndOptions(
SetOwnerWindow(owner_window);
}
Init(isolate);
AttachAsUserData(web_contents());
web_contents()->SetUserData(kElectronApiWebContentsKey,
std::make_unique<UserDataLink>(GetWeakPtr()));
}
WebContents::~WebContents() {
MarkDestroyed();
// The destroy() is called.
if (managed_web_contents()) {
managed_web_contents()->GetView()->SetDelegate(nullptr);
@@ -740,19 +757,19 @@ void WebContents::AddNewContents(
content::WebContents* WebContents::OpenURLFromTab(
content::WebContents* source,
const content::OpenURLParams& params) {
auto weak_this = GetWeakPtr();
if (params.disposition != WindowOpenDisposition::CURRENT_TAB) {
Emit("-new-window", params.url, "", params.disposition, "", params.referrer,
params.post_data);
return nullptr;
}
if (!weak_this)
return nullptr;
// Give user a chance to cancel navigation.
if (Emit("will-navigate", params.url))
return nullptr;
// Don't load the URL if the web contents was marked as destroyed from a
// will-navigate event listener
if (IsDestroyed())
if (!weak_this)
return nullptr;
return CommonWebContentsDelegate::OpenURLFromTab(source, params);
@@ -1217,9 +1234,7 @@ void WebContents::MessageTo(bool internal,
const std::string& channel,
blink::CloneableMessage arguments) {
TRACE_EVENT1("electron", "WebContents::MessageTo", "channel", channel);
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
auto* web_contents = gin_helper::TrackableObject<WebContents>::FromWeakMapID(
isolate, web_contents_id);
auto* web_contents = FromID(web_contents_id);
if (web_contents) {
web_contents->SendIPCMessageWithSender(internal, send_to_all, channel,
@@ -1398,6 +1413,17 @@ bool WebContents::OnMessageReceived(const IPC::Message& message) {
return handled;
}
void WebContents::MarkDestroyed() {
if (GetAllWebContents().Lookup(id_))
GetAllWebContents().Remove(id_);
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
v8::HandleScope scope(isolate);
v8::Local<v8::Object> wrapper;
if (!GetWrapper(isolate).ToLocal(&wrapper))
return;
wrapper->SetAlignedPointerInInternalField(0, nullptr);
}
// There are three ways of destroying a webContents:
// 1. call webContents.destroy();
// 2. garbage collection;
@@ -1419,7 +1445,6 @@ void WebContents::WebContentsDestroyed() {
guest_delegate_->WillDestroy();
// Cleanup relationships with other parts.
RemoveFromWeakMap();
// We can not call Destroy here because we need to call Emit first, but we
// also do not want any method to be used, so just mark as destroyed here.
@@ -1435,7 +1460,13 @@ void WebContents::WebContentsDestroyed() {
}
// Destroy the native class in next tick.
base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, GetDestroyClosure());
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(
[](base::WeakPtr<WebContents> wc) {
if (wc)
delete wc.get();
},
GetWeakPtr()));
}
void WebContents::NavigationEntryCommitted(
@@ -2632,10 +2663,6 @@ v8::Local<v8::Value> WebContents::GetOwnerBrowserWindow(
return v8::Null(isolate);
}
int32_t WebContents::ID() const {
return weak_map_id();
}
v8::Local<v8::Value> WebContents::Session(v8::Isolate* isolate) {
return v8::Local<v8::Value>::New(isolate, session_);
}
@@ -2754,11 +2781,28 @@ v8::Local<v8::Promise> WebContents::TakeHeapSnapshot(
}
// static
void WebContents::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(gin::StringToV8(isolate, "WebContents"));
gin_helper::Destroyable::MakeDestroyable(isolate, prototype);
gin_helper::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
v8::Local<v8::ObjectTemplate> WebContents::FillObjectTemplate(
v8::Isolate* isolate,
v8::Local<v8::ObjectTemplate> templ) {
gin::InvokerOptions options;
options.holder_is_first_argument = true;
options.holder_type = "WebContents";
templ->Set(
gin::StringToSymbol(isolate, "isDestroyed"),
gin::CreateFunctionTemplate(
isolate, base::BindRepeating(&gin_helper::Destroyable::IsDestroyed),
options));
templ->Set(
gin::StringToSymbol(isolate, "destroy"),
gin::CreateFunctionTemplate(
isolate, base::BindRepeating([](gin::Handle<WebContents> handle) {
delete handle.get();
}),
options));
// We use gin_helper::ObjectTemplateBuilder instead of
// gin::ObjectTemplateBuilder here to handle the fact that WebContents is
// destroyable.
return gin_helper::ObjectTemplateBuilder(isolate, templ)
.SetMethod("getBackgroundThrottling",
&WebContents::GetBackgroundThrottling)
.SetMethod("setBackgroundThrottling",
@@ -2870,7 +2914,12 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
.SetProperty("session", &WebContents::Session)
.SetProperty("hostWebContents", &WebContents::HostWebContents)
.SetProperty("devToolsWebContents", &WebContents::DevToolsWebContents)
.SetProperty("debugger", &WebContents::Debugger);
.SetProperty("debugger", &WebContents::Debugger)
.Build();
}
const char* WebContents::GetTypeName() {
return "WebContents";
}
ElectronBrowserContext* WebContents::GetBrowserContext() const {
@@ -2882,7 +2931,17 @@ ElectronBrowserContext* WebContents::GetBrowserContext() const {
gin::Handle<WebContents> WebContents::Create(
v8::Isolate* isolate,
const gin_helper::Dictionary& options) {
return gin::CreateHandle(isolate, new WebContents(isolate, options));
gin::Handle<WebContents> handle =
gin::CreateHandle(isolate, new WebContents(isolate, options));
gin_helper::CallMethod(isolate, handle.get(), "_init");
return handle;
}
// static
gin::Handle<WebContents> WebContents::New(
v8::Isolate* isolate,
const gin_helper::Dictionary& options) {
return Create(isolate, options);
}
// static
@@ -2890,15 +2949,19 @@ gin::Handle<WebContents> WebContents::CreateAndTake(
v8::Isolate* isolate,
std::unique_ptr<content::WebContents> web_contents,
Type type) {
return gin::CreateHandle(
gin::Handle<WebContents> handle = gin::CreateHandle(
isolate, new WebContents(isolate, std::move(web_contents), type));
gin_helper::CallMethod(isolate, handle.get(), "_init");
return handle;
}
// static
WebContents* WebContents::From(content::WebContents* web_contents) {
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
auto* existing = TrackableObject::FromWrappedClass(isolate, web_contents);
return static_cast<WebContents*>(existing);
if (!web_contents)
return nullptr;
UserDataLink* data = static_cast<UserDataLink*>(
web_contents->GetUserData(kElectronApiWebContentsKey));
return data ? data->web_contents.get() : nullptr;
}
// static
@@ -2906,36 +2969,50 @@ gin::Handle<WebContents> WebContents::FromOrCreate(
v8::Isolate* isolate,
content::WebContents* web_contents) {
WebContents* api_web_contents = From(web_contents);
if (!api_web_contents)
if (!api_web_contents) {
api_web_contents = new WebContents(isolate, web_contents);
gin_helper::CallMethod(isolate, api_web_contents, "_init");
}
return gin::CreateHandle(isolate, api_web_contents);
}
// static
WebContents* WebContents::FromID(int32_t id) {
return FromWeakMapID(JavascriptEnvironment::GetIsolate(), id);
return GetAllWebContents().Lookup(id);
}
// static
gin::WrapperInfo WebContents::kWrapperInfo = {gin::kEmbedderNativeGin};
} // namespace api
} // namespace electron
namespace {
using electron::api::GetAllWebContents;
using electron::api::WebContents;
std::vector<gin::Handle<WebContents>> GetAllWebContentsAsV8(
v8::Isolate* isolate) {
std::vector<gin::Handle<WebContents>> list;
for (auto iter = base::IDMap<WebContents*>::iterator(&GetAllWebContents());
!iter.IsAtEnd(); iter.Advance()) {
list.push_back(gin::CreateHandle(isolate, iter.GetCurrentValue()));
}
return list;
}
void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv) {
v8::Isolate* isolate = context->GetIsolate();
gin_helper::Dictionary dict(isolate, exports);
dict.Set("WebContents", WebContents::GetConstructor(isolate)
->GetFunction(context)
.ToLocalChecked());
dict.Set("WebContents", WebContents::GetConstructor(context));
dict.SetMethod("create", &WebContents::Create);
dict.SetMethod("fromId", &WebContents::FromWeakMapID);
dict.SetMethod("getAllWebContents", &WebContents::GetAll);
dict.SetMethod("fromId", &WebContents::FromID);
dict.SetMethod("getAllWebContents", &GetAllWebContentsAsV8);
}
} // namespace

View File

@@ -8,6 +8,7 @@
#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "base/observer_list.h"
@@ -22,14 +23,17 @@
#include "electron/buildflags/buildflags.h"
#include "electron/shell/common/api/api.mojom.h"
#include "gin/handle.h"
#include "gin/wrappable.h"
#include "mojo/public/cpp/bindings/receiver_set.h"
#include "printing/buildflags/buildflags.h"
#include "services/service_manager/public/cpp/binder_registry.h"
#include "shell/browser/api/frame_subscriber.h"
#include "shell/browser/api/save_page_handler.h"
#include "shell/browser/common_web_contents_delegate.h"
#include "shell/browser/event_emitter_mixin.h"
#include "shell/common/gin_helper/cleaned_up_at_exit.h"
#include "shell/common/gin_helper/constructible.h"
#include "shell/common/gin_helper/error_thrower.h"
#include "shell/common/gin_helper/trackable_object.h"
#include "ui/gfx/image/image.h"
#if BUILDFLAG(ENABLE_PRINTING)
@@ -131,7 +135,10 @@ class ExtendedWebContentsObserver : public base::CheckedObserver {
};
// Wrapper around the content::WebContents.
class WebContents : public gin_helper::TrackableObject<WebContents>,
class WebContents : public gin::Wrappable<WebContents>,
public gin_helper::EventEmitterMixin<WebContents>,
public gin_helper::Constructible<WebContents>,
public gin_helper::CleanedUpAtExit,
public CommonWebContentsDelegate,
public content::WebContentsObserver,
public mojom::ElectronBrowser {
@@ -148,6 +155,8 @@ class WebContents : public gin_helper::TrackableObject<WebContents>,
// Create a new WebContents and return the V8 wrapper of it.
static gin::Handle<WebContents> Create(v8::Isolate* isolate,
const gin_helper::Dictionary& options);
static gin::Handle<WebContents> New(v8::Isolate* isolate,
const gin_helper::Dictionary& options);
// Create a new V8 wrapper for an existing |web_content|.
//
@@ -170,8 +179,12 @@ class WebContents : public gin_helper::TrackableObject<WebContents>,
v8::Isolate* isolate,
content::WebContents* web_contents);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
// gin::Wrappable
static gin::WrapperInfo kWrapperInfo;
static v8::Local<v8::ObjectTemplate> FillObjectTemplate(
v8::Isolate*,
v8::Local<v8::ObjectTemplate>);
const char* GetTypeName() override;
base::WeakPtr<WebContents> GetWeakPtr() { return weak_factory_.GetWeakPtr(); }
@@ -375,7 +388,7 @@ class WebContents : public gin_helper::TrackableObject<WebContents>,
const base::FilePath& file_path);
// Properties.
int32_t ID() const;
int32_t ID() const { return id_; }
v8::Local<v8::Value> Session(v8::Isolate* isolate);
content::WebContents* HostWebContents() const;
v8::Local<v8::Value> DevToolsWebContents(v8::Isolate* isolate);
@@ -395,6 +408,25 @@ class WebContents : public gin_helper::TrackableObject<WebContents>,
bool EmitNavigationEvent(const std::string& event,
content::NavigationHandle* navigation_handle);
// this.emit(name, new Event(sender, message), args...);
template <typename... Args>
bool EmitWithSender(base::StringPiece name,
content::RenderFrameHost* sender,
electron::mojom::ElectronBrowser::InvokeCallback callback,
Args&&... args) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Object> wrapper;
if (!GetWrapper(isolate).ToLocal(&wrapper))
return false;
v8::Local<v8::Object> event = gin_helper::internal::CreateNativeEvent(
isolate, wrapper, sender, std::move(callback));
return EmitCustomEvent(name, event, std::forward<Args>(args)...);
}
void MarkDestroyed();
WebContents* embedder() { return embedder_; }
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
@@ -637,6 +669,8 @@ class WebContents : public gin_helper::TrackableObject<WebContents>,
// The type of current WebContents.
Type type_ = Type::BROWSER_WINDOW;
int32_t id_;
// Request id used for findInPage request.
uint32_t request_id_ = 0;

View File

@@ -209,7 +209,7 @@ void CommonWebContentsDelegate::InitWithWebContents(
web_contents, std::make_unique<ElectronPDFWebContentsHelperClient>());
#endif
// Determien whether the WebContents is offscreen.
// Determine whether the WebContents is offscreen.
auto* web_preferences = WebContentsPreferences::From(web_contents);
offscreen_ =
web_preferences && web_preferences->IsEnabled(options::kOffscreen);

View File

@@ -49,10 +49,6 @@
#include "content/public/common/web_preferences.h"
#include "electron/buildflags/buildflags.h"
#include "electron/grit/electron_resources.h"
#include "extensions/browser/extension_navigation_ui_data.h"
#include "extensions/browser/extension_protocols.h"
#include "extensions/common/constants.h"
#include "extensions/common/switches.h"
#include "mojo/public/cpp/bindings/binder_map.h"
#include "net/base/escape.h"
#include "net/ssl/ssl_cert_request_info.h"
@@ -142,9 +138,12 @@
#include "content/public/browser/file_url_loader.h"
#include "content/public/browser/web_ui_url_loader_factory.h"
#include "extensions/browser/api/mime_handler_private/mime_handler_private.h"
#include "extensions/browser/browser_context_keyed_api_factory.h"
#include "extensions/browser/extension_host.h"
#include "extensions/browser/extension_message_filter.h"
#include "extensions/browser/extension_navigation_throttle.h"
#include "extensions/browser/extension_navigation_ui_data.h"
#include "extensions/browser/extension_protocols.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extensions_browser_client.h"
#include "extensions/browser/guest_view/extensions_guest_view_message_filter.h"
@@ -152,8 +151,11 @@
#include "extensions/browser/info_map.h"
#include "extensions/browser/process_manager.h"
#include "extensions/browser/process_map.h"
#include "extensions/browser/url_loader_factory_manager.h"
#include "extensions/common/api/mime_handler.mojom.h"
#include "extensions/common/constants.h"
#include "extensions/common/extension.h"
#include "extensions/common/switches.h"
#include "shell/browser/extensions/electron_extension_message_filter.h"
#include "shell/browser/extensions/electron_extension_system.h"
#include "shell/browser/extensions/electron_extension_web_contents_observer.h"
@@ -720,8 +722,10 @@ void ElectronBrowserClient::AppendExtraCommandLineSwitches(
bool enable_crash_reporter = false;
enable_crash_reporter = breakpad::IsCrashReporterEnabled();
if (enable_crash_reporter) {
command_line->AppendSwitch(::switches::kEnableCrashReporter);
std::string switch_value;
std::string switch_value =
api::crash_reporter::GetClientId() + ",no_channel";
command_line->AppendSwitchASCII(::switches::kEnableCrashReporter,
switch_value);
for (const auto& pair : api::crash_reporter::GetGlobalCrashKeys()) {
if (!switch_value.empty())
switch_value += ",";
@@ -1481,6 +1485,7 @@ bool ElectronBrowserClient::WillCreateURLLoaderFactory(
if (bypass_redirect_checks)
*bypass_redirect_checks = true;
return true;
}
@@ -1499,6 +1504,9 @@ void ElectronBrowserClient::OverrideURLLoaderFactoryParams(
factory_params->is_corb_enabled = false;
}
}
extensions::URLLoaderFactoryManager::OverrideURLLoaderFactoryParams(
browser_context, origin, is_for_isolated_world, factory_params);
}
#if defined(OS_WIN)

View File

@@ -44,9 +44,7 @@ class EventEmitterMixin {
v8::Local<v8::Object> wrapper;
if (!static_cast<T*>(this)->GetWrapper(isolate).ToLocal(&wrapper))
return false;
v8::Local<v8::Object> event =
internal::CreateEvent(isolate, wrapper, custom_event);
return EmitWithEvent(isolate, wrapper, name, event,
return EmitWithEvent(isolate, wrapper, name, custom_event,
std::forward<Args>(args)...);
}

View File

@@ -5,6 +5,7 @@
#include "shell/browser/extensions/electron_component_extension_resource_manager.h"
#include <string>
#include <utility>
#include "base/logging.h"
#include "base/path_service.h"
@@ -13,6 +14,12 @@
#include "build/build_config.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/grit/component_extension_resources_map.h"
#include "electron/buildflags/buildflags.h"
#if BUILDFLAG(ENABLE_PDF_VIEWER)
#include "chrome/browser/pdf/pdf_extension_util.h"
#include "extensions/common/constants.h"
#endif
namespace extensions {
@@ -20,6 +27,19 @@ ElectronComponentExtensionResourceManager::
ElectronComponentExtensionResourceManager() {
AddComponentResourceEntries(kComponentExtensionResources,
kComponentExtensionResourcesSize);
#if BUILDFLAG(ENABLE_PDF_VIEWER)
// Register strings for the PDF viewer, so that $i18n{} replacements work.
base::Value pdf_strings(base::Value::Type::DICTIONARY);
pdf_extension_util::AddStrings(
pdf_extension_util::PdfViewerContext::kPdfViewer, &pdf_strings);
pdf_extension_util::AddAdditionalData(&pdf_strings);
ui::TemplateReplacements pdf_viewer_replacements;
ui::TemplateReplacementsFromDictionaryValue(
base::Value::AsDictionaryValue(pdf_strings), &pdf_viewer_replacements);
extension_template_replacements_[extension_misc::kPdfExtensionId] =
std::move(pdf_viewer_replacements);
#endif
}
ElectronComponentExtensionResourceManager::

View File

@@ -50,8 +50,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 11,0,0,20200730
PRODUCTVERSION 11,0,0,20200730
FILEVERSION 11,0,0,20200812
PRODUCTVERSION 11,0,0,20200812
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L

View File

@@ -24,6 +24,14 @@ bool ElectronDesktopWindowTreeHostWin::PreHandleMSG(UINT message,
return native_window_view_->PreHandleMSG(message, w_param, l_param, result);
}
bool ElectronDesktopWindowTreeHostWin::ShouldPaintAsActive() const {
// Tell Chromium to use system default behavior when rendering inactive
// titlebar, otherwise it would render inactive titlebar as active under
// some cases.
// See also https://github.com/electron/electron/issues/24647.
return false;
}
bool ElectronDesktopWindowTreeHostWin::HasNativeFrame() const {
// Since we never use chromium's titlebar implementation, we can just say
// that we use a native titlebar. This will disable the repaint locking when

View File

@@ -25,6 +25,7 @@ class ElectronDesktopWindowTreeHostWin
WPARAM w_param,
LPARAM l_param,
LRESULT* result) override;
bool ShouldPaintAsActive() const override;
bool HasNativeFrame() const override;
bool GetClientAreaInsets(gfx::Insets* insets,
HMONITOR monitor) const override;

View File

@@ -2,49 +2,55 @@
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include <stddef.h>
#include <vector>
#include "base/numerics/safe_math.h"
#include "gin/handle.h"
#include "gin/object_template_builder.h"
#include "gin/wrappable.h"
#include "shell/common/asar/archive.h"
#include "shell/common/asar/asar_util.h"
#include "shell/common/gin_converters/callback_converter.h"
#include "shell/common/gin_converters/file_path_converter.h"
#include "shell/common/gin_helper/dictionary.h"
#include "shell/common/gin_helper/object_template_builder.h"
#include "shell/common/gin_helper/wrappable.h"
#include "shell/common/gin_helper/error_thrower.h"
#include "shell/common/gin_helper/function_template_extensions.h"
#include "shell/common/gin_helper/promise.h"
#include "shell/common/node_includes.h"
#include "shell/common/node_util.h"
namespace {
class Archive : public gin_helper::Wrappable<Archive> {
class Archive : public gin::Wrappable<Archive> {
public:
static v8::Local<v8::Value> Create(v8::Isolate* isolate,
static gin::Handle<Archive> Create(v8::Isolate* isolate,
const base::FilePath& path) {
auto archive = std::make_unique<asar::Archive>(path);
if (!archive->Init())
return v8::False(isolate);
return (new Archive(isolate, std::move(archive)))->GetWrapper();
return gin::Handle<Archive>();
return gin::CreateHandle(isolate, new Archive(isolate, std::move(archive)));
}
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(gin::StringToV8(isolate, "Archive"));
gin_helper::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
// gin::Wrappable
static gin::WrapperInfo kWrapperInfo;
gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
v8::Isolate* isolate) override {
return gin::ObjectTemplateBuilder(isolate)
.SetProperty("path", &Archive::GetPath)
.SetMethod("getFileInfo", &Archive::GetFileInfo)
.SetMethod("stat", &Archive::Stat)
.SetMethod("readdir", &Archive::Readdir)
.SetMethod("realpath", &Archive::Realpath)
.SetMethod("copyFileOut", &Archive::CopyFileOut)
.SetMethod("getFd", &Archive::GetFD);
.SetMethod("read", &Archive::Read)
.SetMethod("readSync", &Archive::ReadSync);
}
const char* GetTypeName() override { return "Archive"; }
protected:
Archive(v8::Isolate* isolate, std::unique_ptr<asar::Archive> archive)
: archive_(std::move(archive)) {
Init(isolate);
}
: archive_(std::move(archive)) {}
// Returns the path of the file.
base::FilePath GetPath() { return archive_->path(); }
@@ -103,19 +109,75 @@ class Archive : public gin_helper::Wrappable<Archive> {
return gin::ConvertToV8(isolate, new_path);
}
// Return the file descriptor.
int GetFD() const {
if (!archive_)
return -1;
return archive_->GetFD();
v8::Local<v8::ArrayBuffer> ReadSync(gin_helper::ErrorThrower thrower,
uint64_t offset,
uint64_t length) {
base::CheckedNumeric<uint64_t> safe_offset(offset);
base::CheckedNumeric<uint64_t> safe_end = safe_offset + length;
if (!safe_end.IsValid() ||
safe_end.ValueOrDie() > archive_->file()->length()) {
thrower.ThrowError("Out of bounds read");
return v8::Local<v8::ArrayBuffer>();
}
auto array_buffer = v8::ArrayBuffer::New(thrower.isolate(), length);
auto backing_store = array_buffer->GetBackingStore();
memcpy(backing_store->Data(), archive_->file()->data() + offset, length);
return array_buffer;
}
v8::Local<v8::Promise> Read(v8::Isolate* isolate,
uint64_t offset,
uint64_t length) {
gin_helper::Promise<v8::Local<v8::ArrayBuffer>> promise(isolate);
v8::Local<v8::Promise> handle = promise.GetHandle();
base::CheckedNumeric<uint64_t> safe_offset(offset);
base::CheckedNumeric<uint64_t> safe_end = safe_offset + length;
if (!safe_end.IsValid() ||
safe_end.ValueOrDie() > archive_->file()->length()) {
promise.RejectWithErrorMessage("Out of bounds read");
return handle;
}
auto backing_store = v8::ArrayBuffer::NewBackingStore(isolate, length);
base::ThreadPool::PostTaskAndReplyWithResult(
FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_VISIBLE},
base::BindOnce(&Archive::ReadOnIO, isolate, archive_,
std::move(backing_store), offset, length),
base::BindOnce(&Archive::ResolveReadOnUI, std::move(promise)));
return handle;
}
private:
std::unique_ptr<asar::Archive> archive_;
static std::unique_ptr<v8::BackingStore> ReadOnIO(
v8::Isolate* isolate,
std::shared_ptr<asar::Archive> archive,
std::unique_ptr<v8::BackingStore> backing_store,
uint64_t offset,
uint64_t length) {
memcpy(backing_store->Data(), archive->file()->data() + offset, length);
return backing_store;
}
static void ResolveReadOnUI(
gin_helper::Promise<v8::Local<v8::ArrayBuffer>> promise,
std::unique_ptr<v8::BackingStore> backing_store) {
v8::HandleScope scope(promise.isolate());
v8::Context::Scope context_scope(promise.GetContext());
auto array_buffer =
v8::ArrayBuffer::New(promise.isolate(), std::move(backing_store));
promise.Resolve(array_buffer);
}
std::shared_ptr<asar::Archive> archive_;
DISALLOW_COPY_AND_ASSIGN(Archive);
};
// static
gin::WrapperInfo Archive::kWrapperInfo = {gin::kEmbedderNativeGin};
void InitAsarSupport(v8::Isolate* isolate, v8::Local<v8::Value> require) {
// Evaluate asar_bundle.js.
std::vector<v8::Local<v8::String>> asar_bundle_params = {

View File

@@ -117,78 +117,51 @@ bool FillFileInfoWithNode(Archive::FileInfo* info,
} // namespace
Archive::Archive(const base::FilePath& path)
: path_(path), file_(base::File::FILE_OK) {
Archive::Archive(const base::FilePath& path) : path_(path) {
base::ThreadRestrictions::ScopedAllowIO allow_io;
file_.Initialize(path_, base::File::FLAG_OPEN | base::File::FLAG_READ);
#if defined(OS_WIN)
fd_ = _open_osfhandle(reinterpret_cast<intptr_t>(file_.GetPlatformFile()), 0);
#elif defined(OS_POSIX)
fd_ = file_.GetPlatformFile();
#endif
if (base::PathExists(path_) && !file_.Initialize(path_)) {
LOG(ERROR) << "Failed to open ASAR archive at '" << path_.value() << "'";
}
}
Archive::~Archive() {
#if defined(OS_WIN)
if (fd_ != -1) {
_close(fd_);
// Don't close the handle since we already closed the fd.
file_.TakePlatformFile();
}
#endif
base::ThreadRestrictions::ScopedAllowIO allow_io;
file_.Close();
}
Archive::~Archive() {}
bool Archive::Init() {
if (!file_.IsValid()) {
if (file_.error_details() != base::File::FILE_ERROR_NOT_FOUND) {
LOG(WARNING) << "Opening " << path_.value() << ": "
<< base::File::ErrorToString(file_.error_details());
}
return false;
}
std::vector<char> buf;
int len;
buf.resize(8);
{
base::ThreadRestrictions::ScopedAllowIO allow_io;
len = file_.ReadAtCurrentPos(buf.data(), buf.size());
}
if (len != static_cast<int>(buf.size())) {
PLOG(ERROR) << "Failed to read header size from " << path_.value();
if (file_.length() < 8) {
LOG(ERROR) << "Malformed ASAR file at '" << path_.value()
<< "' (too short)";
return false;
}
uint32_t size;
if (!base::PickleIterator(base::Pickle(buf.data(), buf.size()))
.ReadUInt32(&size)) {
LOG(ERROR) << "Failed to parse header size from " << path_.value();
base::PickleIterator size_pickle(
base::Pickle(reinterpret_cast<const char*>(file_.data()), 8));
if (!size_pickle.ReadUInt32(&size)) {
LOG(ERROR) << "Failed to read header size at '" << path_.value() << "'";
return false;
}
buf.resize(size);
{
base::ThreadRestrictions::ScopedAllowIO allow_io;
len = file_.ReadAtCurrentPos(buf.data(), buf.size());
}
if (len != static_cast<int>(buf.size())) {
PLOG(ERROR) << "Failed to read header from " << path_.value();
if (file_.length() - 8 < size) {
LOG(ERROR) << "Malformed ASAR file at '" << path_.value()
<< "' (incorrect header)";
return false;
}
base::PickleIterator header_pickle(
base::Pickle(reinterpret_cast<const char*>(file_.data() + 8), size));
std::string header;
if (!base::PickleIterator(base::Pickle(buf.data(), buf.size()))
.ReadString(&header)) {
LOG(ERROR) << "Failed to parse header from " << path_.value();
if (!header_pickle.ReadString(&header)) {
LOG(ERROR) << "Failed to read header string at '" << path_.value() << "'";
return false;
}
base::Optional<base::Value> value = base::JSONReader::Read(header);
if (!value || !value->is_dict()) {
LOG(ERROR) << "Failed to parse header";
LOG(ERROR) << "Header was not valid JSON at '" << path_.value() << "'";
return false;
}
@@ -291,11 +264,24 @@ bool Archive::CopyFileOut(const base::FilePath& path, base::FilePath* out) {
return true;
}
base::CheckedNumeric<uint64_t> safe_offset(info.offset);
auto safe_end = safe_offset + info.size;
if (!safe_end.IsValid() || safe_end.ValueOrDie() > file_.length())
return false;
auto temp_file = std::make_unique<ScopedTemporaryFile>();
base::FilePath::StringType ext = path.Extension();
if (!temp_file->InitFromFile(&file_, ext, info.offset, info.size))
if (!temp_file->Init(ext))
return false;
base::File dest(temp_file->path(),
base::File::FLAG_OPEN | base::File::FLAG_WRITE);
if (!dest.IsValid())
return false;
dest.WriteAtCurrentPos(
reinterpret_cast<const char*>(file_.data() + info.offset), info.size);
#if defined(OS_POSIX)
if (info.executable) {
// chmod a+x temp_file;
@@ -308,8 +294,4 @@ bool Archive::CopyFileOut(const base::FilePath& path, base::FilePath* out) {
return true;
}
int Archive::GetFD() const {
return fd_;
}
} // namespace asar

View File

@@ -11,6 +11,7 @@
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/files/memory_mapped_file.h"
namespace base {
class DictionaryValue;
@@ -61,16 +62,13 @@ class Archive {
// For unpacked file, this method will return its real path.
bool CopyFileOut(const base::FilePath& path, base::FilePath* out);
// Returns the file's fd.
int GetFD() const;
base::MemoryMappedFile* file() { return &file_; }
base::FilePath path() const { return path_; }
base::DictionaryValue* header() const { return header_.get(); }
private:
base::FilePath path_;
base::File file_;
int fd_ = -1;
base::MemoryMappedFile file_;
uint32_t header_size_ = 0;
std::unique_ptr<base::DictionaryValue> header_;

View File

@@ -48,27 +48,4 @@ bool ScopedTemporaryFile::Init(const base::FilePath::StringType& ext) {
return true;
}
bool ScopedTemporaryFile::InitFromFile(base::File* src,
const base::FilePath::StringType& ext,
uint64_t offset,
uint64_t size) {
if (!src->IsValid())
return false;
if (!Init(ext))
return false;
std::vector<char> buf(size);
int len = src->Read(offset, buf.data(), buf.size());
if (len != static_cast<int>(size))
return false;
base::File dest(path_, base::File::FLAG_OPEN | base::File::FLAG_WRITE);
if (!dest.IsValid())
return false;
return dest.WriteAtCurrentPos(buf.data(), buf.size()) ==
static_cast<int>(size);
}
} // namespace asar

View File

@@ -27,12 +27,6 @@ class ScopedTemporaryFile {
// Init an empty temporary file with a certain extension.
bool Init(const base::FilePath::StringType& ext);
// Init an temporary file and fill it with content of |path|.
bool InitFromFile(base::File* src,
const base::FilePath::StringType& ext,
uint64_t offset,
uint64_t size);
base::FilePath path() const { return path_; }
private:

View File

@@ -157,7 +157,7 @@ v8::Local<v8::Function> CreateConstructor(
CHECK(!called) << "CreateConstructor can only be called for one type once";
called = true;
#endif
v8::Local<v8::FunctionTemplate> templ = CreateFunctionTemplate(
v8::Local<v8::FunctionTemplate> templ = gin_helper::CreateFunctionTemplate(
isolate, base::BindRepeating(&internal::InvokeNew<Sig>, func));
templ->InstanceTemplate()->SetInternalFieldCount(1);
T::BuildPrototype(isolate, templ);

View File

@@ -70,23 +70,6 @@ class EventEmitter : public gin_helper::Wrappable<T> {
return EmitWithEvent(name, event, std::forward<Args>(args)...);
}
// this.emit(name, new Event(sender, message), args...);
template <typename... Args>
bool EmitWithSender(base::StringPiece name,
content::RenderFrameHost* sender,
electron::mojom::ElectronBrowser::InvokeCallback callback,
Args&&... args) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
v8::Local<v8::Object> wrapper = GetWrapper();
if (wrapper.IsEmpty())
return false;
v8::Local<v8::Object> event = internal::CreateNativeEvent(
isolate(), wrapper, sender, std::move(callback));
return EmitWithEvent(name, event, std::forward<Args>(args)...);
}
protected:
EventEmitter() {}

View File

@@ -23,6 +23,7 @@ type CrashInfo = {
_productName: string
_version: string
upload_file_minidump: Buffer // eslint-disable-line camelcase
guid: string
mainProcessSpecific: 'mps' | undefined
rendererSpecific: 'rs' | undefined
globalParam: 'globalValue' | undefined
@@ -174,6 +175,35 @@ ifdescribe(!isLinuxOnArm && !process.mas && !process.env.DISABLE_CRASH_REPORTER_
expect(crash.rendererSpecific).to.be.undefined();
});
describe('with guid', () => {
for (const processType of ['main', 'renderer', 'sandboxed-renderer']) {
it(`when ${processType} crashes`, async () => {
const { port, waitForCrash } = await startServer();
runCrashApp(processType, port);
const crash = await waitForCrash();
expect(crash.guid).to.be.a('string');
});
}
it('is a consistent id', async () => {
let crash1Guid;
let crash2Guid;
{
const { port, waitForCrash } = await startServer();
runCrashApp('main', port);
const crash = await waitForCrash();
crash1Guid = crash.guid;
}
{
const { port, waitForCrash } = await startServer();
runCrashApp('main', port);
const crash = await waitForCrash();
crash2Guid = crash.guid;
}
expect(crash2Guid).to.equal(crash1Guid);
});
});
describe('with extra parameters', () => {
it('when renderer crashes', async () => {
const { port, waitForCrash } = await startServer();

View File

@@ -16,7 +16,12 @@ describe('chrome extensions', () => {
let server: http.Server;
let url: string;
before(async () => {
server = http.createServer((req, res) => res.end(emptyPage));
server = http.createServer((req, res) => {
if (req.url === '/cors') {
res.setHeader('Access-Control-Allow-Origin', 'http://example.com');
}
res.end(emptyPage);
});
await new Promise(resolve => server.listen(0, '127.0.0.1', () => {
url = `http://127.0.0.1:${(server.address() as AddressInfo).port}`;
resolve();
@@ -32,6 +37,19 @@ describe('chrome extensions', () => {
});
});
function fetch (contents: WebContents, url: string) {
return contents.executeJavaScript(`fetch(${JSON.stringify(url)})`);
}
it('bypasses CORS in requests made from extensions', async () => {
const customSession = session.fromPartition(`persist:${require('uuid').v4()}`);
const w = new BrowserWindow({ show: false, webPreferences: { session: customSession, sandbox: true } });
const extension = await customSession.loadExtension(path.join(fixtures, 'extensions', 'ui-page'));
w.loadURL(`${extension.url}bare-page.html`);
await emittedOnce(w.webContents, 'dom-ready');
await expect(fetch(w.webContents, `${url}/cors`)).to.not.be.rejectedWith(TypeError);
});
it('loads an extension', async () => {
// NB. we have to use a persist: session (i.e. non-OTR) because the
// extension registry is redirected to the main session. so installing an

View File

@@ -1,5 +1,6 @@
{
"name": "ui-page",
"version": "1.0",
"manifest_version": 2
"manifest_version": 2,
"permissions": ["<all_urls>"]
}

View File

@@ -0,0 +1 @@
require('uv-dlopen');

View File

@@ -0,0 +1,13 @@
{
"targets": [
{
"target_name": "test_module",
"sources": [ "main.cpp" ],
},
{
"target_name": "libfoo",
"type": "shared_library",
"sources": [ "foo.cpp" ]
}
]
}

View File

@@ -0,0 +1,2 @@
extern "C"
void foo() { }

View File

@@ -0,0 +1,16 @@
const testLoadLibrary = require('./build/Release/test_module');
const lib = (() => {
switch (process.platform) {
case 'linux':
return `${__dirname}/build/Release/foo.so`;
case 'darwin':
return `${__dirname}/build/Release/foo.dylib`;
case 'win32':
return `${__dirname}/build/Release/libfoo.dll`;
default:
throw new Error('unsupported os');
}
})();
testLoadLibrary(lib);

View File

@@ -0,0 +1,42 @@
#include <node_api.h>
#include <uv.h>
namespace test_module {
napi_value TestLoadLibrary(napi_env env, napi_callback_info info) {
size_t argc = 1;
napi_value argv;
napi_status status;
status = napi_get_cb_info(env, info, &argc, &argv, NULL, NULL);
if (status != napi_ok) napi_fatal_error(NULL, 0, NULL, 0);
char lib_path[256];
status = napi_get_value_string_utf8(env, argv, lib_path, 256, NULL);
if (status != napi_ok) napi_fatal_error(NULL, 0, NULL, 0);
uv_lib_t lib;
auto uv_status = uv_dlopen(lib_path, &lib);
if (uv_status == 0) {
napi_value result;
status = napi_get_boolean(env, true, &result);
if (status != napi_ok) napi_fatal_error(NULL, 0, NULL, 0);
return result;
} else {
status = napi_throw_error(env, NULL, uv_dlerror(&lib));
if (status != napi_ok) napi_fatal_error(NULL, 0, NULL, 0);
}
}
napi_value Init(napi_env env, napi_value exports) {
napi_value method;
napi_status status;
status = napi_create_function(env, "testLoadLibrary", NAPI_AUTO_LENGTH,
TestLoadLibrary, NULL, &method);
if (status != napi_ok)
return NULL;
return method;
}
NAPI_MODULE(TestLoadLibrary, Init);
} // namespace test_module

View File

@@ -0,0 +1,5 @@
{
"name": "uv-dlopen",
"version": "0.0.1",
"main": "index.js"
}

View File

@@ -44,6 +44,27 @@ describe('modules support', () => {
});
});
const enablePlatforms: NodeJS.Platform[] = [
'linux',
'darwin',
'win32'
];
ifdescribe(nativeModulesEnabled && enablePlatforms.includes(process.platform))('module that use uv_dlopen', () => {
it('can be required in renderer', async () => {
const w = new BrowserWindow({ show: false, webPreferences: { nodeIntegration: true } });
w.loadURL('about:blank');
await expect(w.webContents.executeJavaScript('{ require(\'uv-dlopen\'); null }')).to.be.fulfilled();
});
ifit(features.isRunAsNodeEnabled())('can be required in node binary', async function () {
const child = childProcess.fork(path.join(fixtures, 'module', 'uv-dlopen.js'));
await new Promise(resolve => child.once('exit', (exitCode) => {
expect(exitCode).to.equal(0);
resolve();
}));
});
});
describe('q', () => {
describe('Q.when', () => {
it('emits the fullfil callback', (done) => {

View File

@@ -10,6 +10,7 @@
"echo": "file:fixtures/native-addon/echo",
"q": "^1.5.1",
"sinon": "^9.0.1",
"uv-dlopen": "./fixtures/native-addon/uv-dlopen/",
"ws": "^7.2.1"
},
"dependencies": {

View File

@@ -268,6 +268,9 @@ uri-js@^4.2.2:
dependencies:
punycode "^2.1.0"
uv-dlopen@./fixtures/native-addon/uv-dlopen/:
version "0.0.1"
worker-loader@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/worker-loader/-/worker-loader-2.0.0.tgz#45fda3ef76aca815771a89107399ee4119b430ac"

View File

@@ -174,6 +174,15 @@ describe('node feature', () => {
});
});
describe('URL handling in the renderer process', () => {
it('can successfully handle WHATWG URLs constructed by Blink', () => {
const url = new URL('file://' + path.resolve(fixtures, 'pages', 'base-page.html'));
expect(() => {
fs.createReadStream(url);
}).to.not.throw();
});
});
describe('error thrown in main process node context', () => {
it('gets emitted as a process uncaughtException event', () => {
const error = ipcRenderer.sendSync('handle-uncaught-exception', 'hello');

View File

@@ -4,7 +4,7 @@
"main": "static/main.js",
"version": "0.1.0",
"scripts": {
"postinstall": "node ../tools/run-if-exists.js node_modules/robotjs node-gyp rebuild"
"postinstall": "node ../script/run-if-exists.js node_modules/robotjs node-gyp rebuild"
},
"devDependencies": {
"basic-auth": "^2.0.1",

View File

@@ -1,17 +0,0 @@
const cp = require('child_process')
const fs = require('fs')
const checkPath = process.argv[2]
const command = process.argv.slice(3)
if (fs.existsSync(checkPath)) {
const child = cp.spawn(
`${command[0]}${process.platform === 'win32' ? '.cmd' :''}`,
command.slice(1),
{
stdio: 'inherit',
cwd: checkPath
}
)
child.on('exit', code => process.exit(code))
}

10
tsconfig.script.json Normal file
View File

@@ -0,0 +1,10 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"rootDir": ".",
"noEmit": true
},
"include": [
"script"
]
}

View File

@@ -68,7 +68,8 @@ declare namespace NodeJS {
readdir(path: string): string[] | false;
realpath(path: string): string | false;
copyFileOut(path: string): string | false;
getFd(): number | -1;
read(offset: number, size: number): Promise<ArrayBuffer>;
readSync(offset: number, size: number): ArrayBuffer;
}
interface AsarBinding {

221
yarn.lock
View File

@@ -72,55 +72,102 @@
"@nodelib/fs.scandir" "2.1.3"
fastq "^1.6.0"
"@octokit/endpoint@^5.1.0":
version "5.2.1"
resolved "https://registry.yarnpkg.com/@octokit/endpoint/-/endpoint-5.2.1.tgz#e5ef98bc4a41fad62b17e71af1a1710f6076b8df"
integrity sha512-GoUsRSRhtbCQugRY8eDWg5BnsczUZNq00qArrP7tKPHFmvz2KzJ8DoEq6IAQhLGwAOBHbZQ/Zml3DiaEKAWwkA==
"@octokit/auth-token@^2.4.0":
version "2.4.2"
resolved "https://registry.yarnpkg.com/@octokit/auth-token/-/auth-token-2.4.2.tgz#10d0ae979b100fa6b72fa0e8e63e27e6d0dbff8a"
integrity sha512-jE/lE/IKIz2v1+/P0u4fJqv0kYwXOTujKemJMFr6FeopsxlIK3+wKDCJGnysg81XID5TgZQbIfuJ5J0lnTiuyQ==
dependencies:
deepmerge "4.0.0"
is-plain-object "^3.0.0"
universal-user-agent "^2.1.0"
url-template "^2.0.8"
"@octokit/types" "^5.0.0"
"@octokit/request-error@^1.0.1", "@octokit/request-error@^1.0.2":
version "1.0.4"
resolved "https://registry.yarnpkg.com/@octokit/request-error/-/request-error-1.0.4.tgz#15e1dc22123ba4a9a4391914d80ec1e5303a23be"
integrity sha512-L4JaJDXn8SGT+5G0uX79rZLv0MNJmfGa4vb4vy1NnpjSnWDLJRy6m90udGwvMmavwsStgbv2QNkPzzTCMmL+ig==
"@octokit/core@^3.0.0":
version "3.1.1"
resolved "https://registry.yarnpkg.com/@octokit/core/-/core-3.1.1.tgz#1856745aa8fb154cf1544a2a1b82586c809c5e66"
integrity sha512-cQ2HGrtyNJ1IBxpTP1U5m/FkMAJvgw7d2j1q3c9P0XUuYilEgF6e4naTpsgm4iVcQeOnccZlw7XHRIUBy0ymcg==
dependencies:
"@octokit/auth-token" "^2.4.0"
"@octokit/graphql" "^4.3.1"
"@octokit/request" "^5.4.0"
"@octokit/types" "^5.0.0"
before-after-hook "^2.1.0"
universal-user-agent "^6.0.0"
"@octokit/endpoint@^6.0.1":
version "6.0.5"
resolved "https://registry.yarnpkg.com/@octokit/endpoint/-/endpoint-6.0.5.tgz#43a6adee813c5ffd2f719e20cfd14a1fee7c193a"
integrity sha512-70K5u6zd45ItOny6aHQAsea8HHQjlQq85yqOMe+Aj8dkhN2qSJ9T+Q3YjUjEYfPRBcuUWNgMn62DQnP/4LAIiQ==
dependencies:
"@octokit/types" "^5.0.0"
is-plain-object "^4.0.0"
universal-user-agent "^6.0.0"
"@octokit/graphql@^4.3.1":
version "4.5.3"
resolved "https://registry.yarnpkg.com/@octokit/graphql/-/graphql-4.5.3.tgz#d5ff0d4a8a33e98614a2a7359dac98bc285e062f"
integrity sha512-JyYvi3j2tOb5ofASEpcg1Advs07H+Ag+I+ez7buuZfNVAmh1IYcDTuxd4gnYH8S2PSGu+f5IdDGxMmkK+5zsdA==
dependencies:
"@octokit/request" "^5.3.0"
"@octokit/types" "^5.0.0"
universal-user-agent "^6.0.0"
"@octokit/plugin-paginate-rest@^2.2.0":
version "2.3.0"
resolved "https://registry.yarnpkg.com/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.3.0.tgz#7d1073e56cfd15d3f99dcfe81fa5d2b466f3a6f6"
integrity sha512-Ye2ZJreP0ZlqJQz8fz+hXvrEAEYK4ay7br1eDpWzr6j76VXs/gKqxFcH8qRzkB3fo/2xh4Vy9VtGii4ZDc9qlA==
dependencies:
"@octokit/types" "^5.2.0"
"@octokit/plugin-request-log@^1.0.0":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@octokit/plugin-request-log/-/plugin-request-log-1.0.0.tgz#eef87a431300f6148c39a7f75f8cfeb218b2547e"
integrity sha512-ywoxP68aOT3zHCLgWZgwUJatiENeHE7xJzYjfz8WI0goynp96wETBF+d95b8g/uL4QmS6owPVlaxiz3wyMAzcw==
"@octokit/plugin-rest-endpoint-methods@4.1.2":
version "4.1.2"
resolved "https://registry.yarnpkg.com/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-4.1.2.tgz#546a8f3e0b514f434a4ad4ef926005f1c81a5a5a"
integrity sha512-PTI7wpbGEZ2IR87TVh+TNWaLcgX/RsZQalFbQCq8XxYUrQ36RHyERrHSNXFy5gkWpspUAOYRSV707JJv6BhqJA==
dependencies:
"@octokit/types" "^5.1.1"
deprecation "^2.3.1"
"@octokit/request-error@^2.0.0":
version "2.0.2"
resolved "https://registry.yarnpkg.com/@octokit/request-error/-/request-error-2.0.2.tgz#0e76b83f5d8fdda1db99027ea5f617c2e6ba9ed0"
integrity sha512-2BrmnvVSV1MXQvEkrb9zwzP0wXFNbPJij922kYBTLIlIafukrGOb+ABBT2+c6wZiuyWDH1K1zmjGQ0toN/wMWw==
dependencies:
"@octokit/types" "^5.0.1"
deprecation "^2.0.0"
once "^1.4.0"
"@octokit/request@^4.0.1":
version "4.1.1"
resolved "https://registry.yarnpkg.com/@octokit/request/-/request-4.1.1.tgz#614262214f48417b4d3b14e047d09a9c8e2f7a09"
integrity sha512-LOyL0i3oxRo418EXRSJNk/3Q4I0/NKawTn6H/CQp+wnrG1UFLGu080gSsgnWobhPo5BpUNgSQ5BRk5FOOJhD1Q==
"@octokit/request@^5.3.0", "@octokit/request@^5.4.0":
version "5.4.7"
resolved "https://registry.yarnpkg.com/@octokit/request/-/request-5.4.7.tgz#fd703ee092e0463ceba49ff7a3e61cb4cf8a0fde"
integrity sha512-FN22xUDP0i0uF38YMbOfx6TotpcENP5W8yJM1e/LieGXn6IoRxDMnBf7tx5RKSW4xuUZ/1P04NFZy5iY3Rax1A==
dependencies:
"@octokit/endpoint" "^5.1.0"
"@octokit/request-error" "^1.0.1"
"@octokit/endpoint" "^6.0.1"
"@octokit/request-error" "^2.0.0"
"@octokit/types" "^5.0.0"
deprecation "^2.0.0"
is-plain-object "^3.0.0"
is-plain-object "^4.0.0"
node-fetch "^2.3.0"
once "^1.4.0"
universal-user-agent "^2.1.0"
universal-user-agent "^6.0.0"
"@octokit/rest@^16.3.2":
version "16.28.2"
resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-16.28.2.tgz#3fc3b8700046ab29ab1e2a4bdf49f89e94f7ba27"
integrity sha512-csuYiHvJ1P/GFDadVn0QhwO83R1+YREjcwCY7ZIezB6aJTRIEidJZj+R7gAkUhT687cqYb4cXTZsDVu9F+Fmug==
"@octokit/rest@^18.0.3":
version "18.0.3"
resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-18.0.3.tgz#96a15ddb3a38dca5de9d75121378d6aa4a234fa5"
integrity sha512-GubgemnLvUJlkhouTM2BtX+g/voYT/Mqh0SASGwTnLvSkW1irjt14N911/ABb6m1Hru0TwScOgFgMFggp3igfQ==
dependencies:
"@octokit/request" "^4.0.1"
"@octokit/request-error" "^1.0.2"
atob-lite "^2.0.0"
before-after-hook "^1.4.0"
btoa-lite "^1.0.0"
deprecation "^2.0.0"
lodash.get "^4.4.2"
lodash.set "^4.3.2"
lodash.uniq "^4.5.0"
octokit-pagination-methods "^1.1.0"
once "^1.4.0"
universal-user-agent "^2.0.0"
url-template "^2.0.8"
"@octokit/core" "^3.0.0"
"@octokit/plugin-paginate-rest" "^2.2.0"
"@octokit/plugin-request-log" "^1.0.0"
"@octokit/plugin-rest-endpoint-methods" "4.1.2"
"@octokit/types@^5.0.0", "@octokit/types@^5.0.1", "@octokit/types@^5.1.1", "@octokit/types@^5.2.0":
version "5.2.0"
resolved "https://registry.yarnpkg.com/@octokit/types/-/types-5.2.0.tgz#d075dc23bf293f540739250b6879e2c1be2fc20c"
integrity sha512-XjOk9y4m8xTLIKPe1NFxNWBdzA2/z3PFFA/bwf4EoH6oS8hM0Y46mEa4Cb+KCyj/tFDznJFahzQ0Aj3o1FYq4A==
dependencies:
"@types/node" ">= 8"
"@primer/octicons@^10.0.0":
version "10.0.0"
@@ -292,6 +339,11 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.6.1.tgz#d5544f6de0aae03eefbb63d5120f6c8be0691946"
integrity sha512-rp7La3m845mSESCgsJePNL/JQyhkOJA6G4vcwvVgkDAwHhGdq5GCumxmPjEk1MZf+8p5ZQAUE7tqgQRQTXN7uQ==
"@types/node@>= 8":
version "14.0.27"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.27.tgz#a151873af5a5e851b51b3b065c9e63390a9e0eb1"
integrity sha512-kVrqXhbclHNHGu9ztnAwSncIgJv/FaxmzXJvGXNdcCpV1b8u1/Mi6z6m0vwy0LzKeXFTPLH0NzwmoJ3fNCIq0g==
"@types/node@^11.13.7":
version "11.13.22"
resolved "https://registry.yarnpkg.com/@types/node/-/node-11.13.22.tgz#91ee88ebfa25072433497f6f3150f84fa8c3a91b"
@@ -980,11 +1032,6 @@ at-least-node@^1.0.0:
resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2"
integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==
atob-lite@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/atob-lite/-/atob-lite-2.0.0.tgz#0fef5ad46f1bd7a8502c65727f0367d5ee43d696"
integrity sha1-D+9a1G8b16hQLGVyfwNn1e5D1pY=
atob@^2.1.1:
version "2.1.2"
resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
@@ -1035,10 +1082,10 @@ bcrypt-pbkdf@^1.0.0:
dependencies:
tweetnacl "^0.14.3"
before-after-hook@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-1.4.0.tgz#2b6bf23dca4f32e628fd2747c10a37c74a4b484d"
integrity sha512-l5r9ir56nda3qu14nAXIlyq1MmUSs0meCIaFAh8HwkFwP1F8eToOuS3ah2VAHHcY04jaYD7FpJC5JTXHYRbkzg==
before-after-hook@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.1.0.tgz#b6c03487f44e24200dd30ca5e6a1979c5d2fb635"
integrity sha512-IWIbu7pMqyw3EAJHzzHbWa85b6oud/yfKYg5rqB5hNE8CeMi3nX+2C2sj0HswfblST86hpVEOAb9x34NZd6P7A==
big.js@^5.2.2:
version "5.2.2"
@@ -1200,11 +1247,6 @@ browserify-zlib@^0.2.0:
dependencies:
pako "~1.0.5"
btoa-lite@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/btoa-lite/-/btoa-lite-1.0.0.tgz#337766da15801210fdd956c22e9c6891ab9d0337"
integrity sha1-M3dm2hWAEhD92VbCLpxokaudAzc=
buffer-alloc-unsafe@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0"
@@ -1951,11 +1993,6 @@ deep-is@^0.1.3, deep-is@~0.1.3:
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=
deepmerge@4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.0.0.tgz#3e3110ca29205f120d7cb064960a39c3d2087c09"
integrity sha512-YZ1rOP5+kHor4hMAH+HRQnBQHg+wvS1un1hAOuIcxcBy0hzcUf6Jg2a1w65kpoOUnurOfZbERwjI1TfZxNjcww==
defaults@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d"
@@ -2019,7 +2056,7 @@ depd@~1.1.2:
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=
deprecation@^2.0.0:
deprecation@^2.0.0, deprecation@^2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919"
integrity sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==
@@ -4034,12 +4071,10 @@ is-plain-object@^2.0.3, is-plain-object@^2.0.4:
dependencies:
isobject "^3.0.1"
is-plain-object@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-3.0.0.tgz#47bfc5da1b5d50d64110806c199359482e75a928"
integrity sha512-tZIpofR+P05k8Aocp7UI/2UTa9lTJSebCXpFFoR9aibpokDj/uXBsJ8luUu0tTVYKkMU6URDUuOfJZ7koewXvg==
dependencies:
isobject "^4.0.0"
is-plain-object@^4.0.0:
version "4.1.1"
resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-4.1.1.tgz#1a14d6452cbd50790edc7fdaa0aed5a40a35ebb5"
integrity sha512-5Aw8LLVsDlZsETVMhoMXzqsXwQqr/0vlnBYzIXJbYo2F4yYlhLHs+Ez7Bod7IIQKWkJbJfxrWD7pA1Dw1TKrwA==
is-posix-bracket@^0.1.0:
version "0.1.1"
@@ -4159,11 +4194,6 @@ isobject@^3.0.0, isobject@^3.0.1:
resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"
integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8=
isobject@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/isobject/-/isobject-4.0.0.tgz#3f1c9155e73b192022a80819bacd0343711697b0"
integrity sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==
isstream@~0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
@@ -4464,26 +4494,11 @@ lodash.flatten@^4.4.0:
resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f"
integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=
lodash.get@^4.4.2:
version "4.4.2"
resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=
lodash.range@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/lodash.range/-/lodash.range-3.2.0.tgz#f461e588f66683f7eadeade513e38a69a565a15d"
integrity sha1-9GHliPZmg/fq3q3lE+OKaaVloV0=
lodash.set@^4.3.2:
version "4.3.2"
resolved "https://registry.yarnpkg.com/lodash.set/-/lodash.set-4.3.2.tgz#d8757b1da807dde24816b0d6a84bea1a76230b23"
integrity sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=
lodash.uniq@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
lodash@^4.0.0, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15:
version "4.17.15"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
@@ -4552,11 +4567,6 @@ lru-cache@^5.1.1:
dependencies:
yallist "^3.0.2"
macos-release@^2.2.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/macos-release/-/macos-release-2.3.0.tgz#eb1930b036c0800adebccd5f17bc4c12de8bb71f"
integrity sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA==
make-dir@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5"
@@ -5221,11 +5231,6 @@ object.values@^1.1.0, object.values@^1.1.1:
function-bind "^1.1.1"
has "^1.0.3"
octokit-pagination-methods@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/octokit-pagination-methods/-/octokit-pagination-methods-1.1.0.tgz#cf472edc9d551055f9ef73f6e42b4dbb4c80bea4"
integrity sha512-fZ4qZdQ2nxJvtcasX7Ghl+WlWS/d9IgnBIwFZXVNNZUmzpno91SX5bc5vuxiuKoCtK78XxGGNuSCrDC7xYB3OQ==
on-finished@~2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947"
@@ -5336,14 +5341,6 @@ os-homedir@^1.0.0:
resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M=
os-name@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/os-name/-/os-name-3.1.0.tgz#dec19d966296e1cd62d701a5a66ee1ddeae70801"
integrity sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==
dependencies:
macos-release "^2.2.0"
windows-release "^3.1.0"
os-tmpdir@^1.0.0, os-tmpdir@~1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
@@ -8094,12 +8091,10 @@ unist-util-visit@^1.0.0, unist-util-visit@^1.1.0, unist-util-visit@^1.1.1, unist
dependencies:
unist-util-visit-parents "^2.0.0"
universal-user-agent@^2.0.0, universal-user-agent@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-2.1.0.tgz#5abfbcc036a1ba490cb941f8fd68c46d3669e8e4"
integrity sha512-8itiX7G05Tu3mGDTdNY2fB4KJ8MgZLS54RdG6PkkfwMAavrXu1mV/lls/GABx9O3Rw4PnTtasxrvbMQoBYY92Q==
dependencies:
os-name "^3.0.0"
universal-user-agent@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-6.0.0.tgz#3381f8503b251c0d9cd21bc1de939ec9df5480ee"
integrity sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==
universalify@^0.1.0:
version "0.1.2"
@@ -8160,11 +8155,6 @@ url-parse-lax@^1.0.0:
dependencies:
prepend-http "^1.0.1"
url-template@^2.0.8:
version "2.0.8"
resolved "https://registry.yarnpkg.com/url-template/-/url-template-2.0.8.tgz#fc565a3cccbff7730c775f5641f9555791439f21"
integrity sha1-/FZaPMy/93MMd19WQflVV5FDnyE=
url@^0.11.0:
version "0.11.0"
resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1"
@@ -8390,13 +8380,6 @@ wide-align@^1.1.0:
dependencies:
string-width "^1.0.2 || 2"
windows-release@^3.1.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/windows-release/-/windows-release-3.2.0.tgz#8122dad5afc303d833422380680a79cdfa91785f"
integrity sha512-QTlz2hKLrdqukrsapKsINzqMgOUpQW268eJ0OaOpJN32h272waxR9fkB9VoWRtK7uKHG5EHJcTXQBD8XZVJkFA==
dependencies:
execa "^1.0.0"
word-wrap@^1.2.3, word-wrap@~1.2.3:
version "1.2.3"
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"