Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support paste from word and lark to univer doc #439

Merged
merged 12 commits into from
Nov 15, 2023
4 changes: 1 addition & 3 deletions packages/base-docs/src/basics/memory-cursor.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class MemoryCursor {
export class MemoryCursor {
cursor: number = 0;

reset() {
Expand All @@ -10,5 +10,3 @@ class MemoryCursor {
this.cursor += pos;
}
}

export default MemoryCursor;
12 changes: 7 additions & 5 deletions packages/base-docs/src/commands/commands/core-editing.command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ export interface IDeleteCommandParams {
}

/**
* The command to delete text.
* The command to delete text, mainly used in BACKSPACE.
*/
export const DeleteCommand: ICommand<IDeleteCommandParams> = {
id: 'doc.command.delete-text',
Expand Down Expand Up @@ -131,6 +131,7 @@ export const DeleteCommand: ICommand<IDeleteCommandParams> = {
IRichTextEditingMutationParams,
IRichTextEditingMutationParams
>(doMutation.id, doMutation.params);

if (result) {
undoRedoService.pushUndoRedo({
unitID: unitId,
Expand Down Expand Up @@ -301,15 +302,16 @@ export const CoverCommand: ICommand<ICoverCommandParams> = {
},
};

function getRetainAndDeleteFromReplace(
export function getRetainAndDeleteFromReplace(
range: ITextRange,
segmentId?: string
segmentId: string = '',
memoryCursor: number = 0
): Array<IRetainMutationParams | IDeleteMutationParams> {
const { startOffset, endOffset, collapsed } = range;
const dos: Array<IRetainMutationParams | IDeleteMutationParams> = [];

const textStart = startOffset + (collapsed ? -1 : 0);
const textEnd = endOffset - 1;
const textStart = startOffset + (collapsed ? -1 : 0) - memoryCursor;
const textEnd = endOffset - 1 - memoryCursor;

if (textStart > 0) {
dos.push({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
IUniverInstanceService,
} from '@univerjs/core';

import MemoryCursor from '../../basics/memory-cursor';
import { MemoryCursor } from '../../basics/memory-cursor';
import { TextSelectionManagerService } from '../../services/text-selection-manager.service';
import { IRichTextEditingMutationParams, RichTextEditingMutation } from '../mutations/core-editing.mutation';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
UpdateDocsAttributeType,
} from '@univerjs/core';

import MemoryCursor from '../../basics/memory-cursor';
import { MemoryCursor } from '../../basics/memory-cursor';
import { DeleteApply } from './functions/delete-apply';
import { InsertApply } from './functions/insert-apply';
import { UpdateAttributeApply } from './functions/update-apply';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,17 @@ export function InsertApply(
throw new Error('no body has changed');
}

bodyModel.insert(insertBody, currentIndex);

updateAttributeByInsert(body, insertBody, textLength, currentIndex);

if (insertBody.dataStream.length > 1 && /\r/.test(insertBody.dataStream)) {
// TODO: @JOCS, The DocumentModel needs to be rewritten to better support the
// large area of updates that are brought about by the paste, abstract the
// methods associated with the DocumentModel insertion, and support atomic operations
bodyModel.reset(body);
} else {
bodyModel.insert(insertBody, currentIndex);
}

console.log('插入的model打印', bodyModel, textLength, currentIndex);
}

Expand Down
6 changes: 3 additions & 3 deletions packages/base-docs/src/doc-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ export class DocPlugin extends Plugin {

this._initializeDependencies(_injector);

this.initializeCommands();
this._initializeCommands();
}

initialize(): void {
Expand All @@ -106,7 +106,7 @@ export class DocPlugin extends Plugin {
// this._markDocAsFocused();
}

initializeCommands(): void {
private _initializeCommands(): void {
(
[
MoveCursorOperation,
Expand Down Expand Up @@ -151,7 +151,7 @@ export class DocPlugin extends Plugin {
});
}

initialConfig(config: IDocPluginConfig) {
private initialConfig(config: IDocPluginConfig) {
this._currentUniverService.docAdded$.subscribe((documentModel) => {
if (documentModel == null) {
throw new Error('documentModel is null');
Expand Down
4 changes: 3 additions & 1 deletion packages/base-docs/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
export * from './basics/component-tools';
export * from './basics/docs-view-key';
export { MemoryCursor } from './basics/memory-cursor';
export {
CoverCommand,
DeleteCommand,
getRetainAndDeleteFromReplace,
type ICoverCommandParams,
type IDeleteCommandParams,
type IIMEInputCommandParams,
Expand All @@ -28,6 +30,6 @@ export {
RichTextEditingMutation,
} from './commands/mutations/core-editing.mutation';
export { MoveCursorOperation, MoveSelectionOperation } from './commands/operations/cursor.operation';
export * from './doc-plugin';
export { DocPlugin, type IDocPluginConfig } from './doc-plugin';
export { DocSkeletonManagerService } from './services/doc-skeleton-manager.service';
export { TextSelectionManagerService } from './services/text-selection-manager.service';
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,13 @@ export class DocSkeletonManagerService implements IDisposable {

setCurrent(searchParm: IDocSkeletonManagerSearch): Nullable<IDocSkeletonManagerParam> {
const param = this._getCurrentBySearch(searchParm);

if (param != null) {
if (param.dirty) {
param.skeleton.makeDirty(true);
param.dirty = false;
}

param.skeleton.calculate();
} else {
const { unitId } = searchParm;
Expand Down
4 changes: 3 additions & 1 deletion packages/base-docs/src/views/doc-canvas-view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ export class DocCanvasView {
@IConfigService private readonly _configService: IConfigService,
@IUniverInstanceService private readonly _currentUniverService: IUniverInstanceService,
@Inject(DocSkeletonManagerService) private readonly _docSkeletonManagerService: DocSkeletonManagerService,
// @IRenderingEngine private readonly _engine: Engine,
@Inject(Injector) private readonly _injector: Injector
) {
this._currentUniverService.currentDoc$.subscribe((documentModel) => {
Expand All @@ -52,6 +51,7 @@ export class DocCanvasView {
}

const unitId = documentModel.getUnitId();

if (!this._loadedMap.has(unitId)) {
this._currentDocumentModel = documentModel;
this._addNewRender();
Expand Down Expand Up @@ -103,6 +103,7 @@ export class DocCanvasView {

scene.on(EVENT_TYPE.wheel, (evt: unknown, state: EventState) => {
const e = evt as IWheelEvent;

if (e.ctrlKey) {
const deltaFactor = Math.abs(e.deltaX);
let scrollNum = deltaFactor < 40 ? 0.2 : deltaFactor < 80 ? 0.4 : 0.2;
Expand Down Expand Up @@ -141,6 +142,7 @@ export class DocCanvasView {
this._addComponent(currentRender);

const should = this._currentDocumentModel.getShouldRenderLoopImmediately();

if (should) {
engine.runRenderLoop(() => {
scene.render();
Expand Down
1 change: 1 addition & 0 deletions packages/base-render/src/basics/font-cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ export class FontCache {
}

this.setFontMeasureCache(fontString, content, cache);

return cache;
}

Expand Down
1 change: 1 addition & 0 deletions packages/base-render/src/components/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export class RenderComponent<T, U> extends BaseObject {
getExtensionsByOrder() {
const extensionArray = Array.from(this._extensions.values());
extensionArray.sort(sortRules);

return extensionArray;
}

Expand Down
1 change: 1 addition & 0 deletions packages/base-render/src/components/docs/doc-skeleton.ts
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,7 @@ export class DocumentSkeleton extends Skeleton {
wrapStrategy: WrapStrategy.UNSPECIFIED,
},
} = documentStyle;

const skeleton = this.__getNullSke();

const docsConfig: IDocsConfig = {
Expand Down
3 changes: 3 additions & 0 deletions packages/base-render/src/components/docs/document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ export class Documents extends DocComponent {

override draw(ctx: CanvasRenderingContext2D, bounds?: IBoundRect) {
const documentSkeleton = this.getSkeleton();

if (!documentSkeleton) {
return;
}
Expand All @@ -195,6 +196,7 @@ export class Documents extends DocComponent {
const parentScale = this.getParentScale();
const extensions = this.getExtensionsByOrder();
const scale = getScale(parentScale);

for (const extension of extensions) {
extension.clearCache();
}
Expand Down Expand Up @@ -267,6 +269,7 @@ export class Documents extends DocComponent {

let alignOffset;
let rotateTranslateXListApply = null;

if (vertexAngle !== 0) {
const {
rotateTranslateXList,
Expand Down
2 changes: 2 additions & 0 deletions packages/base-render/src/render-manager.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,14 @@ export class RenderManagerService implements IRenderManagerService {
private _createRender(unitId: string, engine: Engine, isMainScene: boolean = true): IRender {
const existItem = this.getRenderById(unitId);
let shouldDestroyEngine = true;

if (existItem != null) {
const existEngine = existItem.engine;
if (existEngine === engine) {
shouldDestroyEngine = false;
}
}

this._disposeItem(existItem, shouldDestroyEngine);

const { width, height } = DEFAULT_SCENE_SIZE;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,9 @@ export const DEFAULT_DOCUMENT_DATA_EN: IDocumentData = {
nestingLevel: 0,
textStyle: {
fs: 20,
cl: {
rgb: 'rgb(0, 255, 0)',
},
},
},
paragraphStyle: {
Expand Down
6 changes: 5 additions & 1 deletion packages/core/src/docs/domain/data-stream-tree-node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export class DataStreamTreeNode {
}

split(index: number) {
const { children, parent, startIndex, endIndex, nodeType, content = '' } = this.getProps();
const { children, parent, startIndex, nodeType, content = '' } = this.getProps();

if (this.exclude(index)) {
return;
Expand Down Expand Up @@ -152,14 +152,17 @@ export class DataStreamTreeNode {
if (index == null) {
return -1;
}

return index;
}

remove() {
this.children = [];

if (this.parent == null) {
return;
}

this.parent.children.splice(this.getPositionInParent(), 1);
this.parent = null;
}
Expand Down Expand Up @@ -220,6 +223,7 @@ export class DataStreamTreeNode {

for (let i = 0, len = this.content.length; i < len; i++) {
const char = this.content[i];

if (char === DataStreamTreeTokenType.CUSTOM_BLOCK) {
this.blocks.push(this.startIndex + i);
}
Expand Down
7 changes: 4 additions & 3 deletions packages/core/src/docs/domain/document-body-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ export class DocumentBodyModel extends DocumentBodyModelSimple {
insert(insertBody: IDocumentBody, insertIndex = 0) {
const dataStream = insertBody.dataStream;
let dataStreamLen = dataStream.length;
const insertedNode = this.getParagraphByTree(this.children, insertIndex);
const insertedNode = this.getParagraphByIndex(this.children, insertIndex);

if (insertedNode == null) {
return;
Expand Down Expand Up @@ -279,6 +279,7 @@ export class DocumentBodyModel extends DocumentBodyModelSimple {
currentNode.selfPlus(dataStreamLen, currentNode.getPositionInParent());
const children = currentNode.children;
let isStartFix = false;

for (const node of children) {
if (node === insertedLastNode) {
isStartFix = true;
Expand Down Expand Up @@ -328,7 +329,7 @@ export class DocumentBodyModel extends DocumentBodyModelSimple {
this.deleteTree(nodes, currentIndex, textLength);
}

private getParagraphByTree(nodes: DataStreamTreeNode[], insertIndex: number): Nullable<DataStreamTreeNode> {
private getParagraphByIndex(nodes: DataStreamTreeNode[], insertIndex: number): Nullable<DataStreamTreeNode> {
for (const node of nodes) {
const { children } = node;

Expand All @@ -340,7 +341,7 @@ export class DocumentBodyModel extends DocumentBodyModelSimple {
return node;
}

return this.getParagraphByTree(children, insertIndex);
return this.getParagraphByIndex(children, insertIndex);
}

return null;
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/docs/domain/document-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ export class DocumentModel extends DocumentModelSimple {

override updateDocumentId(unitId: string) {
super.updateDocumentId(unitId);

this._unitId = unitId;
}

Expand Down
1 change: 1 addition & 0 deletions packages/core/src/shared/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,7 @@ export function getDocsUpdateBody(model: IDocumentData, segmentId?: string) {

if (segmentId) {
const { headers, footers } = model;

if (headers?.[segmentId]) {
body = headers[segmentId].body;
} else if (footers?.[segmentId]) {
Expand Down
4 changes: 0 additions & 4 deletions packages/core/src/shared/doc-tool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,5 @@ export function deleteContent(content: string, start: number, end: number) {
return content;
}

// if (start === end) {
// start -= 1;
// }

return content.slice(0, start) + content.slice(end);
}
9 changes: 9 additions & 0 deletions packages/core/src/shared/tools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -633,4 +633,13 @@ export class Tools {
}
return new ObjectArray<T>(array);
}

static hasIntersectionBetweenTwoRanges(
range1Start: number,
range1End: number,
range2Start: number,
range2End: number
) {
return range1End >= range2Start && range2End >= range1Start;
}
}
1 change: 1 addition & 0 deletions packages/ui-plugin-docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
"@types/react": "^18.2.37",
"@types/react-dom": "^18.2.15",
"@vitest/coverage-istanbul": "^0.34.6",
"happy-dom": "^12.10.3",
"less": "^4.2.0",
"ts-node": "^10.9.1",
"vitest": "^0.34.6"
Expand Down
Loading
Loading