mirror of
https://github.com/dream-num/univer.git
synced 2026-10-29 18:06:28 +08:00
refactor: migrate doc to sheet as cell editor and support focus manager & context service (#112)
This commit is contained in:
+7
-7
@@ -93,19 +93,19 @@ module.exports = {
|
||||
},
|
||||
],
|
||||
// eslint-plugin-unused-imports
|
||||
'@typescript-eslint/no-unused-vars': 'off',
|
||||
'unused-imports/no-unused-imports': 'error',
|
||||
'prefer-regex-literals': 'off',
|
||||
'@typescript-eslint/consistent-type-assertions': 'off',
|
||||
'@typescript-eslint/default-param-last': 'off',
|
||||
'grouped-accessor-pairs': 'off',
|
||||
'@typescript-eslint/member-ordering': 'error',
|
||||
'@typescript-eslint/no-explicit-any': 'warn',
|
||||
'no-unsafe-optional-chaining': 'off',
|
||||
'@typescript-eslint/consistent-type-assertions': 'off',
|
||||
'@typescript-eslint/no-redeclare': 'off', // dependency interface and dependency token share the same name
|
||||
'@typescript-eslint/no-unused-vars': 'off',
|
||||
'grouped-accessor-pairs': 'off',
|
||||
'no-magic-numbers': ['warn', { ignore: [0, 1, -1, 2] }],
|
||||
'simple-import-sort/imports': 'error',
|
||||
'no-unsafe-optional-chaining': 'off',
|
||||
'prefer-regex-literals': 'off',
|
||||
'simple-import-sort/exports': 'error',
|
||||
'simple-import-sort/imports': 'error',
|
||||
'unused-imports/no-unused-imports': 'error',
|
||||
},
|
||||
// https://www.npmjs.com/package/eslint-import-resolver-typescript
|
||||
settings: {
|
||||
|
||||
@@ -5,7 +5,7 @@ const args = require('minimist')(process.argv.slice(2));
|
||||
bundle: true,
|
||||
color: true,
|
||||
loader: { '.svg': 'file' },
|
||||
sourcemap: false,
|
||||
sourcemap: true,
|
||||
plugins: [
|
||||
require('esbuild-plugin-clean').clean({
|
||||
patterns: ['./local'],
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="favicon.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>UniverDoc</title>
|
||||
<style>
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app" style="z-index: 1; position: fixed; font-size: 20px; color: green"></div>
|
||||
<div id="univerdoc" style="height: 100vh; width: 100%"></div>
|
||||
<script type="module" src="./src/main.tsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,33 +1,30 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta content="width=device-width, initial-scale=1" name="viewport" />
|
||||
<title>UniverDoc</title>
|
||||
|
||||
<link rel="stylesheet" href="./main.css" />
|
||||
<style>
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
<script>
|
||||
new EventSource('/esbuild').addEventListener('change', () => {
|
||||
location.reload()
|
||||
})
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app" style="z-index: 1; position: fixed; font-size: 20px; color: green;"></div>
|
||||
<div id="univerdoc" style="height: 100%;"></div>
|
||||
|
||||
<script src="./main.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta content="width=device-width, initial-scale=1" name="viewport" />
|
||||
<title>UniverDoc</title>
|
||||
|
||||
<link rel="stylesheet" href="./main.css" />
|
||||
<style>
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
new EventSource('/esbuild').addEventListener('change', () => {
|
||||
location.reload();
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app" style="z-index: 1; position: fixed; font-size: 20px; color: green"></div>
|
||||
<div id="univer-container" style="height: 100%"></div>
|
||||
|
||||
<script src="./main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,17 +1,25 @@
|
||||
import { DocPlugin } from '@univerjs/base-docs';
|
||||
import { RenderEngine } from '@univerjs/base-render';
|
||||
import { UIPlugin } from '@univerjs/base-ui';
|
||||
import { DEFAULT_DOCUMENT_DATA_EN } from '@univerjs/common-plugin-data';
|
||||
import { LocaleType, Univer } from '@univerjs/core';
|
||||
import { DocUIPlugin } from '@univerjs/ui-plugin-docs';
|
||||
|
||||
// univer
|
||||
const univer = new Univer({
|
||||
locale: LocaleType.EN,
|
||||
});
|
||||
|
||||
univer.createUniverDoc(DEFAULT_DOCUMENT_DATA_EN);
|
||||
|
||||
// core plugins
|
||||
univer.registerPlugin(RenderEngine);
|
||||
univer.registerPlugin(DocPlugin);
|
||||
univer.registerPlugin(UIPlugin, {
|
||||
container: 'univer-container',
|
||||
header: true,
|
||||
toolbar: true,
|
||||
});
|
||||
univer.registerPlugin(DocPlugin, {
|
||||
standalone: true,
|
||||
});
|
||||
univer.registerPlugin(DocUIPlugin, {
|
||||
container: 'univerdoc',
|
||||
layout: {
|
||||
@@ -20,3 +28,5 @@ univer.registerPlugin(DocUIPlugin, {
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
univer.createUniverDoc(DEFAULT_DOCUMENT_DATA_EN);
|
||||
|
||||
@@ -5,7 +5,7 @@ const args = require('minimist')(process.argv.slice(2));
|
||||
bundle: true,
|
||||
color: true,
|
||||
loader: { '.svg': 'file' },
|
||||
sourcemap: false,
|
||||
sourcemap: true,
|
||||
plugins: [
|
||||
require('esbuild-plugin-clean').clean({
|
||||
patterns: ['./local'],
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="favicon.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>UniverSheet</title>
|
||||
<style>
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app" style="z-index: 1; position: fixed; font-size: 20px; color: green;"></div>
|
||||
<div id="universheet" style="height: 100%;"></div>
|
||||
<script type="module" src="./src/main.tsx"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -29,6 +29,7 @@
|
||||
"ts-node": "^10.9.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@univerjs/base-docs": "workspace:^0.0.1",
|
||||
"@univerjs/base-render": "workspace:^0.0.1",
|
||||
"@univerjs/base-sheets": "workspace:^0.0.1",
|
||||
"@univerjs/base-ui": "workspace:^0.0.1",
|
||||
@@ -40,8 +41,9 @@
|
||||
"@univerjs/sheets-plugin-import-xlsx": "workspace:^0.0.1",
|
||||
"@univerjs/sheets-plugin-numfmt": "workspace:^0.0.1",
|
||||
"@univerjs/sheets-plugin-operation": "workspace:^0.0.1",
|
||||
"@univerjs/ui-plugin-docs": "workspace:^0.0.1",
|
||||
"@univerjs/ui-plugin-sheets": "workspace:^0.0.1",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0"
|
||||
"react-dom": "^18.2.0",
|
||||
"react": "^18.2.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,35 +1,31 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta content="width=device-width, initial-scale=1" name="viewport" />
|
||||
<title>Univer Sheet</title>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta content="width=device-width, initial-scale=1" name="viewport" />
|
||||
<title>Univer Sheet</title>
|
||||
<link rel="stylesheet" href="./main.css" />
|
||||
<style>
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
<link rel="stylesheet" href="./main.css" />
|
||||
<style>
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
new EventSource('/esbuild').addEventListener('change', () => {
|
||||
console.info('reload--');
|
||||
location.reload();
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body style="overflow: hidden">
|
||||
<div id="app" style="z-index: 1; position: fixed; font-size: 20px; color: green"></div>
|
||||
<div id="univer-container" style="height: 100%"></div>
|
||||
|
||||
<script>
|
||||
new EventSource('/esbuild').addEventListener('change', () => {
|
||||
console.info('reload--')
|
||||
location.reload()
|
||||
})
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body style="overflow: hidden;">
|
||||
<div id="app" style="z-index: 1; position: fixed; font-size: 20px; color: green;"></div>
|
||||
<!-- <div id="universheet" style="height: 225px;width: 400px;"></div> -->
|
||||
<div id="universheet" style="height: 100%;"></div>
|
||||
|
||||
<script src="./main.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
<script src="./main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
import { DocPlugin } from '@univerjs/base-docs';
|
||||
import { RenderEngine } from '@univerjs/base-render';
|
||||
import { SheetPlugin } from '@univerjs/base-sheets';
|
||||
import { UIPlugin } from '@univerjs/base-ui';
|
||||
import { DEFAULT_WORKBOOK_DATA_DEMO } from '@univerjs/common-plugin-data';
|
||||
import { LocaleType, Univer } from '@univerjs/core';
|
||||
import { FindPlugin } from '@univerjs/sheets-plugin-find';
|
||||
import { DEFAULT_FORMULA_DATA_DEMO, FormulaPlugin } from '@univerjs/sheets-plugin-formula';
|
||||
// import { OperationPlugin } from '@univerjs/sheets-plugin-operation';
|
||||
import { ImagePlugin } from '@univerjs/sheets-plugin-image';
|
||||
import { ImportXlsxPlugin } from '@univerjs/sheets-plugin-import-xlsx';
|
||||
import { NumfmtPlugin } from '@univerjs/sheets-plugin-numfmt';
|
||||
import { DocUIPlugin } from '@univerjs/ui-plugin-docs';
|
||||
import { SheetUIPlugin } from '@univerjs/ui-plugin-sheets';
|
||||
|
||||
// univer
|
||||
@@ -15,32 +17,29 @@ const univer = new Univer({
|
||||
locale: LocaleType.EN,
|
||||
});
|
||||
|
||||
// create univer sheet instance
|
||||
univer.createUniverSheet(DEFAULT_WORKBOOK_DATA_DEMO);
|
||||
|
||||
// register plugins
|
||||
univer.registerPlugin(RenderEngine);
|
||||
univer.registerPlugin(SheetPlugin);
|
||||
univer.registerPlugin(SheetUIPlugin, {
|
||||
container: 'universheet',
|
||||
layout: {
|
||||
sheetContainerConfig: {
|
||||
infoBar: true,
|
||||
formulaBar: true,
|
||||
toolbar: true,
|
||||
sheetBar: true,
|
||||
countBar: true,
|
||||
rightMenu: true,
|
||||
},
|
||||
},
|
||||
// core plugins
|
||||
univer.registerPlugin(DocPlugin, {
|
||||
standalone: false,
|
||||
});
|
||||
univer.registerPlugin(DocUIPlugin);
|
||||
univer.registerPlugin(RenderEngine);
|
||||
univer.registerPlugin(UIPlugin, {
|
||||
container: 'univer-container',
|
||||
header: true,
|
||||
toolbar: true,
|
||||
});
|
||||
univer.registerPlugin(SheetPlugin);
|
||||
univer.registerPlugin(SheetUIPlugin);
|
||||
|
||||
// feature plugins
|
||||
univer.registerPlugin(NumfmtPlugin);
|
||||
univer.registerPlugin(FindPlugin);
|
||||
univer.registerPlugin(FormulaPlugin, DEFAULT_FORMULA_DATA_DEMO);
|
||||
univer.registerPlugin(ImportXlsxPlugin);
|
||||
univer.registerPlugin(ImagePlugin);
|
||||
// univer.registerPlugin(OperationPlugin);
|
||||
|
||||
// create univer sheet instance
|
||||
univer.createUniverSheet(DEFAULT_WORKBOOK_DATA_DEMO);
|
||||
|
||||
// use for console test
|
||||
declare global {
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
"@wendellhu/redi": "^0.12.7",
|
||||
"css-vars-ponyfill": "^2.4.6",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0"
|
||||
"react-dom": "^18.2.0",
|
||||
"rxjs": "^7.8.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,31 +13,76 @@ import {
|
||||
isSameLine,
|
||||
TextSelection,
|
||||
} from '@univerjs/base-render';
|
||||
import { DataStreamTreeTokenType, Direction, DocumentModel, ICommandService, ICurrentUniverService, IParagraph, Nullable, Observable } from '@univerjs/core';
|
||||
import { Inject } from '@wendellhu/redi';
|
||||
import {
|
||||
DataStreamTreeTokenType,
|
||||
Direction,
|
||||
Disposable,
|
||||
DisposableCollection,
|
||||
DocumentModel,
|
||||
fromObservable,
|
||||
ICommandService,
|
||||
ICurrentUniverService,
|
||||
IParagraph,
|
||||
Nullable,
|
||||
Observable,
|
||||
toDisposable,
|
||||
} from '@univerjs/core';
|
||||
import { IDisposable, Inject } from '@wendellhu/redi';
|
||||
|
||||
import { DeleteCommand, IMEInputCommand, InsertCommand, UpdateCommand } from '../commands/commands/core-editing.command';
|
||||
import { CanvasView } from '../View/Render/CanvasView';
|
||||
import { DocsViewManagerService } from '../services/docs-view-manager/docs-view-manager.service';
|
||||
import { DocsView } from '../View/Render/Views';
|
||||
|
||||
export class InputController {
|
||||
/**
|
||||
* InputController handles inputting events on the currently focused DocsView and apply edits to corresponding UniverDoc.
|
||||
*/
|
||||
export class InputController extends Disposable {
|
||||
private _previousIMEContent: string = '';
|
||||
|
||||
private _previousIMEStart: number;
|
||||
|
||||
private _currentNodePosition: Nullable<INodePosition>;
|
||||
|
||||
private _editorDisposables: DisposableCollection | null;
|
||||
|
||||
private _currentDocsView: DocsView | null;
|
||||
|
||||
constructor(
|
||||
@Inject(CanvasView) private readonly _canvasView: CanvasView,
|
||||
@Inject(DocsViewManagerService) private readonly _docsViewManager: DocsViewManagerService,
|
||||
@ICurrentUniverService private readonly _currentUniverService: ICurrentUniverService,
|
||||
@ICommandService private readonly _commandService: ICommandService
|
||||
) {
|
||||
this._initialize();
|
||||
super();
|
||||
|
||||
this.disposeWithMe(
|
||||
fromObservable(
|
||||
this._docsViewManager.current$.subscribe((docsView) => {
|
||||
this._currentDocsView?.getDocs().disableEditor();
|
||||
this._editorDisposables?.dispose();
|
||||
this._editorDisposables = null;
|
||||
|
||||
if (docsView) {
|
||||
this._currentDocsView = docsView;
|
||||
this._editorDisposables = this._initialize(docsView);
|
||||
}
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
override dispose(): void {
|
||||
super.dispose();
|
||||
|
||||
this._currentDocsView = null;
|
||||
this._editorDisposables?.dispose();
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/member-ordering
|
||||
moveCursor(_docModel: DocumentModel, direction: Direction) {
|
||||
const documents = (this._canvasView.getDocsView() as DocsView).getDocs();
|
||||
if (!this._currentDocsView) {
|
||||
return;
|
||||
}
|
||||
|
||||
const documents = this._currentDocsView.getDocs();
|
||||
const activeSelection = documents.getActiveSelection();
|
||||
if (!activeSelection) {
|
||||
return false;
|
||||
@@ -115,7 +160,11 @@ export class InputController {
|
||||
|
||||
// eslint-disable-next-line max-lines-per-function
|
||||
deleteLeft() {
|
||||
const document = (this._canvasView.getDocsView() as DocsView).getDocs();
|
||||
if (!this._currentDocsView) {
|
||||
return;
|
||||
}
|
||||
|
||||
const document = this._currentDocsView.getDocs();
|
||||
const activeSelection = document.getActiveSelection();
|
||||
if (!activeSelection) {
|
||||
return;
|
||||
@@ -232,7 +281,11 @@ export class InputController {
|
||||
}
|
||||
|
||||
breakLine() {
|
||||
const document = (this._canvasView.getDocsView() as DocsView).getDocs();
|
||||
if (!this._currentDocsView) {
|
||||
return;
|
||||
}
|
||||
|
||||
const document = this._currentDocsView.getDocs();
|
||||
const activeSelection = document.getActiveSelection();
|
||||
if (!activeSelection) {
|
||||
return;
|
||||
@@ -272,8 +325,8 @@ export class InputController {
|
||||
this._adjustSelection(document as Documents, selectionRemain, span, true);
|
||||
}
|
||||
|
||||
private _initialInput(onInputObservable: Observable<IEditorInputConfig>, docsModel: DocumentModel) {
|
||||
onInputObservable.add((config) => {
|
||||
private _initialInput(onInputObservable: Observable<IEditorInputConfig>, docsModel: DocumentModel): IDisposable {
|
||||
const observer = onInputObservable.add((config) => {
|
||||
const { event, content = '', document, activeSelection, selectionList } = config;
|
||||
|
||||
const e = event as InputEvent;
|
||||
@@ -319,6 +372,8 @@ export class InputController {
|
||||
|
||||
this._adjustSelection(document as Documents, selectionRemain, span);
|
||||
});
|
||||
|
||||
return toDisposable(() => onInputObservable.remove(observer));
|
||||
}
|
||||
|
||||
private _initialComposition(
|
||||
@@ -326,8 +381,8 @@ export class InputController {
|
||||
onCompositionupdateObservable: Observable<IEditorInputConfig>,
|
||||
onCompositionendObservable: Observable<IEditorInputConfig>,
|
||||
docsModel: DocumentModel
|
||||
) {
|
||||
onCompositionstartObservable.add((config) => {
|
||||
): IDisposable {
|
||||
const startObserver = onCompositionstartObservable.add((config) => {
|
||||
const { activeSelection, selectionList } = config;
|
||||
|
||||
const activeRange = activeSelection?.getRange();
|
||||
@@ -346,7 +401,7 @@ export class InputController {
|
||||
this._previousIMEStart = cursor;
|
||||
});
|
||||
|
||||
onCompositionupdateObservable.add(async (config) => {
|
||||
const updateObserver = onCompositionupdateObservable.add(async (config) => {
|
||||
const { event, document, activeSelection } = config;
|
||||
|
||||
let cursor = this._previousIMEStart;
|
||||
@@ -388,9 +443,15 @@ export class InputController {
|
||||
this._previousIMEContent = content;
|
||||
});
|
||||
|
||||
onCompositionendObservable.add((config) => {
|
||||
const endObserver = onCompositionendObservable.add((config) => {
|
||||
this._resetIME();
|
||||
});
|
||||
|
||||
return toDisposable(() => {
|
||||
onCompositionstartObservable.remove(startObserver);
|
||||
onCompositionupdateObservable.remove(updateObserver);
|
||||
onCompositionendObservable.remove(endObserver);
|
||||
});
|
||||
}
|
||||
|
||||
private _getTopOrBottomPosition(document: Documents, span: Nullable<IDocumentSkeletonSpan>, direction: boolean): Nullable<INodePosition> {
|
||||
@@ -661,23 +722,26 @@ export class InputController {
|
||||
document.syncSelection();
|
||||
}
|
||||
|
||||
private _initialize() {
|
||||
const docsView = this._canvasView.getDocsView() as DocsView;
|
||||
private _initialize(docsView: DocsView): DisposableCollection {
|
||||
docsView.getDocs().enableEditor();
|
||||
const events = docsView.getDocs().getEditorInputEvent();
|
||||
|
||||
const docsModel = this._currentUniverService.getCurrentUniverDocInstance().getDocument();
|
||||
const disposableCollection = new DisposableCollection();
|
||||
|
||||
if (!events) {
|
||||
return;
|
||||
return disposableCollection;
|
||||
}
|
||||
|
||||
const { onInputObservable, onCompositionstartObservable, onCompositionupdateObservable, onCompositionendObservable, onSelectionStartObservable } = events;
|
||||
|
||||
this._initialInput(onInputObservable, docsModel);
|
||||
disposableCollection.add(this._initialInput(onInputObservable, docsModel));
|
||||
disposableCollection.add(this._initialComposition(onCompositionstartObservable, onCompositionupdateObservable, onCompositionendObservable, docsModel));
|
||||
|
||||
this._initialComposition(onCompositionstartObservable, onCompositionupdateObservable, onCompositionendObservable, docsModel);
|
||||
|
||||
onSelectionStartObservable.add((nodePosition) => {
|
||||
const observer = onSelectionStartObservable.add((nodePosition) => {
|
||||
this._currentNodePosition = nodePosition;
|
||||
});
|
||||
disposableCollection.add(toDisposable(() => onSelectionStartObservable.remove(observer)));
|
||||
|
||||
return disposableCollection;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,24 @@
|
||||
import { Engine } from '@univerjs/base-render';
|
||||
import { DesktopPlatformService, DesktopShortcutService, IPlatformService, IShortcutService } from '@univerjs/base-ui';
|
||||
import { ICommandService, LocaleService, ObserverManager, Plugin, PLUGIN_NAMES, PluginType, UIObserver } from '@univerjs/core';
|
||||
import { Dependency, Inject, Injector } from '@wendellhu/redi';
|
||||
import { ContextService, DesktopPlatformService, IContextService, IPlatformService, IShortcutService } from '@univerjs/base-ui';
|
||||
import { ICommand, ICommandService, ICurrentUniverService, LocaleService, Plugin, PLUGIN_NAMES, PluginType } from '@univerjs/core';
|
||||
import { Dependency, Inject, Injector, SkipSelf } from '@wendellhu/redi';
|
||||
|
||||
import { DocPluginObserve, install } from './Basics/Observer';
|
||||
import { BreakLineCommand, DeleteCommand, DeleteLeftCommand, IMEInputCommand, InsertCommand, UpdateCommand } from './commands/commands/core-editing.command';
|
||||
import { BreakLineCommand, CoverCommand, DeleteCommand, DeleteLeftCommand, IMEInputCommand, InsertCommand, UpdateCommand } from './commands/commands/core-editing.command';
|
||||
import { RichTextEditingMutation } from './commands/mutations/core-editing.mutation';
|
||||
import { MoveCursorOperation } from './commands/operations/cursor.operation';
|
||||
import { DocumentController } from './Controller/DocumentController';
|
||||
import { en, zh } from './Locale';
|
||||
import { DocsViewManagerService } from './services/docs-view-manager/docs-view-manager.service';
|
||||
import { BreakLineShortcut, DeleteLeftShortcut } from './shortcuts/core-editing.shortcut';
|
||||
import { MoveCursorDownShortcut, MoveCursorLeftShortcut, MoveCursorRightShortcut, MoveCursorUpShortcut } from './shortcuts/cursor.shortcut';
|
||||
import { CANVAS_VIEW_KEY } from './View/Render';
|
||||
import { CanvasView } from './View/Render/CanvasView';
|
||||
import { DocsView } from './View/Render/Views';
|
||||
|
||||
export interface IDocPluginConfig {}
|
||||
export interface IDocPluginConfig {
|
||||
standalone?: boolean;
|
||||
}
|
||||
|
||||
const DEFAULT_DOCUMENT_PLUGIN_DATA = {};
|
||||
|
||||
@@ -32,14 +35,15 @@ export class DocPlugin extends Plugin<DocPluginObserve> {
|
||||
|
||||
constructor(
|
||||
config: Partial<IDocPluginConfig> = {},
|
||||
@Inject(ObserverManager) private readonly _globalObserverManager: ObserverManager,
|
||||
@SkipSelf() @Inject(Injector) _univerInjector: Injector,
|
||||
@Inject(Injector) override _injector: Injector,
|
||||
@Inject(LocaleService) private readonly _localeService: LocaleService
|
||||
@Inject(LocaleService) private readonly _localeService: LocaleService,
|
||||
@ICurrentUniverService private readonly _currentUniverService: ICurrentUniverService
|
||||
) {
|
||||
super(PLUGIN_NAMES.DOCUMENT);
|
||||
|
||||
this._config = Object.assign(DEFAULT_DOCUMENT_PLUGIN_DATA, config);
|
||||
this._initializeDependencies(_injector);
|
||||
this._initializeDependencies(_injector, _univerInjector);
|
||||
this.initializeCommands();
|
||||
}
|
||||
|
||||
@@ -51,11 +55,28 @@ export class DocPlugin extends Plugin<DocPluginObserve> {
|
||||
|
||||
install(this);
|
||||
|
||||
this.listenEventManager();
|
||||
if (this._config.standalone) {
|
||||
this.initCanvasView();
|
||||
}
|
||||
|
||||
this._initController();
|
||||
this._markDocAsFocused();
|
||||
}
|
||||
|
||||
initializeCommands(): void {
|
||||
[MoveCursorOperation, DeleteLeftCommand, BreakLineCommand, InsertCommand, DeleteCommand, UpdateCommand, IMEInputCommand, RichTextEditingMutation].forEach((command) => {
|
||||
(
|
||||
[
|
||||
MoveCursorOperation,
|
||||
DeleteLeftCommand,
|
||||
BreakLineCommand,
|
||||
InsertCommand,
|
||||
DeleteCommand,
|
||||
UpdateCommand,
|
||||
IMEInputCommand,
|
||||
RichTextEditingMutation,
|
||||
CoverCommand,
|
||||
] as ICommand[]
|
||||
).forEach((command) => {
|
||||
this._injector.get(ICommandService).registerCommand(command);
|
||||
});
|
||||
|
||||
@@ -64,12 +85,7 @@ export class DocPlugin extends Plugin<DocPluginObserve> {
|
||||
});
|
||||
}
|
||||
|
||||
initializeAfterUI() {
|
||||
this.initCanvasView();
|
||||
this.initController();
|
||||
}
|
||||
|
||||
initController() {
|
||||
_initController() {
|
||||
this._documentController = new DocumentController(this._injector);
|
||||
}
|
||||
|
||||
@@ -77,14 +93,6 @@ export class DocPlugin extends Plugin<DocPluginObserve> {
|
||||
this._canvasView = this._injector.get(CanvasView);
|
||||
}
|
||||
|
||||
listenEventManager() {
|
||||
// FIXME@wzhudev: this looks strange to be. It should not rely on the event created by a upper layer plugin.
|
||||
// Instead, upper layer plugin should call it.
|
||||
this._getCoreObserver<boolean>('onUIDidMountObservable').add(() => {
|
||||
this.initializeAfterUI();
|
||||
});
|
||||
}
|
||||
|
||||
getConfig() {
|
||||
return this._config;
|
||||
}
|
||||
@@ -151,16 +159,23 @@ export class DocPlugin extends Plugin<DocPluginObserve> {
|
||||
|
||||
override onDestroy(): void {}
|
||||
|
||||
/** @deprecated This will be removed. Modules should inject `ObserverManager` instead of getting it from plugin. */
|
||||
protected _getCoreObserver<T>(type: string) {
|
||||
return this._globalObserverManager.requiredObserver<UIObserver<T>>(type, 'core');
|
||||
private _initializeDependencies(docInjector: Injector, univerInjector: Injector) {
|
||||
(
|
||||
[
|
||||
[CanvasView, { useFactory: () => docInjector.createInstance(CanvasView, this._config.standalone ?? true) }], // FIXME: CanvasView shouldn't be a dependency of DocPlugin. Because it maybe created dynamically.
|
||||
[IPlatformService, { useClass: DesktopPlatformService }],
|
||||
[IContextService, { useClass: ContextService }],
|
||||
] as Dependency[]
|
||||
).forEach((d) => docInjector.add(d));
|
||||
|
||||
// add docs view manager to univer-level injector
|
||||
univerInjector.add([DocsViewManagerService]);
|
||||
}
|
||||
|
||||
private _initializeDependencies(docInjector: Injector) {
|
||||
const dependencies: Dependency[] = [[CanvasView], [IShortcutService, { useClass: DesktopShortcutService }], [IPlatformService, { useClass: DesktopPlatformService }]];
|
||||
|
||||
dependencies.forEach((d) => {
|
||||
docInjector.add(d);
|
||||
});
|
||||
private _markDocAsFocused() {
|
||||
if (this._config.standalone) {
|
||||
const c = this._currentUniverService.getCurrentUniverDocInstance();
|
||||
this._currentUniverService.focusUniverInstance(c.getUnitId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ export class BaseView {
|
||||
}
|
||||
|
||||
export enum CANVAS_VIEW_KEY {
|
||||
MAIN_SCENE = 'mainScene',
|
||||
MAIN_SCENE = 'docMainScene',
|
||||
DOCS_VIEW = 'docsView',
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,13 @@ export class CanvasView {
|
||||
|
||||
private _views: BaseView[] = [];
|
||||
|
||||
constructor(@IRenderingEngine private readonly _engine: Engine, @Inject(Injector) private readonly _injector: Injector) {
|
||||
constructor(
|
||||
// TODO@wzhudev: CanvasView should not be a singleton
|
||||
/** @deprecated This a temporary solution. CanvasView should not be a singleton. */
|
||||
private standalone = true,
|
||||
@IRenderingEngine private readonly _engine: Engine,
|
||||
@Inject(Injector) private readonly _injector: Injector
|
||||
) {
|
||||
this._initialize();
|
||||
}
|
||||
|
||||
@@ -30,12 +36,11 @@ export class CanvasView {
|
||||
private _initialize() {
|
||||
const engine = this._engine;
|
||||
|
||||
const scene = new Scene(CANVAS_VIEW_KEY.MAIN_SCENE, engine, {
|
||||
width: 1200,
|
||||
const scene = (this._scene = new Scene(CANVAS_VIEW_KEY.MAIN_SCENE, engine, {
|
||||
width: 1024,
|
||||
height: 2000,
|
||||
});
|
||||
}));
|
||||
|
||||
this._scene = scene;
|
||||
const viewMain = new Viewport(CANVAS_VIEW_KEY.DOCS_VIEW, scene, {
|
||||
left: 0,
|
||||
top: 0,
|
||||
@@ -76,13 +81,15 @@ export class CanvasView {
|
||||
|
||||
this._viewLoader(scene);
|
||||
|
||||
engine.runRenderLoop(() => {
|
||||
scene.render();
|
||||
const app = document.getElementById('app');
|
||||
if (app) {
|
||||
app.innerText = `fps:${Math.round(engine.getFps()).toString()}`;
|
||||
}
|
||||
});
|
||||
if (this.standalone) {
|
||||
engine.runRenderLoop(() => {
|
||||
scene.render();
|
||||
const app = document.getElementById('app');
|
||||
if (app) {
|
||||
app.innerText = `fps:${Math.round(engine.getFps()).toString()}`;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private _viewLoader(scene: Scene) {
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Documents, DocumentSkeleton, IDocumentSkeletonDrawing, Picture, Scene }
|
||||
import { DocumentModel, ICurrentUniverService, LocaleService } from '@univerjs/core';
|
||||
import { Inject, Injector } from '@wendellhu/redi';
|
||||
|
||||
import { DocsViewManagerService } from '../../../services/docs-view-manager/docs-view-manager.service';
|
||||
import { BaseView, CANVAS_VIEW_KEY, CanvasViewRegistry } from '../BaseView';
|
||||
|
||||
export enum DOCS_VIEW_KEY {
|
||||
@@ -17,8 +18,30 @@ export class DocsView extends BaseView {
|
||||
|
||||
private _documents: Documents;
|
||||
|
||||
constructor(@ICurrentUniverService private readonly _currentUniverService: ICurrentUniverService, @Inject(LocaleService) private readonly _localeService: LocaleService) {
|
||||
private readonly _useExternalModel: boolean;
|
||||
|
||||
private _model: DocumentModel | null = null;
|
||||
|
||||
// TODO: wzhudev this is strange that DocsView depends on current univer service
|
||||
constructor(
|
||||
externalModel: DocumentModel | undefined,
|
||||
@ICurrentUniverService private readonly _currentUniverService: ICurrentUniverService,
|
||||
@Inject(DocsViewManagerService) private _docsViewManagerService: DocsViewManagerService,
|
||||
@Inject(LocaleService) private readonly _localeService: LocaleService
|
||||
) {
|
||||
super();
|
||||
|
||||
if (externalModel) {
|
||||
this._useExternalModel = true;
|
||||
this._model = externalModel;
|
||||
} else {
|
||||
this._useExternalModel = false;
|
||||
}
|
||||
|
||||
const docsModel = this._useExternalModel ? externalModel : this._currentUniverService.getCurrentUniverDocInstance()?.getDocument();
|
||||
if (docsModel) {
|
||||
this._docsViewManagerService.registerCanvasViewForUniverInstance(docsModel!.getUnitId(), this);
|
||||
}
|
||||
}
|
||||
|
||||
getDocumentSkeleton() {
|
||||
@@ -51,12 +74,16 @@ export class DocsView extends BaseView {
|
||||
|
||||
protected override _initialize() {
|
||||
const scene = this.getScene();
|
||||
|
||||
const docsModel = this._currentUniverService.getCurrentUniverDocInstance().getDocument();
|
||||
const docsModel = this._useExternalModel ? this._model! : this._currentUniverService.getCurrentUniverDocInstance()?.getDocument();
|
||||
if (!docsModel) {
|
||||
return;
|
||||
}
|
||||
|
||||
const documentSkeleton = this._buildSkeleton(docsModel);
|
||||
|
||||
const documents = new Documents(DOCS_VIEW_KEY.MAIN, documentSkeleton);
|
||||
const documents = new Documents(DOCS_VIEW_KEY.MAIN, documentSkeleton, {
|
||||
pageMarginLeft: docsModel.documentStyle.marginLeft,
|
||||
pageMarginTop: docsModel.documentStyle.marginTop,
|
||||
});
|
||||
documents.zIndex = 1000;
|
||||
this._documentSkeleton = documentSkeleton;
|
||||
this._documents = documents;
|
||||
@@ -110,8 +137,6 @@ export class DocsView extends BaseView {
|
||||
obj?.translate(obj.left + docsLeft - pageMarginLeft, obj.top + docsTop - pageMarginTop);
|
||||
}
|
||||
}
|
||||
|
||||
documents.enableEditor();
|
||||
}
|
||||
|
||||
private _buildSkeleton(model: DocumentModel) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Rect, Documents, IPageRenderConfig, Scene } from '@univerjs/base-render';
|
||||
import { Documents, IPageRenderConfig, Rect, Scene } from '@univerjs/base-render';
|
||||
import { Injector } from '@wendellhu/redi';
|
||||
|
||||
import { BaseView, CanvasViewRegistry } from '../BaseView';
|
||||
import { DOCS_VIEW_KEY } from './DocsView';
|
||||
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import {
|
||||
CommandType,
|
||||
createEmptyDocSnapshot,
|
||||
getTextIndexByCursor,
|
||||
ICommand,
|
||||
ICommandInfo,
|
||||
ICommandService,
|
||||
ICurrentUniverService,
|
||||
IDocumentBody,
|
||||
IDocumentData,
|
||||
ITextSelectionRange,
|
||||
IUndoRedoService,
|
||||
UpdateDocsAttributeType,
|
||||
@@ -91,7 +94,7 @@ export const InsertCommand: ICommand<IInsertCommandParams> = {
|
||||
const result = await commandService.executeCommand<IRichTextEditingMutationParams, IRichTextEditingMutationParams>(doMutation.id, doMutation.params);
|
||||
if (result) {
|
||||
undoRedoService.pushUndoRedo({
|
||||
URI: 'doc',
|
||||
URI: unitId,
|
||||
undo() {
|
||||
commandService.executeCommand(RichTextEditingMutation.id, result);
|
||||
return true;
|
||||
@@ -143,7 +146,7 @@ export const DeleteCommand: ICommand<IDeleteCommandParams> = {
|
||||
const result = await commandService.executeCommand<IRichTextEditingMutationParams, IRichTextEditingMutationParams>(doMutation.id, doMutation.params);
|
||||
if (result) {
|
||||
undoRedoService.pushUndoRedo({
|
||||
URI: 'doc',
|
||||
URI: unitId,
|
||||
undo() {
|
||||
commandService.executeCommand(RichTextEditingMutation.id, result);
|
||||
return true;
|
||||
@@ -212,7 +215,7 @@ export const UpdateCommand: ICommand<IUpdateCommandParams> = {
|
||||
const result = await commandService.executeCommand<IRichTextEditingMutationParams, IRichTextEditingMutationParams>(doMutation.id, doMutation.params);
|
||||
if (result) {
|
||||
undoRedoService.pushUndoRedo({
|
||||
URI: 'doc',
|
||||
URI: unitId,
|
||||
undo() {
|
||||
commandService.executeCommand(RichTextEditingMutation.id, result);
|
||||
return true;
|
||||
@@ -243,7 +246,6 @@ export const IMEInputCommand: ICommand<IIMEInputCommandParams> = {
|
||||
type: CommandType.COMMAND,
|
||||
handler: async (accessor, params: IIMEInputCommandParams) => {
|
||||
const commandService = accessor.get(ICommandService);
|
||||
const undoRedoService = accessor.get(IUndoRedoService);
|
||||
|
||||
const { unitId, newText, oldTextLen, start, segmentId } = params;
|
||||
const doMutation: ICommandInfo<IRichTextEditingMutationParams> = {
|
||||
@@ -281,7 +283,6 @@ export const IMEInputCommand: ICommand<IIMEInputCommandParams> = {
|
||||
|
||||
const result = await commandService.executeCommand(doMutation.id, doMutation.params);
|
||||
if (!result) {
|
||||
// NOTE: maybe we should throw an error here?
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -289,6 +290,35 @@ export const IMEInputCommand: ICommand<IIMEInputCommandParams> = {
|
||||
},
|
||||
};
|
||||
|
||||
export interface ICoverCommandParams {
|
||||
unitId: string;
|
||||
|
||||
snapshot?: IDocumentData;
|
||||
clearUndoRedoStack?: boolean;
|
||||
}
|
||||
|
||||
export const CoverCommand: ICommand<ICoverCommandParams> = {
|
||||
id: 'doc.command-cover-content',
|
||||
type: CommandType.COMMAND,
|
||||
handler: async (accessor, params: ICoverCommandParams) => {
|
||||
const currentUniverService = accessor.get(ICurrentUniverService);
|
||||
const { unitId, snapshot, clearUndoRedoStack } = params;
|
||||
const doc = currentUniverService.getUniverDocInstance(unitId);
|
||||
if (!doc) {
|
||||
return false;
|
||||
}
|
||||
|
||||
doc.getDocument().reset(snapshot || createEmptyDocSnapshot());
|
||||
|
||||
if (clearUndoRedoStack) {
|
||||
const undoRedoService = accessor.get(IUndoRedoService);
|
||||
undoRedoService.clearUndoRedo(unitId);
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
};
|
||||
|
||||
function getRetainAndDeleteFromReplace(range: ITextSelectionRange, segmentId?: string): Array<IRetainMutationParams | IDeleteMutationParams> {
|
||||
const { cursorStart, cursorEnd, isEndBack, isStartBack, isCollapse } = range;
|
||||
const dos: Array<IRetainMutationParams | IDeleteMutationParams> = [];
|
||||
|
||||
@@ -21,7 +21,7 @@ export function InsertApply(document: DocumentModel, insertBody: IDocumentBody,
|
||||
|
||||
updateAttributeByInsert(body, insertBody, textLength, currentIndex);
|
||||
|
||||
console.log('插入的model打印', bodyModel, body, textLength);
|
||||
// console.log('插入的model打印', bodyModel, body, textLength);
|
||||
}
|
||||
|
||||
function updateAttributeByInsert(body: IDocumentBody, insertBody: IDocumentBody, textLength: number, currentIndex: number) {
|
||||
|
||||
@@ -1 +1,15 @@
|
||||
export {
|
||||
CoverCommand,
|
||||
DeleteCommand,
|
||||
ICoverCommandParams,
|
||||
IDeleteCommandParams,
|
||||
IIMEInputCommandParams,
|
||||
IInsertCommandParams,
|
||||
IMEInputCommand,
|
||||
InsertCommand,
|
||||
IUpdateCommandParams,
|
||||
UpdateCommand,
|
||||
} from './commands/commands/core-editing.command';
|
||||
export * from './DocPlugin';
|
||||
export { DocsViewManagerService } from './services/docs-view-manager/docs-view-manager.service';
|
||||
export { DocsView, DocsViewFactory } from './View/Render/Views/DocsView';
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
/**
|
||||
* This services provides methods to edit the content of the document.
|
||||
*/
|
||||
export class DocEditingService {}
|
||||
@@ -0,0 +1,59 @@
|
||||
import { Disposable, fromObservable, ICurrentUniverService, toDisposable } from '@univerjs/core';
|
||||
import { IDisposable } from '@wendellhu/redi';
|
||||
import { Observable, Subject } from 'rxjs';
|
||||
|
||||
import type { DocsView } from '../../View/Render/Views/DocsView';
|
||||
|
||||
/**
|
||||
* This services manages instances of doc CanvasView and determines which one
|
||||
* the user is currently interacting with.
|
||||
*/
|
||||
export class DocsViewManagerService extends Disposable {
|
||||
readonly current$: Observable<DocsView | null>;
|
||||
|
||||
private readonly _current$: Subject<DocsView | null> = new Subject();
|
||||
|
||||
private readonly _viewsMap = new Map<string, DocsView>();
|
||||
|
||||
constructor(@ICurrentUniverService private readonly _currentUniverService: ICurrentUniverService) {
|
||||
super();
|
||||
|
||||
this.disposeWithMe(
|
||||
fromObservable(
|
||||
this._currentUniverService.focused$.subscribe((id) => {
|
||||
if (!id) {
|
||||
this._current$.next(null);
|
||||
return;
|
||||
}
|
||||
|
||||
// FIXME: if the focused id is a sheet ID, we should focus on the cell editor instead
|
||||
const view = this._viewsMap.get(id);
|
||||
if (view) {
|
||||
this._current$.next(view ?? null);
|
||||
}
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
this.current$ = this._current$.asObservable();
|
||||
}
|
||||
|
||||
override dispose(): void {
|
||||
super.dispose();
|
||||
|
||||
this._viewsMap.clear();
|
||||
this._current$.complete();
|
||||
}
|
||||
|
||||
registerCanvasViewForUniverInstance(unitId: string, docsView: DocsView): IDisposable {
|
||||
this._viewsMap.set(unitId, docsView);
|
||||
|
||||
return toDisposable(() => {
|
||||
this._viewsMap.delete(unitId);
|
||||
});
|
||||
}
|
||||
|
||||
getDocsView(unitId: string): DocsView | undefined {
|
||||
return this._viewsMap.get(unitId);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
import { createIdentifier } from '@wendellhu/redi';
|
||||
|
||||
export interface ISelectionManagerService {}
|
||||
|
||||
export const ISelectionManagerService = createIdentifier<ISelectionManagerService>('doc.selection-manager-service');
|
||||
|
||||
export class SelectionManagerService implements ISelectionManagerService {}
|
||||
@@ -1,13 +1,15 @@
|
||||
import { IShortcutItem, KeyCode } from '@univerjs/base-ui';
|
||||
import { FOCUSING_DOC, IShortcutItem, KeyCode } from '@univerjs/base-ui';
|
||||
|
||||
import { BreakLineCommand, DeleteLeftCommand } from '../commands/commands/core-editing.command';
|
||||
|
||||
export const BreakLineShortcut: IShortcutItem = {
|
||||
id: BreakLineCommand.id,
|
||||
preconditions: (contextService) => contextService.getContextValue(FOCUSING_DOC),
|
||||
binding: KeyCode.ENTER,
|
||||
};
|
||||
|
||||
export const DeleteLeftShortcut: IShortcutItem = {
|
||||
id: DeleteLeftCommand.id,
|
||||
preconditions: (contextService) => contextService.getContextValue(FOCUSING_DOC),
|
||||
binding: KeyCode.BACKSPACE,
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { IShortcutItem, KeyCode } from '@univerjs/base-ui';
|
||||
import { FOCUSING_DOC, IShortcutItem, KeyCode } from '@univerjs/base-ui';
|
||||
import { Direction } from '@univerjs/core';
|
||||
|
||||
import { MoveCursorOperation } from '../commands/operations/cursor.operation';
|
||||
@@ -6,6 +6,7 @@ import { MoveCursorOperation } from '../commands/operations/cursor.operation';
|
||||
export const MoveCursorUpShortcut: IShortcutItem = {
|
||||
id: MoveCursorOperation.id,
|
||||
binding: KeyCode.ARROW_UP,
|
||||
preconditions: (contextService) => contextService.getContextValue(FOCUSING_DOC),
|
||||
staticParameters: {
|
||||
direction: Direction.UP,
|
||||
},
|
||||
@@ -14,6 +15,7 @@ export const MoveCursorUpShortcut: IShortcutItem = {
|
||||
export const MoveCursorDownShortcut: IShortcutItem = {
|
||||
id: MoveCursorOperation.id,
|
||||
binding: KeyCode.ARROW_DOWN,
|
||||
preconditions: (contextService) => contextService.getContextValue(FOCUSING_DOC),
|
||||
staticParameters: {
|
||||
direction: Direction.DOWN,
|
||||
},
|
||||
@@ -22,6 +24,7 @@ export const MoveCursorDownShortcut: IShortcutItem = {
|
||||
export const MoveCursorLeftShortcut: IShortcutItem = {
|
||||
id: MoveCursorOperation.id,
|
||||
binding: KeyCode.ARROW_LEFT,
|
||||
preconditions: (contextService) => contextService.getContextValue(FOCUSING_DOC),
|
||||
staticParameters: {
|
||||
direction: Direction.LEFT,
|
||||
},
|
||||
@@ -30,6 +33,7 @@ export const MoveCursorLeftShortcut: IShortcutItem = {
|
||||
export const MoveCursorRightShortcut: IShortcutItem = {
|
||||
id: MoveCursorOperation.id,
|
||||
binding: KeyCode.ARROW_RIGHT,
|
||||
preconditions: (contextService) => contextService.getContextValue(FOCUSING_DOC),
|
||||
staticParameters: {
|
||||
direction: Direction.RIGHT,
|
||||
},
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import {
|
||||
BooleanNumber,
|
||||
DocumentBodyModel,
|
||||
GridType,
|
||||
IDocStyleBase,
|
||||
IDocumentLayout,
|
||||
@@ -11,12 +12,12 @@ import {
|
||||
ISize,
|
||||
ITextStyle,
|
||||
ITransformState,
|
||||
DocumentBodyModel,
|
||||
} from '@univerjs/core';
|
||||
|
||||
import {
|
||||
IDocumentSkeletonDrawingAnchor,
|
||||
IDocumentSkeletonBullet,
|
||||
IDocumentSkeletonDrawing,
|
||||
IDocumentSkeletonDrawingAnchor,
|
||||
IDocumentSkeletonFontStyle,
|
||||
IDocumentSkeletonFooter,
|
||||
IDocumentSkeletonHeader,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import {
|
||||
ColumnSeparatorType,
|
||||
DocumentModelOrSimple,
|
||||
fromObservable,
|
||||
GridType,
|
||||
HorizontalAlign,
|
||||
ISectionBreak,
|
||||
@@ -47,7 +48,15 @@ export class DocumentSkeleton extends Skeleton {
|
||||
|
||||
constructor(docModel: DocumentModelOrSimple, localeService: LocaleService) {
|
||||
super(localeService);
|
||||
|
||||
this._docModel = docModel;
|
||||
this.disposeWithMe(
|
||||
fromObservable(
|
||||
this._docModel.bodyModel.modelChange$.subscribe(() => {
|
||||
this.calculate();
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
static create(docModel: DocumentModelOrSimple, localeService: LocaleService) {
|
||||
|
||||
@@ -126,9 +126,51 @@ export class DocsEditor {
|
||||
this._scrollToSelection();
|
||||
}
|
||||
|
||||
activate(toLastPosition = false): void {
|
||||
// const documents = this._documents;
|
||||
// if (!documents) {
|
||||
// return;
|
||||
// }
|
||||
// setTimeout(() => {
|
||||
// documents.makeDirty();
|
||||
// });
|
||||
// FIXME: I don't know if this is correct. Just trying it.
|
||||
// const lastCharIndex = documents.getSkeleton()!.getModel().bodyModel.body.dataStream.length;
|
||||
// const span = documents.findNodeByCharIndex(lastCharIndex - 1);
|
||||
// const position = documents.findPositionBySpan(span!);
|
||||
// const remain = this.remain();
|
||||
// if (position && remain) {
|
||||
// remain.startNodePosition = { ...position, isBack: true };
|
||||
// remain.endNodePosition = undefined;
|
||||
// }
|
||||
// if (!this._documents) {
|
||||
// return;
|
||||
// }
|
||||
// TODO
|
||||
// this.activeViewport = this._documents.getActiveViewportByCoord(evtOffsetX, evtOffsetY);
|
||||
// const startNode = this._documents.findNodeByCoord(evtOffsetX, evtOffsetY);
|
||||
// console.log('startNode', startNode, position, evtOffsetX, evtOffsetY);
|
||||
// if (position == null) {
|
||||
// this._deleteAllTextSelection();
|
||||
// return;
|
||||
// }
|
||||
// if (startNode?.node.streamType === DataStreamTreeTokenType.PARAGRAPH) {
|
||||
// position.isBack = true;
|
||||
// }
|
||||
// if (evt.ctrlKey || this._isEmptyTextSelection()) {
|
||||
// const newTextSelection = new TextSelection(this._documents.getScene(), position);
|
||||
// this._addTextSelection(newTextSelection);
|
||||
// } else {
|
||||
// this._updateTextSelection(position);
|
||||
// }
|
||||
// this._activeSelectionRefresh();
|
||||
// this._syncDomToSelection();
|
||||
}
|
||||
|
||||
active(x: number, y: number) {
|
||||
this._container.style.left = `${x}px`;
|
||||
this._container.style.top = `${y}px`;
|
||||
this._container.style.zIndex = `1000`;
|
||||
|
||||
this._cursor.style.animation = 'univer_cursor_blinkStyle 1s steps(1) infinite';
|
||||
this._cursor.style.display = 'revert';
|
||||
@@ -138,14 +180,21 @@ export class DocsEditor {
|
||||
}, 0);
|
||||
}
|
||||
|
||||
deactivate() {
|
||||
focus(): void {
|
||||
this._input.focus();
|
||||
}
|
||||
|
||||
// FIXME: for editor cell editor we don't need to blur the input element
|
||||
deactivate(withoutBlur = true) {
|
||||
this._container.style.left = `0px`;
|
||||
this._container.style.top = `0px`;
|
||||
|
||||
this._cursor.style.animation = '';
|
||||
this._cursor.style.display = 'none';
|
||||
|
||||
this._input.blur();
|
||||
if (!withoutBlur) {
|
||||
this._input.blur();
|
||||
}
|
||||
}
|
||||
|
||||
changeDocuments(documents: DocComponent) {
|
||||
@@ -169,23 +218,16 @@ export class DocsEditor {
|
||||
|
||||
private _initialDom() {
|
||||
const container = document.createElement('div');
|
||||
|
||||
container.style.position = 'absolute';
|
||||
|
||||
container.style.position = 'absolute';
|
||||
|
||||
container.style.left = `0px`;
|
||||
container.style.top = `0px`;
|
||||
|
||||
const inputParent = document.createElement('div');
|
||||
const inputDom = document.createElement('div');
|
||||
|
||||
const cursorDom = document.createElement('div');
|
||||
|
||||
inputParent.appendChild(inputDom);
|
||||
|
||||
container.appendChild(inputParent);
|
||||
|
||||
container.appendChild(cursorDom);
|
||||
|
||||
this._container = container;
|
||||
@@ -675,12 +717,11 @@ export class DocsEditor {
|
||||
const scene = documents.getScene();
|
||||
|
||||
this._downObserver = documents.onPointerDownObserver.add((evt: IPointerEvent | IMouseEvent, state) => {
|
||||
const { offsetX: evtOffsetX, offsetY: evtOffsetY } = evt;
|
||||
|
||||
if (!this._documents) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { offsetX: evtOffsetX, offsetY: evtOffsetY } = evt;
|
||||
this.activeViewport = this._documents.getActiveViewportByCoord(evtOffsetX, evtOffsetY);
|
||||
|
||||
const startNode = this._documents.findNodeByCoord(evtOffsetX, evtOffsetY);
|
||||
|
||||
@@ -90,6 +90,10 @@ export class Documents extends DocComponent {
|
||||
return new Documents(oKey, documentSkeleton, config);
|
||||
}
|
||||
|
||||
getEditor(): DocsEditor {
|
||||
return this._editor;
|
||||
}
|
||||
|
||||
getActiveSelection() {
|
||||
return this._editor.getActiveTextSelection();
|
||||
}
|
||||
@@ -157,6 +161,7 @@ export class Documents extends DocComponent {
|
||||
if (this._hasEditor) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._editor = DocsEditor.create(this);
|
||||
this._hasEditor = true;
|
||||
}
|
||||
@@ -212,6 +217,11 @@ export class Documents extends DocComponent {
|
||||
return;
|
||||
}
|
||||
|
||||
const isDrawingCellEditor = documentSkeleton.getModel().snapshot.id === 'sheet.model.cell-editor';
|
||||
if (isDrawingCellEditor) {
|
||||
console.log('drawing', documentSkeleton, documentSkeleton.getModel().snapshot);
|
||||
}
|
||||
|
||||
// if (this.isCalculateSkeleton) {
|
||||
// documentSkeleton.calculate(bounds);
|
||||
// }
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
import { LocaleService } from '@univerjs/core';
|
||||
import { Disposable, LocaleService } from '@univerjs/core';
|
||||
import { Inject } from '@wendellhu/redi';
|
||||
|
||||
import { IFontLocale } from '../Basics/Interfaces';
|
||||
import { en, zh } from '../Locale';
|
||||
|
||||
export class Skeleton {
|
||||
export class Skeleton extends Disposable {
|
||||
private _fontLocale: IFontLocale;
|
||||
|
||||
private _dirty = true;
|
||||
|
||||
constructor(@Inject(LocaleService) protected readonly _localService: LocaleService) {
|
||||
super();
|
||||
|
||||
this._localeInitial();
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import { TRANSFORM_CHANGE_OBSERVABLE_TYPE } from './Basics/Interfaces';
|
||||
import { PerformanceMonitor } from './Basics/PerformanceMonitor';
|
||||
import { getPointerPrefix, getSizeForDom, IsSafari, requestNewFrame } from './Basics/Tools';
|
||||
import { Canvas } from './Canvas';
|
||||
import { fromWindowEvent } from './common/lifecycle';
|
||||
import { Scene } from './Scene';
|
||||
import { ThinEngine } from './ThinEngine';
|
||||
|
||||
@@ -111,7 +112,9 @@ export class Engine extends ThinEngine<Scene> {
|
||||
setContainer(elem: HTMLElement) {
|
||||
this._container = elem;
|
||||
this._container.appendChild(this._canvasEle);
|
||||
|
||||
this.resize();
|
||||
this.disposeWithMe(fromWindowEvent('resize', () => this.resize()));
|
||||
}
|
||||
|
||||
resize() {
|
||||
@@ -119,7 +122,6 @@ export class Engine extends ThinEngine<Scene> {
|
||||
return;
|
||||
}
|
||||
|
||||
// const { offsetWidth, offsetHeight } = this._container;
|
||||
const { width, height } = getSizeForDom(this._container);
|
||||
this.resizeBySize(width, height);
|
||||
}
|
||||
|
||||
@@ -1,24 +1,18 @@
|
||||
import { Plugin, PLUGIN_NAMES, PluginType } from '@univerjs/core';
|
||||
import { createIdentifier, Injector, Optional } from '@wendellhu/redi';
|
||||
import { createIdentifier, Inject, Injector } from '@wendellhu/redi';
|
||||
|
||||
import { Engine } from './Engine';
|
||||
|
||||
/**
|
||||
* The global rendering engine.
|
||||
*/
|
||||
export const IRenderingEngine = createIdentifier<Engine>('univer.render-engine');
|
||||
|
||||
export class RenderEngine extends Plugin {
|
||||
static override type = PluginType.Univer;
|
||||
|
||||
private _engine: Engine;
|
||||
|
||||
constructor(_config: undefined, @Optional(Injector) override readonly _injector: Injector) {
|
||||
constructor(_config: undefined, @Inject(Injector) override readonly _injector: Injector) {
|
||||
super(PLUGIN_NAMES.BASE_RENDER);
|
||||
|
||||
this._engine = new Engine();
|
||||
|
||||
this._injector?.add([IRenderingEngine, { useFactory: () => this._engine }]);
|
||||
}
|
||||
|
||||
getEngine(): Engine {
|
||||
return this._engine;
|
||||
this._injector.add([IRenderingEngine, { useFactory: () => new Engine() }]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { Observer, Nullable } from '@univerjs/core';
|
||||
import { IKeyboardEvent, IMouseEvent, IPointerEvent, IEvent, DeviceType, PointerInput, IWheelEvent } from './Basics/IEvents';
|
||||
import { Vector2 } from './Basics/Vector2';
|
||||
import { Nullable, Observer } from '@univerjs/core';
|
||||
|
||||
import { BaseObject } from './BaseObject';
|
||||
import { ThinScene } from './ThinScene';
|
||||
import { RENDER_CLASS_TYPE } from './Basics/Const';
|
||||
import { DeviceType, IEvent, IKeyboardEvent, IMouseEvent, IPointerEvent, IWheelEvent, PointerInput } from './Basics/IEvents';
|
||||
import { Vector2 } from './Basics/Vector2';
|
||||
import { ThinScene } from './ThinScene';
|
||||
import { Viewport } from './Viewport';
|
||||
|
||||
export class InputManager {
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { IKeyValue, Nullable } from '@univerjs/core';
|
||||
import { IBoundRect, Vector2 } from './Basics/Vector2';
|
||||
|
||||
import { BaseObject } from './BaseObject';
|
||||
import { ThinScene } from './ThinScene';
|
||||
import { IObjectFullState } from './Basics/Interfaces';
|
||||
import { RENDER_CLASS_TYPE } from './Basics/Const';
|
||||
import { IObjectFullState } from './Basics/Interfaces';
|
||||
import { transformBoundingCoord } from './Basics/Position';
|
||||
import { IBoundRect, Vector2 } from './Basics/Vector2';
|
||||
import { ThinScene } from './ThinScene';
|
||||
|
||||
export class SceneViewer extends BaseObject {
|
||||
private _subScenes = new Map<string, ThinScene>();
|
||||
@@ -14,6 +15,7 @@ export class SceneViewer extends BaseObject {
|
||||
private _allowSelectedClipElement = false;
|
||||
|
||||
constructor(key?: string, props?: IObjectFullState) {
|
||||
// WTF: the name of `props`'s interface ends with State?
|
||||
super(key);
|
||||
this._initialProps(props);
|
||||
}
|
||||
@@ -56,7 +58,7 @@ export class SceneViewer extends BaseObject {
|
||||
}
|
||||
|
||||
getSubScene(sceneKey: string) {
|
||||
for (let [key, scene] of this._subScenes) {
|
||||
for (const [key, scene] of this._subScenes) {
|
||||
if (key === sceneKey) {
|
||||
return scene;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
import { Observable } from '@univerjs/core';
|
||||
import { CURSOR_TYPE, RENDER_CLASS_TYPE } from './Basics/Const';
|
||||
import { ITransformChangeState } from './Basics/Interfaces';
|
||||
import { IEvent } from './Basics/IEvents';
|
||||
import { Disposable, Observable } from '@univerjs/core';
|
||||
import { IDisposable } from '@wendellhu/redi';
|
||||
|
||||
export abstract class ThinEngine<T> {
|
||||
import { CURSOR_TYPE, RENDER_CLASS_TYPE } from './Basics/Const';
|
||||
import { IEvent } from './Basics/IEvents';
|
||||
import { ITransformChangeState } from './Basics/Interfaces';
|
||||
import { Canvas } from './Canvas';
|
||||
|
||||
// FIXME: T should extends something that is disposable
|
||||
export abstract class ThinEngine<T extends IDisposable> extends Disposable {
|
||||
onInputChangedObservable = new Observable<IEvent>();
|
||||
|
||||
onTransformChangeObservable = new Observable<ITransformChangeState>();
|
||||
@@ -62,7 +66,9 @@ export abstract class ThinEngine<T> {
|
||||
return this._activeScene != null;
|
||||
}
|
||||
|
||||
dispose() {
|
||||
override dispose() {
|
||||
super.dispose();
|
||||
|
||||
const scenes = this.getScenes();
|
||||
const sceneKeys = Object.keys(scenes);
|
||||
sceneKeys.forEach((key) => {
|
||||
@@ -79,11 +85,11 @@ export abstract class ThinEngine<T> {
|
||||
}
|
||||
}
|
||||
|
||||
clearCanvas() {}
|
||||
abstract clearCanvas(): void;
|
||||
|
||||
getCanvas() {}
|
||||
abstract getCanvas(): Canvas;
|
||||
|
||||
getCanvasElement() {}
|
||||
abstract getCanvasElement(): HTMLCanvasElement;
|
||||
|
||||
setCanvasCursor(val: CURSOR_TYPE) {}
|
||||
abstract setCanvasCursor(val: CURSOR_TYPE): void;
|
||||
}
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
import { EventState, IKeyValue, Nullable, Observable, Observer } from '@univerjs/core';
|
||||
|
||||
import { EVENT_TYPE, RENDER_CLASS_TYPE } from './Basics/Const';
|
||||
|
||||
import { ITransformChangeState } from './Basics/Interfaces';
|
||||
|
||||
import { Transform } from './Basics/Transform';
|
||||
|
||||
import { IBoundRect, Vector2 } from './Basics/Vector2';
|
||||
import { BaseObject } from './BaseObject';
|
||||
import { EVENT_TYPE, RENDER_CLASS_TYPE } from './Basics/Const';
|
||||
import { IKeyboardEvent, IMouseEvent, IPointerEvent, IWheelEvent } from './Basics/IEvents';
|
||||
import { ITransformChangeState } from './Basics/Interfaces';
|
||||
import { Transform } from './Basics/Transform';
|
||||
import { IBoundRect, Vector2 } from './Basics/Vector2';
|
||||
|
||||
export abstract class ThinScene {
|
||||
onTransformChangeObservable = new Observable<ITransformChangeState>();
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import { toDisposable } from '@univerjs/core';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export function fromWindowEvent<K extends keyof WindowEventMap>(type: K, listener: (this: Window, ev: WindowEventMap[K]) => any, options?: boolean | AddEventListenerOptions) {
|
||||
window.addEventListener(type, listener, options);
|
||||
return toDisposable(() => window.removeEventListener(type, listener, options));
|
||||
}
|
||||
@@ -1,15 +1,15 @@
|
||||
export * from './Locale';
|
||||
export * from './BaseObject';
|
||||
export * from './Basics';
|
||||
export * from './Canvas';
|
||||
export * from './Component';
|
||||
export * from './Custom';
|
||||
export * from './Engine';
|
||||
export * from './BaseObject';
|
||||
export * from './Group';
|
||||
export * from './Layer';
|
||||
export * from './Locale';
|
||||
export { IRenderingEngine, RenderEngine } from './RenderEngine';
|
||||
export * from './Scene';
|
||||
export * from './SceneViewer';
|
||||
export * from './Viewport';
|
||||
export * from './Canvas';
|
||||
export * from './Group';
|
||||
export * from './Shape';
|
||||
export * from './Component';
|
||||
export { RenderEngine, IRenderingEngine } from './RenderEngine';
|
||||
export * from './ScrollTimer';
|
||||
export * from './Shape';
|
||||
export * from './Viewport';
|
||||
|
||||
@@ -76,7 +76,7 @@ export const AddWorksheetMergeCommand: ICommand = {
|
||||
|
||||
if (result && removeResult) {
|
||||
undoRedoService.pushUndoRedo({
|
||||
URI: 'sheet',
|
||||
URI: workbookId,
|
||||
undo() {
|
||||
return (commandService.executeCommand(RemoveWorksheetMergeMutation.id, undoMutationParams) as Promise<boolean>).then((res) => {
|
||||
if (res) return commandService.executeCommand(AddWorksheetMergeMutation.id, undoRemoveMergeMutationParams);
|
||||
|
||||
@@ -45,7 +45,7 @@ export const ClearSelectionContentCommand: ICommand = {
|
||||
undoRedoService.pushUndoRedo({
|
||||
// 如果有多个 mutation 构成一个封装项目,那么要封装在同一个 undo redo element 里面
|
||||
// 通过勾子可以 hook 外部 controller 的代码来增加新的 action
|
||||
URI: 'sheet', // TODO: this URI is fake
|
||||
URI: workbookId,
|
||||
undo() {
|
||||
return (commandService.executeCommand(SetRangeValuesMutation.id, undoClearMutationParams) as Promise<boolean>).then((res) => {
|
||||
if (res) return commandService.executeCommand(SetRangeStyleMutation.id, setStyleMutationParams);
|
||||
|
||||
@@ -62,7 +62,7 @@ export const CopyFormatToRangeCommand: ICommand = {
|
||||
const result = commandService.executeCommand(SetRangeStyleMutation.id, setRangeStyleMutationParams);
|
||||
if (result) {
|
||||
undoRedoService.pushUndoRedo({
|
||||
URI: 'sheet',
|
||||
URI: workbookId,
|
||||
undo() {
|
||||
return commandService.executeCommand(SetRangeStyleMutation.id, undoMutationParams);
|
||||
},
|
||||
|
||||
@@ -62,7 +62,7 @@ export const CopyRangeToCommand: ICommand = {
|
||||
const result = commandService.executeCommand(SetRangeValuesMutation.id, setRangeValuesMutationParams);
|
||||
if (result) {
|
||||
undoRedoService.pushUndoRedo({
|
||||
URI: 'sheet',
|
||||
URI: workbookId,
|
||||
undo() {
|
||||
return commandService.executeCommand(SetRangeValuesMutation.id, undoMutationParams);
|
||||
},
|
||||
|
||||
@@ -43,7 +43,7 @@ export const CopySheetToCommand: ICommand = {
|
||||
const result = commandService.executeCommand(SetWorksheetConfigMutation.id, setWorksheetConfigMutationParams);
|
||||
if (result) {
|
||||
undoRedoService.pushUndoRedo({
|
||||
URI: 'sheet',
|
||||
URI: workbookId,
|
||||
undo() {
|
||||
return commandService.executeCommand(SetWorksheetConfigMutation.id, undoMutationParams);
|
||||
},
|
||||
|
||||
@@ -59,7 +59,7 @@ export const CopyValuesToRangeCommand: ICommand = {
|
||||
const result = commandService.executeCommand(SetRangeFormattedValueMutation.id, setRangeFormattedValueMutationParams);
|
||||
if (result) {
|
||||
undoRedoService.pushUndoRedo({
|
||||
URI: 'sheet',
|
||||
URI: workbookId,
|
||||
undo() {
|
||||
return commandService.executeCommand(SetRangeFormattedValueMutation.id, undoMutationParams);
|
||||
},
|
||||
|
||||
@@ -54,7 +54,7 @@ export const CopySheetCommand: ICommand = {
|
||||
|
||||
if (insertResult && result) {
|
||||
undoRedoService.pushUndoRedo({
|
||||
URI: 'sheet',
|
||||
URI: workbookId,
|
||||
undo() {
|
||||
return (commandService.executeCommand(SetWorksheetActivateMutation.id, undoMutationParams) as Promise<boolean>).then((res) => {
|
||||
if (res) return commandService.executeCommand(RemoveSheetMutation.id, removeSheetMutationParams);
|
||||
|
||||
@@ -45,7 +45,7 @@ export const DeleteRangeMoveLeftCommand: ICommand = {
|
||||
undoRedoService.pushUndoRedo({
|
||||
// 如果有多个 mutation 构成一个封装项目,那么要封装在同一个 undo redo element 里面
|
||||
// 通过勾子可以 hook 外部 controller 的代码来增加新的 action
|
||||
URI: 'sheet', // TODO: this URI is fake
|
||||
URI: workbookId,
|
||||
undo() {
|
||||
return commandService.executeCommand(InsertRangeMutation.id, insertRangeMutationParams);
|
||||
},
|
||||
|
||||
@@ -45,7 +45,7 @@ export const DeleteRangeMoveUpCommand: ICommand = {
|
||||
undoRedoService.pushUndoRedo({
|
||||
// 如果有多个 mutation 构成一个封装项目,那么要封装在同一个 undo redo element 里面
|
||||
// 通过勾子可以 hook 外部 controller 的代码来增加新的 action
|
||||
URI: 'sheet', // TODO: this URI is fake
|
||||
URI: workbookId,
|
||||
undo() {
|
||||
return commandService.executeCommand(InsertRangeMutation.id, insertRangeMutationParams);
|
||||
},
|
||||
|
||||
@@ -56,7 +56,7 @@ export const InsertRangeMoveDownCommand: ICommand = {
|
||||
undoRedoService.pushUndoRedo({
|
||||
// 如果有多个 mutation 构成一个封装项目,那么要封装在同一个 undo redo element 里面
|
||||
// 通过勾子可以 hook 外部 controller 的代码来增加新的 action
|
||||
URI: 'sheet', // TODO: this URI is fake
|
||||
URI: workbookId,
|
||||
undo() {
|
||||
return commandService.executeCommand(DeleteRangeMutation.id, deleteRangeMutationParams);
|
||||
},
|
||||
|
||||
@@ -56,7 +56,7 @@ export const InsertRangeMoveRightCommand: ICommand = {
|
||||
undoRedoService.pushUndoRedo({
|
||||
// 如果有多个 mutation 构成一个封装项目,那么要封装在同一个 undo redo element 里面
|
||||
// 通过勾子可以 hook 外部 controller 的代码来增加新的 action
|
||||
URI: 'sheet', // TODO: this URI is fake
|
||||
URI: workbookId,
|
||||
undo() {
|
||||
return commandService.executeCommand(DeleteRangeMutation.id, deleteRangeMutationParams);
|
||||
},
|
||||
|
||||
@@ -103,7 +103,7 @@ export const InsertRowCommand: ICommand = {
|
||||
|
||||
if (result && deleteResult && removeResult && mergeResult) {
|
||||
undoRedoService.pushUndoRedo({
|
||||
URI: 'sheet',
|
||||
URI: workbookId,
|
||||
undo() {
|
||||
return (commandService.executeCommand(DeleteRangeMutation.id, deleteRangeMutationParams) as Promise<boolean>)
|
||||
.then((res) => {
|
||||
@@ -312,7 +312,7 @@ export const InsertColCommand: ICommand<InsertColCommandBaseParams> = {
|
||||
|
||||
if (result && deleteResult && removeResult && mergeResult) {
|
||||
undoRedoService.pushUndoRedo({
|
||||
URI: 'sheet',
|
||||
URI: workbookId,
|
||||
undo() {
|
||||
return (commandService.executeCommand(DeleteRangeMutation.id, deleteRangeMutationParams) as Promise<boolean>)
|
||||
.then((res) => {
|
||||
|
||||
@@ -66,7 +66,7 @@ export const InsertSheetCommand: ICommand = {
|
||||
|
||||
if (result && activateResult) {
|
||||
undoRedoService.pushUndoRedo({
|
||||
URI: 'sheet',
|
||||
URI: workbookId,
|
||||
undo() {
|
||||
return (commandService.executeCommand(SetWorksheetActivateMutation.id, undoMutationParams) as Promise<boolean>).then((res) => {
|
||||
if (res) return commandService.executeCommand(RemoveSheetMutation.id, removeSheetMutationParams);
|
||||
|
||||
@@ -69,7 +69,7 @@ export const MoveColumnsToCommand: ICommand = {
|
||||
undoRedoService.pushUndoRedo({
|
||||
// 如果有多个 mutation 构成一个封装项目,那么要封装在同一个 undo redo element 里面
|
||||
// 通过勾子可以 hook 外部 controller 的代码来增加新的 action
|
||||
URI: 'sheet', // TODO: this URI is fake
|
||||
URI: workbookId,
|
||||
undo() {
|
||||
return (commandService.executeCommand(InsertColMutation.id, undoRemoveColumnMutationParams) as Promise<boolean>).then((res) => {
|
||||
if (res) return commandService.executeCommand(RemoveColMutation.id, undoMutationParams);
|
||||
|
||||
@@ -64,7 +64,7 @@ export const MoveRangeToCommand: ICommand = {
|
||||
undoRedoService.pushUndoRedo({
|
||||
// 如果有多个 mutation 构成一个封装项目,那么要封装在同一个 undo redo element 里面
|
||||
// 通过勾子可以 hook 外部 controller 的代码来增加新的 action
|
||||
URI: 'sheet', // TODO: this URI is fake
|
||||
URI: workbookId,
|
||||
undo() {
|
||||
return (commandService.executeCommand(SetRangeValuesMutation.id, undoClearMutationParams) as Promise<boolean>).then((res) => {
|
||||
if (res) return commandService.executeCommand(SetRangeValuesMutation.id, undoMutationParams);
|
||||
|
||||
@@ -69,7 +69,7 @@ export const MoveRowsToCommand: ICommand = {
|
||||
undoRedoService.pushUndoRedo({
|
||||
// 如果有多个 mutation 构成一个封装项目,那么要封装在同一个 undo redo element 里面
|
||||
// 通过勾子可以 hook 外部 controller 的代码来增加新的 action
|
||||
URI: 'sheet', // TODO: this URI is fake
|
||||
URI: workbookId,
|
||||
undo() {
|
||||
return (commandService.executeCommand(InsertRowMutation.id, undoRemoveRowMutationParams) as Promise<boolean>).then((res) => {
|
||||
if (res) return commandService.executeCommand(RemoveRowMutation.id, undoMutationParams);
|
||||
|
||||
@@ -107,7 +107,7 @@ export const RemoveRowCommand: ICommand = {
|
||||
|
||||
if (result && deleteResult && removeResult && mergeResult) {
|
||||
undoRedoService.pushUndoRedo({
|
||||
URI: 'sheet',
|
||||
URI: workbookId,
|
||||
undo() {
|
||||
return (commandService.executeCommand(InsertRowMutation.id, undoMutationParams) as Promise<boolean>)
|
||||
.then((res) => {
|
||||
@@ -233,7 +233,7 @@ export const RemoveColCommand: ICommand = {
|
||||
|
||||
if (result && deleteResult && removeResult && mergeResult) {
|
||||
undoRedoService.pushUndoRedo({
|
||||
URI: 'sheet',
|
||||
URI: workbookId,
|
||||
undo() {
|
||||
return (commandService.executeCommand(InsertColMutation.id, undoMutationParams) as Promise<boolean>)
|
||||
.then((res) => {
|
||||
|
||||
@@ -56,7 +56,7 @@ export const RemoveSheetCommand: ICommand = {
|
||||
|
||||
if (result && activeResult) {
|
||||
undoRedoService.pushUndoRedo({
|
||||
URI: 'sheet',
|
||||
URI: workbookId,
|
||||
undo() {
|
||||
return (commandService.executeCommand(InsertSheetMutation.id, InsertSheetMutationParams) as Promise<boolean>).then((res) => {
|
||||
if (res) return commandService.executeCommand(SetWorksheetActivateMutation.id, activeMutationParams);
|
||||
|
||||
@@ -36,7 +36,7 @@ export const RemoveWorksheetMergeCommand: ICommand = {
|
||||
|
||||
if (result) {
|
||||
undoRedoService.pushUndoRedo({
|
||||
URI: 'sheet',
|
||||
URI: workbookId,
|
||||
undo() {
|
||||
return commandService.executeCommand(AddWorksheetMergeMutation.id, undoMutationParams);
|
||||
},
|
||||
|
||||
@@ -330,7 +330,7 @@ export const SetBorderCommand: ICommand<ISetBorderCommandParams> = {
|
||||
undoRedoService.pushUndoRedo({
|
||||
// 如果有多个 mutation 构成一个封装项目,那么要封装在同一个 undo redo element 里面
|
||||
// 通过勾子可以 hook 外部 controller 的代码来增加新的 action
|
||||
URI: 'sheet', // TODO: this URI is fake
|
||||
URI: workbookId,
|
||||
undo() {
|
||||
return commandService.executeCommand(SetBorderStylesMutation.id, undoSetBorderStylesMutationParams);
|
||||
},
|
||||
|
||||
@@ -317,7 +317,7 @@ export const SetBorderCommand: ICommand = {
|
||||
undoRedoService.pushUndoRedo({
|
||||
// 如果有多个 mutation 构成一个封装项目,那么要封装在同一个 undo redo element 里面
|
||||
// 通过勾子可以 hook 外部 controller 的代码来增加新的 action
|
||||
URI: 'sheet', // TODO: this URI is fake
|
||||
URI: workbookId,
|
||||
undo() {
|
||||
return commandService.executeCommand(SetBorderStylesMutation.id, undoSetBorderStylesMutationParams);
|
||||
},
|
||||
|
||||
@@ -40,7 +40,7 @@ export const SetFrozenCancelCommand: ICommand = {
|
||||
|
||||
if (result && frozenResult) {
|
||||
undoRedoService.pushUndoRedo({
|
||||
URI: 'sheet',
|
||||
URI: workbookId,
|
||||
undo() {
|
||||
return (commandService.executeCommand(SetFrozenColumnsMutation.id, frozenColumnMutationParams) as Promise<boolean>).then((res) => {
|
||||
if (res) return commandService.executeCommand(SetFrozenRowsMutation.id, undoMutationParams);
|
||||
|
||||
@@ -34,7 +34,7 @@ export const SetFrozenColumnsCommand: ICommand = {
|
||||
|
||||
if (result) {
|
||||
undoRedoService.pushUndoRedo({
|
||||
URI: 'sheet',
|
||||
URI: workbookId,
|
||||
undo() {
|
||||
return commandService.executeCommand(SetFrozenColumnsMutation.id, undoMutationParams);
|
||||
},
|
||||
|
||||
@@ -34,7 +34,7 @@ export const SetFrozenRowsCommand: ICommand = {
|
||||
|
||||
if (result) {
|
||||
undoRedoService.pushUndoRedo({
|
||||
URI: 'sheet',
|
||||
URI: workbookId,
|
||||
undo() {
|
||||
return commandService.executeCommand(SetFrozenRowsMutation.id, undoMutationParams);
|
||||
},
|
||||
|
||||
@@ -43,7 +43,7 @@ export const SetHideGridlinesCommand: ICommand = {
|
||||
|
||||
if (result) {
|
||||
undoRedoService.pushUndoRedo({
|
||||
URI: 'sheet',
|
||||
URI: workbookId,
|
||||
undo() {
|
||||
return commandService.executeCommand(SetHideGridlinesMutation.id, undoMutationParams);
|
||||
},
|
||||
|
||||
@@ -74,7 +74,7 @@ export const SetRangeFormattedValueCommand: ICommand = {
|
||||
undoRedoService.pushUndoRedo({
|
||||
// 如果有多个 mutation 构成一个封装项目,那么要封装在同一个 undo redo element 里面
|
||||
// 通过勾子可以 hook 外部 controller 的代码来增加新的 action
|
||||
URI: 'sheet', // TODO: this URI is fake
|
||||
URI: workbookId,
|
||||
undo() {
|
||||
return commandService.executeCommand(SetRangeFormattedValueMutation.id, undoSetRangeFormattedValueMutationParams);
|
||||
},
|
||||
|
||||
@@ -1,4 +1,16 @@
|
||||
import { CommandType, ICellData, ICommand, ICommandService, ICurrentUniverService, IUndoRedoService, ObjectMatrix, ObjectMatrixPrimitiveType, Tools } from '@univerjs/core';
|
||||
import {
|
||||
CommandType,
|
||||
ICellData,
|
||||
ICommand,
|
||||
ICommandService,
|
||||
ICurrentUniverService,
|
||||
IRangeData,
|
||||
isICellData,
|
||||
IUndoRedoService,
|
||||
ObjectMatrix,
|
||||
ObjectMatrixPrimitiveType,
|
||||
Tools,
|
||||
} from '@univerjs/core';
|
||||
import { IAccessor } from '@wendellhu/redi';
|
||||
|
||||
import { SelectionManagerService } from '../../Services/selection-manager.service';
|
||||
@@ -7,6 +19,7 @@ import { ISetRangeValuesMutationParams, SetRangeValuesMutation, SetRangeValuesUn
|
||||
export interface ISetRangeValuesCommandParams {
|
||||
worksheetId?: string;
|
||||
workbookId?: string;
|
||||
range?: IRangeData;
|
||||
value: ICellData | ICellData[][] | ObjectMatrixPrimitiveType<ICellData>;
|
||||
}
|
||||
|
||||
@@ -22,47 +35,49 @@ export const SetRangeValuesCommand: ICommand = {
|
||||
const currentUniverService = accessor.get(ICurrentUniverService);
|
||||
const selectionManagerService = accessor.get(SelectionManagerService);
|
||||
|
||||
const range = selectionManagerService.getRangeDatas();
|
||||
if (!range?.length) {
|
||||
const {
|
||||
value,
|
||||
range,
|
||||
workbookId = currentUniverService.getCurrentUniverSheetInstance().getUnitId(),
|
||||
worksheetId = currentUniverService.getCurrentUniverSheetInstance().getWorkBook().getActiveSheet().getSheetId(),
|
||||
} = params;
|
||||
|
||||
const currentSelections = range ? [range] : selectionManagerService.getRangeDatas();
|
||||
if (!currentSelections || !currentSelections.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const workbookId = params.workbookId || currentUniverService.getCurrentUniverSheetInstance().getUnitId();
|
||||
const worksheetId = params.worksheetId || currentUniverService.getCurrentUniverSheetInstance().getWorkBook().getActiveSheet().getSheetId();
|
||||
const cellValue = new ObjectMatrix<ICellData>();
|
||||
let realCellValue: ObjectMatrixPrimitiveType<ICellData> | undefined;
|
||||
|
||||
const { value } = params;
|
||||
let cellValue = new ObjectMatrix<ICellData>();
|
||||
|
||||
for (let i = 0; i < range.length; i++) {
|
||||
const { startRow, startColumn, endRow, endColumn } = range[i];
|
||||
// FIXME: this is actually not ideal
|
||||
for (let i = 0; i < currentSelections.length; i++) {
|
||||
const { startRow, startColumn, endRow, endColumn } = currentSelections[i];
|
||||
if (Tools.isArray(value)) {
|
||||
for (let r = 0; r <= endRow - startRow; r++) {
|
||||
for (let c = 0; c <= endColumn - startColumn; c++) {
|
||||
cellValue.setValue(r + startRow, c + startColumn, value[r][c]);
|
||||
}
|
||||
}
|
||||
} else if (Tools.isObject(value)) {
|
||||
cellValue = value as ObjectMatrix<ICellData>;
|
||||
} else {
|
||||
} else if (isICellData(value)) {
|
||||
cellValue.setValue(startRow, startColumn, value);
|
||||
} else {
|
||||
realCellValue = value as ObjectMatrixPrimitiveType<ICellData>;
|
||||
}
|
||||
}
|
||||
|
||||
const setRangeValuesMutationParams: ISetRangeValuesMutationParams = {
|
||||
rangeData: range,
|
||||
rangeData: currentSelections,
|
||||
worksheetId,
|
||||
workbookId,
|
||||
cellValue: cellValue as any,
|
||||
cellValue: realCellValue ?? cellValue.getMatrix(),
|
||||
};
|
||||
const undoSetRangeValuesMutationParams: ISetRangeValuesMutationParams = SetRangeValuesUndoMutationFactory(accessor, setRangeValuesMutationParams);
|
||||
|
||||
// execute do mutations and add undo mutations to undo stack if completed
|
||||
const result = commandService.executeCommand(SetRangeValuesMutation.id, setRangeValuesMutationParams);
|
||||
if (result) {
|
||||
undoRedoService.pushUndoRedo({
|
||||
// 如果有多个 mutation 构成一个封装项目,那么要封装在同一个 undo redo element 里面
|
||||
// 通过勾子可以 hook 外部 controller 的代码来增加新的 action
|
||||
URI: 'sheet', // TODO: this URI is fake
|
||||
URI: workbookId,
|
||||
undo() {
|
||||
return commandService.executeCommand(SetRangeValuesMutation.id, undoSetRangeValuesMutationParams);
|
||||
},
|
||||
|
||||
@@ -94,7 +94,7 @@ export const SetStyleCommand: ICommand<ISetStyleParams<unknown>> = {
|
||||
const result = commandService.executeCommand(SetRangeStyleMutation.id, setRangeStyleMutationParams);
|
||||
if (result) {
|
||||
undoRedoService.pushUndoRedo({
|
||||
URI: 'sheet', // TODO: this URI is fake: would be replace with Univer business instance id
|
||||
URI: workbookId,
|
||||
undo() {
|
||||
return commandService.executeCommand(SetRangeStyleMutation.id, undoSetRangeStyleMutationParams);
|
||||
},
|
||||
|
||||
@@ -35,7 +35,7 @@ export const SetTabColorCommand: ICommand = {
|
||||
|
||||
if (result) {
|
||||
undoRedoService.pushUndoRedo({
|
||||
URI: 'sheet',
|
||||
URI: workbookId,
|
||||
undo() {
|
||||
return commandService.executeCommand(SetTabColorMutation.id, undoMutationParams);
|
||||
},
|
||||
|
||||
@@ -35,7 +35,7 @@ export const SetWorksheetActivateCommand: ICommand = {
|
||||
// no need
|
||||
// if (result) {
|
||||
// undoRedoService.pushUndoRedo({
|
||||
// URI: 'sheet',
|
||||
// URI: workbookId,
|
||||
// undo() {
|
||||
// return commandService.executeCommand(SetWorksheetActivateMutation.id, undoMutationParams);
|
||||
// },
|
||||
|
||||
@@ -36,7 +36,7 @@ export const SetWorksheetColWidthCommand: ICommand = {
|
||||
const result = commandService.executeCommand(SetWorksheetColWidthMutation.id, redoMutationParams);
|
||||
if (result) {
|
||||
undoRedoService.pushUndoRedo({
|
||||
URI: 'sheet',
|
||||
URI: workbookId,
|
||||
undo() {
|
||||
return commandService.executeCommand(SetWorksheetColWidthMutation.id, undoMutationParams);
|
||||
},
|
||||
|
||||
@@ -36,7 +36,7 @@ export const SetWorksheetColumnHideCommand: ICommand = {
|
||||
const result = commandService.executeCommand(SetWorksheetColumnHideMutation.id, redoMutationParams);
|
||||
if (result) {
|
||||
undoRedoService.pushUndoRedo({
|
||||
URI: 'sheet',
|
||||
URI: workbookId,
|
||||
undo() {
|
||||
return commandService.executeCommand(SetWorksheetColumnShowMutation.id, undoMutationParams);
|
||||
},
|
||||
|
||||
@@ -37,7 +37,7 @@ export const SetWorksheetColumnShowCommand: ICommand = {
|
||||
|
||||
if (result) {
|
||||
undoRedoService.pushUndoRedo({
|
||||
URI: 'sheet',
|
||||
URI: workbookId,
|
||||
undo() {
|
||||
return commandService.executeCommand(SetWorksheetColumnHideMutation.id, undoMutationParams);
|
||||
},
|
||||
|
||||
@@ -54,7 +54,7 @@ export const SetWorksheetHideCommand: ICommand = {
|
||||
|
||||
if (result && activeResult) {
|
||||
undoRedoService.pushUndoRedo({
|
||||
URI: 'sheet',
|
||||
URI: workbookId,
|
||||
undo() {
|
||||
return (commandService.executeCommand(SetWorksheetActivateMutation.id, unActiveMutationParams) as Promise<boolean>).then((res) => {
|
||||
if (res) return commandService.executeCommand(SetWorksheetHideMutation.id, undoMutationParams);
|
||||
|
||||
@@ -34,7 +34,7 @@ export const SetWorksheetNameCommand: ICommand = {
|
||||
|
||||
if (result) {
|
||||
undoRedoService.pushUndoRedo({
|
||||
URI: 'sheet',
|
||||
URI: workbookId,
|
||||
undo() {
|
||||
return commandService.executeCommand(SetWorksheetNameMutation.id, undoMutationParams);
|
||||
},
|
||||
|
||||
@@ -36,7 +36,7 @@ export const SetWorksheetOrderCommand: ICommand = {
|
||||
|
||||
if (result) {
|
||||
undoRedoService.pushUndoRedo({
|
||||
URI: 'sheet',
|
||||
URI: workbookId,
|
||||
undo() {
|
||||
return commandService.executeCommand(SetWorksheetOrderMutation.id, undoMutationParams);
|
||||
},
|
||||
|
||||
@@ -47,7 +47,7 @@ export const SetWorksheetRightToLeftCommand: ICommand = {
|
||||
|
||||
if (result) {
|
||||
undoRedoService.pushUndoRedo({
|
||||
URI: 'sheet',
|
||||
URI: workbookId,
|
||||
undo() {
|
||||
return commandService.executeCommand(SetWorksheetRightToLeftMutation.id, undoMutationParams);
|
||||
},
|
||||
|
||||
@@ -37,7 +37,7 @@ export const SetWorksheetRowHeightCommand: ICommand = {
|
||||
const result = commandService.executeCommand(SetWorksheetRowHeightMutation.id, redoMutationParams);
|
||||
if (result) {
|
||||
undoRedoService.pushUndoRedo({
|
||||
URI: 'sheet',
|
||||
URI: workbookId,
|
||||
undo() {
|
||||
return commandService.executeCommand(SetWorksheetRowHeightMutation.id, undoMutationParams);
|
||||
},
|
||||
|
||||
@@ -36,7 +36,7 @@ export const SetWorksheetRowHideCommand: ICommand = {
|
||||
const result = commandService.executeCommand(SetWorksheetRowHideMutation.id, redoMutationParams);
|
||||
if (result) {
|
||||
undoRedoService.pushUndoRedo({
|
||||
URI: 'sheet',
|
||||
URI: workbookId,
|
||||
undo() {
|
||||
return commandService.executeCommand(SetWorksheetRowShowMutation.id, undoMutationParams);
|
||||
},
|
||||
|
||||
@@ -37,7 +37,7 @@ export const SetWorksheetRowShowCommand: ICommand = {
|
||||
|
||||
if (result) {
|
||||
undoRedoService.pushUndoRedo({
|
||||
URI: 'sheet',
|
||||
URI: workbookId,
|
||||
undo() {
|
||||
return commandService.executeCommand(SetWorksheetRowHideMutation.id, undoMutationParams);
|
||||
},
|
||||
|
||||
@@ -50,7 +50,7 @@ export const SetWorksheetShowCommand: ICommand = {
|
||||
|
||||
if (result && activeResult) {
|
||||
undoRedoService.pushUndoRedo({
|
||||
URI: 'sheet',
|
||||
URI: workbookId,
|
||||
undo() {
|
||||
return (commandService.executeCommand(SetWorksheetActivateMutation.id, unActiveMutationParams) as Promise<boolean>).then((res) => {
|
||||
if (res) return commandService.executeCommand(SetWorksheetHideMutation.id, undoMutationParams);
|
||||
|
||||
@@ -43,7 +43,7 @@ export const SetZoomRatioCommand: ICommand = {
|
||||
|
||||
if (result) {
|
||||
undoRedoService.pushUndoRedo({
|
||||
URI: 'sheet',
|
||||
URI: workbookId,
|
||||
undo() {
|
||||
return commandService.executeCommand(SetZoomRatioMutation.id, undoMutationParams);
|
||||
},
|
||||
|
||||
@@ -57,7 +57,7 @@ export const TrimWhitespaceCommand: ICommand = {
|
||||
undoRedoService.pushUndoRedo({
|
||||
// 如果有多个 mutation 构成一个封装项目,那么要封装在同一个 undo redo element 里面
|
||||
// 通过勾子可以 hook 外部 controller 的代码来增加新的 action
|
||||
URI: 'sheet', // TODO: this URI is fake
|
||||
URI: workbookId,
|
||||
undo() {
|
||||
return commandService.executeCommand(SetRangeFormattedValueMutation.id, undoSetRangeFormattedValueMutationParams);
|
||||
},
|
||||
|
||||
@@ -1,15 +1,4 @@
|
||||
import {
|
||||
CommandType,
|
||||
createRowColIter,
|
||||
ICellData,
|
||||
ICopyToOptionsData,
|
||||
ICurrentUniverService,
|
||||
IMutation,
|
||||
IRangeData,
|
||||
ObjectMatrix,
|
||||
ObjectMatrixPrimitiveType,
|
||||
Tools,
|
||||
} from '@univerjs/core';
|
||||
import { CommandType, ICellData, ICopyToOptionsData, ICurrentUniverService, IMutation, IRangeData, ObjectMatrix, ObjectMatrixPrimitiveType, Tools } from '@univerjs/core';
|
||||
import { IAccessor } from '@wendellhu/redi';
|
||||
|
||||
/** Params of `SetRangeValuesMutation` */
|
||||
@@ -57,6 +46,7 @@ export const SetRangeValuesUndoMutationFactory = (accessor: IAccessor, params: I
|
||||
} as ISetRangeValuesMutationParams;
|
||||
};
|
||||
|
||||
// TODO@Dushusir: this would cover style as well. Which is not expected.
|
||||
export const SetRangeValuesMutation: IMutation<ISetRangeValuesMutationParams, boolean> = {
|
||||
id: 'sheet.mutation.set-range-values',
|
||||
type: CommandType.MUTATION,
|
||||
@@ -76,11 +66,11 @@ export const SetRangeValuesMutation: IMutation<ISetRangeValuesMutationParams, bo
|
||||
const { startRow, startColumn, endColumn, endRow } = rangeData[i];
|
||||
|
||||
// clear selection content
|
||||
createRowColIter(startRow, endRow, startColumn, endColumn).forEach((r, c) => {
|
||||
if (cellMatrix.getValue(r, c)) {
|
||||
cellMatrix.setValue(r, c, { v: null });
|
||||
}
|
||||
});
|
||||
// createRowColIter(startRow, endRow, startColumn, endColumn).forEach((r, c) => {
|
||||
// if (cellMatrix.getValue(r, c)) {
|
||||
// cellMatrix.setValue(r, c, { v: null });
|
||||
// }
|
||||
// });
|
||||
|
||||
newValues.forValue((row, col, newVal) => {
|
||||
const oldVal = cellMatrix.getValue(row, col) || {};
|
||||
@@ -91,23 +81,29 @@ export const SetRangeValuesMutation: IMutation<ISetRangeValuesMutationParams, bo
|
||||
v: null,
|
||||
});
|
||||
} else {
|
||||
// TODO: @wzhudev: add config to change value or format only
|
||||
let dirty = false;
|
||||
|
||||
if (newVal.p != null) {
|
||||
oldVal.p = newVal.p;
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
if (newVal.v != null) {
|
||||
oldVal.v = newVal.v;
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
if (newVal.m != null) {
|
||||
oldVal.m = newVal.m;
|
||||
dirty = true;
|
||||
} else {
|
||||
oldVal.m = String(oldVal.v);
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
if (newVal.t != null) {
|
||||
oldVal.t = newVal.t;
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
cellMatrix.setValue(row, col, oldVal);
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
import { Direction, handleJsonToDom, ICellData, ICommandService, ICurrentUniverService, IDocumentData, IRangeData, IStyleData, Nullable } from '@univerjs/core';
|
||||
import { Inject } from '@wendellhu/redi';
|
||||
|
||||
import { SetSelectionsOperation } from '../Commands/Operations/selection.operation';
|
||||
import { SelectionManagerService } from '../Services/selection-manager.service';
|
||||
|
||||
/**
|
||||
* Cell Editor
|
||||
*/
|
||||
export class CellEditorController {
|
||||
isEditMode: boolean;
|
||||
|
||||
// current edit cell
|
||||
currentEditRangeData: IRangeData;
|
||||
|
||||
constructor(
|
||||
@ICurrentUniverService private readonly _currentUniverService: ICurrentUniverService,
|
||||
@Inject(SelectionManagerService) private readonly _selectionManagerService: SelectionManagerService,
|
||||
@ICommandService private readonly _commandService: ICommandService
|
||||
) {
|
||||
this._commandService.registerCommand(SetSelectionsOperation);
|
||||
}
|
||||
|
||||
setEditMode(value: boolean) {
|
||||
this.isEditMode = value;
|
||||
}
|
||||
|
||||
getEditMode() {
|
||||
return this.isEditMode;
|
||||
}
|
||||
|
||||
setCurrentEditRangeData() {
|
||||
const currentCell = this._selectionManagerService.getLast()?.cellRange;
|
||||
if (!currentCell) return;
|
||||
|
||||
let row;
|
||||
let column;
|
||||
|
||||
if (currentCell.isMerged) {
|
||||
row = currentCell.startRow;
|
||||
column = currentCell.startColumn;
|
||||
} else {
|
||||
row = currentCell.row;
|
||||
column = currentCell.column;
|
||||
}
|
||||
|
||||
this.currentEditRangeData = {
|
||||
startRow: row,
|
||||
startColumn: column,
|
||||
endRow: row,
|
||||
endColumn: column,
|
||||
};
|
||||
}
|
||||
|
||||
getCurrentEditRangeData() {
|
||||
return this.currentEditRangeData;
|
||||
}
|
||||
|
||||
setCurrentEditRangeValue(cell: ICellData) {
|
||||
// only one selection
|
||||
if (this.currentEditRangeData == null) {
|
||||
return;
|
||||
}
|
||||
const { startRow, startColumn, endRow, endColumn } = this.currentEditRangeData;
|
||||
const range = this._currentUniverService.getCurrentUniverSheetInstance().getWorkBook().getActiveSheet().getRange(startRow, startColumn, endRow, endColumn);
|
||||
|
||||
// range.setRangeData(cell);
|
||||
}
|
||||
|
||||
getSelectionValue(): string {
|
||||
const range = this.getActiveRange();
|
||||
|
||||
const value = range && range.getDisplayValue();
|
||||
if (typeof value === 'string') {
|
||||
return value;
|
||||
}
|
||||
if (typeof value === 'object' && value !== null) {
|
||||
return handleJsonToDom(value);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
getSelectionStyle(): Nullable<IStyleData> {
|
||||
return this.getActiveRange()?.getTextStyle();
|
||||
}
|
||||
|
||||
setSelectionValue(value: IDocumentData | string) {
|
||||
const range = this.getActiveRange();
|
||||
if (!range) return;
|
||||
|
||||
if (typeof value === 'string') {
|
||||
// range.setValue(value);
|
||||
}
|
||||
if (typeof value === 'object') {
|
||||
// range.setRangeData({ p: value });
|
||||
}
|
||||
}
|
||||
|
||||
getActiveRange() {
|
||||
const cellRange = this._selectionManagerService.getLast()?.cellRange;
|
||||
if (!cellRange) return;
|
||||
let { row, column } = cellRange;
|
||||
|
||||
if (cellRange.isMerged) {
|
||||
row = cellRange.startRow;
|
||||
column = cellRange.startColumn;
|
||||
}
|
||||
|
||||
return this._currentUniverService.getCurrentUniverSheetInstance().getWorkBook().getActiveSheet().getRange(row, column);
|
||||
}
|
||||
|
||||
handleBackSpace() {}
|
||||
|
||||
handleDirection(direction: Direction) {
|
||||
// todo
|
||||
}
|
||||
}
|
||||
@@ -24,13 +24,11 @@ export class SheetContainerController extends Disposable {
|
||||
private _initialize() {
|
||||
this.disposeWithMe(
|
||||
this._commandService.onCommandExecuted((command: ICommandInfo) => {
|
||||
// refresh selection and worksheet canvas view
|
||||
if (updateCommandList.includes(command.id)) {
|
||||
const workbook = this._currentUniverService.getCurrentUniverSheetInstance().getWorkBook();
|
||||
const unitId = workbook.getUnitId();
|
||||
const worksheet = this._currentUniverService.getCurrentUniverSheetInstance().getWorkBook().getActiveSheet();
|
||||
const worksheet = workbook.getActiveSheet();
|
||||
const sheetId = worksheet.getSheetId();
|
||||
// this._selectionManager.updateToSheet(worksheet);
|
||||
|
||||
this._selectionManagerService.setCurrentSelection({
|
||||
pluginName: NORMAL_SELECTION_PLUGIN_NAME,
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
// @index(['./*.ts','./**/index.ts'], f => `export * from '${f.path}'`)
|
||||
export * from './BasicWorkbook.controller';
|
||||
export * from './BasicWorksheet.controller';
|
||||
export * from './CellEditorController';
|
||||
export * from './CountBarController';
|
||||
// export * from './EditTooltipsController';
|
||||
export * from './SheetBarController';
|
||||
export * from './SheetContainerController';
|
||||
// @endindex
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { Engine, IRenderingEngine, ISelectionTransformerShapeManager, SelectionTransformerShapeManager } from '@univerjs/base-render';
|
||||
import { DEFAULT_SELECTION, ICurrentUniverService, LocaleService, Plugin, PLUGIN_NAMES, PluginType } from '@univerjs/core';
|
||||
import { ISelectionTransformerShapeManager, SelectionTransformerShapeManager } from '@univerjs/base-render';
|
||||
import { DEFAULT_SELECTION, ICommandService, ICurrentUniverService, LocaleService, Plugin, PLUGIN_NAMES, PluginType } from '@univerjs/core';
|
||||
import { Dependency, Inject, Injector } from '@wendellhu/redi';
|
||||
|
||||
import { DEFAULT_SPREADSHEET_PLUGIN_DATA, install, ISheetPluginConfig } from './Basics';
|
||||
import { SheetPluginObserve, uninstall } from './Basics/Observer';
|
||||
import { BasicWorkbookController, CellEditorController, CountBarController, SheetBarController, SheetContainerController } from './Controller';
|
||||
import { SetSelectionsOperation } from './Commands/Operations/selection.operation';
|
||||
import { BasicWorkbookController, CountBarController, SheetBarController, SheetContainerController } from './Controller';
|
||||
import { BasicWorksheetController } from './Controller/BasicWorksheet.controller';
|
||||
import { FormulaBarController } from './Controller/FormulaBarController';
|
||||
import { en, zh } from './Locale';
|
||||
@@ -20,25 +21,18 @@ export class SheetPlugin extends Plugin<SheetPluginObserve> {
|
||||
|
||||
private _config: ISheetPluginConfig;
|
||||
|
||||
private _canvasEngine: Engine;
|
||||
|
||||
// private _editTooltipsController: EditTooltipsController;
|
||||
|
||||
private _formulaBarController: FormulaBarController;
|
||||
|
||||
private _sheetBarController: SheetBarController;
|
||||
|
||||
// private _cellEditorController: CellEditorController;
|
||||
|
||||
private _countBarController: CountBarController;
|
||||
|
||||
// private _hideColumnController: HideColumnController;
|
||||
|
||||
private _sheetContainerController: SheetContainerController;
|
||||
|
||||
constructor(
|
||||
config: Partial<ISheetPluginConfig>,
|
||||
@ICurrentUniverService private readonly _currentUniverService: ICurrentUniverService,
|
||||
@ICommandService private readonly _commandService: ICommandService,
|
||||
@Inject(LocaleService) private readonly _localeService: LocaleService,
|
||||
@Inject(Injector) override readonly _injector: Injector
|
||||
) {
|
||||
@@ -47,6 +41,7 @@ export class SheetPlugin extends Plugin<SheetPluginObserve> {
|
||||
this._config = Object.assign(DEFAULT_SPREADSHEET_PLUGIN_DATA, config);
|
||||
|
||||
this._initializeDependencies(_injector);
|
||||
this._initializeCommands();
|
||||
}
|
||||
|
||||
initialize(): void {
|
||||
@@ -59,7 +54,6 @@ export class SheetPlugin extends Plugin<SheetPluginObserve> {
|
||||
|
||||
this.initConfig();
|
||||
this.initController();
|
||||
this.initCanvasView();
|
||||
this.listenEventManager();
|
||||
}
|
||||
|
||||
@@ -81,23 +75,16 @@ export class SheetPlugin extends Plugin<SheetPluginObserve> {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO@huwenzhao: We don't need to init controllers manually
|
||||
initController() {
|
||||
this._sheetContainerController = this._injector.get(SheetContainerController);
|
||||
this._formulaBarController = this._injector.get(FormulaBarController);
|
||||
// this._editTooltipsController = this._injector.get(EditTooltipsController);
|
||||
this._sheetBarController = this._injector.get(SheetBarController);
|
||||
this._countBarController = this._injector.get(CountBarController);
|
||||
// this._hideColumnController = this._injector.get(HideColumnController);
|
||||
|
||||
this._injector.get(BasicWorksheetController);
|
||||
this._injector.get(BasicWorkbookController);
|
||||
}
|
||||
|
||||
initCanvasView() {
|
||||
this._canvasEngine = this._injector.get(IRenderingEngine);
|
||||
}
|
||||
|
||||
override onMounted(): void {
|
||||
this.initialize();
|
||||
}
|
||||
@@ -114,52 +101,35 @@ export class SheetPlugin extends Plugin<SheetPluginObserve> {
|
||||
this._sheetBarController.listenEventManager();
|
||||
}
|
||||
|
||||
/** @deprecated move to DI system */
|
||||
// getSelectionManager() {
|
||||
// return this._injector.get(ISelectionManager);
|
||||
// }
|
||||
|
||||
private _initializeDependencies(sheetInjector: Injector) {
|
||||
const dependencies: Dependency[] = [
|
||||
[CanvasView],
|
||||
|
||||
[CellEditorController],
|
||||
[SheetContainerController],
|
||||
[FormulaBarController],
|
||||
// [EditTooltipsController],
|
||||
[SheetBarController],
|
||||
[CountBarController],
|
||||
|
||||
// TODO@huwenzhao: this is a temporary solution
|
||||
// [
|
||||
// ISelectionManager,
|
||||
// {
|
||||
// useFactory: (injector: Injector, canvasView: CanvasView) => injector.createInstance(SelectionManager, canvasView.getSheetView(), this._config),
|
||||
// deps: [Injector, CanvasView],
|
||||
// },
|
||||
// ],
|
||||
// [RowTitleController],
|
||||
// [ColumnTitleController],
|
||||
// [DragLineController],
|
||||
// [HideColumnController],
|
||||
|
||||
[BasicWorksheetController],
|
||||
[BasicWorkbookController],
|
||||
|
||||
// services
|
||||
[BorderStyleManagerService],
|
||||
|
||||
[SelectionManagerService],
|
||||
|
||||
[
|
||||
ISelectionTransformerShapeManager,
|
||||
{
|
||||
useClass: SelectionTransformerShapeManager,
|
||||
},
|
||||
],
|
||||
|
||||
// controllers
|
||||
[SheetContainerController],
|
||||
[FormulaBarController],
|
||||
[SheetBarController],
|
||||
[CountBarController],
|
||||
[BasicWorksheetController],
|
||||
[BasicWorkbookController],
|
||||
];
|
||||
|
||||
dependencies.forEach((d) => {
|
||||
sheetInjector.add(d);
|
||||
});
|
||||
}
|
||||
|
||||
private _initializeCommands(): void {
|
||||
this._commandService.registerCommand(SetSelectionsOperation);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ export enum CANVAS_VIEW_KEY {
|
||||
VIEW_LEFT_TOP = 'viewLeftTop',
|
||||
SHEET_VIEW = 'sheetView',
|
||||
DRAG_LINE_VIEW = 'dragLineView',
|
||||
CELL_EDITOR = 'cellEditor',
|
||||
SELECTION_VIEW = 'selectionView',
|
||||
}
|
||||
|
||||
|
||||
@@ -53,11 +53,14 @@ export class CanvasView {
|
||||
const rowTitle = config.rowTitle;
|
||||
const columnTitle = config.columnTitle;
|
||||
|
||||
// How do we know if a business should claim itself as main scene?
|
||||
const scene = new Scene(CANVAS_VIEW_KEY.MAIN_SCENE, engine, {
|
||||
width: 1500,
|
||||
height: 1000,
|
||||
});
|
||||
|
||||
scene.openTransformer();
|
||||
|
||||
this._scene = scene;
|
||||
const viewMain = new Viewport(CANVAS_VIEW_KEY.VIEW_MAIN, scene, {
|
||||
left: rowTitle.width,
|
||||
@@ -89,6 +92,7 @@ export class CanvasView {
|
||||
});
|
||||
// viewMain.linkToViewport(viewLeft, LINK_VIEW_PORT_TYPE.Y);
|
||||
// viewMain.linkToViewport(viewTop, LINK_VIEW_PORT_TYPE.X);
|
||||
// syncing scroll on the main area to headerbars
|
||||
viewMain.onScrollAfterObserver.add((param: IScrollObserverParam) => {
|
||||
const { scrollX, scrollY, actualScrollX, actualScrollY } = param;
|
||||
|
||||
@@ -129,6 +133,7 @@ export class CanvasView {
|
||||
const currentRatio = sheet.getZoomRatio();
|
||||
let nextRatio = +parseFloat(`${currentRatio + ratioDelta}`).toFixed(1);
|
||||
nextRatio = nextRatio >= 4 ? 4 : nextRatio <= 0.1 ? 0.1 : nextRatio;
|
||||
|
||||
// sheet.setZoomRatio(nextRatio);
|
||||
|
||||
e.preventDefault();
|
||||
@@ -145,11 +150,6 @@ export class CanvasView {
|
||||
|
||||
engine.runRenderLoop(() => {
|
||||
scene.render();
|
||||
|
||||
const app = document.getElementById('app');
|
||||
if (app) {
|
||||
app.innerText = `fps:${Math.round(engine.getFps()).toString()}`;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -9,9 +9,10 @@ import {
|
||||
SpreadsheetColumnTitle,
|
||||
SpreadsheetRowTitle,
|
||||
} from '@univerjs/base-render';
|
||||
import { ICurrentUniverService, ISelectionRange, LocaleService, ObserverManager, Worksheet } from '@univerjs/core';
|
||||
import { ICommandService, ICurrentUniverService, ISelectionRange, LocaleService, ObserverManager, Worksheet } from '@univerjs/core';
|
||||
import { Inject, Injector } from '@wendellhu/redi';
|
||||
|
||||
import { SetSelectionsOperation } from '../../Commands/Operations/selection.operation';
|
||||
import { NORMAL_SELECTION_PLUGIN_NAME, SelectionManagerService } from '../../Services/selection-manager.service';
|
||||
import { BaseView, CANVAS_VIEW_KEY, CanvasViewRegistry, SHEET_VIEW_KEY } from '../BaseView';
|
||||
|
||||
@@ -21,6 +22,7 @@ export class SelectionView extends BaseView {
|
||||
constructor(
|
||||
@ICurrentUniverService private readonly _currentUniverService: ICurrentUniverService,
|
||||
@ISelectionTransformerShapeManager private readonly _selectionTransformerShapeManager: ISelectionTransformerShapeManager,
|
||||
@ICommandService private readonly _commandService: ICommandService,
|
||||
@Inject(SelectionManagerService) private readonly _selectionManagerService: SelectionManagerService,
|
||||
@Inject(ObserverManager) private readonly _observerManager: ObserverManager,
|
||||
@Inject(LocaleService) private readonly _localeService: LocaleService
|
||||
@@ -69,7 +71,16 @@ export class SelectionView extends BaseView {
|
||||
spreadsheetLeftTopPlaceholder?.onPointerDownObserver.add((evt: IPointerEvent | IMouseEvent) => {});
|
||||
|
||||
this._selectionTransformerShapeManager.selectionRangeWithStyle$.subscribe((selectionDataWithStyleList) => {
|
||||
this._selectionManagerService.replaceWithNoRefresh(selectionDataWithStyleList.map((selectionDataWithStyle) => convertSelectionDataToRange(selectionDataWithStyle)));
|
||||
const unitId = workbook.getUnitId();
|
||||
const sheetId = worksheet.getSheetId();
|
||||
|
||||
this._commandService.executeCommand(SetSelectionsOperation.id, {
|
||||
unitId,
|
||||
sheetId,
|
||||
pluginName: NORMAL_SELECTION_PLUGIN_NAME,
|
||||
selections: selectionDataWithStyleList.map((selectionDataWithStyle) => convertSelectionDataToRange(selectionDataWithStyle)),
|
||||
});
|
||||
|
||||
const current = selectionDataWithStyleList[selectionDataWithStyleList.length - 1];
|
||||
if (current == null) {
|
||||
return;
|
||||
|
||||
@@ -81,6 +81,7 @@ export {
|
||||
export { CopySheetCommand } from './Commands/Commands/copy-worksheet.command';
|
||||
export { RemoveSheetCommand } from './Commands/Commands/remove-sheet.command';
|
||||
export { RemoveWorksheetMergeCommand } from './Commands/Commands/remove-worksheet-merge.command';
|
||||
export { ISetRangeValuesCommandParams, SetRangeValuesCommand } from './Commands/Commands/set-range-values.command';
|
||||
export { SetTabColorCommand } from './Commands/Commands/set-tab-color.command';
|
||||
export { SetWorksheetHideCommand } from './Commands/Commands/set-worksheet-hide.command';
|
||||
export { SetWorksheetNameCommand } from './Commands/Commands/set-worksheet-name.command';
|
||||
|
||||
@@ -15,7 +15,8 @@ import {
|
||||
} from '@univerjs/base-render';
|
||||
import { DocumentModel, EventState, IPageElement, LocaleService, PageElementType } from '@univerjs/core';
|
||||
import { Inject, Injector } from '@wendellhu/redi';
|
||||
import { ObjectAdaptor, CanvasObjectProviderRegistry } from '../Adaptor';
|
||||
|
||||
import { CanvasObjectProviderRegistry, ObjectAdaptor } from '../Adaptor';
|
||||
|
||||
export enum DOCS_VIEW_KEY {
|
||||
MAIN = '__DocsRender__',
|
||||
@@ -42,6 +43,7 @@ export class DocsAdaptor extends ObjectAdaptor {
|
||||
return this;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line max-lines-per-function
|
||||
override convert(pageElement: IPageElement, mainScene: Scene) {
|
||||
const { id, zIndex, left = 0, top = 0, width, height, angle, scaleX, scaleY, skewX, skewY, flipX, flipY, title, description, document: documentData } = pageElement;
|
||||
if (documentData == null) {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { IRichTextProps, RichText, Scene } from '@univerjs/base-render';
|
||||
import { IPageElement, LocaleService, PageElementType } from '@univerjs/core';
|
||||
|
||||
import { Inject, Injector } from '@wendellhu/redi';
|
||||
import { ObjectAdaptor, CanvasObjectProviderRegistry } from '../Adaptor';
|
||||
|
||||
import { CanvasObjectProviderRegistry, ObjectAdaptor } from '../Adaptor';
|
||||
|
||||
export class RichTextAdaptor extends ObjectAdaptor {
|
||||
override zIndex = 2;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { Engine, Rect, Scene, Slide, Viewport } from '@univerjs/base-render';
|
||||
import { SlideModel, getColorStyle, IColorStyle, IPageElement, ISlidePage, PageElementType } from '@univerjs/core';
|
||||
|
||||
import { getColorStyle, IColorStyle, IPageElement, ISlidePage, PageElementType, SlideModel } from '@univerjs/core';
|
||||
import { Inject, Injector } from '@wendellhu/redi';
|
||||
import { ObjectAdaptor, CanvasObjectProviderRegistry } from '../Adaptor';
|
||||
|
||||
import { CanvasObjectProviderRegistry, ObjectAdaptor } from '../Adaptor';
|
||||
import { ObjectProvider } from '../ObjectProvider';
|
||||
// import { DocsAdaptor, ImageAdaptor, RichTextAdaptor, ShapeAdaptor } from './';
|
||||
|
||||
|
||||
@@ -13,9 +13,10 @@ import {
|
||||
SpreadsheetSkeleton,
|
||||
Viewport,
|
||||
} from '@univerjs/base-render';
|
||||
import { EventState, ICellData, IPageElement, ObjectMatrix, PageElementType, Styles, LocaleService } from '@univerjs/core';
|
||||
import { EventState, ICellData, IPageElement, LocaleService, ObjectMatrix, PageElementType, Styles } from '@univerjs/core';
|
||||
import { Inject, Injector } from '@wendellhu/redi';
|
||||
import { ObjectAdaptor, CanvasObjectProviderRegistry } from '../Adaptor';
|
||||
|
||||
import { CanvasObjectProviderRegistry, ObjectAdaptor } from '../Adaptor';
|
||||
|
||||
enum SHEET_VIEW_KEY {
|
||||
MAIN = 'spreadInSlide',
|
||||
|
||||
@@ -289,12 +289,11 @@ export class CanvasView {
|
||||
|
||||
const { pageElements, pageBackgroundFill } = page;
|
||||
|
||||
// SceneViewers
|
||||
const objects = this._ObjectProvider.convertToRenderObjects(pageElements, this._scene);
|
||||
|
||||
scene.openTransformer();
|
||||
|
||||
this._addBackgroundRect(scene, pageBackgroundFill);
|
||||
|
||||
// So finally SceneViewers are added to the scene as objects. How can we do optimizations on this?
|
||||
scene.addObjects(objects);
|
||||
|
||||
const transformer = scene.getTransformer();
|
||||
|
||||
@@ -45,17 +45,21 @@
|
||||
"@storybook/addon-interactions": "^7.4.1",
|
||||
"@storybook/addon-links": "^7.4.1",
|
||||
"@storybook/blocks": "^7.4.1",
|
||||
"@storybook/react": "^7.4.1",
|
||||
"@storybook/react-vite": "^7.4.1",
|
||||
"@storybook/react": "^7.4.1",
|
||||
"@storybook/testing-library": "^0.2.0",
|
||||
"@testing-library/react": "^14.0.0",
|
||||
"@types/jest": "^29.5.4",
|
||||
"@types/node": "^18.14.0",
|
||||
"@types/react": "^18.2.21",
|
||||
"@types/react-dom": "^18.2.7",
|
||||
"jest": "29.6.4",
|
||||
"@types/react": "^18.2.21",
|
||||
"debug": "^4.3.3",
|
||||
"enzyme": "^3.11.0",
|
||||
"identity-obj-proxy": "^3.0.0",
|
||||
"jest-css-modules-transform": "^4.4.2",
|
||||
"jest-dev-server": "^6.1.1",
|
||||
"jest-environment-jsdom": "^29.6.4",
|
||||
"jest": "29.6.4",
|
||||
"less": "^4.1.1",
|
||||
"storybook": "^7.4.1",
|
||||
"ts-jest": "29.1.1",
|
||||
|
||||
@@ -1,11 +1,4 @@
|
||||
import { Context } from '@univerjs/core/src/Basics/Context';
|
||||
|
||||
// TODO Button const enum; BaseComponentSheet => BaseComponentXXX
|
||||
|
||||
export interface BaseComponentProps {
|
||||
getComponent?: (ref: any) => void; //获取自身组件
|
||||
id?: string; // 组件id
|
||||
|
||||
/** @deprecated */
|
||||
context?: Context;
|
||||
}
|
||||
|
||||
@@ -1,57 +1,58 @@
|
||||
import { Nullable } from '@univerjs/core';
|
||||
import { ICell } from '../../Interfaces/Cell';
|
||||
import { BaseCellEditExtension, BaseCellEditExtensionFactory } from './CellEditExtensionFactory';
|
||||
import { CellEditExtensionRegister } from './CellEditExtensionRegister';
|
||||
|
||||
export class CellEditExtensionManager {
|
||||
static register: CellEditExtensionRegister;
|
||||
|
||||
private _cellEditExtensionFactoryList: BaseCellEditExtensionFactory[];
|
||||
|
||||
static create(): CellEditExtensionRegister {
|
||||
if (!this.register) {
|
||||
this.register = new CellEditExtensionRegister();
|
||||
this.register.initialize();
|
||||
}
|
||||
|
||||
return this.register;
|
||||
}
|
||||
|
||||
/**
|
||||
* inject cell position
|
||||
* @param row
|
||||
* @param column
|
||||
* @param value
|
||||
*/
|
||||
handle(cell: ICell): Nullable<ICell> {
|
||||
const cellEditExtensionFactoryList = CellEditExtensionManager?.register?.cellEditExtensionFactoryList;
|
||||
if (!cellEditExtensionFactoryList) return;
|
||||
// get the sorted list
|
||||
// get the dynamically added list
|
||||
this._cellEditExtensionFactoryList = cellEditExtensionFactoryList;
|
||||
const extension = this._checkExtension(cell);
|
||||
if (extension) {
|
||||
extension.execute();
|
||||
return extension.getCell();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute when the action is matched
|
||||
* @param command
|
||||
* @returns
|
||||
*/
|
||||
private _checkExtension(cell: ICell): BaseCellEditExtension | false {
|
||||
let extension: BaseCellEditExtension | false = false;
|
||||
if (!this._cellEditExtensionFactoryList) return false;
|
||||
|
||||
for (let index = 0; index < this._cellEditExtensionFactoryList.length; index++) {
|
||||
const extensionFactory = this._cellEditExtensionFactoryList[index];
|
||||
extension = extensionFactory.check(cell);
|
||||
if (extension !== false) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return extension;
|
||||
}
|
||||
}
|
||||
import { Nullable } from '@univerjs/core';
|
||||
|
||||
import { ICell } from '../../Interfaces/Cell';
|
||||
import { BaseCellEditExtension, BaseCellEditExtensionFactory } from './CellEditExtensionFactory';
|
||||
import { CellEditExtensionRegister } from './CellEditExtensionRegister';
|
||||
|
||||
export class CellEditExtensionManager {
|
||||
static register: CellEditExtensionRegister;
|
||||
|
||||
private _cellEditExtensionFactoryList: BaseCellEditExtensionFactory[];
|
||||
|
||||
static create(): CellEditExtensionRegister {
|
||||
if (!this.register) {
|
||||
this.register = new CellEditExtensionRegister();
|
||||
this.register.initialize();
|
||||
}
|
||||
|
||||
return this.register;
|
||||
}
|
||||
|
||||
/**
|
||||
* inject cell position
|
||||
* @param row
|
||||
* @param column
|
||||
* @param value
|
||||
*/
|
||||
handle(cell: ICell): Nullable<ICell> {
|
||||
const cellEditExtensionFactoryList = CellEditExtensionManager?.register?.cellEditExtensionFactoryList;
|
||||
if (!cellEditExtensionFactoryList) return;
|
||||
// get the sorted list
|
||||
// get the dynamically added list
|
||||
this._cellEditExtensionFactoryList = cellEditExtensionFactoryList;
|
||||
const extension = this._checkExtension(cell);
|
||||
if (extension) {
|
||||
extension.execute();
|
||||
return extension.getCell();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute when the action is matched
|
||||
* @param command
|
||||
* @returns
|
||||
*/
|
||||
private _checkExtension(cell: ICell): BaseCellEditExtension | false {
|
||||
let extension: BaseCellEditExtension | false = false;
|
||||
if (!this._cellEditExtensionFactoryList) return false;
|
||||
|
||||
for (let index = 0; index < this._cellEditExtensionFactoryList.length; index++) {
|
||||
const extensionFactory = this._cellEditExtensionFactoryList[index];
|
||||
extension = extensionFactory.check(cell);
|
||||
if (extension !== false) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return extension;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
* Use createContext to provide global language and skin settings
|
||||
*/
|
||||
import { LocaleService, ObserverManager } from '@univerjs/core';
|
||||
import { createContext } from 'react';
|
||||
import { Injector } from '@wendellhu/redi';
|
||||
import { createContext } from 'react';
|
||||
|
||||
import { LocaleType } from '../Enum';
|
||||
import { ComponentManager } from './ComponentManager';
|
||||
@@ -18,6 +18,4 @@ export type AppContextValues = {
|
||||
observerManager: ObserverManager;
|
||||
};
|
||||
|
||||
const AppContext = createContext<Partial<AppContextValues>>({});
|
||||
export { AppContext };
|
||||
export default AppContext;
|
||||
export const AppContext = createContext<Partial<AppContextValues>>({});
|
||||
|
||||
@@ -26,6 +26,7 @@ import {
|
||||
FillColorIcon,
|
||||
ForwardIcon,
|
||||
FullBorderIcon,
|
||||
FxIcon,
|
||||
InnerBorderIcon,
|
||||
ItalicIcon,
|
||||
LeftAlignIcon,
|
||||
@@ -48,7 +49,6 @@ import {
|
||||
TopVerticalIcon,
|
||||
UnderLineIcon,
|
||||
VerticalBorderIcon,
|
||||
FxIcon,
|
||||
} from '../Components/Icon';
|
||||
import { Item } from '../Components/Item/Item';
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user