mirror of
https://github.com/electron/electron.git
synced 2026-04-10 03:01:51 -04:00
Compare commits
52 Commits
v11.0.0-ni
...
v11.0.0-ni
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3d2afa45c3 | ||
|
|
4080b04911 | ||
|
|
b09c828dd3 | ||
|
|
f3363bde26 | ||
|
|
f136bf406f | ||
|
|
77ee3da77c | ||
|
|
47f88b65b7 | ||
|
|
d7909b507f | ||
|
|
14aba3f0de | ||
|
|
7ded768743 | ||
|
|
47d451ae52 | ||
|
|
7e84d3a2c1 | ||
|
|
29a7b8f805 | ||
|
|
16c32d2eb2 | ||
|
|
047650b564 | ||
|
|
8311078a96 | ||
|
|
a9eaebb7f4 | ||
|
|
01c9113e2b | ||
|
|
481b19bee6 | ||
|
|
433956ce4f | ||
|
|
b0ea1e14e1 | ||
|
|
4d50f3f62c | ||
|
|
2028492356 | ||
|
|
3fa250d6da | ||
|
|
854b74809a | ||
|
|
cbdfeb1979 | ||
|
|
2224d94c75 | ||
|
|
b6f8cd39e5 | ||
|
|
075a7adcc0 | ||
|
|
14256ee697 | ||
|
|
aaa971ff19 | ||
|
|
5bf423b646 | ||
|
|
4f4c383ec5 | ||
|
|
5ed8afbdb6 | ||
|
|
5f447e4b4f | ||
|
|
4523c90dcd | ||
|
|
6cb23e1d36 | ||
|
|
a2c82f2342 | ||
|
|
9274117e12 | ||
|
|
99874fd71f | ||
|
|
06c47c650a | ||
|
|
30cd9cdf2a | ||
|
|
9c234f3f3f | ||
|
|
01a2e23194 | ||
|
|
15ee34a1f2 | ||
|
|
f53aac97f5 | ||
|
|
1350dc46ed | ||
|
|
6fd302f745 | ||
|
|
e5c721eafc | ||
|
|
a342ab7ce7 | ||
|
|
c3258d6c4e | ||
|
|
b5cd9ce0b3 |
@@ -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:
|
||||
|
||||
15
BUILD.gn
15
BUILD.gn
@@ -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" ]
|
||||
|
||||
@@ -1 +1 @@
|
||||
11.0.0-nightly.20200730
|
||||
11.0.0-nightly.20200812
|
||||
@@ -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)`
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
29
docs/faq.md
29
docs/faq.md
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
> 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
|
||||
|
||||
@@ -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",
|
||||
]
|
||||
|
||||
@@ -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];
|
||||
};
|
||||
|
||||
@@ -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');
|
||||
|
||||
10
package.json
10
package.json
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 &&
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
@@ -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(
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
|
||||
|
||||
@@ -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()];
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
@@ -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) {
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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');
|
||||
@@ -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];
|
||||
@@ -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"
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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')}
|
||||
}
|
||||
@@ -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',
|
||||
|
||||
@@ -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
|
||||
});
|
||||
|
||||
|
||||
@@ -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 () => {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
});
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
17
script/run-if-exists.js
Normal 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));
|
||||
}
|
||||
@@ -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),
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)...);
|
||||
}
|
||||
|
||||
|
||||
@@ -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::
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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_;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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() {}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"name": "ui-page",
|
||||
"version": "1.0",
|
||||
"manifest_version": 2
|
||||
"manifest_version": 2,
|
||||
"permissions": ["<all_urls>"]
|
||||
}
|
||||
|
||||
1
spec-main/fixtures/module/uv-dlopen.js
Normal file
1
spec-main/fixtures/module/uv-dlopen.js
Normal file
@@ -0,0 +1 @@
|
||||
require('uv-dlopen');
|
||||
13
spec-main/fixtures/native-addon/uv-dlopen/binding.gyp
Normal file
13
spec-main/fixtures/native-addon/uv-dlopen/binding.gyp
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"targets": [
|
||||
{
|
||||
"target_name": "test_module",
|
||||
"sources": [ "main.cpp" ],
|
||||
},
|
||||
{
|
||||
"target_name": "libfoo",
|
||||
"type": "shared_library",
|
||||
"sources": [ "foo.cpp" ]
|
||||
}
|
||||
]
|
||||
}
|
||||
2
spec-main/fixtures/native-addon/uv-dlopen/foo.cpp
Normal file
2
spec-main/fixtures/native-addon/uv-dlopen/foo.cpp
Normal file
@@ -0,0 +1,2 @@
|
||||
extern "C"
|
||||
void foo() { }
|
||||
16
spec-main/fixtures/native-addon/uv-dlopen/index.js
Normal file
16
spec-main/fixtures/native-addon/uv-dlopen/index.js
Normal 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);
|
||||
42
spec-main/fixtures/native-addon/uv-dlopen/main.cpp
Normal file
42
spec-main/fixtures/native-addon/uv-dlopen/main.cpp
Normal 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
|
||||
5
spec-main/fixtures/native-addon/uv-dlopen/package.json
Normal file
5
spec-main/fixtures/native-addon/uv-dlopen/package.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "uv-dlopen",
|
||||
"version": "0.0.1",
|
||||
"main": "index.js"
|
||||
}
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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": {
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
10
tsconfig.script.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"rootDir": ".",
|
||||
"noEmit": true
|
||||
},
|
||||
"include": [
|
||||
"script"
|
||||
]
|
||||
}
|
||||
3
typings/internal-ambient.d.ts
vendored
3
typings/internal-ambient.d.ts
vendored
@@ -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
221
yarn.lock
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user