fix(editor): block can be null in widget (#10959)
Closes: [BS-2826](https://linear.app/affine-design/issue/BS-2826/typeerror-thisblock-is-null)
This commit is contained in:
@@ -35,6 +35,10 @@ export class AffineCodeToolbarWidget extends WidgetComponent<
|
|||||||
this,
|
this,
|
||||||
({ abortController }) => {
|
({ abortController }) => {
|
||||||
const codeBlock = this.block;
|
const codeBlock = this.block;
|
||||||
|
if (!codeBlock) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const selection = this.host.selection;
|
const selection = this.host.selection;
|
||||||
|
|
||||||
const textSelection = selection.find(TextSelection);
|
const textSelection = selection.find(TextSelection);
|
||||||
@@ -105,6 +109,9 @@ export class AffineCodeToolbarWidget extends WidgetComponent<
|
|||||||
);
|
);
|
||||||
|
|
||||||
const codeBlock = this.block;
|
const codeBlock = this.block;
|
||||||
|
if (!codeBlock) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
this._hoverController.setReference(codeBlock);
|
this._hoverController.setReference(codeBlock);
|
||||||
this._hoverController.onAbort = () => {
|
this._hoverController.onAbort = () => {
|
||||||
// If the more menu is opened, don't close it.
|
// If the more menu is opened, don't close it.
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ export class NoteSlicer extends WidgetComponent<
|
|||||||
}
|
}
|
||||||
|
|
||||||
get selectedRectEle() {
|
get selectedRectEle() {
|
||||||
return this.block.selectedRectWidget;
|
return this.block?.selectedRectWidget;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _sliceNote() {
|
private _sliceNote() {
|
||||||
@@ -266,6 +266,10 @@ export class NoteSlicer extends WidgetComponent<
|
|||||||
|
|
||||||
this._updateDivingLineAndBlockIds();
|
this._updateDivingLineAndBlockIds();
|
||||||
|
|
||||||
|
if (!block) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
disposables.add(
|
disposables.add(
|
||||||
block.slots.elementResizeStart.subscribe(() => {
|
block.slots.elementResizeStart.subscribe(() => {
|
||||||
this._isResizing = true;
|
this._isResizing = true;
|
||||||
@@ -343,7 +347,7 @@ export class NoteSlicer extends WidgetComponent<
|
|||||||
}
|
}
|
||||||
|
|
||||||
override firstUpdated() {
|
override firstUpdated() {
|
||||||
if (!this.block.service) return;
|
if (!this.block?.service) return;
|
||||||
this.disposables.add(
|
this.disposables.add(
|
||||||
this.block.service.uiEventDispatcher.add('wheel', () => {
|
this.block.service.uiEventDispatcher.add('wheel', () => {
|
||||||
this._hidden = true;
|
this._hidden = true;
|
||||||
|
|||||||
@@ -33,6 +33,9 @@ export class EdgelessDraggingAreaRectWidget extends WidgetComponent<
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
override render() {
|
override render() {
|
||||||
|
if (!this.block) {
|
||||||
|
return nothing;
|
||||||
|
}
|
||||||
const rect = this.block.gfx.tool.draggingViewArea$.value;
|
const rect = this.block.gfx.tool.draggingViewArea$.value;
|
||||||
const tool = this.block.gfx.tool.currentTool$.value;
|
const tool = this.block.gfx.tool.currentTool$.value;
|
||||||
|
|
||||||
|
|||||||
@@ -477,7 +477,7 @@ export class EdgelessSelectedRectWidget extends WidgetComponent<
|
|||||||
this._scaleDirection = undefined;
|
this._scaleDirection = undefined;
|
||||||
this._updateMode();
|
this._updateMode();
|
||||||
|
|
||||||
this.block.slots.elementResizeEnd.next();
|
this.block?.slots.elementResizeEnd.next();
|
||||||
|
|
||||||
this.frameOverlay.clear();
|
this.frameOverlay.clear();
|
||||||
};
|
};
|
||||||
@@ -606,7 +606,7 @@ export class EdgelessSelectedRectWidget extends WidgetComponent<
|
|||||||
const rotation = this._resizeManager.rotation;
|
const rotation = this._resizeManager.rotation;
|
||||||
|
|
||||||
this._dragEndCallback = [];
|
this._dragEndCallback = [];
|
||||||
this.block.slots.elementResizeStart.next();
|
this.block?.slots.elementResizeStart.next();
|
||||||
this.selection.selectedElements.forEach(el => {
|
this.selection.selectedElements.forEach(el => {
|
||||||
el.stash('xywh');
|
el.stash('xywh');
|
||||||
|
|
||||||
@@ -846,7 +846,7 @@ export class EdgelessSelectedRectWidget extends WidgetComponent<
|
|||||||
}
|
}
|
||||||
|
|
||||||
get edgelessSlots() {
|
get edgelessSlots() {
|
||||||
return this.block.slots;
|
return this.block?.slots;
|
||||||
}
|
}
|
||||||
|
|
||||||
get frameOverlay() {
|
get frameOverlay() {
|
||||||
@@ -1327,41 +1327,46 @@ export class EdgelessSelectedRectWidget extends WidgetComponent<
|
|||||||
selection.slots.updated.subscribe(this._updateOnSelectionChange)
|
selection.slots.updated.subscribe(this._updateOnSelectionChange)
|
||||||
);
|
);
|
||||||
|
|
||||||
_disposables.add(
|
if (block) {
|
||||||
block.slots.readonlyUpdated.subscribe(() => this.requestUpdate())
|
_disposables.add(
|
||||||
);
|
block.slots.readonlyUpdated.subscribe(() => this.requestUpdate())
|
||||||
|
);
|
||||||
|
|
||||||
|
_disposables.add(
|
||||||
|
block.slots.elementResizeStart.subscribe(
|
||||||
|
() => (this._isResizing = true)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
_disposables.add(
|
||||||
|
block.slots.elementResizeEnd.subscribe(() => (this._isResizing = false))
|
||||||
|
);
|
||||||
|
|
||||||
|
block.handleEvent(
|
||||||
|
'keyDown',
|
||||||
|
ctx => {
|
||||||
|
const event = ctx.get('defaultState').event;
|
||||||
|
if (event instanceof KeyboardEvent) {
|
||||||
|
this._shift(event);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ global: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
block.handleEvent(
|
||||||
|
'keyUp',
|
||||||
|
ctx => {
|
||||||
|
const event = ctx.get('defaultState').event;
|
||||||
|
if (event instanceof KeyboardEvent) {
|
||||||
|
this._shift(event);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ global: true }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
_disposables.add(
|
|
||||||
block.slots.elementResizeStart.subscribe(() => (this._isResizing = true))
|
|
||||||
);
|
|
||||||
_disposables.add(
|
|
||||||
block.slots.elementResizeEnd.subscribe(() => (this._isResizing = false))
|
|
||||||
);
|
|
||||||
_disposables.add(() => {
|
_disposables.add(() => {
|
||||||
this._propDisposables.forEach(disposable => disposable.unsubscribe());
|
this._propDisposables.forEach(disposable => disposable.unsubscribe());
|
||||||
});
|
});
|
||||||
|
|
||||||
this.block.handleEvent(
|
|
||||||
'keyDown',
|
|
||||||
ctx => {
|
|
||||||
const event = ctx.get('defaultState').event;
|
|
||||||
if (event instanceof KeyboardEvent) {
|
|
||||||
this._shift(event);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ global: true }
|
|
||||||
);
|
|
||||||
|
|
||||||
this.block.handleEvent(
|
|
||||||
'keyUp',
|
|
||||||
ctx => {
|
|
||||||
const event = ctx.get('defaultState').event;
|
|
||||||
if (event instanceof KeyboardEvent) {
|
|
||||||
this._shift(event);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ global: true }
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private _shift(event: KeyboardEvent) {
|
private _shift(event: KeyboardEvent) {
|
||||||
|
|||||||
@@ -335,6 +335,9 @@ export class EdgelessToolbarWidget extends WidgetComponent<
|
|||||||
}
|
}
|
||||||
|
|
||||||
private get _quickTools() {
|
private get _quickTools() {
|
||||||
|
if (!this.block) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
return getQuickTools({ edgeless: this.block });
|
return getQuickTools({ edgeless: this.block });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -376,6 +379,9 @@ export class EdgelessToolbarWidget extends WidgetComponent<
|
|||||||
}
|
}
|
||||||
|
|
||||||
private get _seniorTools() {
|
private get _seniorTools() {
|
||||||
|
if (!this.block) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
return getSeniorTools({
|
return getSeniorTools({
|
||||||
edgeless: this.block,
|
edgeless: this.block,
|
||||||
toolbarContainer: this.toolbarContainer,
|
toolbarContainer: this.toolbarContainer,
|
||||||
@@ -573,6 +579,9 @@ export class EdgelessToolbarWidget extends WidgetComponent<
|
|||||||
.get(ThemeProvider)
|
.get(ThemeProvider)
|
||||||
.theme$.subscribe(mode => this._themeProvider.setValue(mode))
|
.theme$.subscribe(mode => this._themeProvider.setValue(mode))
|
||||||
);
|
);
|
||||||
|
if (!this.block) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
this._disposables.add(
|
this._disposables.add(
|
||||||
this.block.bindHotKey(
|
this.block.bindHotKey(
|
||||||
{
|
{
|
||||||
@@ -603,6 +612,9 @@ export class EdgelessToolbarWidget extends WidgetComponent<
|
|||||||
|
|
||||||
override firstUpdated() {
|
override firstUpdated() {
|
||||||
const { _disposables, block, gfx } = this;
|
const { _disposables, block, gfx } = this;
|
||||||
|
if (!block) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_disposables.add(
|
_disposables.add(
|
||||||
gfx.viewport.viewportUpdated.subscribe(() => this.requestUpdate())
|
gfx.viewport.viewportUpdated.subscribe(() => this.requestUpdate())
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ export class AffineEdgelessZoomToolbarWidget extends WidgetComponent<
|
|||||||
|
|
||||||
this.disposables.add(
|
this.disposables.add(
|
||||||
effect(() => {
|
effect(() => {
|
||||||
const currentTool = this.edgeless.gfx.tool.currentToolName$.value;
|
const currentTool = this.edgeless?.gfx.tool.currentToolName$.value;
|
||||||
|
|
||||||
if (currentTool !== 'frameNavigator') {
|
if (currentTool !== 'frameNavigator') {
|
||||||
this._hide = false;
|
this._hide = false;
|
||||||
|
|||||||
@@ -37,6 +37,9 @@ export class AffineImageToolbarWidget extends WidgetComponent<
|
|||||||
this,
|
this,
|
||||||
({ abortController }) => {
|
({ abortController }) => {
|
||||||
const imageBlock = this.block;
|
const imageBlock = this.block;
|
||||||
|
if (!imageBlock) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
const selection = this.host.selection;
|
const selection = this.host.selection;
|
||||||
|
|
||||||
const textSelection = selection.find(TextSelection);
|
const textSelection = selection.find(TextSelection);
|
||||||
@@ -103,6 +106,9 @@ export class AffineImageToolbarWidget extends WidgetComponent<
|
|||||||
);
|
);
|
||||||
|
|
||||||
const imageBlock = this.block;
|
const imageBlock = this.block;
|
||||||
|
if (!imageBlock) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
this._hoverController.setReference(imageBlock);
|
this._hoverController.setReference(imageBlock);
|
||||||
this._hoverController.onAbort = () => {
|
this._hoverController.onAbort = () => {
|
||||||
// If the more menu is opened, don't close it.
|
// If the more menu is opened, don't close it.
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ export class AffineKeyboardToolbarWidget extends WidgetComponent<
|
|||||||
if (blur) {
|
if (blur) {
|
||||||
if (document.activeElement === this._docTitle?.inlineEditorContainer) {
|
if (document.activeElement === this._docTitle?.inlineEditorContainer) {
|
||||||
this._docTitle?.inlineEditor?.setInlineRange(null);
|
this._docTitle?.inlineEditor?.setInlineRange(null);
|
||||||
} else if (document.activeElement === this.block.rootComponent) {
|
} else if (document.activeElement === this.block?.rootComponent) {
|
||||||
this.std.selection.clear();
|
this.std.selection.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -46,7 +46,7 @@ export class AffineKeyboardToolbarWidget extends WidgetComponent<
|
|||||||
override connectedCallback(): void {
|
override connectedCallback(): void {
|
||||||
super.connectedCallback();
|
super.connectedCallback();
|
||||||
|
|
||||||
const { rootComponent } = this.block;
|
const rootComponent = this.block?.rootComponent;
|
||||||
if (rootComponent) {
|
if (rootComponent) {
|
||||||
this.disposables.addFromEvent(rootComponent, 'focus', () => {
|
this.disposables.addFromEvent(rootComponent, 'focus', () => {
|
||||||
this._show$.value = true;
|
this._show$.value = true;
|
||||||
@@ -79,7 +79,7 @@ export class AffineKeyboardToolbarWidget extends WidgetComponent<
|
|||||||
|
|
||||||
if (!this._show$.value) return nothing;
|
if (!this._show$.value) return nothing;
|
||||||
|
|
||||||
if (!this.block.rootComponent) return nothing;
|
if (!this.block?.rootComponent) return nothing;
|
||||||
|
|
||||||
return html`<blocksuite-portal
|
return html`<blocksuite-portal
|
||||||
.shadowDom=${false}
|
.shadowDom=${false}
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ export class AffineLinkedDocWidget extends WidgetComponent<
|
|||||||
}
|
}
|
||||||
|
|
||||||
private readonly _renderLinkedDocMenu = () => {
|
private readonly _renderLinkedDocMenu = () => {
|
||||||
if (!this.block.rootComponent) return nothing;
|
if (!this.block?.rootComponent) return nothing;
|
||||||
|
|
||||||
return html`<affine-mobile-linked-doc-menu
|
return html`<affine-mobile-linked-doc-menu
|
||||||
.context=${this._context}
|
.context=${this._context}
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ export class AffinePageDraggingAreaWidget extends WidgetComponent<
|
|||||||
});
|
});
|
||||||
this._lastPointerState = state;
|
this._lastPointerState = state;
|
||||||
|
|
||||||
if (shouldAutoScroll) {
|
if (shouldAutoScroll && this.scrollContainer) {
|
||||||
const rect = this.scrollContainer.getBoundingClientRect();
|
const rect = this.scrollContainer.getBoundingClientRect();
|
||||||
const result = autoScroll(this.scrollContainer, state.raw.y - rect.top);
|
const result = autoScroll(this.scrollContainer, state.raw.y - rect.top);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
@@ -173,6 +173,9 @@ export class AffinePageDraggingAreaWidget extends WidgetComponent<
|
|||||||
}
|
}
|
||||||
|
|
||||||
private get scrollContainer() {
|
private get scrollContainer() {
|
||||||
|
if (!this.block) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
return getScrollContainer(this.block);
|
return getScrollContainer(this.block);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,6 +49,9 @@ export class AffineSurfaceRefToolbar extends WidgetComponent<
|
|||||||
this,
|
this,
|
||||||
({ abortController }) => {
|
({ abortController }) => {
|
||||||
const surfaceRefBlock = this.block;
|
const surfaceRefBlock = this.block;
|
||||||
|
if (!surfaceRefBlock) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
const selection = this.host.selection;
|
const selection = this.host.selection;
|
||||||
|
|
||||||
const textSelection = selection.find(TextSelection);
|
const textSelection = selection.find(TextSelection);
|
||||||
@@ -100,6 +103,9 @@ export class AffineSurfaceRefToolbar extends WidgetComponent<
|
|||||||
super.connectedCallback();
|
super.connectedCallback();
|
||||||
|
|
||||||
this.moreGroups = getMoreMenuConfig(this.std).configure(this.moreGroups);
|
this.moreGroups = getMoreMenuConfig(this.std).configure(this.moreGroups);
|
||||||
|
if (!this.block) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
this._hoverController.setReference(this.block);
|
this._hoverController.setReference(this.block);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -161,6 +161,8 @@ export class PointerEventWatcher {
|
|||||||
if (this.widget.isGfxDragHandleVisible) return;
|
if (this.widget.isGfxDragHandleVisible) return;
|
||||||
|
|
||||||
const point = new Point(state.raw.x, state.raw.y);
|
const point = new Point(state.raw.x, state.raw.y);
|
||||||
|
if (!this.widget.rootComponent) return;
|
||||||
|
|
||||||
const closestBlock = getClosestBlockByPoint(
|
const closestBlock = getClosestBlockByPoint(
|
||||||
this.widget.host,
|
this.widget.host,
|
||||||
this.widget.rootComponent,
|
this.widget.rootComponent,
|
||||||
@@ -246,6 +248,8 @@ export class PointerEventWatcher {
|
|||||||
// When pointer on drag handle, should do nothing
|
// When pointer on drag handle, should do nothing
|
||||||
if (element.closest('.affine-drag-handle-container')) return;
|
if (element.closest('.affine-drag-handle-container')) return;
|
||||||
|
|
||||||
|
if (!this.widget.rootComponent) return;
|
||||||
|
|
||||||
// When pointer out of note block hover area or inside database, should hide drag handle
|
// When pointer out of note block hover area or inside database, should hide drag handle
|
||||||
const point = new Point(state.raw.x, state.raw.y);
|
const point = new Point(state.raw.x, state.raw.y);
|
||||||
|
|
||||||
|
|||||||
@@ -284,6 +284,9 @@ export class EdgelessAutoConnectWidget extends WidgetComponent<RootBlockModel> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _initLabels() {
|
private _initLabels() {
|
||||||
|
if (!this.block) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const { service } = this.block;
|
const { service } = this.block;
|
||||||
const surfaceRefs = service.doc
|
const surfaceRefs = service.doc
|
||||||
.getBlocksByFlavour('affine:surface-ref')
|
.getBlocksByFlavour('affine:surface-ref')
|
||||||
|
|||||||
@@ -144,6 +144,10 @@ export class AffineDocRemoteSelectionWidget extends WidgetComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _getCursorRect(selections: BaseSelection[]): SelectionRect | null {
|
private _getCursorRect(selections: BaseSelection[]): SelectionRect | null {
|
||||||
|
if (!this.block) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.block.model.flavour !== 'affine:page') {
|
if (this.block.model.flavour !== 'affine:page') {
|
||||||
console.error('remote selection widget must be used in page component');
|
console.error('remote selection widget must be used in page component');
|
||||||
return null;
|
return null;
|
||||||
@@ -208,6 +212,10 @@ export class AffineDocRemoteSelectionWidget extends WidgetComponent {
|
|||||||
private readonly _getSelectionRect = (
|
private readonly _getSelectionRect = (
|
||||||
selections: BaseSelection[]
|
selections: BaseSelection[]
|
||||||
): SelectionRect[] => {
|
): SelectionRect[] => {
|
||||||
|
if (!this.block) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
if (this.block.model.flavour !== 'affine:page') {
|
if (this.block.model.flavour !== 'affine:page') {
|
||||||
console.error('remote selection widget must be used in page component');
|
console.error('remote selection widget must be used in page component');
|
||||||
return [];
|
return [];
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ export class AffineSlashMenuWidget extends WidgetComponent {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.block.model.flavour !== 'affine:page') {
|
if (this.block?.model.flavour !== 'affine:page') {
|
||||||
console.error('SlashMenuWidget should be used in RootBlock');
|
console.error('SlashMenuWidget should be used in RootBlock');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ export class WidgetComponent<
|
|||||||
};
|
};
|
||||||
|
|
||||||
get block() {
|
get block() {
|
||||||
return this.std.view.getBlock(this.model.id) as B;
|
return this.std.view.getBlock(this.model.id) as B | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
get doc() {
|
get doc() {
|
||||||
|
|||||||
@@ -424,18 +424,20 @@ export class AffineAIPanelWidget extends WidgetComponent {
|
|||||||
'pointerdown',
|
'pointerdown',
|
||||||
this._onDocumentClick
|
this._onDocumentClick
|
||||||
);
|
);
|
||||||
this.disposables.add(
|
if (this.block) {
|
||||||
this.block.host.event.add('pointerDown', evtState =>
|
this.disposables.add(
|
||||||
this._onDocumentClick(
|
this.block.host.event.add('pointerDown', evtState =>
|
||||||
evtState.get('pointerState').event as PointerEvent
|
this._onDocumentClick(
|
||||||
|
evtState.get('pointerState').event as PointerEvent
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
);
|
||||||
);
|
this.disposables.add(
|
||||||
this.disposables.add(
|
this.block.host.event.add('click', () => {
|
||||||
this.block.host.event.add('click', () => {
|
return this.state !== 'hidden' ? true : false;
|
||||||
return this.state !== 'hidden' ? true : false;
|
})
|
||||||
})
|
);
|
||||||
);
|
}
|
||||||
this.disposables.addFromEvent(this, 'wheel', stopPropagation);
|
this.disposables.addFromEvent(this, 'wheel', stopPropagation);
|
||||||
this.disposables.addFromEvent(this, 'pointerdown', stopPropagation);
|
this.disposables.addFromEvent(this, 'pointerdown', stopPropagation);
|
||||||
this.disposables.addFromEvent(this, 'pointerup', stopPropagation);
|
this.disposables.addFromEvent(this, 'pointerup', stopPropagation);
|
||||||
|
|||||||
Reference in New Issue
Block a user