fix(editor): ref on click slots should not be global (#9830)

fix AF-2129
This commit is contained in:
pengx17
2025-01-22 05:20:55 +00:00
parent 720a596559
commit 4c665594d6
15 changed files with 47 additions and 20 deletions

View File

@@ -119,9 +119,10 @@ export class LinkCell extends BaseCellRenderer<string> {
return; return;
} }
std std.getOptional(RefNodeSlotsProvider)?.docLinkClicked.emit({
.getOptional(RefNodeSlotsProvider) pageId: this.docId,
?.docLinkClicked.emit({ pageId: this.docId }); host: std.host,
});
}; };
get std() { get std() {

View File

@@ -216,6 +216,7 @@ export class EmbedLinkedDocBlockComponent extends EmbedBlockComponent<EmbedLinke
...this.referenceInfo$.peek(), ...this.referenceInfo$.peek(),
openMode, openMode,
event, event,
host: this.host,
}); });
}; };

View File

@@ -323,7 +323,7 @@ export class EmbedSyncedDocBlockComponent extends EmbedBlockComponent<EmbedSynce
this.std this.std
.getOptional(RefNodeSlotsProvider) .getOptional(RefNodeSlotsProvider)
?.docLinkClicked.emit({ ...event, pageId }); ?.docLinkClicked.emit({ ...event, pageId, host: this.host });
}; };
refreshData = () => { refreshData = () => {
@@ -387,8 +387,7 @@ export class EmbedSyncedDocBlockComponent extends EmbedBlockComponent<EmbedSynce
let editorHost: EditorHost | null = this.host; let editorHost: EditorHost | null = this.host;
while (editorHost && !this._cycle) { while (editorHost && !this._cycle) {
this._cycle = !!editorHost && editorHost.doc.id === this.model.pageId; this._cycle = !!editorHost && editorHost.doc.id === this.model.pageId;
editorHost = editorHost = editorHost.parentElement?.closest('editor-host') ?? null;
editorHost.parentElement?.closest<EditorHost>('editor-host') ?? null;
} }
} }

View File

@@ -84,14 +84,15 @@ export class FootNotePopup extends WithDisposable(LitElement) {
const referenceType = this.footnote.reference.type; const referenceType = this.footnote.reference.type;
const { docId, url } = this.footnote.reference; const { docId, url } = this.footnote.reference;
switch (referenceType) { switch (referenceType) {
case 'doc': case 'doc': {
if (!docId) { if (!docId) {
break; break;
} }
this.std this.std
.getOptional(RefNodeSlotsProvider) .getOptional(RefNodeSlotsProvider)
?.docLinkClicked.emit({ pageId: docId }); ?.docLinkClicked.emit({ pageId: docId, host: this.std.host });
break; break;
}
case 'url': case 'url':
if (!url) { if (!url) {
break; break;

View File

@@ -56,11 +56,14 @@ export class AffineLink extends ShadowlessElement {
if (!referenceInfo) return; if (!referenceInfo) return;
const refNodeSlotsProvider = this.std?.getOptional(RefNodeSlotsProvider); const refNodeSlotsProvider = this.std?.getOptional(RefNodeSlotsProvider);
if (!refNodeSlotsProvider) return; if (!refNodeSlotsProvider || !this.std) return;
e?.preventDefault(); e?.preventDefault();
refNodeSlotsProvider.docLinkClicked.emit(referenceInfo); refNodeSlotsProvider.docLinkClicked.emit({
...referenceInfo,
host: this.std.host,
});
}; };
private readonly _whenHover = new HoverController( private readonly _whenHover = new HoverController(

View File

@@ -200,9 +200,10 @@ export class AffineReference extends WithDisposable(ShadowlessElement) {
private _onClick() { private _onClick() {
if (!this.config.interactable) return; if (!this.config.interactable) return;
this.std this.std.getOptional(RefNodeSlotsProvider)?.docLinkClicked.emit({
.getOptional(RefNodeSlotsProvider) ...this.referenceInfo,
?.docLinkClicked.emit(this.referenceInfo); host: this.std.host,
});
} }
override connectedCallback() { override connectedCallback() {

View File

@@ -71,6 +71,7 @@ export class ReferencePopup extends WithDisposable(LitElement) {
this.std.getOptional(RefNodeSlotsProvider)?.docLinkClicked.emit({ this.std.getOptional(RefNodeSlotsProvider)?.docLinkClicked.emit({
...this.referenceInfo, ...this.referenceInfo,
...event, ...event,
host: this.std.host,
}); });
}; };

View File

@@ -1,11 +1,13 @@
import type { ReferenceInfo } from '@blocksuite/affine-model'; import type { ReferenceInfo } from '@blocksuite/affine-model';
import type { OpenDocMode } from '@blocksuite/affine-shared/services'; import type { OpenDocMode } from '@blocksuite/affine-shared/services';
import type { EditorHost } from '@blocksuite/block-std';
import type { Slot } from '@blocksuite/global/utils'; import type { Slot } from '@blocksuite/global/utils';
export type DocLinkClickedEvent = ReferenceInfo & { export type DocLinkClickedEvent = ReferenceInfo & {
// default is active view // default is active view
openMode?: OpenDocMode; openMode?: OpenDocMode;
event?: MouseEvent; event?: MouseEvent;
host: EditorHost;
}; };
export type RefNodeSlots = { export type RefNodeSlots = {

View File

@@ -433,6 +433,7 @@ const CREATE_AS_DOC = {
host.std.getOptional(RefNodeSlotsProvider)?.docLinkClicked.emit({ host.std.getOptional(RefNodeSlotsProvider)?.docLinkClicked.emit({
pageId: newDoc.id, pageId: newDoc.id,
host,
}); });
let complete = false; let complete = false;
(function addContent() { (function addContent() {

View File

@@ -30,7 +30,10 @@ import { pageHistoryModalAtom } from '../../../components/atoms/page-history';
import { useBlockSuiteMetaHelper } from './use-block-suite-meta-helper'; import { useBlockSuiteMetaHelper } from './use-block-suite-meta-helper';
import { useExportPage } from './use-export-page'; import { useExportPage } from './use-export-page';
export function useRegisterBlocksuiteEditorCommands(editor: Editor) { export function useRegisterBlocksuiteEditorCommands(
editor: Editor,
active: boolean
) {
const doc = useService(DocService).doc; const doc = useService(DocService).doc;
const docId = doc.id; const docId = doc.id;
const mode = useLiveData(editor.mode$); const mode = useLiveData(editor.mode$);
@@ -82,6 +85,10 @@ export function useRegisterBlocksuiteEditorCommands(editor: Editor) {
const openInAppService = useServiceOptional(OpenInAppService); const openInAppService = useServiceOptional(OpenInAppService);
useEffect(() => { useEffect(() => {
if (!active) {
return;
}
const unsubs: Array<() => void> = []; const unsubs: Array<() => void> = [];
const preconditionStrategy = () => const preconditionStrategy = () =>
PreconditionStrategy.InPaperOrEdgeless && !trash; PreconditionStrategy.InPaperOrEdgeless && !trash;
@@ -375,5 +382,6 @@ export function useRegisterBlocksuiteEditorCommands(editor: Editor) {
defaultPageWidth, defaultPageWidth,
checked, checked,
openInAppService, openInAppService,
active,
]); ]);
} }

View File

@@ -25,6 +25,9 @@ export function useRegisterCopyLinkCommands({
}); });
useEffect(() => { useEffect(() => {
if (!isActiveView) {
return;
}
const unsubs: Array<() => void> = []; const unsubs: Array<() => void> = [];
unsubs.push( unsubs.push(

View File

@@ -165,7 +165,7 @@ const DetailPageImpl = memo(function DetailPageImpl() {
return; return;
}, [globalContext, isActiveView, isInTrash]); }, [globalContext, isActiveView, isInTrash]);
useRegisterBlocksuiteEditorCommands(editor); useRegisterBlocksuiteEditorCommands(editor, isActiveView);
const title = useLiveData(doc.title$); const title = useLiveData(doc.title$);
usePageDocumentTitle(title); usePageDocumentTitle(title);
@@ -182,7 +182,10 @@ const DetailPageImpl = memo(function DetailPageImpl() {
disposable.add( disposable.add(
// the event should not be emitted by AffineReference // the event should not be emitted by AffineReference
refNodeSlots.docLinkClicked.on( refNodeSlots.docLinkClicked.on(
({ pageId, params, openMode, event }) => { ({ pageId, params, openMode, event, host }) => {
if (host !== editorHost) {
return;
}
openMode ??= openMode ??=
event && isNewTabTrigger(event) event && isNewTabTrigger(event)
? 'open-in-new-tab' ? 'open-in-new-tab'

View File

@@ -91,8 +91,10 @@ export const EditorChatPanel = forwardRef(function EditorChatPanel(
const docModeService = editor.host.std.get(DocModeProvider); const docModeService = editor.host.std.get(DocModeProvider);
const refNodeService = editor.host.std.getOptional(RefNodeSlotsProvider); const refNodeService = editor.host.std.getOptional(RefNodeSlotsProvider);
const disposable = [ const disposable = [
refNodeService?.docLinkClicked.on(() => { refNodeService?.docLinkClicked.on(({ host }) => {
(chatPanelRef.current as ChatPanel).doc = editor.doc; if (host === editor.host) {
(chatPanelRef.current as ChatPanel).doc = editor.doc;
}
}), }),
docModeService?.onPrimaryModeChange(() => { docModeService?.onPrimaryModeChange(() => {
if (!editor.host) return; if (!editor.host) return;

View File

@@ -1,7 +1,6 @@
import { useThemeColorV2 } from '@affine/component'; import { useThemeColorV2 } from '@affine/component';
import { PageDetailSkeleton } from '@affine/component/page-detail-skeleton'; import { PageDetailSkeleton } from '@affine/component/page-detail-skeleton';
import { AffineErrorBoundary } from '@affine/core/components/affine/affine-error-boundary'; import { AffineErrorBoundary } from '@affine/core/components/affine/affine-error-boundary';
import { useRegisterBlocksuiteEditorCommands } from '@affine/core/components/hooks/affine/use-register-blocksuite-editor-commands';
import { useActiveBlocksuiteEditor } from '@affine/core/components/hooks/use-block-suite-editor'; import { useActiveBlocksuiteEditor } from '@affine/core/components/hooks/use-block-suite-editor';
import { useDocMetaHelper } from '@affine/core/components/hooks/use-block-suite-page-meta'; import { useDocMetaHelper } from '@affine/core/components/hooks/use-block-suite-page-meta';
import { usePageDocumentTitle } from '@affine/core/components/hooks/use-global-state'; import { usePageDocumentTitle } from '@affine/core/components/hooks/use-global-state';
@@ -140,7 +139,6 @@ const DetailPageImpl = () => {
}; };
}, [globalContext, isInTrash]); }, [globalContext, isInTrash]);
useRegisterBlocksuiteEditorCommands(editor);
const title = useLiveData(doc.title$); const title = useLiveData(doc.title$);
usePageDocumentTitle(title); usePageDocumentTitle(title);

View File

@@ -106,6 +106,9 @@ function DocPeekPreviewEditor({
disposableGroup.add( disposableGroup.add(
// todo(@pengx17): seems not working // todo(@pengx17): seems not working
refNodeSlots.docLinkClicked.on(options => { refNodeSlots.docLinkClicked.on(options => {
if (options.host !== editorContainer.host) {
return;
}
peekView peekView
.open({ .open({
docRef: { docId: options.pageId }, docRef: { docId: options.pageId },