mirror of
https://github.com/electron/electron.git
synced 2026-04-10 03:01:51 -04:00
Compare commits
31 Commits
v18.0.0-ni
...
v18.0.0-al
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4d2968bfc1 | ||
|
|
56c6d25e98 | ||
|
|
b346f909e7 | ||
|
|
939bfa50f6 | ||
|
|
2289a52fb3 | ||
|
|
aeee9cfb78 | ||
|
|
e34d7f5d6f | ||
|
|
f5dc2a6535 | ||
|
|
365933f1f3 | ||
|
|
8e0e2d40e2 | ||
|
|
db9ab80694 | ||
|
|
32ae67c873 | ||
|
|
c6d061c2d4 | ||
|
|
d657cd8ed6 | ||
|
|
e693738f7c | ||
|
|
63908ccf89 | ||
|
|
3768a7b25f | ||
|
|
86f8faea6b | ||
|
|
20ed5701e9 | ||
|
|
16fcad3488 | ||
|
|
7caa88c46f | ||
|
|
cabad35383 | ||
|
|
8ec81c1437 | ||
|
|
7f517ba878 | ||
|
|
bac0a28324 | ||
|
|
4f6b8d06be | ||
|
|
8803e7f020 | ||
|
|
7814f96413 | ||
|
|
65bee9120f | ||
|
|
335f24b0d0 | ||
|
|
1cf36822e3 |
@@ -45,7 +45,7 @@ executors:
|
||||
type: enum
|
||||
enum: ["medium", "xlarge", "2xlarge+"]
|
||||
docker:
|
||||
- image: ghcr.io/electron/build:27db4a3e3512bfd2e47f58cea69922da0835f1d9
|
||||
- image: ghcr.io/electron/build:e6bebd08a51a0d78ec23e5b3fd7e7c0846412328
|
||||
resource_class: << parameters.size >>
|
||||
|
||||
macos:
|
||||
@@ -890,12 +890,12 @@ step-touch-sync-done: &step-touch-sync-done
|
||||
step-maybe-restore-src-cache: &step-maybe-restore-src-cache
|
||||
restore_cache:
|
||||
keys:
|
||||
- v8-src-cache-{{ checksum "src/electron/.depshash" }}
|
||||
- v12-src-cache-{{ checksum "src/electron/.depshash" }}
|
||||
name: Restoring src cache
|
||||
step-maybe-restore-src-cache-marker: &step-maybe-restore-src-cache-marker
|
||||
restore_cache:
|
||||
keys:
|
||||
- v1-src-cache-marker-{{ checksum "src/electron/.depshash" }}
|
||||
- v5-src-cache-marker-{{ checksum "src/electron/.depshash" }}
|
||||
name: Restoring src cache marker
|
||||
|
||||
# Restore exact or closest git cache based on the hash of DEPS and .circle-sync-done
|
||||
@@ -904,10 +904,10 @@ step-maybe-restore-src-cache-marker: &step-maybe-restore-src-cache-marker
|
||||
step-maybe-restore-git-cache: &step-maybe-restore-git-cache
|
||||
restore_cache:
|
||||
paths:
|
||||
- ~/.gclient-cache
|
||||
- gclient-cache
|
||||
keys:
|
||||
- v2-gclient-cache-{{ checksum "src/electron/.circle-sync-done" }}-{{ checksum "src/electron/DEPS" }}
|
||||
- v2-gclient-cache-{{ checksum "src/electron/.circle-sync-done" }}
|
||||
- v5-gclient-cache-{{ checksum "src/electron/.circle-sync-done" }}-{{ checksum "src/electron/DEPS" }}
|
||||
- v5-gclient-cache-{{ checksum "src/electron/.circle-sync-done" }}
|
||||
name: Conditionally restoring git cache
|
||||
|
||||
step-restore-out-cache: &step-restore-out-cache
|
||||
@@ -924,15 +924,15 @@ step-set-git-cache-path: &step-set-git-cache-path
|
||||
command: |
|
||||
# CircleCI does not support interpolation when setting environment variables.
|
||||
# https://circleci.com/docs/2.0/env-vars/#setting-an-environment-variable-in-a-shell-command
|
||||
echo 'export GIT_CACHE_PATH="$HOME/.gclient-cache"' >> $BASH_ENV
|
||||
echo 'export GIT_CACHE_PATH="$PWD/gclient-cache"' >> $BASH_ENV
|
||||
|
||||
# Persist the git cache based on the hash of DEPS and .circle-sync-done
|
||||
# If the src cache was restored above then this will persist an empty cache
|
||||
step-save-git-cache: &step-save-git-cache
|
||||
save_cache:
|
||||
paths:
|
||||
- ~/.gclient-cache
|
||||
key: v2-gclient-cache-{{ checksum "src/electron/.circle-sync-done" }}-{{ checksum "src/electron/DEPS" }}
|
||||
- gclient-cache
|
||||
key: v5-gclient-cache-{{ checksum "src/electron/.circle-sync-done" }}-{{ checksum "src/electron/DEPS" }}
|
||||
name: Persisting git cache
|
||||
|
||||
step-save-out-cache: &step-save-out-cache
|
||||
@@ -977,7 +977,7 @@ step-save-src-cache: &step-save-src-cache
|
||||
save_cache:
|
||||
paths:
|
||||
- /var/portal
|
||||
key: v8-src-cache-{{ checksum "/var/portal/src/electron/.depshash" }}
|
||||
key: v12-src-cache-{{ checksum "/var/portal/src/electron/.depshash" }}
|
||||
name: Persisting src cache
|
||||
step-make-src-cache-marker: &step-make-src-cache-marker
|
||||
run:
|
||||
@@ -987,7 +987,7 @@ step-save-src-cache-marker: &step-save-src-cache-marker
|
||||
save_cache:
|
||||
paths:
|
||||
- .src-cache-marker
|
||||
key: v1-src-cache-marker-{{ checksum "/var/portal/src/electron/.depshash" }}
|
||||
key: v5-src-cache-marker-{{ checksum "/var/portal/src/electron/.depshash" }}
|
||||
|
||||
step-maybe-early-exit-no-doc-change: &step-maybe-early-exit-no-doc-change
|
||||
run:
|
||||
@@ -1352,10 +1352,6 @@ commands:
|
||||
- *step-gclient-sync
|
||||
- store_artifacts:
|
||||
path: patches
|
||||
- when:
|
||||
condition: << parameters.save-git-cache >>
|
||||
steps:
|
||||
- *step-save-git-cache
|
||||
# These next few steps reset Electron to the correct commit regardless of which cache was restored
|
||||
- run:
|
||||
name: Wipe Electron
|
||||
@@ -1364,6 +1360,11 @@ commands:
|
||||
- *step-run-electron-only-hooks
|
||||
- *step-generate-deps-hash-cleanly
|
||||
- *step-mark-sync-done
|
||||
# Save git cache AFTER sync marked done because other jobs expect that to be the case
|
||||
- when:
|
||||
condition: << parameters.save-git-cache >>
|
||||
steps:
|
||||
- *step-save-git-cache
|
||||
- *step-minimize-workspace-size-from-checkout
|
||||
- *step-delete-git-directories
|
||||
- when:
|
||||
@@ -1547,6 +1548,7 @@ jobs:
|
||||
environment:
|
||||
<<: *env-linux-medium
|
||||
<<: *env-testing-build
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
|
||||
<<: *steps-electron-ts-compile-for-doc-change
|
||||
|
||||
# Layer 1: Checkout.
|
||||
|
||||
@@ -1 +1 @@
|
||||
18.0.0-nightly.20220125
|
||||
18.0.0-alpha.1
|
||||
@@ -92,7 +92,7 @@ function loadApplicationPackage (packagePath: string) {
|
||||
try {
|
||||
packageJson = require(packageJsonPath);
|
||||
} catch (e) {
|
||||
showErrorMessage(`Unable to parse ${packageJsonPath}\n\n${e.message}`);
|
||||
showErrorMessage(`Unable to parse ${packageJsonPath}\n\n${(e as Error).message}`);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ function loadApplicationPackage (packagePath: string) {
|
||||
const filePath = Module._resolveFilename(packagePath, module, true);
|
||||
app.setAppPath(appPath || path.dirname(filePath));
|
||||
} catch (e) {
|
||||
showErrorMessage(`Unable to find Electron app at ${packagePath}\n\n${e.message}`);
|
||||
showErrorMessage(`Unable to find Electron app at ${packagePath}\n\n${(e as Error).message}`);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -119,7 +119,7 @@ function loadApplicationPackage (packagePath: string) {
|
||||
Module._load(packagePath, module, true);
|
||||
} catch (e) {
|
||||
console.error('App threw an error during load');
|
||||
console.error(e.stack || e);
|
||||
console.error((e as Error).stack || e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -954,9 +954,9 @@ app.setJumpList([
|
||||
])
|
||||
```
|
||||
|
||||
### `app.requestSingleInstanceLock()`
|
||||
### `app.requestSingleInstanceLock([additionalData])`
|
||||
|
||||
* `additionalData` unknown (optional) - A JSON object containing additional data to send to the first instance.
|
||||
* `additionalData` Record<any, any> (optional) - A JSON object containing additional data to send to the first instance.
|
||||
|
||||
Returns `boolean`
|
||||
|
||||
|
||||
@@ -388,7 +388,7 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
|
||||
contain the layout of the document—without requiring scrolling. Enabling
|
||||
this will cause the `preferred-size-changed` event to be emitted on the
|
||||
`WebContents` when the preferred size changes. Default is `false`.
|
||||
* `titleBarOverlay` Object | Boolean (optional) - When using a frameless window in conjuction with `win.setWindowButtonVisibility(true)` on macOS or using a `titleBarStyle` so that the standard window controls ("traffic lights" on macOS) are visible, this property enables the Window Controls Overlay [JavaScript APIs][overlay-javascript-apis] and [CSS Environment Variables][overlay-css-env-vars]. Specifying `true` will result in an overlay with default system colors. Default is `false`.
|
||||
* `titleBarOverlay` Object | Boolean (optional) - When using a frameless window in conjunction with `win.setWindowButtonVisibility(true)` on macOS or using a `titleBarStyle` so that the standard window controls ("traffic lights" on macOS) are visible, this property enables the Window Controls Overlay [JavaScript APIs][overlay-javascript-apis] and [CSS Environment Variables][overlay-css-env-vars]. Specifying `true` will result in an overlay with default system colors. Default is `false`.
|
||||
* `color` String (optional) _Windows_ - The CSS color of the Window Controls Overlay when enabled. Default is the system color.
|
||||
* `symbolColor` String (optional) _Windows_ - The CSS color of the symbols on the Window Controls Overlay when enabled. Default is the system color.
|
||||
* `height` Integer (optional) _macOS_ _Windows_ - The height of the title bar and Window Controls Overlay in pixels. Default is system height.
|
||||
|
||||
@@ -76,7 +76,7 @@ Writes `markup` to the clipboard.
|
||||
```js
|
||||
const { clipboard } = require('electron')
|
||||
|
||||
clipboard.writeHTML('<b>Hi</b')
|
||||
clipboard.writeHTML('<b>Hi</b>')
|
||||
```
|
||||
|
||||
### `clipboard.readImage([type])`
|
||||
|
||||
@@ -102,8 +102,8 @@ has been included below for completeness:
|
||||
| `boolean` | Simple | ✅ | ✅ | N/A |
|
||||
| `Object` | Complex | ✅ | ✅ | Keys must be supported using only "Simple" types in this table. Values must be supported in this table. Prototype modifications are dropped. Sending custom classes will copy values but not the prototype. |
|
||||
| `Array` | Complex | ✅ | ✅ | Same limitations as the `Object` type |
|
||||
| `Error` | Complex | ✅ | ✅ | Errors that are thrown are also copied, this can result in the message and stack trace of the error changing slightly due to being thrown in a different context |
|
||||
| `Promise` | Complex | ✅ | ✅ | Promises are only proxied if they are the return value or exact parameter. Promises nested in arrays or objects will be dropped. |
|
||||
| `Error` | Complex | ✅ | ✅ | Errors that are thrown are also copied, this can result in the message and stack trace of the error changing slightly due to being thrown in a different context, and any custom properties on the Error object [will be lost](https://github.com/electron/electron/issues/25596) |
|
||||
| `Promise` | Complex | ✅ | ✅ | N/A
|
||||
| `Function` | Complex | ✅ | ✅ | Prototype modifications are dropped. Sending classes or constructors will not work. |
|
||||
| [Cloneable Types](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm) | Simple | ✅ | ✅ | See the linked document on cloneable types |
|
||||
| `Element` | Complex | ✅ | ✅ | Prototype modifications are dropped. Sending custom elements will not work. |
|
||||
|
||||
@@ -28,7 +28,7 @@ When `informational` is passed, the dock icon will bounce for one second.
|
||||
However, the request remains active until either the application becomes active
|
||||
or the request is canceled.
|
||||
|
||||
**Nota Bene:** This method can only be used while the app is not focused; when the app is focused it will return -1.
|
||||
**Note:** This method can only be used while the app is not focused; when the app is focused it will return -1.
|
||||
|
||||
#### `dock.cancelBounce(id)` _macOS_
|
||||
|
||||
|
||||
@@ -124,7 +124,7 @@ When specifying a `role` on macOS, `label` and `accelerator` are the only
|
||||
options that will affect the menu item. All other options will be ignored.
|
||||
Lowercase `role`, e.g. `toggledevtools`, is still supported.
|
||||
|
||||
**Nota Bene:** The `enabled` and `visibility` properties are not available for top-level menu items in the tray on macOS.
|
||||
**Note:** The `enabled` and `visibility` properties are not available for top-level menu items in the tray on macOS.
|
||||
|
||||
### Instance Properties
|
||||
|
||||
|
||||
@@ -508,6 +508,14 @@ Returns:
|
||||
|
||||
Emitted when the user is requesting to change the zoom level using the mouse wheel.
|
||||
|
||||
#### Event: 'blur'
|
||||
|
||||
Emitted when the `WebContents` loses focus.
|
||||
|
||||
#### Event: 'focus'
|
||||
|
||||
Emitted when the `WebContents` gains focus.
|
||||
|
||||
#### Event: 'devtools-opened'
|
||||
|
||||
Emitted when DevTools is opened.
|
||||
|
||||
@@ -98,6 +98,7 @@ Some examples of valid `urls`:
|
||||
* `resourceType` string - Can be `mainFrame`, `subFrame`, `stylesheet`, `script`, `image`, `font`, `object`, `xhr`, `ping`, `cspReport`, `media`, `webSocket` or `other`.
|
||||
* `referrer` string
|
||||
* `timestamp` Double
|
||||
* `uploadData` [UploadData[]](structures/upload-data.md) (optional)
|
||||
* `requestHeaders` Record<string, string>
|
||||
* `callback` Function
|
||||
* `beforeSendResponse` Object
|
||||
|
||||
@@ -98,45 +98,40 @@ $ gclient sync -f
|
||||
|
||||
## Building
|
||||
|
||||
**Set the environment variable for chromium build tools**
|
||||
|
||||
On Linux & MacOS
|
||||
|
||||
```sh
|
||||
$ cd src
|
||||
$ export CHROMIUM_BUILDTOOLS_PATH=`pwd`/buildtools
|
||||
$ gn gen out/Testing --args="import(\"//electron/build/args/testing.gn\") $GN_EXTRA_ARGS"
|
||||
```
|
||||
|
||||
Or on Windows (without the optional argument):
|
||||
On Windows:
|
||||
|
||||
```sh
|
||||
$ cd src
|
||||
$ set CHROMIUM_BUILDTOOLS_PATH=%cd%\buildtools
|
||||
```
|
||||
|
||||
**To generate Testing build config of Electron:**
|
||||
|
||||
```sh
|
||||
$ gn gen out/Testing --args="import(\"//electron/build/args/testing.gn\")"
|
||||
```
|
||||
|
||||
This will generate a build directory `out/Testing` under `src/` with
|
||||
the testing build configuration. You can replace `Testing` with another name,
|
||||
but it should be a subdirectory of `out`.
|
||||
Also you shouldn't have to run `gn gen` again—if you want to change the
|
||||
build arguments, you can run `gn args out/Testing` to bring up an editor.
|
||||
|
||||
To see the list of available build configuration options, run `gn args
|
||||
out/Testing --list`.
|
||||
|
||||
**For generating Testing build config of
|
||||
Electron:**
|
||||
**To generate Release build config of Electron:**
|
||||
|
||||
```sh
|
||||
$ gn gen out/Testing --args="import(\"//electron/build/args/testing.gn\") $GN_EXTRA_ARGS"
|
||||
$ gn gen out/Release --args="import(\"//electron/build/args/release.gn\")"
|
||||
```
|
||||
|
||||
**For generating Release (aka "non-component" or "static") build config of
|
||||
Electron:**
|
||||
**Note:** This will generate a `out/Testing` or `out/Release` build directory under `src/` with the testing or release build depending upon the configuration passed above. You can replace `Testing|Release` with another names, but it should be a subdirectory of `out`.
|
||||
|
||||
```sh
|
||||
$ gn gen out/Release --args="import(\"//electron/build/args/release.gn\") $GN_EXTRA_ARGS"
|
||||
```
|
||||
Also you shouldn't have to run `gn gen` again—if you want to change the build arguments, you can run `gn args out/Testing` to bring up an editor. To see the list of available build configuration options, run `gn args out/Testing --list`.
|
||||
|
||||
**To build, run `ninja` with the `electron` target:**
|
||||
Nota Bene: This will also take a while and probably heat up your lap.
|
||||
Note: This will also take a while and probably heat up your lap.
|
||||
|
||||
For the testing configuration:
|
||||
|
||||
@@ -169,13 +164,13 @@ $ ./out/Testing/electron
|
||||
On linux, first strip the debugging and symbol information:
|
||||
|
||||
```sh
|
||||
electron/script/strip-binaries.py -d out/Release
|
||||
$ electron/script/strip-binaries.py -d out/Release
|
||||
```
|
||||
|
||||
To package the electron build as a distributable zip file:
|
||||
|
||||
```sh
|
||||
ninja -C out/Release electron:electron_dist_zip
|
||||
$ ninja -C out/Release electron:electron_dist_zip
|
||||
```
|
||||
|
||||
### Cross-compiling
|
||||
|
||||
@@ -29,7 +29,17 @@ Follow the guidelines below for building **Electron itself** on Linux, for the p
|
||||
* [clang](https://clang.llvm.org/get_started.html) 3.4 or later.
|
||||
* Development headers of GTK 3 and libnotify.
|
||||
|
||||
On Ubuntu, install the following libraries:
|
||||
On Ubuntu >= 20.04, install the following libraries:
|
||||
|
||||
```sh
|
||||
$ sudo apt-get install build-essential clang libdbus-1-dev libgtk-3-dev \
|
||||
libnotify-dev libasound2-dev libcap-dev \
|
||||
libcups2-dev libxtst-dev \
|
||||
libxss1 libnss3-dev gcc-multilib g++-multilib curl \
|
||||
gperf bison python3-dbusmock openjdk-8-jre
|
||||
```
|
||||
|
||||
On Ubuntu < 20.04, install the following libraries:
|
||||
|
||||
```sh
|
||||
$ sudo apt-get install build-essential clang libdbus-1-dev libgtk-3-dev \
|
||||
|
||||
@@ -32,10 +32,13 @@ filenames = {
|
||||
"shell/browser/notifications/linux/notification_presenter_linux.cc",
|
||||
"shell/browser/notifications/linux/notification_presenter_linux.h",
|
||||
"shell/browser/relauncher_linux.cc",
|
||||
"shell/browser/ui/electron_desktop_window_tree_host_linux.cc",
|
||||
"shell/browser/ui/file_dialog_gtk.cc",
|
||||
"shell/browser/ui/message_box_gtk.cc",
|
||||
"shell/browser/ui/tray_icon_gtk.cc",
|
||||
"shell/browser/ui/tray_icon_gtk.h",
|
||||
"shell/browser/ui/views/client_frame_view_linux.cc",
|
||||
"shell/browser/ui/views/client_frame_view_linux.h",
|
||||
"shell/common/application_info_linux.cc",
|
||||
"shell/common/language_util_linux.cc",
|
||||
"shell/common/node_bindings_linux.cc",
|
||||
@@ -413,6 +416,8 @@ filenames = {
|
||||
"shell/browser/native_browser_view.h",
|
||||
"shell/browser/native_window.cc",
|
||||
"shell/browser/native_window.h",
|
||||
"shell/browser/native_window_features.cc",
|
||||
"shell/browser/native_window_features.h",
|
||||
"shell/browser/native_window_observer.h",
|
||||
"shell/browser/net/asar/asar_file_validator.cc",
|
||||
"shell/browser/net/asar/asar_file_validator.h",
|
||||
|
||||
@@ -35,7 +35,7 @@ const spawnUpdate = function (args: string[], detached: boolean, callback: Funct
|
||||
spawnedArgs = args || [];
|
||||
}
|
||||
} catch (error1) {
|
||||
error = error1;
|
||||
error = error1 as Error;
|
||||
|
||||
// Shouldn't happen, but still guard it.
|
||||
process.nextTick(function () {
|
||||
|
||||
@@ -15,7 +15,7 @@ export class IpcMainImpl extends EventEmitter {
|
||||
try {
|
||||
e._reply(await Promise.resolve(fn(e, ...args)));
|
||||
} catch (err) {
|
||||
e._throw(err);
|
||||
e._throw(err as Error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "electron",
|
||||
"version": "18.0.0-nightly.20220125",
|
||||
"version": "18.0.0-alpha.1",
|
||||
"repository": "https://github.com/electron/electron",
|
||||
"description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
|
||||
"devDependencies": {
|
||||
@@ -67,7 +67,7 @@
|
||||
"timers-browserify": "1.4.2",
|
||||
"ts-loader": "^8.0.2",
|
||||
"ts-node": "6.2.0",
|
||||
"typescript": "^4.1.3",
|
||||
"typescript": "^4.5.5",
|
||||
"webpack": "^4.43.0",
|
||||
"webpack-cli": "^3.3.12",
|
||||
"wrapper-webpack-plugin": "^2.1.0"
|
||||
|
||||
@@ -11,7 +11,7 @@ majority of changes originally come from these PRs:
|
||||
This patch also fixes callback for manual user cancellation and success.
|
||||
|
||||
diff --git a/chrome/browser/printing/print_job.cc b/chrome/browser/printing/print_job.cc
|
||||
index 0de0532d64897c91ce0f72d165976e12e1dec03e..13167ca3f9c0d4895fecd40ab1e2d397c6e85a0b 100644
|
||||
index 0de0532d64897c91ce0f72d165976e12e1dec03e..735da67a83b10c56d747e2a2b512f7b7d1aae142 100644
|
||||
--- a/chrome/browser/printing/print_job.cc
|
||||
+++ b/chrome/browser/printing/print_job.cc
|
||||
@@ -88,6 +88,7 @@ bool PrintWithReducedRasterization(PrefService* prefs) {
|
||||
@@ -54,50 +54,11 @@ index 0de0532d64897c91ce0f72d165976e12e1dec03e..13167ca3f9c0d4895fecd40ab1e2d397
|
||||
? PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3_WITH_TYPE42_FONTS
|
||||
: PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3;
|
||||
}
|
||||
@@ -504,6 +510,20 @@ void PrintJob::OnPageDone(PrintedPage* page) {
|
||||
}
|
||||
#endif // defined(OS_WIN)
|
||||
|
||||
+void PrintJob::OnUserInitCancelled() {
|
||||
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
+ // Make sure a `Cancel()` is broadcast.
|
||||
+ auto details = base::MakeRefCounted<JobEventDetails>(JobEventDetails::USER_INIT_CANCELED,
|
||||
+ 0, nullptr);
|
||||
+ content::NotificationService::current()->Notify(
|
||||
+ chrome::NOTIFICATION_PRINT_JOB_EVENT, content::Source<PrintJob>(this),
|
||||
+ content::Details<JobEventDetails>(details.get()));
|
||||
+
|
||||
+ for (auto& observer : observers_) {
|
||||
+ observer.OnUserInitCancelled();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
void PrintJob::OnFailed() {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
|
||||
diff --git a/chrome/browser/printing/print_job.h b/chrome/browser/printing/print_job.h
|
||||
index e19f62354edb8acad722c6680296b7d2f55f51fe..b5539171655d78634ee89faf3516d23ce5718353 100644
|
||||
index e19f62354edb8acad722c6680296b7d2f55f51fe..51c41b4dbab81ffe5840d59ef45b661cf5c5534b 100644
|
||||
--- a/chrome/browser/printing/print_job.h
|
||||
+++ b/chrome/browser/printing/print_job.h
|
||||
@@ -53,6 +53,7 @@ class PrintJob : public base::RefCountedThreadSafe<PrintJob> {
|
||||
public:
|
||||
virtual void OnDocDone(int job_id, PrintedDocument* document) {}
|
||||
virtual void OnJobDone() {}
|
||||
+ virtual void OnUserInitCancelled() {}
|
||||
virtual void OnFailed() {}
|
||||
};
|
||||
|
||||
@@ -100,6 +101,9 @@ class PrintJob : public base::RefCountedThreadSafe<PrintJob> {
|
||||
// Called when the document is done printing.
|
||||
virtual void OnDocDone(int job_id, PrintedDocument* document);
|
||||
|
||||
+ // Called if the user cancels the print job.
|
||||
+ virtual void OnUserInitCancelled();
|
||||
+
|
||||
// Called if the document fails to print.
|
||||
virtual void OnFailed();
|
||||
|
||||
@@ -257,6 +261,9 @@ class JobEventDetails : public base::RefCountedThreadSafe<JobEventDetails> {
|
||||
@@ -257,6 +257,9 @@ class JobEventDetails : public base::RefCountedThreadSafe<JobEventDetails> {
|
||||
public:
|
||||
// Event type.
|
||||
enum Type {
|
||||
@@ -108,7 +69,7 @@ index e19f62354edb8acad722c6680296b7d2f55f51fe..b5539171655d78634ee89faf3516d23c
|
||||
NEW_DOC,
|
||||
|
||||
diff --git a/chrome/browser/printing/print_job_worker.cc b/chrome/browser/printing/print_job_worker.cc
|
||||
index d8f67ab5116483eb2eeb4cc09f19bbcbccb74b37..b4ab0984765c9711ddacf32f7147108cdfbc5096 100644
|
||||
index d8f67ab5116483eb2eeb4cc09f19bbcbccb74b37..4283a5743c695a7376722f80925722d9e7a6496e 100644
|
||||
--- a/chrome/browser/printing/print_job_worker.cc
|
||||
+++ b/chrome/browser/printing/print_job_worker.cc
|
||||
@@ -20,13 +20,13 @@
|
||||
@@ -126,18 +87,7 @@ index d8f67ab5116483eb2eeb4cc09f19bbcbccb74b37..b4ab0984765c9711ddacf32f7147108c
|
||||
#include "printing/backend/print_backend.h"
|
||||
#include "printing/buildflags/buildflags.h"
|
||||
#include "printing/mojom/print.mojom.h"
|
||||
@@ -125,6 +125,10 @@ void FailedNotificationCallback(PrintJob* print_job) {
|
||||
print_job->OnFailed();
|
||||
}
|
||||
|
||||
+void UserInitCancelledNotificationCallback(PrintJob* print_job) {
|
||||
+ print_job->OnUserInitCancelled();
|
||||
+}
|
||||
+
|
||||
#if defined(OS_WIN)
|
||||
void PageNotificationCallback(PrintJob* print_job, PrintedPage* page) {
|
||||
print_job->OnPageDone(page);
|
||||
@@ -245,16 +249,21 @@ void PrintJobWorker::UpdatePrintSettings(base::Value new_settings,
|
||||
@@ -245,16 +245,21 @@ void PrintJobWorker::UpdatePrintSettings(base::Value new_settings,
|
||||
#endif // defined(OS_LINUX) && defined(USE_CUPS)
|
||||
}
|
||||
|
||||
@@ -162,21 +112,8 @@ index d8f67ab5116483eb2eeb4cc09f19bbcbccb74b37..b4ab0984765c9711ddacf32f7147108c
|
||||
}
|
||||
|
||||
#if defined(OS_CHROMEOS)
|
||||
@@ -270,6 +279,12 @@ void PrintJobWorker::UpdatePrintSettingsFromPOD(
|
||||
|
||||
void PrintJobWorker::GetSettingsDone(SettingsCallback callback,
|
||||
mojom::ResultCode result) {
|
||||
+ if (result == mojom::ResultCode::kCanceled) {
|
||||
+ print_job_->PostTask(
|
||||
+ FROM_HERE,
|
||||
+ base::BindOnce(&UserInitCancelledNotificationCallback,
|
||||
+ base::RetainedRef(print_job_.get())));
|
||||
+ }
|
||||
std::move(callback).Run(printing_context_->TakeAndResetSettings(), result);
|
||||
}
|
||||
|
||||
diff --git a/chrome/browser/printing/print_view_manager_base.cc b/chrome/browser/printing/print_view_manager_base.cc
|
||||
index c9f1502da55d89de0eede73a7d39047c090594d0..1320afa83016ea72e5dbc23b1ed63cf91d439102 100644
|
||||
index c9f1502da55d89de0eede73a7d39047c090594d0..c857a48e00c3535c74691f4e36d44e0478e3b15c 100644
|
||||
--- a/chrome/browser/printing/print_view_manager_base.cc
|
||||
+++ b/chrome/browser/printing/print_view_manager_base.cc
|
||||
@@ -29,10 +29,10 @@
|
||||
@@ -228,7 +165,26 @@ index c9f1502da55d89de0eede73a7d39047c090594d0..1320afa83016ea72e5dbc23b1ed63cf9
|
||||
RenderParamsFromPrintSettings(printer_query->settings(),
|
||||
params->params.get());
|
||||
params->params->document_cookie = printer_query->cookie();
|
||||
@@ -319,12 +325,14 @@ PrintViewManagerBase::PrintViewManagerBase(content::WebContents* web_contents)
|
||||
@@ -270,6 +276,7 @@ void ScriptedPrintReplyOnIO(
|
||||
mojom::PrintManagerHost::ScriptedPrintCallback callback) {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
||||
mojom::PrintPagesParamsPtr params = CreateEmptyPrintPagesParamsPtr();
|
||||
+
|
||||
if (printer_query->last_status() == mojom::ResultCode::kSuccess &&
|
||||
printer_query->settings().dpi()) {
|
||||
RenderParamsFromPrintSettings(printer_query->settings(),
|
||||
@@ -279,8 +286,9 @@ void ScriptedPrintReplyOnIO(
|
||||
}
|
||||
bool has_valid_cookie = params->params->document_cookie;
|
||||
bool has_dpi = !params->params->dpi.IsEmpty();
|
||||
+ bool canceled = printer_query->last_status() == mojom::ResultCode::kCanceled;
|
||||
content::GetUIThreadTaskRunner({})->PostTask(
|
||||
- FROM_HERE, base::BindOnce(std::move(callback), std::move(params)));
|
||||
+ FROM_HERE, base::BindOnce(std::move(callback), std::move(params), canceled));
|
||||
|
||||
if (has_dpi && has_valid_cookie) {
|
||||
queue->QueuePrinterQuery(std::move(printer_query));
|
||||
@@ -319,12 +327,14 @@ PrintViewManagerBase::PrintViewManagerBase(content::WebContents* web_contents)
|
||||
: PrintManager(web_contents),
|
||||
queue_(g_browser_process->print_job_manager()->queue()) {
|
||||
DCHECK(queue_);
|
||||
@@ -243,7 +199,7 @@ index c9f1502da55d89de0eede73a7d39047c090594d0..1320afa83016ea72e5dbc23b1ed63cf9
|
||||
}
|
||||
|
||||
PrintViewManagerBase::~PrintViewManagerBase() {
|
||||
@@ -332,7 +340,10 @@ PrintViewManagerBase::~PrintViewManagerBase() {
|
||||
@@ -332,7 +342,10 @@ PrintViewManagerBase::~PrintViewManagerBase() {
|
||||
DisconnectFromCurrentPrintJob();
|
||||
}
|
||||
|
||||
@@ -255,22 +211,39 @@ index c9f1502da55d89de0eede73a7d39047c090594d0..1320afa83016ea72e5dbc23b1ed63cf9
|
||||
auto weak_this = weak_ptr_factory_.GetWeakPtr();
|
||||
DisconnectFromCurrentPrintJob();
|
||||
if (!weak_this)
|
||||
@@ -347,7 +358,13 @@ bool PrintViewManagerBase::PrintNow(content::RenderFrameHost* rfh) {
|
||||
@@ -347,7 +360,9 @@ bool PrintViewManagerBase::PrintNow(content::RenderFrameHost* rfh) {
|
||||
// go in `ReleasePrintJob()`.
|
||||
|
||||
SetPrintingRFH(rfh);
|
||||
- GetPrintRenderFrame(rfh)->PrintRequestedPages();
|
||||
+ callback_ = std::move(callback);
|
||||
+
|
||||
+ if (!callback_.is_null()) {
|
||||
+ print_job_->AddObserver(*this);
|
||||
+ }
|
||||
+
|
||||
+ GetPrintRenderFrame(rfh)->PrintRequestedPages(silent, std::move(settings));
|
||||
|
||||
for (auto& observer : GetObservers())
|
||||
observer.OnPrintNow(rfh);
|
||||
@@ -506,9 +523,9 @@ void PrintViewManagerBase::ScriptedPrintReply(
|
||||
@@ -491,7 +506,8 @@ void PrintViewManagerBase::GetDefaultPrintSettingsReply(
|
||||
void PrintViewManagerBase::ScriptedPrintReply(
|
||||
ScriptedPrintCallback callback,
|
||||
int process_id,
|
||||
- mojom::PrintPagesParamsPtr params) {
|
||||
+ mojom::PrintPagesParamsPtr params,
|
||||
+ bool canceled) {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
|
||||
if (!content::RenderProcessHost::FromID(process_id)) {
|
||||
@@ -499,16 +515,19 @@ void PrintViewManagerBase::ScriptedPrintReply(
|
||||
return;
|
||||
}
|
||||
|
||||
+ if (canceled)
|
||||
+ UserInitCanceled();
|
||||
+
|
||||
set_cookie(params->params->document_cookie);
|
||||
- std::move(callback).Run(std::move(params));
|
||||
+ std::move(callback).Run(std::move(params), canceled);
|
||||
}
|
||||
|
||||
void PrintViewManagerBase::UpdatePrintingEnabled() {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
// The Unretained() is safe because ForEachFrame() is synchronous.
|
||||
@@ -283,7 +256,7 @@ index c9f1502da55d89de0eede73a7d39047c090594d0..1320afa83016ea72e5dbc23b1ed63cf9
|
||||
}
|
||||
|
||||
void PrintViewManagerBase::NavigationStopped() {
|
||||
@@ -622,12 +639,13 @@ void PrintViewManagerBase::DidPrintDocument(
|
||||
@@ -622,12 +641,13 @@ void PrintViewManagerBase::DidPrintDocument(
|
||||
void PrintViewManagerBase::GetDefaultPrintSettings(
|
||||
GetDefaultPrintSettingsCallback callback) {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
@@ -298,7 +271,7 @@ index c9f1502da55d89de0eede73a7d39047c090594d0..1320afa83016ea72e5dbc23b1ed63cf9
|
||||
content::RenderFrameHost* render_frame_host = GetCurrentTargetFrame();
|
||||
auto callback_wrapper =
|
||||
base::BindOnce(&PrintViewManagerBase::GetDefaultPrintSettingsReply,
|
||||
@@ -645,18 +663,20 @@ void PrintViewManagerBase::UpdatePrintSettings(
|
||||
@@ -645,18 +665,20 @@ void PrintViewManagerBase::UpdatePrintSettings(
|
||||
base::Value job_settings,
|
||||
UpdatePrintSettingsCallback callback) {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
@@ -320,7 +293,7 @@ index c9f1502da55d89de0eede73a7d39047c090594d0..1320afa83016ea72e5dbc23b1ed63cf9
|
||||
content::BrowserContext* context =
|
||||
web_contents() ? web_contents()->GetBrowserContext() : nullptr;
|
||||
PrefService* prefs =
|
||||
@@ -666,6 +686,7 @@ void PrintViewManagerBase::UpdatePrintSettings(
|
||||
@@ -666,6 +688,7 @@ void PrintViewManagerBase::UpdatePrintSettings(
|
||||
if (value > 0)
|
||||
job_settings.SetIntKey(kSettingRasterizePdfDpi, value);
|
||||
}
|
||||
@@ -328,7 +301,16 @@ index c9f1502da55d89de0eede73a7d39047c090594d0..1320afa83016ea72e5dbc23b1ed63cf9
|
||||
|
||||
auto callback_wrapper =
|
||||
base::BindOnce(&PrintViewManagerBase::UpdatePrintSettingsReply,
|
||||
@@ -714,7 +735,6 @@ void PrintViewManagerBase::PrintingFailed(int32_t cookie) {
|
||||
@@ -691,7 +714,7 @@ void PrintViewManagerBase::ScriptedPrint(mojom::ScriptedPrintParamsPtr params,
|
||||
// didn't happen for some reason.
|
||||
bad_message::ReceivedBadMessage(
|
||||
render_process_host, bad_message::PVMB_SCRIPTED_PRINT_FENCED_FRAME);
|
||||
- std::move(callback).Run(CreateEmptyPrintPagesParamsPtr());
|
||||
+ std::move(callback).Run(CreateEmptyPrintPagesParamsPtr(), false);
|
||||
return;
|
||||
}
|
||||
int process_id = render_process_host->GetID();
|
||||
@@ -714,7 +737,6 @@ void PrintViewManagerBase::PrintingFailed(int32_t cookie) {
|
||||
PrintManager::PrintingFailed(cookie);
|
||||
|
||||
#if BUILDFLAG(ENABLE_PRINT_PREVIEW)
|
||||
@@ -336,7 +318,7 @@ index c9f1502da55d89de0eede73a7d39047c090594d0..1320afa83016ea72e5dbc23b1ed63cf9
|
||||
#endif
|
||||
|
||||
ReleasePrinterQuery();
|
||||
@@ -729,6 +749,11 @@ void PrintViewManagerBase::RemoveObserver(Observer& observer) {
|
||||
@@ -729,6 +751,11 @@ void PrintViewManagerBase::RemoveObserver(Observer& observer) {
|
||||
}
|
||||
|
||||
void PrintViewManagerBase::ShowInvalidPrinterSettingsError() {
|
||||
@@ -348,7 +330,7 @@ index c9f1502da55d89de0eede73a7d39047c090594d0..1320afa83016ea72e5dbc23b1ed63cf9
|
||||
base::ThreadTaskRunnerHandle::Get()->PostTask(
|
||||
FROM_HERE, base::BindOnce(&ShowWarningMessageBox,
|
||||
l10n_util::GetStringUTF16(
|
||||
@@ -739,8 +764,10 @@ void PrintViewManagerBase::RenderFrameHostStateChanged(
|
||||
@@ -739,8 +766,10 @@ void PrintViewManagerBase::RenderFrameHostStateChanged(
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
content::RenderFrameHost::LifecycleState /*old_state*/,
|
||||
content::RenderFrameHost::LifecycleState new_state) {
|
||||
@@ -359,19 +341,19 @@ index c9f1502da55d89de0eede73a7d39047c090594d0..1320afa83016ea72e5dbc23b1ed63cf9
|
||||
}
|
||||
|
||||
void PrintViewManagerBase::DidStartLoading() {
|
||||
@@ -808,6 +835,11 @@ void PrintViewManagerBase::OnJobDone() {
|
||||
@@ -808,6 +837,11 @@ void PrintViewManagerBase::OnJobDone() {
|
||||
ReleasePrintJob();
|
||||
}
|
||||
|
||||
+void PrintViewManagerBase::OnUserInitCancelled() {
|
||||
+ printing_cancelled_ = true;
|
||||
+void PrintViewManagerBase::UserInitCanceled() {
|
||||
+ printing_canceled_ = true;
|
||||
+ ReleasePrintJob();
|
||||
+}
|
||||
+
|
||||
void PrintViewManagerBase::OnFailed() {
|
||||
TerminatePrintJob(true);
|
||||
}
|
||||
@@ -869,7 +901,10 @@ bool PrintViewManagerBase::CreateNewPrintJob(
|
||||
@@ -869,7 +903,10 @@ bool PrintViewManagerBase::CreateNewPrintJob(
|
||||
|
||||
// Disconnect the current |print_job_|.
|
||||
auto weak_this = weak_ptr_factory_.GetWeakPtr();
|
||||
@@ -383,40 +365,21 @@ index c9f1502da55d89de0eede73a7d39047c090594d0..1320afa83016ea72e5dbc23b1ed63cf9
|
||||
if (!weak_this)
|
||||
return false;
|
||||
|
||||
@@ -891,8 +926,6 @@ bool PrintViewManagerBase::CreateNewPrintJob(
|
||||
: PrintJob::Source::PRINT_PREVIEW,
|
||||
/*source_id=*/"");
|
||||
#endif
|
||||
- print_job_->AddObserver(*this);
|
||||
-
|
||||
printing_succeeded_ = false;
|
||||
return true;
|
||||
}
|
||||
@@ -944,14 +977,21 @@ void PrintViewManagerBase::ReleasePrintJob() {
|
||||
@@ -944,6 +981,13 @@ void PrintViewManagerBase::ReleasePrintJob() {
|
||||
content::RenderFrameHost* rfh = printing_rfh_;
|
||||
printing_rfh_ = nullptr;
|
||||
|
||||
+ if (!callback_.is_null()) {
|
||||
+ print_job_->RemoveObserver(*this);
|
||||
+
|
||||
+ std::string cb_str = "";
|
||||
+ if (!printing_succeeded_)
|
||||
+ cb_str = printing_cancelled_ ? "cancelled" : "failed";
|
||||
+ cb_str = printing_canceled_ ? "canceled" : "failed";
|
||||
+ std::move(callback_).Run(printing_succeeded_, cb_str);
|
||||
+ }
|
||||
+
|
||||
if (!print_job_)
|
||||
return;
|
||||
|
||||
if (rfh)
|
||||
GetPrintRenderFrame(rfh)->PrintingDone(printing_succeeded_);
|
||||
|
||||
- print_job_->RemoveObserver(*this);
|
||||
-
|
||||
// Don't close the worker thread.
|
||||
print_job_ = nullptr;
|
||||
}
|
||||
@@ -989,7 +1029,7 @@ bool PrintViewManagerBase::RunInnerMessageLoop() {
|
||||
@@ -989,7 +1033,7 @@ bool PrintViewManagerBase::RunInnerMessageLoop() {
|
||||
}
|
||||
|
||||
bool PrintViewManagerBase::OpportunisticallyCreatePrintJob(int cookie) {
|
||||
@@ -426,7 +389,7 @@ index c9f1502da55d89de0eede73a7d39047c090594d0..1320afa83016ea72e5dbc23b1ed63cf9
|
||||
|
||||
if (!cookie) {
|
||||
diff --git a/chrome/browser/printing/print_view_manager_base.h b/chrome/browser/printing/print_view_manager_base.h
|
||||
index 5771a3ebd76145c6cf8a2ccc33abc886802ed59f..1562d6331a9cafd530db42c436e878bac427566d 100644
|
||||
index 5771a3ebd76145c6cf8a2ccc33abc886802ed59f..fb3af5e3f57f868fd00716f76f70aa63c4cb99c9 100644
|
||||
--- a/chrome/browser/printing/print_view_manager_base.h
|
||||
+++ b/chrome/browser/printing/print_view_manager_base.h
|
||||
@@ -37,6 +37,8 @@ namespace printing {
|
||||
@@ -450,15 +413,25 @@ index 5771a3ebd76145c6cf8a2ccc33abc886802ed59f..1562d6331a9cafd530db42c436e878ba
|
||||
|
||||
#if BUILDFLAG(ENABLE_PRINT_PREVIEW)
|
||||
// Prints the document in |print_data| with settings specified in
|
||||
@@ -143,6 +148,7 @@ class PrintViewManagerBase : public PrintManager, public PrintJob::Observer {
|
||||
// PrintJob::Observer overrides:
|
||||
void OnDocDone(int job_id, PrintedDocument* document) override;
|
||||
void OnJobDone() override;
|
||||
+ void OnUserInitCancelled() override;
|
||||
void OnFailed() override;
|
||||
@@ -106,6 +111,7 @@ class PrintViewManagerBase : public PrintManager, public PrintJob::Observer {
|
||||
ScriptedPrintCallback callback) override;
|
||||
void ShowInvalidPrinterSettingsError() override;
|
||||
void PrintingFailed(int32_t cookie) override;
|
||||
+ void UserInitCanceled();
|
||||
|
||||
base::ObserverList<Observer>& GetObservers() { return observers_; }
|
||||
@@ -252,9 +258,15 @@ class PrintViewManagerBase : public PrintManager, public PrintJob::Observer {
|
||||
// Adds and removes observers for `PrintViewManagerBase` events. The order in
|
||||
// which notifications are sent to observers is undefined. Observers must be
|
||||
@@ -197,7 +203,8 @@ class PrintViewManagerBase : public PrintManager, public PrintJob::Observer {
|
||||
// Runs `callback` with `params` to reply to ScriptedPrint().
|
||||
void ScriptedPrintReply(ScriptedPrintCallback callback,
|
||||
int process_id,
|
||||
- mojom::PrintPagesParamsPtr params);
|
||||
+ mojom::PrintPagesParamsPtr params,
|
||||
+ bool canceled);
|
||||
|
||||
// Requests the RenderView to render all the missing pages for the print job.
|
||||
// No-op if no print job is pending. Returns true if at least one page has
|
||||
@@ -252,9 +259,15 @@ class PrintViewManagerBase : public PrintManager, public PrintJob::Observer {
|
||||
// The current RFH that is printing with a system printing dialog.
|
||||
raw_ptr<content::RenderFrameHost> printing_rfh_ = nullptr;
|
||||
|
||||
@@ -468,14 +441,14 @@ index 5771a3ebd76145c6cf8a2ccc33abc886802ed59f..1562d6331a9cafd530db42c436e878ba
|
||||
// Indication of success of the print job.
|
||||
bool printing_succeeded_ = false;
|
||||
|
||||
+ // Indication of whether the print job was manually cancelled
|
||||
+ bool printing_cancelled_ = false;
|
||||
+ // Indication of whether the print job was manually canceled
|
||||
+ bool printing_canceled_ = false;
|
||||
+
|
||||
// Set while running an inner message loop inside RenderAllMissingPagesNow().
|
||||
// This means we are _blocking_ until all the necessary pages have been
|
||||
// rendered or the print settings are being loaded.
|
||||
diff --git a/components/printing/common/print.mojom b/components/printing/common/print.mojom
|
||||
index 51ebcb4ae399018d3fd8566656596a7ef1f148af..5f2b807fc364131f4c3e6a1646ec522ddc826d9c 100644
|
||||
index 51ebcb4ae399018d3fd8566656596a7ef1f148af..c0fbff95137e2e5bccb9702a8cc858df2d989964 100644
|
||||
--- a/components/printing/common/print.mojom
|
||||
+++ b/components/printing/common/print.mojom
|
||||
@@ -274,7 +274,7 @@ interface PrintPreviewUI {
|
||||
@@ -487,8 +460,17 @@ index 51ebcb4ae399018d3fd8566656596a7ef1f148af..5f2b807fc364131f4c3e6a1646ec522d
|
||||
|
||||
// Tells the RenderFrame to switch the CSS to print media type, render every
|
||||
// requested page using the print preview document's frame/node, and then
|
||||
@@ -341,7 +341,7 @@ interface PrintManagerHost {
|
||||
// Request the print settings from the user. This step is about showing
|
||||
// UI to the user to select the final print settings.
|
||||
[Sync]
|
||||
- ScriptedPrint(ScriptedPrintParams params) => (PrintPagesParams settings);
|
||||
+ ScriptedPrint(ScriptedPrintParams params) => (PrintPagesParams settings, bool canceled);
|
||||
|
||||
// Tells the browser that there are invalid printer settings.
|
||||
ShowInvalidPrinterSettingsError();
|
||||
diff --git a/components/printing/renderer/print_render_frame_helper.cc b/components/printing/renderer/print_render_frame_helper.cc
|
||||
index 650b5550f982fa5c5c522efaa9b8e305b7edc5e7..260b5521dccadf07eba2c67fa3d9c3da80b49104 100644
|
||||
index 650b5550f982fa5c5c522efaa9b8e305b7edc5e7..1b776a614d6e0f6c3ae13ef3c705bc19544cfe12 100644
|
||||
--- a/components/printing/renderer/print_render_frame_helper.cc
|
||||
+++ b/components/printing/renderer/print_render_frame_helper.cc
|
||||
@@ -39,6 +39,7 @@
|
||||
@@ -657,6 +639,15 @@ index 650b5550f982fa5c5c522efaa9b8e305b7edc5e7..260b5521dccadf07eba2c67fa3d9c3da
|
||||
notify_browser_of_print_failure_ = false;
|
||||
GetPrintManagerHost()->ShowInvalidPrinterSettingsError();
|
||||
return false;
|
||||
@@ -2350,7 +2380,7 @@ mojom::PrintPagesParamsPtr PrintRenderFrameHelper::GetPrintSettingsFromUser(
|
||||
std::move(params),
|
||||
base::BindOnce(
|
||||
[](base::OnceClosure quit_closure, mojom::PrintPagesParamsPtr* output,
|
||||
- mojom::PrintPagesParamsPtr input) {
|
||||
+ mojom::PrintPagesParamsPtr input, bool canceled) {
|
||||
*output = std::move(input);
|
||||
std::move(quit_closure).Run();
|
||||
},
|
||||
@@ -2579,18 +2609,7 @@ void PrintRenderFrameHelper::RequestPrintPreview(PrintPreviewRequestType type) {
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ LINUX_BINARIES = [
|
||||
'libEGL.so',
|
||||
'libGLESv2.so',
|
||||
'libffmpeg.so',
|
||||
'libvk_swiftshader.so'
|
||||
'libvk_swiftshader.so',
|
||||
'swiftshader/libEGL.so',
|
||||
'swiftshader/libGLESv2.so',
|
||||
]
|
||||
|
||||
@@ -373,8 +373,11 @@ void BrowserWindow::SetBackgroundColor(const std::string& color_name) {
|
||||
SkColor color = ParseHexColor(color_name);
|
||||
web_contents()->SetPageBaseBackgroundColor(color);
|
||||
auto* rwhv = web_contents()->GetRenderWidgetHostView();
|
||||
if (rwhv)
|
||||
if (rwhv) {
|
||||
rwhv->SetBackgroundColor(color);
|
||||
static_cast<content::RenderWidgetHostViewBase*>(rwhv)
|
||||
->SetContentBackgroundColor(color);
|
||||
}
|
||||
// Also update the web preferences object otherwise the view will be reset on
|
||||
// the next load URL call
|
||||
if (api_web_contents_) {
|
||||
|
||||
@@ -599,6 +599,12 @@ bool IsDevToolsFileSystemAdded(content::WebContents* web_contents,
|
||||
return file_system_paths.find(file_system_path) != file_system_paths.end();
|
||||
}
|
||||
|
||||
void SetBackgroundColor(content::RenderWidgetHostView* rwhv, SkColor color) {
|
||||
rwhv->SetBackgroundColor(color);
|
||||
static_cast<content::RenderWidgetHostViewBase*>(rwhv)
|
||||
->SetContentBackgroundColor(color);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
@@ -1457,7 +1463,7 @@ void WebContents::HandleNewRenderFrame(
|
||||
absl::optional<SkColor> color =
|
||||
guest ? SK_ColorTRANSPARENT : web_preferences->GetBackgroundColor();
|
||||
web_contents()->SetPageBaseBackgroundColor(color);
|
||||
rwhv->SetBackgroundColor(color.value_or(SK_ColorWHITE));
|
||||
SetBackgroundColor(rwhv, color.value_or(SK_ColorWHITE));
|
||||
}
|
||||
|
||||
if (!background_throttling_)
|
||||
@@ -1473,6 +1479,15 @@ void WebContents::HandleNewRenderFrame(
|
||||
web_frame->Connect();
|
||||
}
|
||||
|
||||
void WebContents::OnBackgroundColorChanged() {
|
||||
absl::optional<SkColor> color = web_contents()->GetBackgroundColor();
|
||||
if (color.has_value()) {
|
||||
auto* const view = web_contents()->GetRenderWidgetHostView();
|
||||
static_cast<content::RenderWidgetHostViewBase*>(view)
|
||||
->SetContentBackgroundColor(color.value());
|
||||
}
|
||||
}
|
||||
|
||||
void WebContents::RenderFrameCreated(
|
||||
content::RenderFrameHost* render_frame_host) {
|
||||
HandleNewRenderFrame(render_frame_host);
|
||||
@@ -1614,6 +1629,16 @@ void WebContents::DidAcquireFullscreen(content::RenderFrameHost* rfh) {
|
||||
set_fullscreen_frame(rfh);
|
||||
}
|
||||
|
||||
void WebContents::OnWebContentsFocused(
|
||||
content::RenderWidgetHost* render_widget_host) {
|
||||
Emit("focus");
|
||||
}
|
||||
|
||||
void WebContents::OnWebContentsLostFocus(
|
||||
content::RenderWidgetHost* render_widget_host) {
|
||||
Emit("blur");
|
||||
}
|
||||
|
||||
void WebContents::DOMContentLoaded(
|
||||
content::RenderFrameHost* render_frame_host) {
|
||||
auto* web_frame = WebFrameMain::FromRenderFrameHost(render_frame_host);
|
||||
@@ -4053,7 +4078,7 @@ gin::Handle<WebContents> WebContents::CreateFromWebPreferences(
|
||||
// only set rwhv background color if a color exists
|
||||
auto* rwhv = web_contents->web_contents()->GetRenderWidgetHostView();
|
||||
if (rwhv && color.has_value())
|
||||
rwhv->SetBackgroundColor(color.value());
|
||||
SetBackgroundColor(rwhv, color.value());
|
||||
}
|
||||
} else {
|
||||
// Create one if not.
|
||||
|
||||
@@ -578,6 +578,7 @@ class WebContents : public ExclusiveAccessContext,
|
||||
// content::WebContentsObserver:
|
||||
void BeforeUnloadFired(bool proceed,
|
||||
const base::TimeTicks& proceed_time) override;
|
||||
void OnBackgroundColorChanged() override;
|
||||
void RenderFrameCreated(content::RenderFrameHost* render_frame_host) override;
|
||||
void RenderFrameDeleted(content::RenderFrameHost* render_frame_host) override;
|
||||
void RenderFrameHostChanged(content::RenderFrameHost* old_host,
|
||||
@@ -620,6 +621,10 @@ class WebContents : public ExclusiveAccessContext,
|
||||
void DidChangeThemeColor() override;
|
||||
void OnCursorChanged(const content::WebCursor& cursor) override;
|
||||
void DidAcquireFullscreen(content::RenderFrameHost* rfh) override;
|
||||
void OnWebContentsFocused(
|
||||
content::RenderWidgetHost* render_widget_host) override;
|
||||
void OnWebContentsLostFocus(
|
||||
content::RenderWidgetHost* render_widget_host) override;
|
||||
|
||||
// InspectableWebContentsDelegate:
|
||||
void DevToolsReloadPage() override;
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "base/values.h"
|
||||
#include "content/public/browser/web_contents_user_data.h"
|
||||
#include "shell/browser/browser.h"
|
||||
#include "shell/browser/native_window_features.h"
|
||||
#include "shell/browser/window_list.h"
|
||||
#include "shell/common/color_util.h"
|
||||
#include "shell/common/gin_helper/dictionary.h"
|
||||
@@ -25,6 +26,11 @@
|
||||
#include "ui/display/win/screen_win.h"
|
||||
#endif
|
||||
|
||||
#if defined(USE_OZONE) || defined(USE_X11)
|
||||
#include "ui/base/ui_base_features.h"
|
||||
#include "ui/ozone/public/ozone_platform.h"
|
||||
#endif
|
||||
|
||||
namespace gin {
|
||||
|
||||
template <>
|
||||
@@ -108,6 +114,17 @@ NativeWindow::NativeWindow(const gin_helper::Dictionary& options,
|
||||
if (parent)
|
||||
options.Get("modal", &is_modal_);
|
||||
|
||||
#if defined(USE_OZONE)
|
||||
// Ozone X11 likes to prefer custom frames, but we don't need them unless
|
||||
// on Wayland.
|
||||
if (base::FeatureList::IsEnabled(features::kWaylandWindowDecorations) &&
|
||||
!ui::OzonePlatform::GetInstance()
|
||||
->GetPlatformRuntimeProperties()
|
||||
.supports_server_side_window_decorations) {
|
||||
has_client_frame_ = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
WindowList::AddWindow(this);
|
||||
}
|
||||
|
||||
@@ -144,16 +161,16 @@ void NativeWindow::InitFromOptions(const gin_helper::Dictionary& options) {
|
||||
// On Linux and Window we may already have maximum size defined.
|
||||
extensions::SizeConstraints size_constraints(
|
||||
use_content_size ? GetContentSizeConstraints() : GetSizeConstraints());
|
||||
int min_height = 0, min_width = 0;
|
||||
if (options.Get(options::kMinHeight, &min_height) ||
|
||||
options.Get(options::kMinWidth, &min_width)) {
|
||||
size_constraints.set_minimum_size(gfx::Size(min_width, min_height));
|
||||
}
|
||||
int max_height = INT_MAX, max_width = INT_MAX;
|
||||
if (options.Get(options::kMaxHeight, &max_height) ||
|
||||
options.Get(options::kMaxWidth, &max_width)) {
|
||||
size_constraints.set_maximum_size(gfx::Size(max_width, max_height));
|
||||
}
|
||||
int min_width = size_constraints.GetMinimumSize().width();
|
||||
int min_height = size_constraints.GetMinimumSize().height();
|
||||
options.Get(options::kMinWidth, &min_width);
|
||||
options.Get(options::kMinHeight, &min_height);
|
||||
size_constraints.set_minimum_size(gfx::Size(min_width, min_height));
|
||||
int max_width = size_constraints.GetMaximumSize().width();
|
||||
int max_height = size_constraints.GetMaximumSize().height();
|
||||
options.Get(options::kMaxWidth, &max_width);
|
||||
options.Get(options::kMaxHeight, &max_height);
|
||||
size_constraints.set_maximum_size(gfx::Size(max_width, max_height));
|
||||
if (use_content_size) {
|
||||
SetContentSizeConstraints(size_constraints);
|
||||
} else {
|
||||
|
||||
@@ -332,6 +332,7 @@ class NativeWindow : public base::SupportsUserData,
|
||||
bool has_frame() const { return has_frame_; }
|
||||
void set_has_frame(bool has_frame) { has_frame_ = has_frame; }
|
||||
|
||||
bool has_client_frame() const { return has_client_frame_; }
|
||||
bool transparent() const { return transparent_; }
|
||||
bool enable_larger_than_screen() const { return enable_larger_than_screen_; }
|
||||
|
||||
@@ -381,6 +382,11 @@ class NativeWindow : public base::SupportsUserData,
|
||||
// Whether window has standard frame.
|
||||
bool has_frame_ = true;
|
||||
|
||||
// Whether window has standard frame, but it's drawn by Electron (the client
|
||||
// application) instead of the OS. Currently only has meaning on Linux for
|
||||
// Wayland hosts.
|
||||
bool has_client_frame_ = false;
|
||||
|
||||
// Whether window is transparent.
|
||||
bool transparent_ = false;
|
||||
|
||||
|
||||
10
shell/browser/native_window_features.cc
Normal file
10
shell/browser/native_window_features.cc
Normal file
@@ -0,0 +1,10 @@
|
||||
// Copyright (c) 2022 Slack Technologies, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/native_window_features.h"
|
||||
|
||||
namespace features {
|
||||
const base::Feature kWaylandWindowDecorations{
|
||||
"WaylandWindowDecorations", base::FEATURE_DISABLED_BY_DEFAULT};
|
||||
}
|
||||
14
shell/browser/native_window_features.h
Normal file
14
shell/browser/native_window_features.h
Normal file
@@ -0,0 +1,14 @@
|
||||
// Copyright (c) 2022 Slack Technologies, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ELECTRON_SHELL_BROWSER_NATIVE_WINDOW_FEATURES_H_
|
||||
#define ELECTRON_SHELL_BROWSER_NATIVE_WINDOW_FEATURES_H_
|
||||
|
||||
#include "base/feature_list.h"
|
||||
|
||||
namespace features {
|
||||
extern const base::Feature kWaylandWindowDecorations;
|
||||
}
|
||||
|
||||
#endif // ELECTRON_SHELL_BROWSER_NATIVE_WINDOW_FEATURES_H_
|
||||
@@ -295,12 +295,12 @@ NativeWindowMac::NativeWindowMac(const gin_helper::Dictionary& options,
|
||||
|
||||
NSUInteger styleMask = NSWindowStyleMaskTitled;
|
||||
|
||||
// The NSWindowStyleMaskFullSizeContentView style removes rounded corners
|
||||
// for framless window.
|
||||
// Removing NSWindowStyleMaskTitled removes window title, which removes
|
||||
// rounded corners of window.
|
||||
bool rounded_corner = true;
|
||||
options.Get(options::kRoundedCorners, &rounded_corner);
|
||||
if (!rounded_corner && !has_frame())
|
||||
styleMask = NSWindowStyleMaskFullSizeContentView;
|
||||
styleMask = 0;
|
||||
|
||||
if (minimizable)
|
||||
styleMask |= NSMiniaturizableWindowMask;
|
||||
@@ -1350,7 +1350,7 @@ void NativeWindowMac::UpdateVibrancyRadii(bool fullscreen) {
|
||||
|
||||
if (vibrantView != nil && !vibrancy_type_.empty()) {
|
||||
const bool no_rounded_corner =
|
||||
[window_ styleMask] & NSWindowStyleMaskFullSizeContentView;
|
||||
!([window_ styleMask] & NSWindowStyleMaskTitled);
|
||||
if (!has_frame() && !is_modal() && !no_rounded_corner) {
|
||||
CGFloat radius;
|
||||
if (fullscreen) {
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "content/public/browser/desktop_media_id.h"
|
||||
#include "shell/browser/api/electron_api_web_contents.h"
|
||||
#include "shell/browser/native_browser_view_views.h"
|
||||
#include "shell/browser/native_window_features.h"
|
||||
#include "shell/browser/ui/drag_util.h"
|
||||
#include "shell/browser/ui/inspectable_web_contents.h"
|
||||
#include "shell/browser/ui/inspectable_web_contents_view.h"
|
||||
@@ -47,9 +48,11 @@
|
||||
#include "base/strings/string_util.h"
|
||||
#include "shell/browser/browser.h"
|
||||
#include "shell/browser/linux/unity_service.h"
|
||||
#include "shell/browser/ui/electron_desktop_window_tree_host_linux.h"
|
||||
#include "shell/browser/ui/views/client_frame_view_linux.h"
|
||||
#include "shell/browser/ui/views/frameless_view.h"
|
||||
#include "shell/browser/ui/views/native_frame_view.h"
|
||||
#include "ui/views/widget/desktop_aura/desktop_window_tree_host_linux.h"
|
||||
#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
|
||||
#include "ui/views/window/native_frame_view.h"
|
||||
|
||||
#if defined(USE_X11)
|
||||
@@ -78,7 +81,6 @@
|
||||
#include "ui/display/screen.h"
|
||||
#include "ui/display/win/screen_win.h"
|
||||
#include "ui/gfx/color_utils.h"
|
||||
#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
|
||||
#endif
|
||||
|
||||
namespace electron {
|
||||
@@ -227,9 +229,10 @@ NativeWindowViews::NativeWindowViews(const gin_helper::Dictionary& options,
|
||||
params.bounds = bounds;
|
||||
params.delegate = this;
|
||||
params.type = views::Widget::InitParams::TYPE_WINDOW;
|
||||
params.remove_standard_frame = !has_frame();
|
||||
params.remove_standard_frame = !has_frame() || has_client_frame();
|
||||
|
||||
if (transparent())
|
||||
// If a client frame, we need to draw our own shadows.
|
||||
if (transparent() || has_client_frame())
|
||||
params.opacity = views::Widget::InitParams::WindowOpacity::kTranslucent;
|
||||
|
||||
// The given window is most likely not rectangular since it uses
|
||||
@@ -253,6 +256,13 @@ NativeWindowViews::NativeWindowViews(const gin_helper::Dictionary& options,
|
||||
// Set WM_CLASS.
|
||||
params.wm_class_name = base::ToLowerASCII(name);
|
||||
params.wm_class_class = name;
|
||||
|
||||
if (base::FeatureList::IsEnabled(features::kWaylandWindowDecorations)) {
|
||||
auto* native_widget = new views::DesktopNativeWidgetAura(widget());
|
||||
params.native_widget = native_widget;
|
||||
params.desktop_window_tree_host =
|
||||
new ElectronDesktopWindowTreeHostLinux(this, native_widget);
|
||||
}
|
||||
#endif
|
||||
|
||||
widget()->Init(std::move(params));
|
||||
@@ -337,7 +347,7 @@ NativeWindowViews::NativeWindowViews(const gin_helper::Dictionary& options,
|
||||
::SetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE, ex_style);
|
||||
#endif
|
||||
|
||||
if (has_frame()) {
|
||||
if (has_frame() && !has_client_frame()) {
|
||||
// TODO(zcbenz): This was used to force using native frame on Windows 2003,
|
||||
// we should check whether setting it in InitParams can work.
|
||||
widget()->set_frame_type(views::Widget::FrameType::kForceNative);
|
||||
@@ -584,6 +594,7 @@ void NativeWindowViews::Unmaximize() {
|
||||
#if defined(OS_WIN)
|
||||
if (transparent()) {
|
||||
SetBounds(restore_bounds_, false);
|
||||
NotifyWindowUnmaximize();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@@ -1553,7 +1564,7 @@ bool NativeWindowViews::ShouldDescendIntoChildForEventHandling(
|
||||
return false;
|
||||
|
||||
// And the events on border for dragging resizable frameless window.
|
||||
if (!has_frame() && resizable_) {
|
||||
if ((!has_frame() || has_client_frame()) && resizable_) {
|
||||
auto* frame =
|
||||
static_cast<FramelessView*>(widget()->non_client_view()->frame_view());
|
||||
return frame->ResizingBorderHitTest(location) == HTNOWHERE;
|
||||
@@ -1573,10 +1584,12 @@ NativeWindowViews::CreateNonClientFrameView(views::Widget* widget) {
|
||||
frame_view->Init(this, widget);
|
||||
return frame_view;
|
||||
#else
|
||||
if (has_frame()) {
|
||||
if (has_frame() && !has_client_frame()) {
|
||||
return std::make_unique<NativeFrameView>(this, widget);
|
||||
} else {
|
||||
auto frame_view = std::make_unique<FramelessView>();
|
||||
auto frame_view = has_frame() && has_client_frame()
|
||||
? std::make_unique<ClientFrameViewLinux>()
|
||||
: std::make_unique<FramelessView>();
|
||||
frame_view->Init(this, widget);
|
||||
return frame_view;
|
||||
}
|
||||
|
||||
@@ -187,6 +187,7 @@ void NativeWindowViews::Maximize() {
|
||||
auto display = display::Screen::GetScreen()->GetDisplayNearestWindow(
|
||||
GetNativeWindow());
|
||||
SetBounds(display.work_area(), false);
|
||||
NotifyWindowMaximize();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -50,8 +50,8 @@ END
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 18,0,0,20220125
|
||||
PRODUCTVERSION 18,0,0,20220125
|
||||
FILEVERSION 18,0,0,1
|
||||
PRODUCTVERSION 18,0,0,1
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
||||
@@ -95,36 +95,18 @@ void SerialChooserContext::GrantPortPermission(
|
||||
const device::mojom::SerialPortInfo& port,
|
||||
content::RenderFrameHost* render_frame_host) {
|
||||
base::Value value = PortInfoToValue(port);
|
||||
port_info_.insert({port.token, value.Clone()});
|
||||
|
||||
if (CanStorePersistentEntry(port)) {
|
||||
auto* web_contents =
|
||||
content::WebContents::FromRenderFrameHost(render_frame_host);
|
||||
auto* permission_helper =
|
||||
WebContentsPermissionHelper::FromWebContents(web_contents);
|
||||
permission_helper->GrantSerialPortPermission(origin, std::move(value),
|
||||
render_frame_host);
|
||||
return;
|
||||
}
|
||||
|
||||
ephemeral_ports_[origin].insert(port.token);
|
||||
auto* web_contents =
|
||||
content::WebContents::FromRenderFrameHost(render_frame_host);
|
||||
auto* permission_helper =
|
||||
WebContentsPermissionHelper::FromWebContents(web_contents);
|
||||
permission_helper->GrantSerialPortPermission(origin, std::move(value),
|
||||
render_frame_host);
|
||||
}
|
||||
|
||||
bool SerialChooserContext::HasPortPermission(
|
||||
const url::Origin& origin,
|
||||
const device::mojom::SerialPortInfo& port,
|
||||
content::RenderFrameHost* render_frame_host) {
|
||||
auto it = ephemeral_ports_.find(origin);
|
||||
if (it != ephemeral_ports_.end()) {
|
||||
const std::set<base::UnguessableToken> ports = it->second;
|
||||
if (base::Contains(ports, port.token))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!CanStorePersistentEntry(port)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto* web_contents =
|
||||
content::WebContents::FromRenderFrameHost(render_frame_host);
|
||||
auto* permission_helper =
|
||||
@@ -194,8 +176,6 @@ void SerialChooserContext::OnPortRemoved(
|
||||
device::mojom::SerialPortInfoPtr port) {
|
||||
for (auto& observer : port_observer_list_)
|
||||
observer.OnPortRemoved(*port);
|
||||
|
||||
port_info_.erase(port->token);
|
||||
}
|
||||
|
||||
void SerialChooserContext::EnsurePortManagerConnection() {
|
||||
@@ -221,10 +201,6 @@ void SerialChooserContext::SetUpPortManagerConnection(
|
||||
void SerialChooserContext::OnPortManagerConnectionError() {
|
||||
port_manager_.reset();
|
||||
client_receiver_.reset();
|
||||
|
||||
port_info_.clear();
|
||||
|
||||
ephemeral_ports_.clear();
|
||||
}
|
||||
|
||||
} // namespace electron
|
||||
|
||||
@@ -82,12 +82,6 @@ class SerialChooserContext : public KeyedService,
|
||||
mojo::PendingRemote<device::mojom::SerialPortManager> manager);
|
||||
void OnPortManagerConnectionError();
|
||||
|
||||
// Tracks the set of ports to which an origin has access to.
|
||||
std::map<url::Origin, std::set<base::UnguessableToken>> ephemeral_ports_;
|
||||
|
||||
// Holds information about ports in |ephemeral_ports_|.
|
||||
std::map<base::UnguessableToken, base::Value> port_info_;
|
||||
|
||||
mojo::Remote<device::mojom::SerialPortManager> port_manager_;
|
||||
mojo::Receiver<device::mojom::SerialPortManagerClient> client_receiver_{this};
|
||||
base::ObserverList<PortObserver> port_observer_list_;
|
||||
|
||||
@@ -159,6 +159,15 @@ bool ScopedDisableResize::disable_resize_ = false;
|
||||
return [[self contentView] superview];
|
||||
}
|
||||
|
||||
- (BOOL)validateUserInterfaceItem:(id<NSValidatedUserInterfaceItem>)item {
|
||||
// By default "Close Window" is always disabled when window has no title, to
|
||||
// support closing a window without title we need to manually do menu item
|
||||
// validation. This code path is used by the "roundedCorners" option.
|
||||
if ([item action] == @selector(performClose:))
|
||||
return shell_->IsClosable();
|
||||
return [super validateUserInterfaceItem:item];
|
||||
}
|
||||
|
||||
// By overriding this built-in method the corners of the vibrant view (if set)
|
||||
// will be smooth.
|
||||
- (NSImage*)_cornerMask {
|
||||
@@ -195,7 +204,10 @@ bool ScopedDisableResize::disable_resize_ = false;
|
||||
if (shell_->title_bar_style() ==
|
||||
electron::NativeWindowMac::TitleBarStyle::kCustomButtonsOnHover) {
|
||||
[[self delegate] windowShouldClose:self];
|
||||
} else if (shell_->IsSimpleFullScreen()) {
|
||||
} else if (!([self styleMask] & NSWindowStyleMaskTitled)) {
|
||||
// performClose does not work for windows without title, so we have to
|
||||
// emulate its behavior. This code path is used by "simpleFullscreen" and
|
||||
// "roundedCorners" options.
|
||||
if ([[self delegate] respondsToSelector:@selector(windowShouldClose:)]) {
|
||||
if (![[self delegate] windowShouldClose:self])
|
||||
return;
|
||||
|
||||
149
shell/browser/ui/electron_desktop_window_tree_host_linux.cc
Normal file
149
shell/browser/ui/electron_desktop_window_tree_host_linux.cc
Normal file
@@ -0,0 +1,149 @@
|
||||
// Copyright (c) 2021 Ryan Gonzalez.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
// Portions of this file are sourced from
|
||||
// chrome/browser/ui/views/frame/browser_desktop_window_tree_host_linux.cc,
|
||||
// Copyright (c) 2019 The Chromium Authors,
|
||||
// which is governed by a BSD-style license
|
||||
|
||||
#include "shell/browser/ui/electron_desktop_window_tree_host_linux.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "base/i18n/rtl.h"
|
||||
#include "shell/browser/ui/views/client_frame_view_linux.h"
|
||||
#include "ui/gfx/geometry/rect.h"
|
||||
#include "ui/gfx/geometry/skia_conversions.h"
|
||||
#include "ui/platform_window/platform_window.h"
|
||||
#include "ui/views/linux_ui/linux_ui.h"
|
||||
#include "ui/views/widget/desktop_aura/desktop_window_tree_host.h"
|
||||
#include "ui/views/widget/desktop_aura/desktop_window_tree_host_linux.h"
|
||||
#include "ui/views/window/non_client_view.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
ElectronDesktopWindowTreeHostLinux::ElectronDesktopWindowTreeHostLinux(
|
||||
NativeWindowViews* native_window_view,
|
||||
views::DesktopNativeWidgetAura* desktop_native_widget_aura)
|
||||
: views::DesktopWindowTreeHostLinux(native_window_view->widget(),
|
||||
desktop_native_widget_aura),
|
||||
native_window_view_(native_window_view) {}
|
||||
|
||||
ElectronDesktopWindowTreeHostLinux::~ElectronDesktopWindowTreeHostLinux() =
|
||||
default;
|
||||
|
||||
bool ElectronDesktopWindowTreeHostLinux::SupportsClientFrameShadow() const {
|
||||
return platform_window()->CanSetDecorationInsets() &&
|
||||
platform_window()->IsTranslucentWindowOpacitySupported();
|
||||
}
|
||||
|
||||
void ElectronDesktopWindowTreeHostLinux::OnWidgetInitDone() {
|
||||
views::DesktopWindowTreeHostLinux::OnWidgetInitDone();
|
||||
UpdateFrameHints();
|
||||
}
|
||||
|
||||
void ElectronDesktopWindowTreeHostLinux::OnBoundsChanged(
|
||||
const BoundsChange& change) {
|
||||
views::DesktopWindowTreeHostLinux::OnBoundsChanged(change);
|
||||
UpdateFrameHints();
|
||||
}
|
||||
|
||||
void ElectronDesktopWindowTreeHostLinux::OnWindowStateChanged(
|
||||
ui::PlatformWindowState old_state,
|
||||
ui::PlatformWindowState new_state) {
|
||||
views::DesktopWindowTreeHostLinux::OnWindowStateChanged(old_state, new_state);
|
||||
UpdateFrameHints();
|
||||
}
|
||||
|
||||
void ElectronDesktopWindowTreeHostLinux::OnNativeThemeUpdated(
|
||||
ui::NativeTheme* observed_theme) {
|
||||
UpdateFrameHints();
|
||||
}
|
||||
|
||||
void ElectronDesktopWindowTreeHostLinux::OnDeviceScaleFactorChanged() {
|
||||
UpdateFrameHints();
|
||||
}
|
||||
|
||||
void ElectronDesktopWindowTreeHostLinux::UpdateFrameHints() {
|
||||
if (SupportsClientFrameShadow() && native_window_view_->has_frame() &&
|
||||
native_window_view_->has_client_frame()) {
|
||||
UpdateClientDecorationHints(static_cast<ClientFrameViewLinux*>(
|
||||
native_window_view_->widget()->non_client_view()->frame_view()));
|
||||
}
|
||||
|
||||
SizeConstraintsChanged();
|
||||
}
|
||||
|
||||
void ElectronDesktopWindowTreeHostLinux::UpdateClientDecorationHints(
|
||||
ClientFrameViewLinux* view) {
|
||||
ui::PlatformWindow* window = platform_window();
|
||||
bool showing_frame = !native_window_view_->IsFullscreen();
|
||||
float scale = device_scale_factor();
|
||||
|
||||
bool should_set_opaque_region = window->IsTranslucentWindowOpacitySupported();
|
||||
|
||||
gfx::Insets insets;
|
||||
gfx::Insets input_insets;
|
||||
if (showing_frame) {
|
||||
insets = view->GetBorderDecorationInsets();
|
||||
if (base::i18n::IsRTL()) {
|
||||
insets.Set(insets.top(), insets.right(), insets.bottom(), insets.left());
|
||||
}
|
||||
|
||||
input_insets = view->GetInputInsets();
|
||||
}
|
||||
|
||||
gfx::Insets scaled_insets = gfx::ScaleToCeiledInsets(insets, scale);
|
||||
window->SetDecorationInsets(&scaled_insets);
|
||||
|
||||
gfx::Rect input_bounds(view->GetWidget()->GetWindowBoundsInScreen().size());
|
||||
input_bounds.Inset(insets + input_insets);
|
||||
gfx::Rect scaled_bounds = gfx::ScaleToEnclosingRect(input_bounds, scale);
|
||||
window->SetInputRegion(&scaled_bounds);
|
||||
|
||||
if (should_set_opaque_region) {
|
||||
// The opaque region is a list of rectangles that contain only fully
|
||||
// opaque pixels of the window. We need to convert the clipping
|
||||
// rounded-rect into this format.
|
||||
SkRRect rrect = view->GetRoundedWindowContentBounds();
|
||||
gfx::RectF rectf(view->GetWindowContentBounds());
|
||||
rectf.Scale(scale);
|
||||
// It is acceptable to omit some pixels that are opaque, but the region
|
||||
// must not include any translucent pixels. Therefore, we must
|
||||
// conservatively scale to the enclosed rectangle.
|
||||
gfx::Rect rect = gfx::ToEnclosedRect(rectf);
|
||||
|
||||
// Create the initial region from the clipping rectangle without rounded
|
||||
// corners.
|
||||
SkRegion region(gfx::RectToSkIRect(rect));
|
||||
|
||||
// Now subtract out the small rectangles that cover the corners.
|
||||
struct {
|
||||
SkRRect::Corner corner;
|
||||
bool left;
|
||||
bool upper;
|
||||
} kCorners[] = {
|
||||
{SkRRect::kUpperLeft_Corner, true, true},
|
||||
{SkRRect::kUpperRight_Corner, false, true},
|
||||
{SkRRect::kLowerLeft_Corner, true, false},
|
||||
{SkRRect::kLowerRight_Corner, false, false},
|
||||
};
|
||||
for (const auto& corner : kCorners) {
|
||||
auto radii = rrect.radii(corner.corner);
|
||||
auto rx = std::ceil(scale * radii.x());
|
||||
auto ry = std::ceil(scale * radii.y());
|
||||
auto corner_rect = SkIRect::MakeXYWH(
|
||||
corner.left ? rect.x() : rect.right() - rx,
|
||||
corner.upper ? rect.y() : rect.bottom() - ry, rx, ry);
|
||||
region.op(corner_rect, SkRegion::kDifference_Op);
|
||||
}
|
||||
|
||||
// Convert the region to a list of rectangles.
|
||||
std::vector<gfx::Rect> opaque_region;
|
||||
for (SkRegion::Iterator i(region); !i.done(); i.next())
|
||||
opaque_region.push_back(gfx::SkIRectToRect(i.rect()));
|
||||
window->SetOpaqueRegion(&opaque_region);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace electron
|
||||
71
shell/browser/ui/electron_desktop_window_tree_host_linux.h
Normal file
71
shell/browser/ui/electron_desktop_window_tree_host_linux.h
Normal file
@@ -0,0 +1,71 @@
|
||||
// Copyright (c) 2021 Ryan Gonzalez.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
// Portions of this file are sourced from
|
||||
// chrome/browser/ui/views/frame/browser_desktop_window_tree_host_linux.h,
|
||||
// Copyright (c) 2019 The Chromium Authors,
|
||||
// which is governed by a BSD-style license
|
||||
|
||||
#ifndef ELECTRON_SHELL_BROWSER_UI_ELECTRON_DESKTOP_WINDOW_TREE_HOST_LINUX_H_
|
||||
#define ELECTRON_SHELL_BROWSER_UI_ELECTRON_DESKTOP_WINDOW_TREE_HOST_LINUX_H_
|
||||
|
||||
#include "base/scoped_observation.h"
|
||||
#include "shell/browser/native_window_views.h"
|
||||
#include "shell/browser/ui/views/client_frame_view_linux.h"
|
||||
#include "ui/native_theme/native_theme_observer.h"
|
||||
#include "ui/views/linux_ui/device_scale_factor_observer.h"
|
||||
#include "ui/views/widget/desktop_aura/desktop_window_tree_host_linux.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
class ElectronDesktopWindowTreeHostLinux
|
||||
: public views::DesktopWindowTreeHostLinux,
|
||||
public ui::NativeThemeObserver,
|
||||
public views::DeviceScaleFactorObserver {
|
||||
public:
|
||||
ElectronDesktopWindowTreeHostLinux(
|
||||
NativeWindowViews* native_window_view,
|
||||
views::DesktopNativeWidgetAura* desktop_native_widget_aura);
|
||||
~ElectronDesktopWindowTreeHostLinux() override;
|
||||
|
||||
// disable copy
|
||||
ElectronDesktopWindowTreeHostLinux(
|
||||
const ElectronDesktopWindowTreeHostLinux&) = delete;
|
||||
ElectronDesktopWindowTreeHostLinux& operator=(
|
||||
const ElectronDesktopWindowTreeHostLinux&) = delete;
|
||||
|
||||
bool SupportsClientFrameShadow() const;
|
||||
|
||||
protected:
|
||||
// views::DesktopWindowTreeHostLinuxImpl:
|
||||
void OnWidgetInitDone() override;
|
||||
|
||||
// ui::PlatformWindowDelegate
|
||||
void OnBoundsChanged(const BoundsChange& change) override;
|
||||
void OnWindowStateChanged(ui::PlatformWindowState old_state,
|
||||
ui::PlatformWindowState new_state) override;
|
||||
|
||||
// ui::NativeThemeObserver:
|
||||
void OnNativeThemeUpdated(ui::NativeTheme* observed_theme) override;
|
||||
|
||||
// views::OnDeviceScaleFactorChanged:
|
||||
void OnDeviceScaleFactorChanged() override;
|
||||
|
||||
private:
|
||||
void UpdateFrameHints();
|
||||
void UpdateClientDecorationHints(ClientFrameViewLinux* view);
|
||||
|
||||
NativeWindowViews* native_window_view_; // weak ref
|
||||
|
||||
base::ScopedObservation<ui::NativeTheme, ui::NativeThemeObserver>
|
||||
theme_observation_{this};
|
||||
base::ScopedObservation<views::LinuxUI,
|
||||
views::DeviceScaleFactorObserver,
|
||||
&views::LinuxUI::AddDeviceScaleFactorObserver,
|
||||
&views::LinuxUI::RemoveDeviceScaleFactorObserver>
|
||||
scale_observation_{this};
|
||||
};
|
||||
|
||||
} // namespace electron
|
||||
|
||||
#endif // ELECTRON_SHELL_BROWSER_UI_ELECTRON_DESKTOP_WINDOW_TREE_HOST_LINUX_H_
|
||||
463
shell/browser/ui/views/client_frame_view_linux.cc
Normal file
463
shell/browser/ui/views/client_frame_view_linux.cc
Normal file
@@ -0,0 +1,463 @@
|
||||
// Copyright (c) 2021 Ryan Gonzalez.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/ui/views/client_frame_view_linux.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "cc/paint/paint_filter.h"
|
||||
#include "cc/paint/paint_flags.h"
|
||||
#include "shell/browser/native_window_views.h"
|
||||
#include "shell/browser/ui/electron_desktop_window_tree_host_linux.h"
|
||||
#include "shell/browser/ui/views/frameless_view.h"
|
||||
#include "ui/base/hit_test.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
#include "ui/gfx/canvas.h"
|
||||
#include "ui/gfx/font_list.h"
|
||||
#include "ui/gfx/geometry/insets.h"
|
||||
#include "ui/gfx/geometry/rect.h"
|
||||
#include "ui/gfx/geometry/skia_conversions.h"
|
||||
#include "ui/gfx/skia_util.h"
|
||||
#include "ui/gfx/text_constants.h"
|
||||
#include "ui/gtk/gtk_compat.h" // nogncheck
|
||||
#include "ui/gtk/gtk_util.h"
|
||||
#include "ui/native_theme/native_theme.h"
|
||||
#include "ui/strings/grit/ui_strings.h"
|
||||
#include "ui/views/controls/button/image_button.h"
|
||||
#include "ui/views/linux_ui/linux_ui.h"
|
||||
#include "ui/views/linux_ui/nav_button_provider.h"
|
||||
#include "ui/views/style/typography.h"
|
||||
#include "ui/views/widget/widget.h"
|
||||
#include "ui/views/window/frame_buttons.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
namespace {
|
||||
|
||||
// These values should be the same as Chromium uses.
|
||||
constexpr int kResizeOutsideBorderSize = 10;
|
||||
constexpr int kResizeInsideBoundsSize = 5;
|
||||
|
||||
} // namespace
|
||||
|
||||
// static
|
||||
const char ClientFrameViewLinux::kViewClassName[] = "ClientFrameView";
|
||||
|
||||
ClientFrameViewLinux::ClientFrameViewLinux()
|
||||
: theme_(ui::NativeTheme::GetInstanceForNativeUi()),
|
||||
nav_button_provider_(
|
||||
views::LinuxUI::instance()->CreateNavButtonProvider()),
|
||||
nav_buttons_{
|
||||
NavButton{views::NavButtonProvider::FrameButtonDisplayType::kClose,
|
||||
views::FrameButton::kClose, &views::Widget::Close,
|
||||
IDS_APP_ACCNAME_CLOSE, HTCLOSE},
|
||||
NavButton{views::NavButtonProvider::FrameButtonDisplayType::kMaximize,
|
||||
views::FrameButton::kMaximize, &views::Widget::Maximize,
|
||||
IDS_APP_ACCNAME_MAXIMIZE, HTMAXBUTTON},
|
||||
NavButton{views::NavButtonProvider::FrameButtonDisplayType::kRestore,
|
||||
views::FrameButton::kMaximize, &views::Widget::Restore,
|
||||
IDS_APP_ACCNAME_RESTORE, HTMAXBUTTON},
|
||||
NavButton{views::NavButtonProvider::FrameButtonDisplayType::kMinimize,
|
||||
views::FrameButton::kMinimize, &views::Widget::Minimize,
|
||||
IDS_APP_ACCNAME_MINIMIZE, HTMINBUTTON},
|
||||
},
|
||||
trailing_frame_buttons_{views::FrameButton::kMinimize,
|
||||
views::FrameButton::kMaximize,
|
||||
views::FrameButton::kClose} {
|
||||
for (auto& button : nav_buttons_) {
|
||||
button.button = new views::ImageButton();
|
||||
button.button->SetImageVerticalAlignment(views::ImageButton::ALIGN_MIDDLE);
|
||||
button.button->SetAccessibleName(
|
||||
l10n_util::GetStringUTF16(button.accessibility_id));
|
||||
AddChildView(button.button);
|
||||
}
|
||||
|
||||
title_ = new views::Label();
|
||||
title_->SetSubpixelRenderingEnabled(false);
|
||||
title_->SetAutoColorReadabilityEnabled(false);
|
||||
title_->SetHorizontalAlignment(gfx::ALIGN_CENTER);
|
||||
title_->SetVerticalAlignment(gfx::ALIGN_MIDDLE);
|
||||
title_->SetTextStyle(views::style::STYLE_TAB_ACTIVE);
|
||||
AddChildView(title_);
|
||||
|
||||
native_theme_observer_.Observe(theme_);
|
||||
window_button_order_observer_.Observe(views::LinuxUI::instance());
|
||||
}
|
||||
|
||||
ClientFrameViewLinux::~ClientFrameViewLinux() {
|
||||
views::LinuxUI::instance()->RemoveWindowButtonOrderObserver(this);
|
||||
theme_->RemoveObserver(this);
|
||||
}
|
||||
|
||||
void ClientFrameViewLinux::Init(NativeWindowViews* window,
|
||||
views::Widget* frame) {
|
||||
FramelessView::Init(window, frame);
|
||||
|
||||
// Unretained() is safe because the subscription is saved into an instance
|
||||
// member and thus will be cancelled upon the instance's destruction.
|
||||
paint_as_active_changed_subscription_ =
|
||||
frame_->RegisterPaintAsActiveChangedCallback(base::BindRepeating(
|
||||
&ClientFrameViewLinux::PaintAsActiveChanged, base::Unretained(this)));
|
||||
|
||||
auto* tree_host = static_cast<ElectronDesktopWindowTreeHostLinux*>(
|
||||
ElectronDesktopWindowTreeHostLinux::GetHostForWidget(
|
||||
window->GetAcceleratedWidget()));
|
||||
host_supports_client_frame_shadow_ = tree_host->SupportsClientFrameShadow();
|
||||
|
||||
frame_provider_ = views::LinuxUI::instance()->GetWindowFrameProvider(
|
||||
!host_supports_client_frame_shadow_);
|
||||
|
||||
UpdateWindowTitle();
|
||||
|
||||
for (auto& button : nav_buttons_) {
|
||||
// Unretained() is safe because the buttons are added as children to, and
|
||||
// thus owned by, this view. Thus, the buttons themselves will be destroyed
|
||||
// when this view is destroyed, and the frame's life must never outlive the
|
||||
// view.
|
||||
button.button->SetCallback(
|
||||
base::BindRepeating(button.callback, base::Unretained(frame)));
|
||||
}
|
||||
|
||||
UpdateThemeValues();
|
||||
}
|
||||
|
||||
gfx::Insets ClientFrameViewLinux::GetBorderDecorationInsets() const {
|
||||
return frame_provider_->GetFrameThicknessDip();
|
||||
}
|
||||
|
||||
gfx::Insets ClientFrameViewLinux::GetInputInsets() const {
|
||||
return gfx::Insets(
|
||||
host_supports_client_frame_shadow_ ? -kResizeOutsideBorderSize : 0);
|
||||
}
|
||||
|
||||
gfx::Rect ClientFrameViewLinux::GetWindowContentBounds() const {
|
||||
gfx::Rect content_bounds = bounds();
|
||||
content_bounds.Inset(GetBorderDecorationInsets());
|
||||
return content_bounds;
|
||||
}
|
||||
|
||||
SkRRect ClientFrameViewLinux::GetRoundedWindowContentBounds() const {
|
||||
SkRect rect = gfx::RectToSkRect(GetWindowContentBounds());
|
||||
SkRRect rrect;
|
||||
|
||||
if (!frame_->IsMaximized()) {
|
||||
SkPoint round_point{theme_values_.window_border_radius,
|
||||
theme_values_.window_border_radius};
|
||||
SkPoint radii[] = {round_point, round_point, {}, {}};
|
||||
rrect.setRectRadii(rect, radii);
|
||||
} else {
|
||||
rrect.setRect(rect);
|
||||
}
|
||||
|
||||
return rrect;
|
||||
}
|
||||
|
||||
void ClientFrameViewLinux::OnNativeThemeUpdated(
|
||||
ui::NativeTheme* observed_theme) {
|
||||
UpdateThemeValues();
|
||||
}
|
||||
|
||||
void ClientFrameViewLinux::OnWindowButtonOrderingChange(
|
||||
const std::vector<views::FrameButton>& leading_buttons,
|
||||
const std::vector<views::FrameButton>& trailing_buttons) {
|
||||
leading_frame_buttons_ = leading_buttons;
|
||||
trailing_frame_buttons_ = trailing_buttons;
|
||||
|
||||
InvalidateLayout();
|
||||
}
|
||||
|
||||
int ClientFrameViewLinux::ResizingBorderHitTest(const gfx::Point& point) {
|
||||
return ResizingBorderHitTestImpl(
|
||||
point,
|
||||
GetBorderDecorationInsets() + gfx::Insets(kResizeInsideBoundsSize));
|
||||
}
|
||||
|
||||
gfx::Rect ClientFrameViewLinux::GetBoundsForClientView() const {
|
||||
gfx::Rect client_bounds = bounds();
|
||||
if (!frame_->IsFullscreen()) {
|
||||
client_bounds.Inset(GetBorderDecorationInsets());
|
||||
client_bounds.Inset(0, GetTitlebarBounds().height(), 0, 0);
|
||||
}
|
||||
return client_bounds;
|
||||
}
|
||||
|
||||
gfx::Rect ClientFrameViewLinux::GetWindowBoundsForClientBounds(
|
||||
const gfx::Rect& client_bounds) const {
|
||||
gfx::Insets insets = bounds().InsetsFrom(GetBoundsForClientView());
|
||||
return gfx::Rect(std::max(0, client_bounds.x() - insets.left()),
|
||||
std::max(0, client_bounds.y() - insets.top()),
|
||||
client_bounds.width() + insets.width(),
|
||||
client_bounds.height() + insets.height());
|
||||
}
|
||||
|
||||
int ClientFrameViewLinux::NonClientHitTest(const gfx::Point& point) {
|
||||
int component = ResizingBorderHitTest(point);
|
||||
if (component != HTNOWHERE) {
|
||||
return component;
|
||||
}
|
||||
|
||||
for (auto& button : nav_buttons_) {
|
||||
if (button.button->GetVisible() &&
|
||||
button.button->GetMirroredBounds().Contains(point)) {
|
||||
return button.hit_test_id;
|
||||
}
|
||||
}
|
||||
|
||||
if (GetTitlebarBounds().Contains(point)) {
|
||||
return HTCAPTION;
|
||||
}
|
||||
|
||||
return FramelessView::NonClientHitTest(point);
|
||||
}
|
||||
|
||||
void ClientFrameViewLinux::GetWindowMask(const gfx::Size& size,
|
||||
SkPath* window_mask) {
|
||||
// Nothing to do here, as transparency is used for decorations, not masks.
|
||||
}
|
||||
|
||||
void ClientFrameViewLinux::UpdateWindowTitle() {
|
||||
title_->SetText(base::UTF8ToUTF16(window_->GetTitle()));
|
||||
}
|
||||
|
||||
void ClientFrameViewLinux::SizeConstraintsChanged() {
|
||||
InvalidateLayout();
|
||||
}
|
||||
|
||||
gfx::Size ClientFrameViewLinux::CalculatePreferredSize() const {
|
||||
return SizeWithDecorations(FramelessView::CalculatePreferredSize());
|
||||
}
|
||||
|
||||
gfx::Size ClientFrameViewLinux::GetMinimumSize() const {
|
||||
return SizeWithDecorations(FramelessView::GetMinimumSize());
|
||||
}
|
||||
|
||||
gfx::Size ClientFrameViewLinux::GetMaximumSize() const {
|
||||
return SizeWithDecorations(FramelessView::GetMaximumSize());
|
||||
}
|
||||
|
||||
void ClientFrameViewLinux::Layout() {
|
||||
FramelessView::Layout();
|
||||
|
||||
if (frame_->IsFullscreen()) {
|
||||
// Just hide everything and return.
|
||||
for (NavButton& button : nav_buttons_) {
|
||||
button.button->SetVisible(false);
|
||||
}
|
||||
|
||||
title_->SetVisible(false);
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateButtonImages();
|
||||
LayoutButtons();
|
||||
|
||||
gfx::Rect title_bounds(GetTitlebarContentBounds());
|
||||
title_bounds.Inset(theme_values_.title_padding);
|
||||
|
||||
title_->SetVisible(true);
|
||||
title_->SetBounds(title_bounds.x(), title_bounds.y(), title_bounds.width(),
|
||||
title_bounds.height());
|
||||
}
|
||||
|
||||
void ClientFrameViewLinux::OnPaint(gfx::Canvas* canvas) {
|
||||
if (!frame_->IsFullscreen()) {
|
||||
frame_provider_->PaintWindowFrame(canvas, GetLocalBounds(),
|
||||
GetTitlebarBounds().bottom(),
|
||||
ShouldPaintAsActive());
|
||||
}
|
||||
}
|
||||
|
||||
const char* ClientFrameViewLinux::GetClassName() const {
|
||||
return kViewClassName;
|
||||
}
|
||||
|
||||
void ClientFrameViewLinux::PaintAsActiveChanged() {
|
||||
UpdateThemeValues();
|
||||
}
|
||||
|
||||
void ClientFrameViewLinux::UpdateThemeValues() {
|
||||
gtk::GtkCssContext window_context =
|
||||
gtk::AppendCssNodeToStyleContext({}, "GtkWindow#window.background.csd");
|
||||
gtk::GtkCssContext headerbar_context = gtk::AppendCssNodeToStyleContext(
|
||||
{}, "GtkHeaderBar#headerbar.default-decoration.titlebar");
|
||||
gtk::GtkCssContext title_context = gtk::AppendCssNodeToStyleContext(
|
||||
headerbar_context, "GtkLabel#label.title");
|
||||
gtk::GtkCssContext button_context = gtk::AppendCssNodeToStyleContext(
|
||||
headerbar_context, "GtkButton#button.image-button");
|
||||
|
||||
gtk_style_context_set_parent(headerbar_context, window_context);
|
||||
gtk_style_context_set_parent(title_context, headerbar_context);
|
||||
gtk_style_context_set_parent(button_context, headerbar_context);
|
||||
|
||||
// ShouldPaintAsActive asks the widget, so assume active if the widget is not
|
||||
// set yet.
|
||||
if (GetWidget() != nullptr && !ShouldPaintAsActive()) {
|
||||
gtk_style_context_set_state(window_context, GTK_STATE_FLAG_BACKDROP);
|
||||
gtk_style_context_set_state(headerbar_context, GTK_STATE_FLAG_BACKDROP);
|
||||
gtk_style_context_set_state(title_context, GTK_STATE_FLAG_BACKDROP);
|
||||
gtk_style_context_set_state(button_context, GTK_STATE_FLAG_BACKDROP);
|
||||
}
|
||||
|
||||
theme_values_.window_border_radius = frame_provider_->GetTopCornerRadiusDip();
|
||||
|
||||
gtk::GtkStyleContextGet(headerbar_context, "min-height",
|
||||
&theme_values_.titlebar_min_height, nullptr);
|
||||
theme_values_.titlebar_padding =
|
||||
gtk::GtkStyleContextGetPadding(headerbar_context);
|
||||
|
||||
theme_values_.title_color = gtk::GtkStyleContextGetColor(title_context);
|
||||
theme_values_.title_padding = gtk::GtkStyleContextGetPadding(title_context);
|
||||
|
||||
gtk::GtkStyleContextGet(button_context, "min-height",
|
||||
&theme_values_.button_min_size, nullptr);
|
||||
theme_values_.button_padding = gtk::GtkStyleContextGetPadding(button_context);
|
||||
|
||||
title_->SetEnabledColor(theme_values_.title_color);
|
||||
|
||||
InvalidateLayout();
|
||||
SchedulePaint();
|
||||
}
|
||||
|
||||
views::NavButtonProvider::FrameButtonDisplayType
|
||||
ClientFrameViewLinux::GetButtonTypeToSkip() const {
|
||||
return frame_->IsMaximized()
|
||||
? views::NavButtonProvider::FrameButtonDisplayType::kMaximize
|
||||
: views::NavButtonProvider::FrameButtonDisplayType::kRestore;
|
||||
}
|
||||
|
||||
void ClientFrameViewLinux::UpdateButtonImages() {
|
||||
nav_button_provider_->RedrawImages(theme_values_.button_min_size,
|
||||
frame_->IsMaximized(),
|
||||
ShouldPaintAsActive());
|
||||
|
||||
views::NavButtonProvider::FrameButtonDisplayType skip_type =
|
||||
GetButtonTypeToSkip();
|
||||
|
||||
for (NavButton& button : nav_buttons_) {
|
||||
if (button.type == skip_type) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (size_t state_id = 0; state_id < views::Button::STATE_COUNT;
|
||||
state_id++) {
|
||||
views::Button::ButtonState state =
|
||||
static_cast<views::Button::ButtonState>(state_id);
|
||||
button.button->SetImage(
|
||||
state, nav_button_provider_->GetImage(button.type, state));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ClientFrameViewLinux::LayoutButtons() {
|
||||
for (NavButton& button : nav_buttons_) {
|
||||
button.button->SetVisible(false);
|
||||
}
|
||||
|
||||
gfx::Rect remaining_content_bounds = GetTitlebarContentBounds();
|
||||
LayoutButtonsOnSide(ButtonSide::kLeading, &remaining_content_bounds);
|
||||
LayoutButtonsOnSide(ButtonSide::kTrailing, &remaining_content_bounds);
|
||||
}
|
||||
|
||||
void ClientFrameViewLinux::LayoutButtonsOnSide(
|
||||
ButtonSide side,
|
||||
gfx::Rect* remaining_content_bounds) {
|
||||
views::NavButtonProvider::FrameButtonDisplayType skip_type =
|
||||
GetButtonTypeToSkip();
|
||||
|
||||
std::vector<views::FrameButton> frame_buttons;
|
||||
|
||||
switch (side) {
|
||||
case ButtonSide::kLeading:
|
||||
frame_buttons = leading_frame_buttons_;
|
||||
break;
|
||||
case ButtonSide::kTrailing:
|
||||
frame_buttons = trailing_frame_buttons_;
|
||||
// We always lay buttons out going from the edge towards the center, but
|
||||
// they are given to us as left-to-right, so reverse them.
|
||||
std::reverse(frame_buttons.begin(), frame_buttons.end());
|
||||
break;
|
||||
default:
|
||||
NOTREACHED();
|
||||
}
|
||||
|
||||
for (views::FrameButton frame_button : frame_buttons) {
|
||||
auto* button = std::find_if(
|
||||
nav_buttons_.begin(), nav_buttons_.end(), [&](const NavButton& test) {
|
||||
return test.type != skip_type && test.frame_button == frame_button;
|
||||
});
|
||||
CHECK(button != nav_buttons_.end())
|
||||
<< "Failed to find frame button: " << static_cast<int>(frame_button);
|
||||
|
||||
if (button->type == skip_type) {
|
||||
continue;
|
||||
}
|
||||
|
||||
button->button->SetVisible(true);
|
||||
|
||||
int button_width = theme_values_.button_min_size;
|
||||
int next_button_offset =
|
||||
button_width + nav_button_provider_->GetInterNavButtonSpacing();
|
||||
|
||||
int x_position = 0;
|
||||
gfx::Insets inset_after_placement;
|
||||
|
||||
switch (side) {
|
||||
case ButtonSide::kLeading:
|
||||
x_position = remaining_content_bounds->x();
|
||||
inset_after_placement.set_left(next_button_offset);
|
||||
break;
|
||||
case ButtonSide::kTrailing:
|
||||
x_position = remaining_content_bounds->right() - button_width;
|
||||
inset_after_placement.set_right(next_button_offset);
|
||||
break;
|
||||
default:
|
||||
NOTREACHED();
|
||||
}
|
||||
|
||||
button->button->SetBounds(x_position, remaining_content_bounds->y(),
|
||||
button_width, remaining_content_bounds->height());
|
||||
remaining_content_bounds->Inset(inset_after_placement);
|
||||
}
|
||||
}
|
||||
|
||||
gfx::Rect ClientFrameViewLinux::GetTitlebarBounds() const {
|
||||
if (frame_->IsFullscreen()) {
|
||||
return gfx::Rect();
|
||||
}
|
||||
|
||||
int font_height = gfx::FontList().GetHeight();
|
||||
int titlebar_height =
|
||||
std::max(font_height, theme_values_.titlebar_min_height) +
|
||||
GetTitlebarContentInsets().height();
|
||||
|
||||
gfx::Insets decoration_insets = GetBorderDecorationInsets();
|
||||
|
||||
// We add the inset height here, so the .Inset() that follows won't reduce it
|
||||
// to be too small.
|
||||
gfx::Rect titlebar(width(), titlebar_height + decoration_insets.height());
|
||||
titlebar.Inset(decoration_insets);
|
||||
return titlebar;
|
||||
}
|
||||
|
||||
gfx::Insets ClientFrameViewLinux::GetTitlebarContentInsets() const {
|
||||
return theme_values_.titlebar_padding +
|
||||
nav_button_provider_->GetTopAreaSpacing();
|
||||
}
|
||||
|
||||
gfx::Rect ClientFrameViewLinux::GetTitlebarContentBounds() const {
|
||||
gfx::Rect titlebar(GetTitlebarBounds());
|
||||
titlebar.Inset(GetTitlebarContentInsets());
|
||||
return titlebar;
|
||||
}
|
||||
|
||||
gfx::Size ClientFrameViewLinux::SizeWithDecorations(gfx::Size size) const {
|
||||
gfx::Insets decoration_insets = GetBorderDecorationInsets();
|
||||
|
||||
size.Enlarge(0, GetTitlebarBounds().height());
|
||||
size.Enlarge(decoration_insets.width(), decoration_insets.height());
|
||||
return size;
|
||||
}
|
||||
|
||||
} // namespace electron
|
||||
143
shell/browser/ui/views/client_frame_view_linux.h
Normal file
143
shell/browser/ui/views/client_frame_view_linux.h
Normal file
@@ -0,0 +1,143 @@
|
||||
// Copyright (c) 2021 Ryan Gonzalez.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ELECTRON_SHELL_BROWSER_UI_VIEWS_CLIENT_FRAME_VIEW_LINUX_H_
|
||||
#define ELECTRON_SHELL_BROWSER_UI_VIEWS_CLIENT_FRAME_VIEW_LINUX_H_
|
||||
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "base/scoped_observation.h"
|
||||
#include "shell/browser/ui/views/frameless_view.h"
|
||||
#include "ui/native_theme/native_theme.h"
|
||||
#include "ui/native_theme/native_theme_observer.h"
|
||||
#include "ui/views/controls/button/image_button.h"
|
||||
#include "ui/views/controls/label.h"
|
||||
#include "ui/views/linux_ui/linux_ui.h"
|
||||
#include "ui/views/linux_ui/nav_button_provider.h"
|
||||
#include "ui/views/linux_ui/window_button_order_observer.h"
|
||||
#include "ui/views/linux_ui/window_frame_provider.h"
|
||||
#include "ui/views/widget/widget.h"
|
||||
#include "ui/views/window/frame_buttons.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
class ClientFrameViewLinux : public FramelessView,
|
||||
public ui::NativeThemeObserver,
|
||||
public views::WindowButtonOrderObserver {
|
||||
public:
|
||||
static const char kViewClassName[];
|
||||
ClientFrameViewLinux();
|
||||
~ClientFrameViewLinux() override;
|
||||
|
||||
void Init(NativeWindowViews* window, views::Widget* frame) override;
|
||||
|
||||
// These are here for ElectronDesktopWindowTreeHostLinux to use.
|
||||
gfx::Insets GetBorderDecorationInsets() const;
|
||||
gfx::Insets GetInputInsets() const;
|
||||
gfx::Rect GetWindowContentBounds() const;
|
||||
SkRRect GetRoundedWindowContentBounds() const;
|
||||
|
||||
protected:
|
||||
// ui::NativeThemeObserver:
|
||||
void OnNativeThemeUpdated(ui::NativeTheme* observed_theme) override;
|
||||
|
||||
// views::WindowButtonOrderObserver:
|
||||
void OnWindowButtonOrderingChange(
|
||||
const std::vector<views::FrameButton>& leading_buttons,
|
||||
const std::vector<views::FrameButton>& trailing_buttons) override;
|
||||
|
||||
// Overriden from FramelessView:
|
||||
int ResizingBorderHitTest(const gfx::Point& point) override;
|
||||
|
||||
// Overriden from views::NonClientFrameView:
|
||||
gfx::Rect GetBoundsForClientView() const override;
|
||||
gfx::Rect GetWindowBoundsForClientBounds(
|
||||
const gfx::Rect& client_bounds) const override;
|
||||
int NonClientHitTest(const gfx::Point& point) override;
|
||||
void GetWindowMask(const gfx::Size& size, SkPath* window_mask) override;
|
||||
void UpdateWindowTitle() override;
|
||||
void SizeConstraintsChanged() override;
|
||||
|
||||
// Overridden from View:
|
||||
gfx::Size CalculatePreferredSize() const override;
|
||||
gfx::Size GetMinimumSize() const override;
|
||||
gfx::Size GetMaximumSize() const override;
|
||||
void Layout() override;
|
||||
void OnPaint(gfx::Canvas* canvas) override;
|
||||
const char* GetClassName() const override;
|
||||
|
||||
private:
|
||||
static constexpr int kNavButtonCount = 4;
|
||||
|
||||
struct NavButton {
|
||||
views::NavButtonProvider::FrameButtonDisplayType type;
|
||||
views::FrameButton frame_button;
|
||||
void (views::Widget::*callback)();
|
||||
int accessibility_id;
|
||||
int hit_test_id;
|
||||
views::ImageButton* button{nullptr};
|
||||
};
|
||||
|
||||
struct ThemeValues {
|
||||
float window_border_radius;
|
||||
|
||||
int titlebar_min_height;
|
||||
gfx::Insets titlebar_padding;
|
||||
|
||||
SkColor title_color;
|
||||
gfx::Insets title_padding;
|
||||
|
||||
int button_min_size;
|
||||
gfx::Insets button_padding;
|
||||
};
|
||||
|
||||
void PaintAsActiveChanged();
|
||||
|
||||
void UpdateThemeValues();
|
||||
|
||||
enum class ButtonSide { kLeading, kTrailing };
|
||||
|
||||
views::NavButtonProvider::FrameButtonDisplayType GetButtonTypeToSkip() const;
|
||||
void UpdateButtonImages();
|
||||
void LayoutButtons();
|
||||
void LayoutButtonsOnSide(ButtonSide side,
|
||||
gfx::Rect* remaining_content_bounds);
|
||||
|
||||
gfx::Rect GetTitlebarBounds() const;
|
||||
gfx::Insets GetTitlebarContentInsets() const;
|
||||
gfx::Rect GetTitlebarContentBounds() const;
|
||||
|
||||
gfx::Size SizeWithDecorations(gfx::Size size) const;
|
||||
|
||||
ui::NativeTheme* theme_;
|
||||
ThemeValues theme_values_;
|
||||
|
||||
views::Label* title_;
|
||||
|
||||
std::unique_ptr<views::NavButtonProvider> nav_button_provider_;
|
||||
std::array<NavButton, kNavButtonCount> nav_buttons_;
|
||||
|
||||
std::vector<views::FrameButton> leading_frame_buttons_;
|
||||
std::vector<views::FrameButton> trailing_frame_buttons_;
|
||||
|
||||
bool host_supports_client_frame_shadow_ = false;
|
||||
|
||||
views::WindowFrameProvider* frame_provider_;
|
||||
|
||||
base::ScopedObservation<ui::NativeTheme, ui::NativeThemeObserver>
|
||||
native_theme_observer_{this};
|
||||
base::ScopedObservation<views::LinuxUI,
|
||||
views::WindowButtonOrderObserver,
|
||||
&views::LinuxUI::AddWindowButtonOrderObserver,
|
||||
&views::LinuxUI::RemoveWindowButtonOrderObserver>
|
||||
window_button_order_observer_{this};
|
||||
|
||||
base::CallbackListSubscription paint_as_active_changed_subscription_;
|
||||
};
|
||||
|
||||
} // namespace electron
|
||||
|
||||
#endif // ELECTRON_SHELL_BROWSER_UI_VIEWS_CLIENT_FRAME_VIEW_LINUX_H_
|
||||
@@ -33,7 +33,11 @@ void FramelessView::Init(NativeWindowViews* window, views::Widget* frame) {
|
||||
}
|
||||
|
||||
int FramelessView::ResizingBorderHitTest(const gfx::Point& point) {
|
||||
// Check the frame first, as we allow a small area overlapping the contents
|
||||
return ResizingBorderHitTestImpl(point, gfx::Insets(kResizeInsideBoundsSize));
|
||||
}
|
||||
|
||||
int FramelessView::ResizingBorderHitTestImpl(const gfx::Point& point,
|
||||
const gfx::Insets& resize_border) {
|
||||
// to be used for resize handles.
|
||||
bool can_ever_resize = frame_->widget_delegate()
|
||||
? frame_->widget_delegate()->CanResize()
|
||||
@@ -47,12 +51,11 @@ int FramelessView::ResizingBorderHitTest(const gfx::Point& point) {
|
||||
|
||||
// Don't allow overlapping resize handles when the window is maximized or
|
||||
// fullscreen, as it can't be resized in those states.
|
||||
int resize_border = frame_->IsMaximized() || frame_->IsFullscreen()
|
||||
? 0
|
||||
: kResizeInsideBoundsSize;
|
||||
return GetHTComponentForFrame(point, gfx::Insets(resize_border),
|
||||
kResizeAreaCornerSize, kResizeAreaCornerSize,
|
||||
can_ever_resize);
|
||||
bool allow_overlapping_handles =
|
||||
!frame_->IsMaximized() && !frame_->IsFullscreen();
|
||||
return GetHTComponentForFrame(
|
||||
point, allow_overlapping_handles ? resize_border : gfx::Insets(),
|
||||
kResizeAreaCornerSize, kResizeAreaCornerSize, can_ever_resize);
|
||||
}
|
||||
|
||||
gfx::Rect FramelessView::GetBoundsForClientView() const {
|
||||
|
||||
@@ -28,9 +28,14 @@ class FramelessView : public views::NonClientFrameView {
|
||||
virtual void Init(NativeWindowViews* window, views::Widget* frame);
|
||||
|
||||
// Returns whether the |point| is on frameless window's resizing border.
|
||||
int ResizingBorderHitTest(const gfx::Point& point);
|
||||
virtual int ResizingBorderHitTest(const gfx::Point& point);
|
||||
|
||||
protected:
|
||||
// Helper function for subclasses to implement ResizingBorderHitTest with a
|
||||
// custom resize inset.
|
||||
int ResizingBorderHitTestImpl(const gfx::Point& point,
|
||||
const gfx::Insets& resize_border);
|
||||
|
||||
// views::NonClientFrameView:
|
||||
gfx::Rect GetBoundsForClientView() const override;
|
||||
gfx::Rect GetWindowBoundsForClientBounds(
|
||||
|
||||
@@ -81,7 +81,7 @@ void WebViewGuestDelegate::OnZoomLevelChanged(
|
||||
api_web_contents_->GetZoomController()->SetZoomLevel(level);
|
||||
}
|
||||
// Change the default zoom factor to match the embedders' new zoom level.
|
||||
double zoom_factor = blink::PageZoomFactorToZoomLevel(level);
|
||||
double zoom_factor = blink::PageZoomLevelToZoomFactor(level);
|
||||
api_web_contents_->GetZoomController()->SetDefaultZoomFactor(zoom_factor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,6 +111,14 @@ describe('BrowserWindow module', () => {
|
||||
await closed;
|
||||
});
|
||||
|
||||
it('closes window without rounded corners', async () => {
|
||||
await closeWindow(w);
|
||||
w = new BrowserWindow({ show: false, frame: false, roundedCorners: false });
|
||||
const closed = emittedOnce(w, 'closed');
|
||||
w.close();
|
||||
await closed;
|
||||
});
|
||||
|
||||
it('should not crash if called after webContents is destroyed', () => {
|
||||
w.webContents.destroy();
|
||||
w.webContents.on('destroyed', () => w.close());
|
||||
@@ -1111,7 +1119,7 @@ describe('BrowserWindow module', () => {
|
||||
await unmaximize;
|
||||
expectBoundsEqual(w.getNormalBounds(), bounds);
|
||||
});
|
||||
it('can check transparent window maximization', async () => {
|
||||
it('correctly checks transparent window maximization state', async () => {
|
||||
w.destroy();
|
||||
w = new BrowserWindow({
|
||||
show: false,
|
||||
@@ -1120,12 +1128,12 @@ describe('BrowserWindow module', () => {
|
||||
transparent: true
|
||||
});
|
||||
|
||||
const maximize = emittedOnce(w, 'resize');
|
||||
const maximize = emittedOnce(w, 'maximize');
|
||||
w.show();
|
||||
w.maximize();
|
||||
await maximize;
|
||||
expect(w.isMaximized()).to.equal(true);
|
||||
const unmaximize = emittedOnce(w, 'resize');
|
||||
const unmaximize = emittedOnce(w, 'unmaximize');
|
||||
w.unmaximize();
|
||||
await unmaximize;
|
||||
expect(w.isMaximized()).to.equal(false);
|
||||
@@ -1641,7 +1649,15 @@ describe('BrowserWindow module', () => {
|
||||
});
|
||||
|
||||
ifdescribe(process.platform === 'darwin')('BrowserWindow.setVibrancy(type)', () => {
|
||||
afterEach(closeAllWindows);
|
||||
let appProcess: childProcess.ChildProcessWithoutNullStreams | undefined;
|
||||
|
||||
afterEach(() => {
|
||||
if (appProcess && !appProcess.killed) {
|
||||
appProcess.kill();
|
||||
appProcess = undefined;
|
||||
}
|
||||
closeAllWindows();
|
||||
});
|
||||
|
||||
it('allows setting, changing, and removing the vibrancy', () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
@@ -1660,6 +1676,15 @@ describe('BrowserWindow module', () => {
|
||||
w.setVibrancy('i-am-not-a-valid-vibrancy-type' as any);
|
||||
}).to.not.throw();
|
||||
});
|
||||
|
||||
it('Allows setting a transparent window via CSS', async () => {
|
||||
const appPath = path.join(__dirname, 'fixtures', 'apps', 'background-color-transparent');
|
||||
|
||||
appProcess = childProcess.spawn(process.execPath, [appPath]);
|
||||
|
||||
const [code] = await emittedOnce(appProcess, 'exit');
|
||||
expect(code).to.equal(0);
|
||||
});
|
||||
});
|
||||
|
||||
ifdescribe(process.platform === 'darwin')('trafficLightPosition', () => {
|
||||
@@ -3241,6 +3266,19 @@ describe('BrowserWindow module', () => {
|
||||
await maximize;
|
||||
});
|
||||
|
||||
it('emits an event when a transparent window is maximized', async () => {
|
||||
const w = new BrowserWindow({
|
||||
show: false,
|
||||
frame: false,
|
||||
transparent: true
|
||||
});
|
||||
|
||||
const maximize = emittedOnce(w, 'maximize');
|
||||
w.show();
|
||||
w.maximize();
|
||||
await maximize;
|
||||
});
|
||||
|
||||
it('emits only one event when frameless window is maximized', () => {
|
||||
const w = new BrowserWindow({ show: false, frame: false });
|
||||
let emitted = 0;
|
||||
@@ -3259,6 +3297,22 @@ describe('BrowserWindow module', () => {
|
||||
await unmaximize;
|
||||
});
|
||||
|
||||
it('emits an event when a transparent window is unmaximized', async () => {
|
||||
const w = new BrowserWindow({
|
||||
show: false,
|
||||
frame: false,
|
||||
transparent: true
|
||||
});
|
||||
|
||||
const maximize = emittedOnce(w, 'maximize');
|
||||
const unmaximize = emittedOnce(w, 'unmaximize');
|
||||
w.show();
|
||||
w.maximize();
|
||||
await maximize;
|
||||
w.unmaximize();
|
||||
await unmaximize;
|
||||
});
|
||||
|
||||
it('emits an event when window is minimized', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const minimize = emittedOnce(w, 'minimize');
|
||||
|
||||
@@ -372,7 +372,7 @@ describe('contextBridge', () => {
|
||||
try {
|
||||
root.example();
|
||||
} catch (e) {
|
||||
return e.message;
|
||||
return (e as Error).message;
|
||||
}
|
||||
});
|
||||
expect(result).equal('oh no');
|
||||
|
||||
@@ -24,7 +24,7 @@ describe('ipc module', () => {
|
||||
const result = await ipcRenderer.invoke('test', ...args);
|
||||
ipcRenderer.send('result', { result });
|
||||
} catch (e) {
|
||||
ipcRenderer.send('result', { error: e.message });
|
||||
ipcRenderer.send('result', { error: (e as Error).message });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -357,7 +357,7 @@ describe('webContents module', () => {
|
||||
});
|
||||
|
||||
it('sets appropriate error information on rejection', async () => {
|
||||
let err;
|
||||
let err: any;
|
||||
try {
|
||||
await w.loadURL('file:non-existent');
|
||||
} catch (e) {
|
||||
@@ -807,10 +807,10 @@ describe('webContents module', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('focus()', () => {
|
||||
describe('when the web contents is hidden', () => {
|
||||
describe('focus APIs', () => {
|
||||
describe('focus()', () => {
|
||||
afterEach(closeAllWindows);
|
||||
it('does not blur the focused window', async () => {
|
||||
it('does not blur the focused window when the web contents is hidden', async () => {
|
||||
const w = new BrowserWindow({ show: false, webPreferences: { nodeIntegration: true } });
|
||||
w.show();
|
||||
await w.loadURL('about:blank');
|
||||
@@ -825,6 +825,56 @@ describe('webContents module', () => {
|
||||
expect(childFocused).to.be.false();
|
||||
});
|
||||
});
|
||||
|
||||
describe('focus event', () => {
|
||||
afterEach(closeAllWindows);
|
||||
it('is triggered when web contents is focused', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
await w.loadURL('about:blank');
|
||||
const devToolsOpened = emittedOnce(w.webContents, 'devtools-opened');
|
||||
w.webContents.openDevTools();
|
||||
await devToolsOpened;
|
||||
w.webContents.devToolsWebContents!.focus();
|
||||
const focusPromise = emittedOnce(w.webContents, 'focus');
|
||||
w.webContents.focus();
|
||||
await expect(focusPromise).to.eventually.be.fulfilled();
|
||||
});
|
||||
|
||||
it('is triggered when BrowserWindow is focused', async () => {
|
||||
const window1 = new BrowserWindow({ show: false });
|
||||
const window2 = new BrowserWindow({ show: false });
|
||||
|
||||
await Promise.all([
|
||||
window1.loadURL('about:blank'),
|
||||
window2.loadURL('about:blank')
|
||||
]);
|
||||
|
||||
window1.showInactive();
|
||||
window2.showInactive();
|
||||
|
||||
let focusPromise = emittedOnce(window1.webContents, 'focus');
|
||||
window1.focus();
|
||||
await expect(focusPromise).to.eventually.be.fulfilled();
|
||||
|
||||
focusPromise = emittedOnce(window2.webContents, 'focus');
|
||||
window2.focus();
|
||||
await expect(focusPromise).to.eventually.be.fulfilled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('blur event', () => {
|
||||
afterEach(closeAllWindows);
|
||||
it('is triggered when web contents is blurred', async () => {
|
||||
const w = new BrowserWindow({ show: true });
|
||||
await w.loadURL('about:blank');
|
||||
const blurPromise = emittedOnce(w.webContents, 'blur');
|
||||
const devToolsOpened = emittedOnce(w.webContents, 'devtools-opened');
|
||||
w.webContents.openDevTools({ mode: 'detach' });
|
||||
await devToolsOpened;
|
||||
w.webContents.devToolsWebContents!.focus();
|
||||
await expect(blurPromise).to.eventually.be.fulfilled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getOSProcessId()', () => {
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>test-color-window</title>
|
||||
<style>
|
||||
body {
|
||||
background: green;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body id="body">
|
||||
<script src="./renderer.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
59
spec-main/fixtures/apps/background-color-transparent/main.js
Normal file
59
spec-main/fixtures/apps/background-color-transparent/main.js
Normal file
@@ -0,0 +1,59 @@
|
||||
const { app, BrowserWindow, desktopCapturer, ipcMain } = require('electron');
|
||||
const getColors = require('get-image-colors');
|
||||
|
||||
const colors = {};
|
||||
|
||||
// Fetch the test window.
|
||||
const getWindow = async () => {
|
||||
const sources = await desktopCapturer.getSources({ types: ['window'] });
|
||||
const filtered = sources.filter(s => s.name === 'test-color-window');
|
||||
|
||||
if (filtered.length === 0) {
|
||||
throw new Error('Could not find test window');
|
||||
}
|
||||
|
||||
return filtered[0];
|
||||
};
|
||||
|
||||
async function createWindow () {
|
||||
const mainWindow = new BrowserWindow({
|
||||
frame: false,
|
||||
transparent: true,
|
||||
vibrancy: 'under-window',
|
||||
webPreferences: {
|
||||
contextIsolation: false,
|
||||
nodeIntegration: true
|
||||
}
|
||||
});
|
||||
|
||||
await mainWindow.loadFile('index.html');
|
||||
|
||||
// Get initial green background color.
|
||||
const window = await getWindow();
|
||||
const buf = window.thumbnail.toPNG();
|
||||
const result = await getColors(buf, { count: 1, type: 'image/png' });
|
||||
colors.green = result[0].hex();
|
||||
}
|
||||
|
||||
ipcMain.on('set-transparent', async () => {
|
||||
// Get updated background color.
|
||||
const window = await getWindow();
|
||||
const buf = window.thumbnail.toPNG();
|
||||
const result = await getColors(buf, { count: 1, type: 'image/png' });
|
||||
colors.transparent = result[0].hex();
|
||||
|
||||
const { green, transparent } = colors;
|
||||
process.exit(green === transparent ? 1 : 0);
|
||||
});
|
||||
|
||||
app.whenReady().then(() => {
|
||||
createWindow();
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) createWindow();
|
||||
});
|
||||
});
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') app.quit();
|
||||
});
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"name": "background-color-transparent",
|
||||
"main": "main.js"
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
const { ipcRenderer } = require('electron');
|
||||
|
||||
window.setTimeout(async (_) => {
|
||||
document.body.style.background = 'transparent';
|
||||
|
||||
window.setTimeout(async (_) => {
|
||||
ipcRenderer.send('set-transparent');
|
||||
}, 2000);
|
||||
}, 3000);
|
||||
@@ -213,7 +213,7 @@ describe('node feature', () => {
|
||||
|
||||
ifdescribe(features.isRunAsNodeEnabled())('inspector', () => {
|
||||
let child: childProcess.ChildProcessWithoutNullStreams;
|
||||
let exitPromise: Promise<any[]>;
|
||||
let exitPromise: Promise<any[]> | null;
|
||||
|
||||
afterEach(async () => {
|
||||
if (child && exitPromise) {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
"dependencies": {
|
||||
"chai-as-promised": "^7.1.1",
|
||||
"dirty-chai": "^2.0.1",
|
||||
"get-image-colors": "^4.0.0",
|
||||
"pdfjs-dist": "^2.2.228"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,11 +77,60 @@ ajv@^6.1.0:
|
||||
json-schema-traverse "^0.4.1"
|
||||
uri-js "^4.2.2"
|
||||
|
||||
ajv@^6.12.3:
|
||||
version "6.12.6"
|
||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
|
||||
integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
|
||||
dependencies:
|
||||
fast-deep-equal "^3.1.1"
|
||||
fast-json-stable-stringify "^2.0.0"
|
||||
json-schema-traverse "^0.4.1"
|
||||
uri-js "^4.2.2"
|
||||
|
||||
asn1@~0.2.3:
|
||||
version "0.2.6"
|
||||
resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d"
|
||||
integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==
|
||||
dependencies:
|
||||
safer-buffer "~2.1.0"
|
||||
|
||||
assert-plus@1.0.0, assert-plus@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
|
||||
integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=
|
||||
|
||||
asynckit@^0.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
|
||||
integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
|
||||
|
||||
aws-sign2@~0.7.0:
|
||||
version "0.7.0"
|
||||
resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
|
||||
integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=
|
||||
|
||||
aws4@^1.8.0:
|
||||
version "1.11.0"
|
||||
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59"
|
||||
integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==
|
||||
|
||||
bcrypt-pbkdf@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e"
|
||||
integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=
|
||||
dependencies:
|
||||
tweetnacl "^0.14.3"
|
||||
|
||||
big.js@^5.2.2:
|
||||
version "5.2.2"
|
||||
resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328"
|
||||
integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==
|
||||
|
||||
boolbase@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
|
||||
integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24=
|
||||
|
||||
busboy@^0.3.1:
|
||||
version "0.3.1"
|
||||
resolved "https://registry.yarnpkg.com/busboy/-/busboy-0.3.1.tgz#170899274c5bf38aae27d5c62b71268cd585fd1b"
|
||||
@@ -89,6 +138,11 @@ busboy@^0.3.1:
|
||||
dependencies:
|
||||
dicer "0.3.0"
|
||||
|
||||
caseless@~0.12.0:
|
||||
version "0.12.0"
|
||||
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
|
||||
integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
|
||||
|
||||
chai-as-promised@^7.1.1:
|
||||
version "7.1.1"
|
||||
resolved "https://registry.yarnpkg.com/chai-as-promised/-/chai-as-promised-7.1.1.tgz#08645d825deb8696ee61725dbf590c012eb00ca0"
|
||||
@@ -101,6 +155,107 @@ check-error@^1.0.2:
|
||||
resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82"
|
||||
integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=
|
||||
|
||||
cheerio@^0.22.0:
|
||||
version "0.22.0"
|
||||
resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-0.22.0.tgz#a9baa860a3f9b595a6b81b1a86873121ed3a269e"
|
||||
integrity sha1-qbqoYKP5tZWmuBsahocxIe06Jp4=
|
||||
dependencies:
|
||||
css-select "~1.2.0"
|
||||
dom-serializer "~0.1.0"
|
||||
entities "~1.1.1"
|
||||
htmlparser2 "^3.9.1"
|
||||
lodash.assignin "^4.0.9"
|
||||
lodash.bind "^4.1.4"
|
||||
lodash.defaults "^4.0.1"
|
||||
lodash.filter "^4.4.0"
|
||||
lodash.flatten "^4.2.0"
|
||||
lodash.foreach "^4.3.0"
|
||||
lodash.map "^4.4.0"
|
||||
lodash.merge "^4.4.0"
|
||||
lodash.pick "^4.2.1"
|
||||
lodash.reduce "^4.4.0"
|
||||
lodash.reject "^4.4.0"
|
||||
lodash.some "^4.4.0"
|
||||
|
||||
chroma-js@^1.1.1:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/chroma-js/-/chroma-js-1.4.1.tgz#eb2d9c4d1ff24616be84b35119f4d26f8205f134"
|
||||
integrity sha512-jTwQiT859RTFN/vIf7s+Vl/Z2LcMrvMv3WUFmd/4u76AdlFC0NTNgqEEFPcRiHmAswPsMiQEDZLM8vX8qXpZNQ==
|
||||
|
||||
chroma-js@^2.1.0:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/chroma-js/-/chroma-js-2.1.2.tgz#1075cb9ae25bcb2017c109394168b5cf3aa500ec"
|
||||
integrity sha512-ri/ouYDWuxfus3UcaMxC1Tfp3IE9K5iQzxc2hSxbBRVNQFut1UuGAsZmiAf2mOUubzGJwgMSv9lHg+XqLaz1QQ==
|
||||
dependencies:
|
||||
cross-env "^6.0.3"
|
||||
|
||||
combined-stream@^1.0.6, combined-stream@~1.0.6:
|
||||
version "1.0.8"
|
||||
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
|
||||
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
|
||||
dependencies:
|
||||
delayed-stream "~1.0.0"
|
||||
|
||||
core-util-is@1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
||||
integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
|
||||
|
||||
cross-env@^6.0.3:
|
||||
version "6.0.3"
|
||||
resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-6.0.3.tgz#4256b71e49b3a40637a0ce70768a6ef5c72ae941"
|
||||
integrity sha512-+KqxF6LCvfhWvADcDPqo64yVIB31gv/jQulX2NGzKS/g3GEVz6/pt4wjHFtFWsHMddebWD/sDthJemzM4MaAag==
|
||||
dependencies:
|
||||
cross-spawn "^7.0.0"
|
||||
|
||||
cross-spawn@^7.0.0:
|
||||
version "7.0.3"
|
||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
|
||||
integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
|
||||
dependencies:
|
||||
path-key "^3.1.0"
|
||||
shebang-command "^2.0.0"
|
||||
which "^2.0.1"
|
||||
|
||||
css-select@~1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858"
|
||||
integrity sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=
|
||||
dependencies:
|
||||
boolbase "~1.0.0"
|
||||
css-what "2.1"
|
||||
domutils "1.5.1"
|
||||
nth-check "~1.0.1"
|
||||
|
||||
css-what@2.1:
|
||||
version "2.1.3"
|
||||
resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2"
|
||||
integrity sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==
|
||||
|
||||
cwise-compiler@^1.1.2:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/cwise-compiler/-/cwise-compiler-1.1.3.tgz#f4d667410e850d3a313a7d2db7b1e505bb034cc5"
|
||||
integrity sha1-9NZnQQ6FDToxOn0tt7HlBbsDTMU=
|
||||
dependencies:
|
||||
uniq "^1.0.0"
|
||||
|
||||
dashdash@^1.12.0:
|
||||
version "1.14.1"
|
||||
resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
|
||||
integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=
|
||||
dependencies:
|
||||
assert-plus "^1.0.0"
|
||||
|
||||
data-uri-to-buffer@0.0.3:
|
||||
version "0.0.3"
|
||||
resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-0.0.3.tgz#18ae979a6a0ca994b0625853916d2662bbae0b1a"
|
||||
integrity sha1-GK6XmmoMqZSwYlhTkW0mYruuCxo=
|
||||
|
||||
delayed-stream@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
|
||||
integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk=
|
||||
|
||||
dicer@0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/dicer/-/dicer-0.3.0.tgz#eacd98b3bfbf92e8ab5c2fdb71aaac44bb06b872"
|
||||
@@ -118,6 +273,63 @@ dirty-chai@^2.0.1:
|
||||
resolved "https://registry.yarnpkg.com/dirty-chai/-/dirty-chai-2.0.1.tgz#6b2162ef17f7943589da840abc96e75bda01aff3"
|
||||
integrity sha512-ys79pWKvDMowIDEPC6Fig8d5THiC0DJ2gmTeGzVAoEH18J8OzLud0Jh7I9IWg3NSk8x2UocznUuFmfHCXYZx9w==
|
||||
|
||||
dom-serializer@0:
|
||||
version "0.2.2"
|
||||
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51"
|
||||
integrity sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==
|
||||
dependencies:
|
||||
domelementtype "^2.0.1"
|
||||
entities "^2.0.0"
|
||||
|
||||
dom-serializer@~0.1.0:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.1.tgz#1ec4059e284babed36eec2941d4a970a189ce7c0"
|
||||
integrity sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==
|
||||
dependencies:
|
||||
domelementtype "^1.3.0"
|
||||
entities "^1.1.1"
|
||||
|
||||
domelementtype@1, domelementtype@^1.3.0, domelementtype@^1.3.1:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f"
|
||||
integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==
|
||||
|
||||
domelementtype@^2.0.1:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57"
|
||||
integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==
|
||||
|
||||
domhandler@^2.3.0:
|
||||
version "2.4.2"
|
||||
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803"
|
||||
integrity sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==
|
||||
dependencies:
|
||||
domelementtype "1"
|
||||
|
||||
domutils@1.5.1:
|
||||
version "1.5.1"
|
||||
resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf"
|
||||
integrity sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=
|
||||
dependencies:
|
||||
dom-serializer "0"
|
||||
domelementtype "1"
|
||||
|
||||
domutils@^1.5.1:
|
||||
version "1.7.0"
|
||||
resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a"
|
||||
integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==
|
||||
dependencies:
|
||||
dom-serializer "0"
|
||||
domelementtype "1"
|
||||
|
||||
ecc-jsbn@~0.1.1:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9"
|
||||
integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=
|
||||
dependencies:
|
||||
jsbn "~0.1.0"
|
||||
safer-buffer "^2.1.0"
|
||||
|
||||
"echo@file:fixtures/native-addon/echo":
|
||||
version "0.0.1"
|
||||
|
||||
@@ -126,6 +338,31 @@ emojis-list@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389"
|
||||
integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k=
|
||||
|
||||
entities@^1.1.1, entities@~1.1.1:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56"
|
||||
integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==
|
||||
|
||||
entities@^2.0.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55"
|
||||
integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==
|
||||
|
||||
extend@~3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
|
||||
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
|
||||
|
||||
extsprintf@1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
|
||||
integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=
|
||||
|
||||
extsprintf@^1.2.0:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07"
|
||||
integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==
|
||||
|
||||
fast-deep-equal@^3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4"
|
||||
@@ -136,21 +373,184 @@ fast-json-stable-stringify@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
|
||||
integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
|
||||
|
||||
forever-agent@~0.6.1:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
|
||||
integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=
|
||||
|
||||
form-data@~2.3.2:
|
||||
version "2.3.3"
|
||||
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6"
|
||||
integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==
|
||||
dependencies:
|
||||
asynckit "^0.4.0"
|
||||
combined-stream "^1.0.6"
|
||||
mime-types "^2.1.12"
|
||||
|
||||
get-image-colors@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/get-image-colors/-/get-image-colors-4.0.0.tgz#c8fe161c386b5ae6300d953eac6bccc05a56069d"
|
||||
integrity sha512-qQZ5vyqgJkQp1c8ZRwKGL03oDsyBBUKiwr4GbB2T4F+tHpfQrw1PjKMQai7jcjRdC2wIHl2rV+6ZuHKttpyk7A==
|
||||
dependencies:
|
||||
chroma-js "^2.1.0"
|
||||
get-pixels "^3.3.2"
|
||||
get-rgba-palette "^2.0.1"
|
||||
get-svg-colors "^1.5.1"
|
||||
pify "^5.0.0"
|
||||
|
||||
get-pixels@^3.3.2:
|
||||
version "3.3.3"
|
||||
resolved "https://registry.yarnpkg.com/get-pixels/-/get-pixels-3.3.3.tgz#71e2dfd4befb810b5478a61c6354800976ce01c7"
|
||||
integrity sha512-5kyGBn90i9tSMUVHTqkgCHsoWoR+/lGbl4yC83Gefyr0HLIhgSWEx/2F/3YgsZ7UpYNuM6pDhDK7zebrUJ5nXg==
|
||||
dependencies:
|
||||
data-uri-to-buffer "0.0.3"
|
||||
jpeg-js "^0.4.1"
|
||||
mime-types "^2.0.1"
|
||||
ndarray "^1.0.13"
|
||||
ndarray-pack "^1.1.1"
|
||||
node-bitmap "0.0.1"
|
||||
omggif "^1.0.5"
|
||||
parse-data-uri "^0.2.0"
|
||||
pngjs "^3.3.3"
|
||||
request "^2.44.0"
|
||||
through "^2.3.4"
|
||||
|
||||
get-rgba-palette@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/get-rgba-palette/-/get-rgba-palette-2.0.1.tgz#5ce70f75c6ef52882f54dd079e5ed68b5a2323ca"
|
||||
integrity sha1-XOcPdcbvUogvVN0Hnl7Wi1ojI8o=
|
||||
dependencies:
|
||||
quantize "^1.0.1"
|
||||
|
||||
get-svg-colors@^1.5.1:
|
||||
version "1.5.1"
|
||||
resolved "https://registry.yarnpkg.com/get-svg-colors/-/get-svg-colors-1.5.1.tgz#59f4004f5fb4fc0b0eaaec36dce004b3b10f188b"
|
||||
integrity sha512-G3gXrkLrlmv2gqZvs05ap/kcGbchhNtUNaoaP6dIefRcrGPqSa17dGp5ap/2yN8Xs2Wi5mWn16Ww+nFuVU8lTw==
|
||||
dependencies:
|
||||
cheerio "^0.22.0"
|
||||
chroma-js "^1.1.1"
|
||||
is-svg "^3.0.0"
|
||||
lodash.compact "^3.0.0"
|
||||
lodash.uniq "^4.5.0"
|
||||
|
||||
getpass@^0.1.1:
|
||||
version "0.1.7"
|
||||
resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
|
||||
integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=
|
||||
dependencies:
|
||||
assert-plus "^1.0.0"
|
||||
|
||||
har-schema@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
|
||||
integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=
|
||||
|
||||
har-validator@~5.1.3:
|
||||
version "5.1.5"
|
||||
resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd"
|
||||
integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==
|
||||
dependencies:
|
||||
ajv "^6.12.3"
|
||||
har-schema "^2.0.0"
|
||||
|
||||
has-flag@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
|
||||
integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
|
||||
|
||||
html-comment-regex@^1.1.0:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.2.tgz#97d4688aeb5c81886a364faa0cad1dda14d433a7"
|
||||
integrity sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==
|
||||
|
||||
htmlparser2@^3.9.1:
|
||||
version "3.10.1"
|
||||
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f"
|
||||
integrity sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==
|
||||
dependencies:
|
||||
domelementtype "^1.3.1"
|
||||
domhandler "^2.3.0"
|
||||
domutils "^1.5.1"
|
||||
entities "^1.1.1"
|
||||
inherits "^2.0.1"
|
||||
readable-stream "^3.1.1"
|
||||
|
||||
http-signature@~1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
|
||||
integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=
|
||||
dependencies:
|
||||
assert-plus "^1.0.0"
|
||||
jsprim "^1.2.2"
|
||||
sshpk "^1.7.0"
|
||||
|
||||
inherits@^2.0.1, inherits@^2.0.3:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
||||
|
||||
iota-array@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/iota-array/-/iota-array-1.0.0.tgz#81ef57fe5d05814cd58c2483632a99c30a0e8087"
|
||||
integrity sha1-ge9X/l0FgUzVjCSDYyqZwwoOgIc=
|
||||
|
||||
is-buffer@^1.0.2:
|
||||
version "1.1.6"
|
||||
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
|
||||
integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
|
||||
|
||||
is-svg@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-3.0.0.tgz#9321dbd29c212e5ca99c4fa9794c714bcafa2f75"
|
||||
integrity sha512-gi4iHK53LR2ujhLVVj+37Ykh9GLqYHX6JOVXbLAucaG/Cqw9xwdFOjDM2qeifLs1sF1npXXFvDu0r5HNgCMrzQ==
|
||||
dependencies:
|
||||
html-comment-regex "^1.1.0"
|
||||
|
||||
is-typedarray@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
|
||||
integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
|
||||
|
||||
isarray@0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
|
||||
integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=
|
||||
|
||||
isexe@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
|
||||
integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
|
||||
|
||||
isstream@~0.1.2:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
|
||||
integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
|
||||
|
||||
jpeg-js@^0.4.1:
|
||||
version "0.4.3"
|
||||
resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.4.3.tgz#6158e09f1983ad773813704be80680550eff977b"
|
||||
integrity sha512-ru1HWKek8octvUHFHvE5ZzQ1yAsJmIvRdGWvSoKV52XKyuyYA437QWDttXT8eZXDSbuMpHlLzPDZUPd6idIz+Q==
|
||||
|
||||
jsbn@~0.1.0:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
|
||||
integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM=
|
||||
|
||||
json-schema-traverse@^0.4.1:
|
||||
version "0.4.1"
|
||||
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
|
||||
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
|
||||
|
||||
json-schema@0.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5"
|
||||
integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==
|
||||
|
||||
json-stringify-safe@~5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
|
||||
integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
|
||||
|
||||
json5@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe"
|
||||
@@ -158,6 +558,16 @@ json5@^1.0.1:
|
||||
dependencies:
|
||||
minimist "^1.2.0"
|
||||
|
||||
jsprim@^1.2.2:
|
||||
version "1.4.2"
|
||||
resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.2.tgz#712c65533a15c878ba59e9ed5f0e26d5b77c5feb"
|
||||
integrity sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==
|
||||
dependencies:
|
||||
assert-plus "1.0.0"
|
||||
extsprintf "1.3.0"
|
||||
json-schema "0.4.0"
|
||||
verror "1.10.0"
|
||||
|
||||
just-extend@^4.0.2:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-4.1.0.tgz#7278a4027d889601640ee0ce0e5a00b992467da4"
|
||||
@@ -172,16 +582,114 @@ loader-utils@^1.0.0:
|
||||
emojis-list "^2.0.0"
|
||||
json5 "^1.0.1"
|
||||
|
||||
lodash.assignin@^4.0.9:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.assignin/-/lodash.assignin-4.2.0.tgz#ba8df5fb841eb0a3e8044232b0e263a8dc6a28a2"
|
||||
integrity sha1-uo31+4QesKPoBEIysOJjqNxqKKI=
|
||||
|
||||
lodash.bind@^4.1.4:
|
||||
version "4.2.1"
|
||||
resolved "https://registry.yarnpkg.com/lodash.bind/-/lodash.bind-4.2.1.tgz#7ae3017e939622ac31b7d7d7dcb1b34db1690d35"
|
||||
integrity sha1-euMBfpOWIqwxt9fX3LGzTbFpDTU=
|
||||
|
||||
lodash.compact@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/lodash.compact/-/lodash.compact-3.0.1.tgz#540ce3837745975807471e16b4a2ba21e7256ca5"
|
||||
integrity sha1-VAzjg3dFl1gHRx4WtKK6IeclbKU=
|
||||
|
||||
lodash.defaults@^4.0.1:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c"
|
||||
integrity sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=
|
||||
|
||||
lodash.filter@^4.4.0:
|
||||
version "4.6.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.filter/-/lodash.filter-4.6.0.tgz#668b1d4981603ae1cc5a6fa760143e480b4c4ace"
|
||||
integrity sha1-ZosdSYFgOuHMWm+nYBQ+SAtMSs4=
|
||||
|
||||
lodash.flatten@^4.2.0:
|
||||
version "4.4.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f"
|
||||
integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=
|
||||
|
||||
lodash.foreach@^4.3.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.foreach/-/lodash.foreach-4.5.0.tgz#1a6a35eace401280c7f06dddec35165ab27e3e53"
|
||||
integrity sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM=
|
||||
|
||||
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.map@^4.4.0:
|
||||
version "4.6.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.map/-/lodash.map-4.6.0.tgz#771ec7839e3473d9c4cde28b19394c3562f4f6d3"
|
||||
integrity sha1-dx7Hg540c9nEzeKLGTlMNWL09tM=
|
||||
|
||||
lodash.merge@^4.4.0:
|
||||
version "4.6.2"
|
||||
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
|
||||
integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
|
||||
|
||||
lodash.pick@^4.2.1:
|
||||
version "4.4.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3"
|
||||
integrity sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=
|
||||
|
||||
lodash.reduce@^4.4.0:
|
||||
version "4.6.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.reduce/-/lodash.reduce-4.6.0.tgz#f1ab6b839299ad48f784abbf476596f03b914d3b"
|
||||
integrity sha1-8atrg5KZrUj3hKu/R2WW8DuRTTs=
|
||||
|
||||
lodash.reject@^4.4.0:
|
||||
version "4.6.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.reject/-/lodash.reject-4.6.0.tgz#80d6492dc1470864bbf583533b651f42a9f52415"
|
||||
integrity sha1-gNZJLcFHCGS79YNTO2UfQqn1JBU=
|
||||
|
||||
lodash.some@^4.4.0:
|
||||
version "4.6.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d"
|
||||
integrity sha1-G7nzFO9ri63tE7VJFpsqlF62jk0=
|
||||
|
||||
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=
|
||||
|
||||
mime-db@1.51.0:
|
||||
version "1.51.0"
|
||||
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.51.0.tgz#d9ff62451859b18342d960850dc3cfb77e63fb0c"
|
||||
integrity sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==
|
||||
|
||||
mime-types@^2.0.1, mime-types@^2.1.12, mime-types@~2.1.19:
|
||||
version "2.1.34"
|
||||
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.34.tgz#5a712f9ec1503511a945803640fafe09d3793c24"
|
||||
integrity sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==
|
||||
dependencies:
|
||||
mime-db "1.51.0"
|
||||
|
||||
minimist@^1.2.0:
|
||||
version "1.2.5"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
|
||||
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
|
||||
|
||||
ndarray-pack@^1.1.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/ndarray-pack/-/ndarray-pack-1.2.1.tgz#8caebeaaa24d5ecf70ff86020637977da8ee585a"
|
||||
integrity sha1-jK6+qqJNXs9w/4YCBjeXfajuWFo=
|
||||
dependencies:
|
||||
cwise-compiler "^1.1.2"
|
||||
ndarray "^1.0.13"
|
||||
|
||||
ndarray@^1.0.13:
|
||||
version "1.0.19"
|
||||
resolved "https://registry.yarnpkg.com/ndarray/-/ndarray-1.0.19.tgz#6785b5f5dfa58b83e31ae5b2a058cfd1ab3f694e"
|
||||
integrity sha512-B4JHA4vdyZU30ELBw3g7/p9bZupyew5a7tX1Y/gGeF2hafrPaQZhgrGQfsvgfYbgdFZjYwuEcnaobeM/WMW+HQ==
|
||||
dependencies:
|
||||
iota-array "^1.0.0"
|
||||
is-buffer "^1.0.2"
|
||||
|
||||
nise@^4.0.1:
|
||||
version "4.0.3"
|
||||
resolved "https://registry.yarnpkg.com/nise/-/nise-4.0.3.tgz#9f79ff02fa002ed5ffbc538ad58518fa011dc913"
|
||||
@@ -193,11 +701,45 @@ nise@^4.0.1:
|
||||
just-extend "^4.0.2"
|
||||
path-to-regexp "^1.7.0"
|
||||
|
||||
node-bitmap@0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/node-bitmap/-/node-bitmap-0.0.1.tgz#180eac7003e0c707618ef31368f62f84b2a69091"
|
||||
integrity sha1-GA6scAPgxwdhjvMTaPYvhLKmkJE=
|
||||
|
||||
node-ensure@^0.0.0:
|
||||
version "0.0.0"
|
||||
resolved "https://registry.yarnpkg.com/node-ensure/-/node-ensure-0.0.0.tgz#ecae764150de99861ec5c810fd5d096b183932a7"
|
||||
integrity sha1-7K52QVDemYYexcgQ/V0Jaxg5Mqc=
|
||||
|
||||
nth-check@~1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c"
|
||||
integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==
|
||||
dependencies:
|
||||
boolbase "~1.0.0"
|
||||
|
||||
oauth-sign@~0.9.0:
|
||||
version "0.9.0"
|
||||
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
|
||||
integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==
|
||||
|
||||
omggif@^1.0.5:
|
||||
version "1.0.10"
|
||||
resolved "https://registry.yarnpkg.com/omggif/-/omggif-1.0.10.tgz#ddaaf90d4a42f532e9e7cb3a95ecdd47f17c7b19"
|
||||
integrity sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw==
|
||||
|
||||
parse-data-uri@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/parse-data-uri/-/parse-data-uri-0.2.0.tgz#bf04d851dd5c87b0ab238e5d01ace494b604b4c9"
|
||||
integrity sha1-vwTYUd1ch7CrI45dAazklLYEtMk=
|
||||
dependencies:
|
||||
data-uri-to-buffer "0.0.3"
|
||||
|
||||
path-key@^3.1.0:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
|
||||
integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
|
||||
|
||||
path-to-regexp@^1.7.0:
|
||||
version "1.8.0"
|
||||
resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a"
|
||||
@@ -213,7 +755,27 @@ pdfjs-dist@^2.2.228:
|
||||
node-ensure "^0.0.0"
|
||||
worker-loader "^2.0.0"
|
||||
|
||||
punycode@^2.1.0:
|
||||
performance-now@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
|
||||
integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
|
||||
|
||||
pify@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/pify/-/pify-5.0.0.tgz#1f5eca3f5e87ebec28cc6d54a0e4aaf00acc127f"
|
||||
integrity sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==
|
||||
|
||||
pngjs@^3.3.3:
|
||||
version "3.4.0"
|
||||
resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-3.4.0.tgz#99ca7d725965fb655814eaf65f38f12bbdbf555f"
|
||||
integrity sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==
|
||||
|
||||
psl@^1.1.28:
|
||||
version "1.8.0"
|
||||
resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24"
|
||||
integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==
|
||||
|
||||
punycode@^2.1.0, punycode@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
|
||||
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
|
||||
@@ -223,6 +785,61 @@ q@^1.5.1:
|
||||
resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
|
||||
integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=
|
||||
|
||||
qs@~6.5.2:
|
||||
version "6.5.3"
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad"
|
||||
integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==
|
||||
|
||||
quantize@^1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/quantize/-/quantize-1.0.2.tgz#d25ac200a77b6d70f40127ca171a10e33c8546de"
|
||||
integrity sha1-0lrCAKd7bXD0ASfKFxoQ4zyFRt4=
|
||||
|
||||
readable-stream@^3.1.1:
|
||||
version "3.6.0"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
|
||||
integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==
|
||||
dependencies:
|
||||
inherits "^2.0.3"
|
||||
string_decoder "^1.1.1"
|
||||
util-deprecate "^1.0.1"
|
||||
|
||||
request@^2.44.0:
|
||||
version "2.88.2"
|
||||
resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3"
|
||||
integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==
|
||||
dependencies:
|
||||
aws-sign2 "~0.7.0"
|
||||
aws4 "^1.8.0"
|
||||
caseless "~0.12.0"
|
||||
combined-stream "~1.0.6"
|
||||
extend "~3.0.2"
|
||||
forever-agent "~0.6.1"
|
||||
form-data "~2.3.2"
|
||||
har-validator "~5.1.3"
|
||||
http-signature "~1.2.0"
|
||||
is-typedarray "~1.0.0"
|
||||
isstream "~0.1.2"
|
||||
json-stringify-safe "~5.0.1"
|
||||
mime-types "~2.1.19"
|
||||
oauth-sign "~0.9.0"
|
||||
performance-now "^2.1.0"
|
||||
qs "~6.5.2"
|
||||
safe-buffer "^5.1.2"
|
||||
tough-cookie "~2.5.0"
|
||||
tunnel-agent "^0.6.0"
|
||||
uuid "^3.3.2"
|
||||
|
||||
safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
|
||||
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
|
||||
|
||||
safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
|
||||
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
|
||||
|
||||
schema-utils@^0.4.0:
|
||||
version "0.4.7"
|
||||
resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.7.tgz#ba74f597d2be2ea880131746ee17d0a093c68187"
|
||||
@@ -231,6 +848,18 @@ schema-utils@^0.4.0:
|
||||
ajv "^6.1.0"
|
||||
ajv-keywords "^3.1.0"
|
||||
|
||||
shebang-command@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea"
|
||||
integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==
|
||||
dependencies:
|
||||
shebang-regex "^3.0.0"
|
||||
|
||||
shebang-regex@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
|
||||
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
|
||||
|
||||
sinon@^9.0.1:
|
||||
version "9.0.2"
|
||||
resolved "https://registry.yarnpkg.com/sinon/-/sinon-9.0.2.tgz#b9017e24633f4b1c98dfb6e784a5f0509f5fd85d"
|
||||
@@ -244,11 +873,33 @@ sinon@^9.0.1:
|
||||
nise "^4.0.1"
|
||||
supports-color "^7.1.0"
|
||||
|
||||
sshpk@^1.7.0:
|
||||
version "1.17.0"
|
||||
resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.17.0.tgz#578082d92d4fe612b13007496e543fa0fbcbe4c5"
|
||||
integrity sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==
|
||||
dependencies:
|
||||
asn1 "~0.2.3"
|
||||
assert-plus "^1.0.0"
|
||||
bcrypt-pbkdf "^1.0.0"
|
||||
dashdash "^1.12.0"
|
||||
ecc-jsbn "~0.1.1"
|
||||
getpass "^0.1.1"
|
||||
jsbn "~0.1.0"
|
||||
safer-buffer "^2.0.2"
|
||||
tweetnacl "~0.14.0"
|
||||
|
||||
streamsearch@0.1.2:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a"
|
||||
integrity sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=
|
||||
|
||||
string_decoder@^1.1.1:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e"
|
||||
integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==
|
||||
dependencies:
|
||||
safe-buffer "~5.2.0"
|
||||
|
||||
supports-color@^7.1.0:
|
||||
version "7.1.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1"
|
||||
@@ -256,11 +907,41 @@ supports-color@^7.1.0:
|
||||
dependencies:
|
||||
has-flag "^4.0.0"
|
||||
|
||||
through@^2.3.4:
|
||||
version "2.3.8"
|
||||
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
|
||||
integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=
|
||||
|
||||
tough-cookie@~2.5.0:
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2"
|
||||
integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==
|
||||
dependencies:
|
||||
psl "^1.1.28"
|
||||
punycode "^2.1.1"
|
||||
|
||||
tunnel-agent@^0.6.0:
|
||||
version "0.6.0"
|
||||
resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
|
||||
integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=
|
||||
dependencies:
|
||||
safe-buffer "^5.0.1"
|
||||
|
||||
tweetnacl@^0.14.3, tweetnacl@~0.14.0:
|
||||
version "0.14.5"
|
||||
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
|
||||
integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=
|
||||
|
||||
type-detect@4.0.8, type-detect@^4.0.8:
|
||||
version "4.0.8"
|
||||
resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c"
|
||||
integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==
|
||||
|
||||
uniq@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff"
|
||||
integrity sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=
|
||||
|
||||
uri-js@^4.2.2:
|
||||
version "4.2.2"
|
||||
resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0"
|
||||
@@ -268,9 +949,35 @@ uri-js@^4.2.2:
|
||||
dependencies:
|
||||
punycode "^2.1.0"
|
||||
|
||||
util-deprecate@^1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
|
||||
integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
|
||||
|
||||
uuid@^3.3.2:
|
||||
version "3.4.0"
|
||||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
|
||||
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
|
||||
|
||||
uv-dlopen@./fixtures/native-addon/uv-dlopen/:
|
||||
version "0.0.1"
|
||||
|
||||
verror@1.10.0:
|
||||
version "1.10.0"
|
||||
resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"
|
||||
integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=
|
||||
dependencies:
|
||||
assert-plus "^1.0.0"
|
||||
core-util-is "1.0.2"
|
||||
extsprintf "^1.2.0"
|
||||
|
||||
which@^2.0.1:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1"
|
||||
integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==
|
||||
dependencies:
|
||||
isexe "^2.0.0"
|
||||
|
||||
worker-loader@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/worker-loader/-/worker-loader-2.0.0.tgz#45fda3ef76aca815771a89107399ee4119b430ac"
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"rootDir": "spec-main"
|
||||
},
|
||||
"include": [
|
||||
"spec-main",
|
||||
"typings"
|
||||
|
||||
51
typings/internal-ambient.d.ts
vendored
51
typings/internal-ambient.d.ts
vendored
@@ -294,60 +294,9 @@ declare interface Window {
|
||||
}
|
||||
};
|
||||
WebView: typeof ElectronInternal.WebViewElement;
|
||||
ResizeObserver: ResizeObserver;
|
||||
trustedTypes: TrustedTypePolicyFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* The ResizeObserver interface is used to observe changes to Element's content
|
||||
* rect.
|
||||
*
|
||||
* It is modeled after MutationObserver and IntersectionObserver.
|
||||
*/
|
||||
declare class ResizeObserver {
|
||||
constructor (callback: ResizeObserverCallback);
|
||||
|
||||
/**
|
||||
* Adds target to the list of observed elements.
|
||||
*/
|
||||
observe: (target: Element) => void;
|
||||
|
||||
/**
|
||||
* Removes target from the list of observed elements.
|
||||
*/
|
||||
unobserve: (target: Element) => void;
|
||||
|
||||
/**
|
||||
* Clears both the observationTargets and activeTargets lists.
|
||||
*/
|
||||
disconnect: () => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* This callback delivers ResizeObserver's notifications. It is invoked by a
|
||||
* broadcast active observations algorithm.
|
||||
*/
|
||||
interface ResizeObserverCallback {
|
||||
(entries: ResizeObserverEntry[], observer: ResizeObserver): void;
|
||||
}
|
||||
|
||||
interface ResizeObserverEntry {
|
||||
/**
|
||||
* @param target The Element whose size has changed.
|
||||
*/
|
||||
new (target: Element): ResizeObserverEntry;
|
||||
|
||||
/**
|
||||
* The Element whose size has changed.
|
||||
*/
|
||||
readonly target: Element;
|
||||
|
||||
/**
|
||||
* Element's content rect when ResizeObserverCallback is invoked.
|
||||
*/
|
||||
readonly contentRect: DOMRectReadOnly;
|
||||
}
|
||||
|
||||
// https://w3c.github.io/webappsec-trusted-types/dist/spec/#trusted-types
|
||||
|
||||
type TrustedHTML = string;
|
||||
|
||||
34
yarn.lock
34
yarn.lock
@@ -4982,9 +4982,11 @@ nice-try@^1.0.4:
|
||||
integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
|
||||
|
||||
node-fetch@^2.3.0:
|
||||
version "2.6.1"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
|
||||
integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==
|
||||
version "2.6.7"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad"
|
||||
integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==
|
||||
dependencies:
|
||||
whatwg-url "^5.0.0"
|
||||
|
||||
node-libs-browser@^2.2.1:
|
||||
version "2.2.1"
|
||||
@@ -7387,6 +7389,11 @@ toidentifier@1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553"
|
||||
integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==
|
||||
|
||||
tr46@~0.0.3:
|
||||
version "0.0.3"
|
||||
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
|
||||
integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=
|
||||
|
||||
trough@^2.0.0:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/trough/-/trough-2.0.2.tgz#94a3aa9d5ce379fc561f6244905b3f36b7458d96"
|
||||
@@ -7491,10 +7498,10 @@ typedarray@^0.0.6:
|
||||
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
|
||||
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
|
||||
|
||||
typescript@^4.1.3:
|
||||
version "4.1.3"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.1.3.tgz#519d582bd94cba0cf8934c7d8e8467e473f53bb7"
|
||||
integrity sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==
|
||||
typescript@^4.5.5:
|
||||
version "4.5.5"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.5.tgz#d8c953832d28924a9e3d37c73d729c846c5896f3"
|
||||
integrity sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==
|
||||
|
||||
uc.micro@^1.0.1, uc.micro@^1.0.5:
|
||||
version "1.0.6"
|
||||
@@ -7889,6 +7896,11 @@ wcwidth@^1.0.1:
|
||||
dependencies:
|
||||
defaults "^1.0.3"
|
||||
|
||||
webidl-conversions@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
|
||||
integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=
|
||||
|
||||
webpack-cli@^3.3.12:
|
||||
version "3.3.12"
|
||||
resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.3.12.tgz#94e9ada081453cd0aa609c99e500012fd3ad2d4a"
|
||||
@@ -7943,6 +7955,14 @@ webpack@^4.43.0:
|
||||
watchpack "^1.6.1"
|
||||
webpack-sources "^1.4.1"
|
||||
|
||||
whatwg-url@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d"
|
||||
integrity sha1-lmRU6HZUYuN2RNNib2dCzotwll0=
|
||||
dependencies:
|
||||
tr46 "~0.0.3"
|
||||
webidl-conversions "^3.0.0"
|
||||
|
||||
which-module@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"
|
||||
|
||||
Reference in New Issue
Block a user