mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-13 21:05:19 +00:00
fix(editor): remove rootRect and modify layout
This commit is contained in:
@@ -31,10 +31,8 @@ export const RenderRoot: FC<PropsWithChildren<RenderRootProps>> = ({
|
||||
editorElement,
|
||||
children,
|
||||
}) => {
|
||||
const contentRef = useRef<HTMLDivElement>(null);
|
||||
const selectionRef = useRef<SelectionRef>(null);
|
||||
const triggeredBySelect = useRef(false);
|
||||
const [container, setContainer] = useState<HTMLDivElement>();
|
||||
const [pageWidth, setPageWidth] = useState<number>(MIN_PAGE_WIDTH);
|
||||
const isOnDrag = useIsOnDrag(editor);
|
||||
|
||||
@@ -55,13 +53,6 @@ export const RenderRoot: FC<PropsWithChildren<RenderRootProps>> = ({
|
||||
}
|
||||
}, [editor.workspace, rootId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (container) {
|
||||
editor.container = container;
|
||||
editor.getHooks().render();
|
||||
}
|
||||
}, [editor, container]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchPageBlockWidth();
|
||||
|
||||
@@ -85,11 +76,7 @@ export const RenderRoot: FC<PropsWithChildren<RenderRootProps>> = ({
|
||||
event: React.MouseEvent<HTMLDivElement, MouseEvent>
|
||||
) => {
|
||||
selectionRef.current?.onMouseMove(event);
|
||||
if (!contentRef.current) {
|
||||
return;
|
||||
}
|
||||
const rootRect: DOMRect = contentRef.current.getBoundingClientRect();
|
||||
editor.getHooks().onRootNodeMouseMove(event, rootRect);
|
||||
editor.getHooks().onRootNodeMouseMove(event);
|
||||
|
||||
const slidingBlock = await editor.getBlockByPoint(
|
||||
new Point(event.clientX, event.clientY)
|
||||
@@ -100,7 +87,6 @@ export const RenderRoot: FC<PropsWithChildren<RenderRootProps>> = ({
|
||||
blockId: slidingBlock.id,
|
||||
dom: slidingBlock.dom,
|
||||
rect: slidingBlock.dom.getBoundingClientRect(),
|
||||
rootRect: rootRect,
|
||||
type: slidingBlock.type,
|
||||
properties: slidingBlock.getProperties(),
|
||||
});
|
||||
@@ -149,33 +135,21 @@ export const RenderRoot: FC<PropsWithChildren<RenderRootProps>> = ({
|
||||
};
|
||||
|
||||
const onDragOver = (event: React.DragEvent<Element>) => {
|
||||
event.dataTransfer.dropEffect = 'move';
|
||||
event.preventDefault();
|
||||
if (!contentRef.current) {
|
||||
return;
|
||||
}
|
||||
const rootRect: DOMRect = contentRef.current.getBoundingClientRect();
|
||||
editor.dragDropManager.handlerEditorDragOver(event);
|
||||
if (editor.dragDropManager.isEnabled()) {
|
||||
editor.getHooks().onRootNodeDragOver(event, rootRect);
|
||||
editor.getHooks().onRootNodeDragOver(event);
|
||||
}
|
||||
};
|
||||
|
||||
const onDragOverCapture = (event: React.DragEvent<Element>) => {
|
||||
event.preventDefault();
|
||||
if (!contentRef.current) {
|
||||
return;
|
||||
}
|
||||
const rootRect: DOMRect = contentRef.current.getBoundingClientRect();
|
||||
if (editor.dragDropManager.isEnabled()) {
|
||||
editor.getHooks().onRootNodeDragOver(event, rootRect);
|
||||
editor.getHooks().onRootNodeDragOver(event);
|
||||
}
|
||||
};
|
||||
|
||||
const onDragEnd = (event: React.DragEvent<Element>) => {
|
||||
const rootRect: DOMRect = contentRef.current.getBoundingClientRect();
|
||||
editor.dragDropManager.handlerEditorDragEnd(event);
|
||||
editor.getHooks().onRootNodeDragEnd(event, rootRect);
|
||||
editor.getHooks().onRootNodeDragEnd(event);
|
||||
};
|
||||
|
||||
const onDrop = (event: React.DragEvent<Element>) => {
|
||||
@@ -192,7 +166,10 @@ export const RenderRoot: FC<PropsWithChildren<RenderRootProps>> = ({
|
||||
<Container
|
||||
isWhiteboard={editor.isWhiteboard}
|
||||
ref={ref => {
|
||||
ref && setContainer(ref);
|
||||
if (ref != null && ref !== editor.container) {
|
||||
editor.container = ref;
|
||||
editor.getHooks().render();
|
||||
}
|
||||
}}
|
||||
onMouseMove={onMouseMove}
|
||||
onMouseDown={onMouseDown}
|
||||
@@ -208,18 +185,13 @@ export const RenderRoot: FC<PropsWithChildren<RenderRootProps>> = ({
|
||||
onDrop={onDrop}
|
||||
isOnDrag={isOnDrag}
|
||||
>
|
||||
<Content
|
||||
ref={contentRef}
|
||||
style={{ maxWidth: pageWidth + 'px' }}
|
||||
>
|
||||
<Content style={{ maxWidth: pageWidth + 'px' }}>
|
||||
{children}
|
||||
{patchedNodes}
|
||||
</Content>
|
||||
{/** TODO: remove selectionManager insert */}
|
||||
{container && editor && (
|
||||
<SelectionRect ref={selectionRef} editor={editor} />
|
||||
)}
|
||||
{editor && <SelectionRect ref={selectionRef} editor={editor} />}
|
||||
{editor.isWhiteboard ? null : <ScrollBlank editor={editor} />}
|
||||
{patchedNodes}
|
||||
</Container>
|
||||
</RootContext.Provider>
|
||||
);
|
||||
@@ -281,6 +253,8 @@ function ScrollBlank({ editor }: { editor: BlockEditor }) {
|
||||
);
|
||||
}
|
||||
|
||||
const PADDING_X = 150;
|
||||
|
||||
const Container = styled('div')(
|
||||
({
|
||||
isWhiteboard,
|
||||
@@ -290,9 +264,7 @@ const Container = styled('div')(
|
||||
isOnDrag: boolean;
|
||||
}) => ({
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
overflowY: isWhiteboard ? 'unset' : 'auto',
|
||||
padding: isWhiteboard ? 0 : '96px 150px 0 150px',
|
||||
padding: isWhiteboard ? 0 : `96px ${PADDING_X}px 0 ${PADDING_X}px`,
|
||||
minWidth: isWhiteboard ? 'unset' : '940px',
|
||||
position: 'relative',
|
||||
...(isOnDrag && {
|
||||
@@ -309,7 +281,9 @@ const Content = styled('div')({
|
||||
margin: '0 auto',
|
||||
transitionDuration: '.2s',
|
||||
transitionTimingFunction: 'ease-in',
|
||||
position: 'relative',
|
||||
});
|
||||
|
||||
const ScrollBlankContainter = styled('div')({ paddingBottom: '30vh' });
|
||||
const ScrollBlankContainter = styled('div')({
|
||||
paddingBottom: '30vh',
|
||||
margin: `0 -${PADDING_X}px`,
|
||||
});
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import { AsyncBlock, BlockEditor } from '../editor';
|
||||
import { ReactElement } from 'react';
|
||||
|
||||
export const dragDropWrapperClass = 'drag-drop-wrapper';
|
||||
|
||||
interface DragDropWrapperProps {
|
||||
editor: BlockEditor;
|
||||
block: AsyncBlock;
|
||||
@@ -14,25 +12,16 @@ export function DragDropWrapper({
|
||||
editor,
|
||||
block,
|
||||
}: DragDropWrapperProps) {
|
||||
const handler_drag_over: React.DragEventHandler<
|
||||
HTMLDivElement
|
||||
> = async event => {
|
||||
event.preventDefault();
|
||||
const rootDom = await editor.getBlockDomById(editor.getRootBlockId());
|
||||
if (block.dom && rootDom) {
|
||||
const handlerDragOver: React.DragEventHandler<HTMLDivElement> = event => {
|
||||
if (block.dom) {
|
||||
editor.getHooks().afterOnNodeDragOver(event, {
|
||||
blockId: block.id,
|
||||
dom: block.dom,
|
||||
rect: block.dom?.getBoundingClientRect(),
|
||||
rootRect: rootDom.getBoundingClientRect(),
|
||||
type: block.type,
|
||||
properties: block.getProperties(),
|
||||
});
|
||||
}
|
||||
};
|
||||
return (
|
||||
<div onDragOver={handler_drag_over} className={dragDropWrapperClass}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
return <div onDragOver={handlerDragOver}>{children}</div>;
|
||||
}
|
||||
|
||||
@@ -15,37 +15,37 @@ interface PluginHookInfo {
|
||||
}
|
||||
|
||||
export class Hooks implements HooksRunner, PluginHooks {
|
||||
private hooks_map: Map<string, PluginHookInfo[]> = new Map();
|
||||
private _hooksMap: Map<string, PluginHookInfo[]> = new Map();
|
||||
|
||||
dispose() {
|
||||
this.hooks_map.clear();
|
||||
this._hooksMap.clear();
|
||||
}
|
||||
|
||||
private run_hook(key: HookType, ...params: unknown[]): void {
|
||||
const hook_infos: PluginHookInfo[] = this.hooks_map.get(key) || [];
|
||||
hook_infos.forEach(hook_info => {
|
||||
if (hook_info.once) {
|
||||
this.removeHook(key, hook_info.callback);
|
||||
private _runHook(key: HookType, ...params: unknown[]): void {
|
||||
const hookInfos: PluginHookInfo[] = this._hooksMap.get(key) || [];
|
||||
hookInfos.forEach(hookInfo => {
|
||||
if (hookInfo.once) {
|
||||
this.removeHook(key, hookInfo.callback);
|
||||
}
|
||||
let is_stopped_propagation = false;
|
||||
let isStoppedPropagation = false;
|
||||
const hookOption: HookBaseArgs = {
|
||||
stopImmediatePropagation: () => {
|
||||
is_stopped_propagation = true;
|
||||
isStoppedPropagation = true;
|
||||
},
|
||||
};
|
||||
hook_info.callback.call(
|
||||
hook_info.thisObj || this,
|
||||
hookInfo.callback.call(
|
||||
hookInfo.thisObj || this,
|
||||
...params,
|
||||
hookOption
|
||||
);
|
||||
return is_stopped_propagation;
|
||||
return isStoppedPropagation;
|
||||
});
|
||||
}
|
||||
|
||||
private has_hook(key: HookType, callback: AnyFunction): boolean {
|
||||
const hook_infos: PluginHookInfo[] = this.hooks_map.get(key) || [];
|
||||
for (let i = hook_infos.length - 1; i >= 0; i--) {
|
||||
if (hook_infos[i].callback === callback) {
|
||||
private _hasHook(key: HookType, callback: AnyFunction): boolean {
|
||||
const hookInfos: PluginHookInfo[] = this._hooksMap.get(key) || [];
|
||||
for (let i = hookInfos.length - 1; i >= 0; i--) {
|
||||
if (hookInfos[i].callback === callback) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -59,14 +59,14 @@ export class Hooks implements HooksRunner, PluginHooks {
|
||||
thisObj?: AnyThisType,
|
||||
once?: boolean
|
||||
): void {
|
||||
if (this.has_hook(key, callback)) {
|
||||
if (this._hasHook(key, callback)) {
|
||||
throw new Error('Duplicate registration of the same class');
|
||||
}
|
||||
if (!this.hooks_map.has(key)) {
|
||||
this.hooks_map.set(key, []);
|
||||
if (!this._hooksMap.has(key)) {
|
||||
this._hooksMap.set(key, []);
|
||||
}
|
||||
const hook_infos: PluginHookInfo[] = this.hooks_map.get(key);
|
||||
hook_infos.push({ callback, thisObj, once });
|
||||
const hookInfos: PluginHookInfo[] = this._hooksMap.get(key);
|
||||
hookInfos.push({ callback, thisObj, once });
|
||||
}
|
||||
|
||||
// 执行一次
|
||||
@@ -80,122 +80,112 @@ export class Hooks implements HooksRunner, PluginHooks {
|
||||
|
||||
// 移除
|
||||
public removeHook(key: HookType, callback: AnyFunction): void {
|
||||
const hook_infos: PluginHookInfo[] = this.hooks_map.get(key) || [];
|
||||
for (let i = hook_infos.length - 1; i >= 0; i--) {
|
||||
if (hook_infos[i].callback === callback) {
|
||||
hook_infos.splice(i, 1);
|
||||
const hookInfos: PluginHookInfo[] = this._hooksMap.get(key) || [];
|
||||
for (let i = hookInfos.length - 1; i >= 0; i--) {
|
||||
if (hookInfos[i].callback === callback) {
|
||||
hookInfos.splice(i, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public init(): void {
|
||||
this.run_hook(HookType.INIT);
|
||||
this._runHook(HookType.INIT);
|
||||
}
|
||||
|
||||
public render(): void {
|
||||
this.run_hook(HookType.RENDER);
|
||||
this._runHook(HookType.RENDER);
|
||||
}
|
||||
|
||||
public onRootNodeKeyDown(e: React.KeyboardEvent<HTMLDivElement>): void {
|
||||
this.run_hook(HookType.ON_ROOT_NODE_KEYDOWN, e);
|
||||
this._runHook(HookType.ON_ROOT_NODE_KEYDOWN, e);
|
||||
}
|
||||
|
||||
public onRootNodeKeyDownCapture(
|
||||
e: React.KeyboardEvent<HTMLDivElement>
|
||||
): void {
|
||||
this.run_hook(HookType.ON_ROOT_NODE_KEYDOWN_CAPTURE, e);
|
||||
this._runHook(HookType.ON_ROOT_NODE_KEYDOWN_CAPTURE, e);
|
||||
}
|
||||
|
||||
public onRootNodeKeyUp(e: React.KeyboardEvent<HTMLDivElement>): void {
|
||||
this.run_hook(HookType.ON_ROOT_NODE_KEYUP, e);
|
||||
this._runHook(HookType.ON_ROOT_NODE_KEYUP, e);
|
||||
}
|
||||
|
||||
public onRootNodeMouseDown(
|
||||
e: React.MouseEvent<HTMLDivElement, MouseEvent>
|
||||
): void {
|
||||
this.run_hook(HookType.ON_ROOTNODE_MOUSE_DOWN, e);
|
||||
this._runHook(HookType.ON_ROOTNODE_MOUSE_DOWN, e);
|
||||
}
|
||||
|
||||
public onRootNodeMouseMove(
|
||||
e: React.MouseEvent<HTMLDivElement, MouseEvent>,
|
||||
root_rect: DOMRect
|
||||
e: React.MouseEvent<HTMLDivElement, MouseEvent>
|
||||
): void {
|
||||
this.run_hook(HookType.ON_ROOTNODE_MOUSE_MOVE, e, root_rect);
|
||||
this._runHook(HookType.ON_ROOTNODE_MOUSE_MOVE, e);
|
||||
}
|
||||
|
||||
public onRootNodeMouseUp(
|
||||
e: React.MouseEvent<HTMLDivElement, MouseEvent>
|
||||
): void {
|
||||
this.run_hook(HookType.ON_ROOTNODE_MOUSE_UP, e);
|
||||
this._runHook(HookType.ON_ROOTNODE_MOUSE_UP, e);
|
||||
}
|
||||
|
||||
public onRootNodeMouseOut(
|
||||
e: React.MouseEvent<HTMLDivElement, MouseEvent>
|
||||
): void {
|
||||
this.run_hook(HookType.ON_ROOTNODE_MOUSE_OUT, e);
|
||||
this._runHook(HookType.ON_ROOTNODE_MOUSE_OUT, e);
|
||||
}
|
||||
|
||||
public onRootNodeMouseLeave(
|
||||
e: React.MouseEvent<HTMLDivElement, MouseEvent>
|
||||
): void {
|
||||
this.run_hook(HookType.ON_ROOTNODE_MOUSE_LEAVE, e);
|
||||
this._runHook(HookType.ON_ROOTNODE_MOUSE_LEAVE, e);
|
||||
}
|
||||
|
||||
public afterOnNodeMouseMove(
|
||||
e: React.MouseEvent<HTMLDivElement, MouseEvent>,
|
||||
node: BlockDomInfo
|
||||
): void {
|
||||
this.run_hook(HookType.AFTER_ON_NODE_MOUSE_MOVE, e, node);
|
||||
this._runHook(HookType.AFTER_ON_NODE_MOUSE_MOVE, e, node);
|
||||
}
|
||||
|
||||
public afterOnResize(
|
||||
e: React.MouseEvent<HTMLDivElement, MouseEvent>
|
||||
): void {
|
||||
this.run_hook(HookType.AFTER_ON_RESIZE, e);
|
||||
this._runHook(HookType.AFTER_ON_RESIZE, e);
|
||||
}
|
||||
|
||||
public onRootNodeDragOver(
|
||||
e: React.DragEvent<Element>,
|
||||
root_rect: DOMRect
|
||||
): void {
|
||||
this.run_hook(HookType.ON_ROOTNODE_DRAG_OVER, e, root_rect);
|
||||
public onRootNodeDragOver(e: React.DragEvent<Element>): void {
|
||||
this._runHook(HookType.ON_ROOTNODE_DRAG_OVER, e);
|
||||
}
|
||||
|
||||
public onRootNodeDragEnd(
|
||||
e: React.DragEvent<Element>,
|
||||
root_rect: DOMRect
|
||||
): void {
|
||||
this.run_hook(HookType.ON_ROOTNODE_DRAG_END, e, root_rect);
|
||||
public onRootNodeDragEnd(e: React.DragEvent<Element>): void {
|
||||
this._runHook(HookType.ON_ROOTNODE_DRAG_END, e);
|
||||
}
|
||||
|
||||
public onRootNodeDrop(e: React.DragEvent<Element>): void {
|
||||
this.run_hook(HookType.ON_ROOTNODE_DROP, e);
|
||||
this._runHook(HookType.ON_ROOTNODE_DROP, e);
|
||||
}
|
||||
|
||||
public onRootNodeDragOverCapture(
|
||||
e: React.DragEvent<Element>,
|
||||
root_rect: DOMRect
|
||||
): void {
|
||||
this.run_hook(HookType.ON_ROOTNODE_DRAG_OVER_CAPTURE, e, root_rect);
|
||||
public onRootNodeDragOverCapture(e: React.DragEvent<Element>): void {
|
||||
this._runHook(HookType.ON_ROOTNODE_DRAG_OVER_CAPTURE, e);
|
||||
}
|
||||
|
||||
public afterOnNodeDragOver(
|
||||
e: React.DragEvent<Element>,
|
||||
node: BlockDomInfo
|
||||
): void {
|
||||
this.run_hook(HookType.AFTER_ON_NODE_DRAG_OVER, e, node);
|
||||
this._runHook(HookType.AFTER_ON_NODE_DRAG_OVER, e, node);
|
||||
}
|
||||
|
||||
public onSearch(): void {
|
||||
this.run_hook(HookType.ON_SEARCH);
|
||||
this._runHook(HookType.ON_SEARCH);
|
||||
}
|
||||
|
||||
public beforeCopy(e: ClipboardEvent): void {
|
||||
this.run_hook(HookType.BEFORE_COPY, e);
|
||||
this._runHook(HookType.BEFORE_COPY, e);
|
||||
}
|
||||
|
||||
public beforeCut(e: ClipboardEvent): void {
|
||||
this.run_hook(HookType.BEFORE_CUT, e);
|
||||
this._runHook(HookType.BEFORE_CUT, e);
|
||||
}
|
||||
|
||||
public onRootNodeScroll(e: React.UIEvent): void {
|
||||
|
||||
@@ -186,7 +186,6 @@ export interface BlockDomInfo {
|
||||
dom: HTMLElement;
|
||||
type: BlockFlavorKeys;
|
||||
rect: DOMRect;
|
||||
rootRect: DOMRect;
|
||||
properties: Record<string, unknown>;
|
||||
}
|
||||
|
||||
@@ -201,8 +200,7 @@ export interface HooksRunner {
|
||||
e: React.MouseEvent<HTMLDivElement, MouseEvent>
|
||||
) => void;
|
||||
onRootNodeMouseMove: (
|
||||
e: React.MouseEvent<HTMLDivElement, MouseEvent>,
|
||||
root_rect: DOMRect
|
||||
e: React.MouseEvent<HTMLDivElement, MouseEvent>
|
||||
) => void;
|
||||
onRootNodeMouseUp: (
|
||||
e: React.MouseEvent<HTMLDivElement, MouseEvent>
|
||||
@@ -219,14 +217,8 @@ export interface HooksRunner {
|
||||
node: BlockDomInfo
|
||||
) => void;
|
||||
afterOnResize: (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => void;
|
||||
onRootNodeDragOver: (
|
||||
e: React.DragEvent<Element>,
|
||||
root_rect: DOMRect
|
||||
) => void;
|
||||
onRootNodeDragEnd: (
|
||||
e: React.DragEvent<Element>,
|
||||
root_rect: DOMRect
|
||||
) => void;
|
||||
onRootNodeDragOver: (e: React.DragEvent<Element>) => void;
|
||||
onRootNodeDragEnd: (e: React.DragEvent<Element>) => void;
|
||||
onRootNodeDrop: (e: React.DragEvent<Element>) => void;
|
||||
afterOnNodeDragOver: (
|
||||
e: React.DragEvent<Element>,
|
||||
|
||||
Reference in New Issue
Block a user