feat: repair paste cursor

This commit is contained in:
SaikaSakura
2022-08-11 22:06:50 +08:00
parent 0a265f9981
commit 322fb098a4
5 changed files with 109 additions and 26 deletions
@@ -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 &&