blob: f85bad8db842442ed1ce65a62b39eb494f7a59ad [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 '/strings.m.js';
import {assert} from 'chrome://resources/js/assert.js';
import {EventTracker} from 'chrome://resources/js/event_tracker.js';
import {loadTimeData} from 'chrome://resources/js/load_time_data.js';
import {CrLitElement} from 'chrome://resources/lit/v3_0/lit.rollup.js';
import type {Point} from 'chrome://resources/mojo/ui/gfx/geometry/mojom/geometry.mojom-webui.js';
import {getCss} from './app.css.js';
import {getHtml} from './app.html.js';
import {ActorOverlayBrowserProxy} from './browser_proxy.js';
export interface ActorOverlayAppElement {
$: {magicCursor: HTMLDivElement};
}
export class ActorOverlayAppElement extends CrLitElement {
static get is() {
return 'actor-overlay-app';
}
static override get styles() {
return getCss();
}
override render() {
return getHtml.bind(this)();
}
static override get properties() {
return {
borderGlowVisible_: {type: Boolean},
};
}
protected accessor borderGlowVisible_: boolean = false;
private eventTracker_: EventTracker = new EventTracker();
private setScrimBackgroundListenerId_: number | null = null;
private setBorderGlowVisibilityListenerId_: number | null = null;
private shouldShowCursor_: boolean =
loadTimeData.getBoolean('isMagicCursorEnabled');
private isCursorInitialized_: boolean = false;
private isStandaloneBorderGlowEnabled_: boolean =
loadTimeData.getBoolean('isStandaloneBorderGlowEnabled');
override connectedCallback() {
super.connectedCallback();
const proxy = ActorOverlayBrowserProxy.getInstance();
this.eventTracker_.add(this, 'pointerenter', () => {
proxy.handler.onHoverStatusChanged(true);
});
this.eventTracker_.add(this, 'pointerleave', () => {
proxy.handler.onHoverStatusChanged(false);
});
this.addEventListener('wheel', this.onWheelEvent_);
// Background scrim
this.setScrimBackgroundListenerId_ =
proxy.callbackRouter.setScrimBackground.addListener(
this.setScrimBackground.bind(this));
// Border Glow
this.setBorderGlowVisibilityListenerId_ =
proxy.callbackRouter.setBorderGlowVisibility.addListener(
this.setBorderGlowVisibility.bind(this));
proxy.handler.getCurrentBorderGlowVisibility().then(
({isVisible}) => this.setBorderGlowVisibility(isVisible));
}
override disconnectedCallback() {
super.disconnectedCallback();
this.eventTracker_.removeAll();
this.removeEventListener('wheel', this.onWheelEvent_);
assert(this.setScrimBackgroundListenerId_);
ActorOverlayBrowserProxy.getInstance().callbackRouter.removeListener(
this.setScrimBackgroundListenerId_);
assert(this.setBorderGlowVisibilityListenerId_);
ActorOverlayBrowserProxy.getInstance().callbackRouter.removeListener(
this.setBorderGlowVisibilityListenerId_);
}
// Prevents user scroll gestures (mouse wheel, touchpad) from moving the
// overlay.
private onWheelEvent_(e: WheelEvent) {
e.preventDefault();
e.stopPropagation();
}
private setScrimBackground(isVisible: boolean) {
isVisible ? this.classList.add('background-visible') :
this.classList.remove('background-visible');
}
private setBorderGlowVisibility(isVisible: boolean) {
this.borderGlowVisible_ = this.isStandaloneBorderGlowEnabled_ && isVisible;
}
// TODO(crbug.com/422539773): Make function private once it's called via the
// browser.
moveCursorTo(point: Point) {
if (!this.$.magicCursor || !this.shouldShowCursor_) {
return;
}
if (!this.isCursorInitialized_) {
this.$.magicCursor.style.opacity = '1';
this.isCursorInitialized_ = true;
}
this.$.magicCursor.style.transform =
`translate(${point.x}px, ${point.y}px)`;
}
}
declare global {
interface HTMLElementTagNameMap {
'actor-overlay-app': ActorOverlayAppElement;
}
}
customElements.define(ActorOverlayAppElement.is, ActorOverlayAppElement);