mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-30 00:29:46 +08:00
feat: repair paste cursor
This commit is contained in:
@@ -905,6 +905,19 @@ class SlateUtils {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public insertNodes(
|
||||||
|
nodes: SlateNode | Array<SlateNode>,
|
||||||
|
options?: Parameters<typeof Transforms.insertNodes>[2]
|
||||||
|
) {
|
||||||
|
Transforms.insertNodes(this.editor, nodes, {
|
||||||
|
...options,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public getNodeByPath(path: Path) {
|
||||||
|
Editor.node(this.editor, path);
|
||||||
|
}
|
||||||
|
|
||||||
public getStartSelection() {
|
public getStartSelection() {
|
||||||
return {
|
return {
|
||||||
anchor: this.getStart(),
|
anchor: this.getStart(),
|
||||||
|
|||||||
@@ -3,7 +3,13 @@ import type {
|
|||||||
SlateUtils,
|
SlateUtils,
|
||||||
TextAlignOptions,
|
TextAlignOptions,
|
||||||
} from '@toeverything/components/common';
|
} from '@toeverything/components/common';
|
||||||
import { Point, Selection as SlateSelection } from 'slate';
|
import {
|
||||||
|
BaseRange,
|
||||||
|
Node,
|
||||||
|
Path,
|
||||||
|
Point,
|
||||||
|
Selection as SlateSelection,
|
||||||
|
} from 'slate';
|
||||||
import { Editor } from '../editor';
|
import { Editor } from '../editor';
|
||||||
|
|
||||||
type TextUtilsFunctions =
|
type TextUtilsFunctions =
|
||||||
@@ -28,7 +34,10 @@ type TextUtilsFunctions =
|
|||||||
| 'removeSelection'
|
| 'removeSelection'
|
||||||
| 'insertReference'
|
| 'insertReference'
|
||||||
| 'isCollapsed'
|
| 'isCollapsed'
|
||||||
| 'blur';
|
| 'blur'
|
||||||
|
| 'setSelection'
|
||||||
|
| 'insertNodes'
|
||||||
|
| 'getNodeByPath';
|
||||||
|
|
||||||
type ExtendedTextUtils = SlateUtils & {
|
type ExtendedTextUtils = SlateUtils & {
|
||||||
setLinkModalVisible: (visible: boolean) => void;
|
setLinkModalVisible: (visible: boolean) => void;
|
||||||
@@ -193,6 +202,59 @@ export class BlockHelper {
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* set selection of a text input
|
||||||
|
* @param {string} blockId
|
||||||
|
* @param {BaseRange} selection
|
||||||
|
* @return {*}
|
||||||
|
* @memberof BlockHelper
|
||||||
|
*/
|
||||||
|
public setSelection(blockId: string, selection: BaseRange) {
|
||||||
|
const text_utils = this._blockTextUtilsMap[blockId];
|
||||||
|
if (text_utils) {
|
||||||
|
return text_utils.setSelection(selection);
|
||||||
|
}
|
||||||
|
console.warn('Could find the block text utils');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* insert nodes in text
|
||||||
|
* @param {string} blockId
|
||||||
|
* @param {Array<Node>} nodes
|
||||||
|
* @param {Parameters<TextUtils['insertNodes']>[1]} options
|
||||||
|
* @return {*}
|
||||||
|
* @memberof BlockHelper
|
||||||
|
*/
|
||||||
|
public insertNodes(
|
||||||
|
blockId: string,
|
||||||
|
nodes: Array<Node>,
|
||||||
|
options?: Parameters<TextUtils['insertNodes']>[1]
|
||||||
|
) {
|
||||||
|
const text_utils = this._blockTextUtilsMap[blockId];
|
||||||
|
if (text_utils) {
|
||||||
|
return text_utils.insertNodes(nodes, options);
|
||||||
|
}
|
||||||
|
console.warn('Could find the block text utils');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* get text(slate node) by path
|
||||||
|
* @param {string} blockId
|
||||||
|
* @param {Path} path
|
||||||
|
* @return {*}
|
||||||
|
* @memberof BlockHelper
|
||||||
|
*/
|
||||||
|
public getNodeByPath(blockId: string, path: Path) {
|
||||||
|
const text_utils = this._blockTextUtilsMap[blockId];
|
||||||
|
if (text_utils) {
|
||||||
|
return text_utils.getNodeByPath(path);
|
||||||
|
}
|
||||||
|
console.warn('Could find the block text utils');
|
||||||
|
}
|
||||||
|
|
||||||
public transformPoint(
|
public transformPoint(
|
||||||
blockId: string,
|
blockId: string,
|
||||||
...restArgs: Parameters<TextUtils['transformPoint']>
|
...restArgs: Parameters<TextUtils['transformPoint']>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { HooksRunner } from '../types';
|
/* eslint-disable max-lines */
|
||||||
import {
|
import {
|
||||||
OFFICE_CLIPBOARD_MIMETYPE,
|
OFFICE_CLIPBOARD_MIMETYPE,
|
||||||
InnerClipInfo,
|
InnerClipInfo,
|
||||||
@@ -187,10 +187,15 @@ export class Paste {
|
|||||||
const pureText = !shouldSplitBlock
|
const pureText = !shouldSplitBlock
|
||||||
? blocks[0].properties.text.value
|
? blocks[0].properties.text.value
|
||||||
: [{ text: '' }];
|
: [{ text: '' }];
|
||||||
this._editor.blockHelper.setBlockBlur(
|
this._editor.blockHelper.insertNodes(
|
||||||
currentSelectInfo.blocks[0].blockId
|
selectedBlock.id,
|
||||||
|
pureText,
|
||||||
|
{ select: true }
|
||||||
);
|
);
|
||||||
|
return;
|
||||||
|
//TODO repair the following logics
|
||||||
|
|
||||||
|
/**
|
||||||
const { startInfo, endInfo } = currentSelectInfo.blocks[0];
|
const { startInfo, endInfo } = currentSelectInfo.blocks[0];
|
||||||
|
|
||||||
// 选中的当前的可编辑block的文字信息
|
// 选中的当前的可编辑block的文字信息
|
||||||
@@ -414,13 +419,13 @@ export class Paste {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const pastedTextLength = pureText.reduce(
|
// const pastedTextLength = pureText.reduce(
|
||||||
(sumLength: number, textItem: TextValueItem) => {
|
// (sumLength: number, textItem: TextValueItem) => {
|
||||||
sumLength += textItem.text.length;
|
// sumLength += textItem.text.length;
|
||||||
return sumLength;
|
// return sumLength;
|
||||||
},
|
// },
|
||||||
0
|
// 0
|
||||||
);
|
// );
|
||||||
|
|
||||||
// this._editor.selectionManager.moveCursor(
|
// this._editor.selectionManager.moveCursor(
|
||||||
// window.getSelection().getRangeAt(0),
|
// window.getSelection().getRangeAt(0),
|
||||||
@@ -429,6 +434,7 @@ export class Paste {
|
|||||||
// );
|
// );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
} else {
|
} else {
|
||||||
const pasteBlocks = await this._createBlocks(blocks);
|
const pasteBlocks = await this._createBlocks(blocks);
|
||||||
pasteBlocks.forEach(block => {
|
pasteBlocks.forEach(block => {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import {Editor} from "../editor";
|
import { Editor } from '../editor';
|
||||||
|
|
||||||
export const shouldHandlerContinue = (event: Event, editor: Editor) => {
|
export const shouldHandlerContinue = (event: Event, editor: Editor) => {
|
||||||
const filterNodes = ['INPUT', 'SELECT', 'TEXTAREA'];
|
const filterNodes = ['INPUT', 'SELECT', 'TEXTAREA'];
|
||||||
|
|||||||
@@ -322,16 +322,16 @@ export class SelectionManager implements VirgoSelection {
|
|||||||
if (selectionRect.isIntersect(domToRect(block.dom))) {
|
if (selectionRect.isIntersect(domToRect(block.dom))) {
|
||||||
const childrenBlocks = await block.children();
|
const childrenBlocks = await block.children();
|
||||||
// should check directly in structured block
|
// should check directly in structured block
|
||||||
const structuredChildrenBlocks: Array<AsyncBlock> = childrenBlocks.filter(
|
const structuredChildrenBlocks: Array<AsyncBlock> =
|
||||||
childBlock => {
|
childrenBlocks.filter(childBlock => {
|
||||||
return this._editor.getView(childBlock.type).layoutOnly;
|
return this._editor.getView(childBlock.type).layoutOnly;
|
||||||
}
|
});
|
||||||
);
|
|
||||||
for await (const childBlock of structuredChildrenBlocks) {
|
for await (const childBlock of structuredChildrenBlocks) {
|
||||||
const childSelectedNodes = await this.calcRenderBlockIntersect(
|
const childSelectedNodes =
|
||||||
selectionRect,
|
await this.calcRenderBlockIntersect(
|
||||||
childBlock
|
selectionRect,
|
||||||
);
|
childBlock
|
||||||
|
);
|
||||||
selectedNodes.push(...childSelectedNodes);
|
selectedNodes.push(...childSelectedNodes);
|
||||||
}
|
}
|
||||||
const selectableChildren = childrenBlocks.filter(childBlock => {
|
const selectableChildren = childrenBlocks.filter(childBlock => {
|
||||||
@@ -348,10 +348,11 @@ export class SelectionManager implements VirgoSelection {
|
|||||||
}
|
}
|
||||||
// if just only has one selected maybe select the children
|
// if just only has one selected maybe select the children
|
||||||
if (selectedNodes.length === 1) {
|
if (selectedNodes.length === 1) {
|
||||||
const childrenSelectedNodes: Array<AsyncBlock> = await this.calcRenderBlockIntersect(
|
const childrenSelectedNodes: Array<AsyncBlock> =
|
||||||
selectionRect,
|
await this.calcRenderBlockIntersect(
|
||||||
selectedNodes[0]
|
selectionRect,
|
||||||
);
|
selectedNodes[0]
|
||||||
|
);
|
||||||
if (childrenSelectedNodes.length)
|
if (childrenSelectedNodes.length)
|
||||||
return childrenSelectedNodes;
|
return childrenSelectedNodes;
|
||||||
}
|
}
|
||||||
@@ -584,7 +585,8 @@ export class SelectionManager implements VirgoSelection {
|
|||||||
} else {
|
} else {
|
||||||
const new_node = await this._editor.getBlockById(newNodeId);
|
const new_node = await this._editor.getBlockById(newNodeId);
|
||||||
if (new_node) {
|
if (new_node) {
|
||||||
const new_node_children_ids = await new_node.childrenIds;
|
const new_node_children_ids =
|
||||||
|
await new_node.childrenIds;
|
||||||
let select_ids_new = this._selectedNodesIds;
|
let select_ids_new = this._selectedNodesIds;
|
||||||
if (
|
if (
|
||||||
new_node_children_ids &&
|
new_node_children_ids &&
|
||||||
|
|||||||
Reference in New Issue
Block a user