import type { EmbedHtmlModel, EmbedHtmlStyles } from '@blocksuite/affine-model'; import { BlockSelection } from '@blocksuite/block-std'; import { html } from 'lit'; import { query, state } from 'lit/decorators.js'; import { classMap } from 'lit/directives/class-map.js'; import { type StyleInfo, styleMap } from 'lit/directives/style-map.js'; import { EmbedBlockComponent } from '../common/embed-block-element.js'; import { HtmlIcon, styles } from './styles.js'; export class EmbedHtmlBlockComponent extends EmbedBlockComponent { static override styles = styles; override _cardStyle: (typeof EmbedHtmlStyles)[number] = 'html'; protected _isDragging = false; protected _isResizing = false; close = () => { document.exitFullscreen().catch(console.error); }; protected embedHtmlStyle: StyleInfo = {}; open = () => { this.iframeWrapper?.requestFullscreen().catch(console.error); }; refreshData = () => {}; private _handleDoubleClick(event: MouseEvent) { event.stopPropagation(); this.open(); } private _selectBlock() { const selectionManager = this.host.selection; const blockSelection = selectionManager.create(BlockSelection, { blockId: this.blockId, }); selectionManager.setGroup('note', [blockSelection]); } protected _handleClick(event: MouseEvent) { event.stopPropagation(); this._selectBlock(); } override connectedCallback() { super.connectedCallback(); this._cardStyle = this.model.style; // this is required to prevent iframe from capturing pointer events this.disposables.add( this.selected$.subscribe(selected => { this._showOverlay = this._isResizing || this._isDragging || !selected; }) ); // this is required to prevent iframe from capturing pointer events this.handleEvent('dragStart', () => { this._isDragging = true; this._showOverlay = this._isResizing || this._isDragging || !this.selected$.peek(); }); this.handleEvent('dragEnd', () => { this._isDragging = false; this._showOverlay = this._isResizing || this._isDragging || !this.selected$.peek(); }); } override renderBlock(): unknown { const titleText = 'Basic HTML Page Structure'; const htmlSrc = ` ${this.model.html} `; return this.renderEmbed(() => { if (!this.model.html) { return html`
Empty
`; } return html`
${HtmlIcon}
${titleText}
`; }); } @state() protected accessor _showOverlay = true; @query('.embed-html-block-iframe-wrapper') accessor iframeWrapper!: HTMLDivElement; }