blob: 436fcba0bafe3c42969b4fdfa4339b8ecbde9656 [file] [log] [blame]
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import {assert} from '//resources/js/assert.js';
import {CrLitElement} from '//resources/lit/v3_0/lit.rollup.js';
import {getCss} from './content_region.css.js';
import {TabWebviewElement} from './webview.js';
export class ContentRegion extends CrLitElement {
static get is() {
return 'content-region';
}
static override get styles() {
return getCss();
}
// Please DO NOT trigger Lit's reactive update. The DOM tree of this component
// must be manipulated manually.
// A <cr-webview>'s render frame is connected to its parent frame by
// RenderFrameProxyHost at the browser side. This proxy is disconnected as
// soon as the <cr-webview> element is detached from its parent. Re-attaching
// the element does not re-estabilish the proxy.
override render() {
return '';
}
override shouldUpdate(_: Map<string, any>) {
return false;
}
private webviews: Map<string, TabWebviewElement> = new Map();
activeWebview?: TabWebviewElement;
activateTab(tabId: string) {
const webview = this.webviews.get(tabId);
assert(webview);
if (this.activeWebview === webview) {
return;
}
if (this.activeWebview) {
this.activeWebview.setActive(false);
}
this.activeWebview = webview;
webview.setActive(true);
}
hasTab(tabId: string) {
return this.webviews.has(tabId);
}
createWebView(tabId: string, isActive: boolean) {
if (this.hasTab(tabId)) {
return;
}
const webview = new TabWebviewElement(tabId);
this.webviews.set(tabId, webview);
this.shadowRoot.appendChild(webview);
if (isActive) {
this.activateTab(tabId);
}
this.requestUpdate();
}
removeTab(tabId: string) {
const webview = this.webviews.get(tabId);
assert(webview);
this.webviews.delete(tabId);
webview.remove();
this.requestUpdate();
}
}
declare global {
interface HTMLElementTagNameMap {
'content-region': ContentRegion;
}
}
customElements.define(ContentRegion.is, ContentRegion);