// /* eslint-disable */ // import { assertExists } from '@blockeditor/global/utils'; // import { // type DeltaInsert, // INLINE_ROOT_ATTR, // type InlineRootElement, // ZERO_WIDTH_SPACE, // } from '@blockeditor/inline'; // import { ShadowlessElement } from '@blockeditor/lit'; // import { css, html } from 'lit'; // import { customElement, property, state } from 'lit/decorators.js'; // import { styleMap } from 'lit/directives/style-map.js'; // import { getModelByElement } from '../../../../utils/query.js'; // import type { AffineTextAttributes } from '../../affine-inline-specs.js'; // import { affineTextStyles } from '../affine-text.js'; // import type { AIPopup } from './ai-popup/ai-popup.js'; // import { toggleAIPopup } from './ai-popup/toggle-ai-popup.js'; // @customElement('affine-ai') // export class AffineAI extends ShadowlessElement { // @property({ type: Object }) // delta: DeltaInsert = { // insert: ZERO_WIDTH_SPACE, // }; // get ai() { // const ai = this.delta.attributes?.ai; // if (!ai) { // return ''; // } // return ai; // } // get inlineEditor() { // const inlineRoot = this.closest>( // `[${INLINE_ROOT_ATTR}]` // ); // assertExists(inlineRoot); // return inlineRoot.inlineEditor; // } // @property({ attribute: false }) // popoverHoverOpenDelay = 150; // @state() // private _popoverTimer = 0; // private _isAIHover = false; // private _isAIPopupHover = false; // private _popup: AIPopup | null = null; // static override styles = css` // affine-ai > a { // white-space: nowrap; // word-break: break-word; // color: var(--affine-ai-color); // fill: var(--affine-ai-color); // text-decoration: none; // cursor: pointer; // } // affine-ai > a:hover [data-v-text='true'] { // text-decoration: underline; // } // affine-ai > a > v-text { // white-space: break-spaces; // } // `; // constructor() { // super(); // this.addEventListener('mouseenter', this._onHover); // this.addEventListener('mouseleave', this._onHoverEnd); // } // private _onHover(e: MouseEvent) { // if (this._isAIHover) { // return; // } else { // this._isAIHover = true; // } // const model = getModelByElement(this); // if (model.page.readonly) return; // this._popoverTimer = window.setTimeout(() => { // this._onDelayHover(e); // }, this.popoverHoverOpenDelay); // } // private _onDelayHover(e: MouseEvent) { // if (!(e.target instanceof HTMLElement) || !document.contains(e.target)) { // return; // } // const selfInlineRange = this.inlineEditor.getInlineRangeFromElement(this); // assertExists(selfInlineRange); // const popup = toggleAIPopup(this.inlineEditor, 'view', selfInlineRange); // popup.addEventListener('mouseenter', () => { // this._isAIPopupHover = true; // }); // popup.addEventListener('mouseleave', () => { // this._isAIPopupHover = false; // popup.remove(); // this._popup = null; // }); // this._popup = popup; // } // private _onHoverEnd() { // this._isAIHover = false; // clearTimeout(this._popoverTimer); // new Promise(resolve => { // setTimeout(() => { // resolve(); // }, 500); // }) // .then(() => { // const model = getModelByElement(this); // if (this._isAIHover && !model.page.readonly) return; // if (!this._isAIPopupHover) { // if (this._popup) { // this._popup.remove(); // this._popup = null; // } // } // }) // .catch(console.error); // } // // Workaround for AIs not working in contenteditable div // // see also https://stackoverflow.com/questions/12059211/how-to-make-clickable-anchor-in-contenteditable-div // // // // Note: We cannot use JS to directly open a new page as this may be blocked by the browser. // // // // Please also note that when readonly mode active, // // this workaround is not necessary and AIs work normally. // // see https://github.com/toeverything/AFFiNE/issues/1540 // private _onMouseUp() { // const anchorElement = this.querySelector('a'); // assertExists(anchorElement); // if (!anchorElement.isContentEditable) return; // anchorElement.contentEditable = 'false'; // setTimeout(() => { // anchorElement.removeAttribute('contenteditable'); // }, 0); // } // override render() { // const style = this.delta.attributes // ? affineTextStyles(this.delta.attributes) // : styleMap({}); // return html``; // } // } // declare global { // interface HTMLElementTagNameMap { // 'affine-ai': AffineAI; // } // }