feat: add transparent
webpreference to webview (#40301)
* feat: add transparent option to WebContents * feat: add transparent attribute to webview * test: add tests for webview transparent attribute * docs: add transparent attribute to webview docs * fix: run tests on macOS only * refactor: remove unneeded html tag * fix: only apply transparent option to guests * refactor: correct comment * refactor: use opaque instead Retains current webview behaviour by default. * fix: correct variable name to guest_opaque_ * refactor: use transparent webpreference * docs: remove unused web preference * fix: uncomment condition for transparency test * docs: converted to list format and linked to MDN * fix: make webviews transparent by default again * fix: rebase error --------- Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
This commit is contained in:
parent
8c71e2adc9
commit
5086071294
5 changed files with 106 additions and 3 deletions
|
@ -221,7 +221,9 @@ windows. Popups are disabled by default.
|
|||
```
|
||||
|
||||
A `string` which is a comma separated list of strings which specifies the web preferences to be set on the webview.
|
||||
The full list of supported preference strings can be found in [BrowserWindow](browser-window.md#new-browserwindowoptions).
|
||||
The full list of supported preference strings can be found in [BrowserWindow](browser-window.md#new-browserwindowoptions). In addition, webview supports the following preferences:
|
||||
|
||||
* `transparent` boolean (optional) - Whether to enable background transparency for the guest page. Default is `true`. **Note:** The guest page's text and background colors are derived from the [color scheme](https://developer.mozilla.org/en-US/docs/Web/CSS/color-scheme) of its root element. When transparency is enabled, the text color will still change accordingly but the background will remain transparent.
|
||||
|
||||
The string follows the same format as the features string in `window.open`.
|
||||
A name by itself is given a `true` boolean value.
|
||||
|
|
|
@ -822,6 +822,9 @@ WebContents::WebContents(v8::Isolate* isolate,
|
|||
// Get type
|
||||
options.Get("type", &type_);
|
||||
|
||||
// Get transparent for guest view
|
||||
options.Get("transparent", &guest_transparent_);
|
||||
|
||||
bool b = false;
|
||||
if (options.Get(options::kOffscreen, &b) && b)
|
||||
type_ = Type::kOffScreen;
|
||||
|
@ -3778,7 +3781,7 @@ void WebContents::SetImageAnimationPolicy(const std::string& new_policy) {
|
|||
}
|
||||
|
||||
void WebContents::SetBackgroundColor(absl::optional<SkColor> maybe_color) {
|
||||
SkColor color = maybe_color.value_or(type_ == Type::kWebView ||
|
||||
SkColor color = maybe_color.value_or((IsGuest() && guest_transparent_) ||
|
||||
type_ == Type::kBrowserView
|
||||
? SK_ColorTRANSPARENT
|
||||
: SK_ColorWHITE);
|
||||
|
|
|
@ -801,6 +801,9 @@ class WebContents : public ExclusiveAccessContext,
|
|||
// The type of current WebContents.
|
||||
Type type_ = Type::kBrowserWindow;
|
||||
|
||||
// Weather the guest view should be transparent
|
||||
bool guest_transparent_ = true;
|
||||
|
||||
int32_t id_;
|
||||
|
||||
// Request id used for findInPage request.
|
||||
|
|
15
spec/fixtures/pages/flex-webview.html
vendored
Normal file
15
spec/fixtures/pages/flex-webview.html
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
<style>
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
display: flex;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
webview {
|
||||
flex: 1;
|
||||
}
|
||||
</style>
|
|
@ -1,6 +1,6 @@
|
|||
import * as path from 'node:path';
|
||||
import * as url from 'node:url';
|
||||
import { BrowserWindow, session, ipcMain, app, WebContents } from 'electron/main';
|
||||
import { BrowserWindow, session, ipcMain, app, WebContents, screen } from 'electron/main';
|
||||
import { closeAllWindows } from './lib/window-helpers';
|
||||
import { emittedUntil } from './lib/events-helpers';
|
||||
import { ifit, ifdescribe, defer, itremote, useRemoteContext, listen } from './lib/spec-helpers';
|
||||
|
@ -9,6 +9,7 @@ import * as http from 'node:http';
|
|||
import * as auth from 'basic-auth';
|
||||
import { once } from 'node:events';
|
||||
import { setTimeout } from 'node:timers/promises';
|
||||
import { areColorsSimilar, captureScreen, HexColors, getPixelColor } from './lib/screen-helpers';
|
||||
|
||||
declare let WebView: any;
|
||||
const features = process._linkedBinding('electron_common_features');
|
||||
|
@ -773,6 +774,85 @@ describe('<webview> tag', function () {
|
|||
});
|
||||
});
|
||||
|
||||
describe('webpreferences attribute', () => {
|
||||
const WINDOW_BACKGROUND_COLOR = '#55ccbb';
|
||||
|
||||
let w: BrowserWindow;
|
||||
before(async () => {
|
||||
w = new BrowserWindow({
|
||||
webPreferences: {
|
||||
webviewTag: true,
|
||||
nodeIntegration: true,
|
||||
contextIsolation: false
|
||||
}
|
||||
});
|
||||
await w.loadURL(`file://${fixtures}/pages/flex-webview.html`);
|
||||
w.setBackgroundColor(WINDOW_BACKGROUND_COLOR);
|
||||
});
|
||||
afterEach(async () => {
|
||||
await w.webContents.executeJavaScript(`{
|
||||
for (const el of document.querySelectorAll('webview')) el.remove();
|
||||
}`);
|
||||
});
|
||||
after(() => w.close());
|
||||
|
||||
// Linux and arm64 platforms (WOA and macOS) do not return any capture sources
|
||||
ifit(process.platform === 'darwin' && process.arch === 'x64')('is transparent by default', async () => {
|
||||
await loadWebView(w.webContents, {
|
||||
src: 'data:text/html,foo'
|
||||
});
|
||||
|
||||
await setTimeout(1000);
|
||||
|
||||
const display = screen.getPrimaryDisplay();
|
||||
const screenCapture = await captureScreen();
|
||||
const centerColor = getPixelColor(screenCapture, {
|
||||
x: display.size.width / 2,
|
||||
y: display.size.height / 2
|
||||
});
|
||||
|
||||
expect(areColorsSimilar(centerColor, WINDOW_BACKGROUND_COLOR)).to.be.true();
|
||||
});
|
||||
|
||||
// Linux and arm64 platforms (WOA and macOS) do not return any capture sources
|
||||
ifit(process.platform === 'darwin' && process.arch === 'x64')('remains transparent when set', async () => {
|
||||
await loadWebView(w.webContents, {
|
||||
src: 'data:text/html,foo',
|
||||
webpreferences: 'transparent=yes'
|
||||
});
|
||||
|
||||
await setTimeout(1000);
|
||||
|
||||
const display = screen.getPrimaryDisplay();
|
||||
const screenCapture = await captureScreen();
|
||||
const centerColor = getPixelColor(screenCapture, {
|
||||
x: display.size.width / 2,
|
||||
y: display.size.height / 2
|
||||
});
|
||||
|
||||
expect(areColorsSimilar(centerColor, WINDOW_BACKGROUND_COLOR)).to.be.true();
|
||||
});
|
||||
|
||||
// Linux and arm64 platforms (WOA and macOS) do not return any capture sources
|
||||
ifit(process.platform === 'darwin' && process.arch === 'x64')('can disable transparency', async () => {
|
||||
await loadWebView(w.webContents, {
|
||||
src: 'data:text/html,foo',
|
||||
webpreferences: 'transparent=no'
|
||||
});
|
||||
|
||||
await setTimeout(1000);
|
||||
|
||||
const display = screen.getPrimaryDisplay();
|
||||
const screenCapture = await captureScreen();
|
||||
const centerColor = getPixelColor(screenCapture, {
|
||||
x: display.size.width / 2,
|
||||
y: display.size.height / 2
|
||||
});
|
||||
|
||||
expect(areColorsSimilar(centerColor, HexColors.WHITE)).to.be.true();
|
||||
});
|
||||
});
|
||||
|
||||
describe('permission request handlers', () => {
|
||||
let w: BrowserWindow;
|
||||
beforeEach(async () => {
|
||||
|
|
Loading…
Reference in a new issue