refactor(core): support @DependentOn decorator (#2397)

* refactor(core): support @DependentOn decorator

* chore: rename API

* chore: prettify jsdoc

* chore: declare more dependencies

* refactor: change thread comment plugin relationships

* refactor: refactor link plugin

* fix: fix plugin names

* feat: hook filter plugins

* chore: fix md
This commit is contained in:
Wenzhao Hu
2024-06-03 16:46:25 +08:00
committed by GitHub
parent 0a9a980c09
commit f339ebd390
26 changed files with 256 additions and 196 deletions
-2
View File
@@ -21,7 +21,6 @@ import { LocaleType, LogLevel, Tools, Univer } from '@univerjs/core';
import { defaultTheme } from '@univerjs/design';
import { UniverDocsPlugin } from '@univerjs/docs';
import { UniverDocsUIPlugin } from '@univerjs/docs-ui';
import { UniverFormulaEnginePlugin } from '@univerjs/engine-formula';
import { UniverRenderEnginePlugin } from '@univerjs/engine-render';
import { UniverSheetsPlugin } from '@univerjs/sheets';
import { UniverSheetsFormulaPlugin } from '@univerjs/sheets-formula';
@@ -63,7 +62,6 @@ function factory(id: string) {
// sheet feature plugins
univer.registerPlugin(UniverSheetsNumfmtPlugin);
univer.registerPlugin(UniverFormulaEnginePlugin);
univer.registerPlugin(UniverSheetsFormulaPlugin);
// create univer sheet instance
+3 -13
View File
@@ -20,7 +20,6 @@ import { UniverDocsPlugin } from '@univerjs/docs';
import { UniverDocsUIPlugin } from '@univerjs/docs-ui';
import { UniverFormulaEnginePlugin } from '@univerjs/engine-formula';
import { UniverRenderEnginePlugin } from '@univerjs/engine-render';
import { UniverFindReplacePlugin } from '@univerjs/find-replace';
import { UniverSheetsFilterPlugin } from '@univerjs/sheets-filter';
import type { IUniverRPCMainThreadConfig } from '@univerjs/rpc';
import { UniverRPCMainThreadPlugin } from '@univerjs/rpc';
@@ -38,13 +37,9 @@ import { UniverSheetsThreadCommentPlugin } from '@univerjs/sheets-thread-comment
import { UniverDebuggerPlugin } from '@univerjs/debugger';
import { UniverSheetsHyperLinkUIPlugin } from '@univerjs/sheets-hyper-link-ui';
import { FUniver } from '@univerjs/facade';
import { IThreadCommentMentionDataService } from '@univerjs/thread-comment-ui';
import { UniverDrawingPlugin } from '@univerjs/drawing';
import { UniverDrawingUIPlugin } from '@univerjs/drawing-ui';
import { UniverSheetsDrawingPlugin } from '@univerjs/sheets-drawing';
import { IThreadCommentMentionDataService, UniverThreadCommentUIPlugin } from '@univerjs/thread-comment-ui';
import { UniverSheetsDrawingUIPlugin } from '@univerjs/sheets-drawing-ui';
import { UniverDocsDrawingPlugin } from '@univerjs/docs-drawing';
import { DEFAULT_WORKBOOK_DATA_DEMO } from '../data/sheets/demo/default-workbook-data-demo';
import { enUS, ruRU, zhCN } from '../locales';
@@ -74,8 +69,6 @@ univer.registerPlugin(UniverUIPlugin, {
container: 'app',
});
univer.registerPlugin(UniverDrawingPlugin);
univer.registerPlugin(UniverDocsUIPlugin);
univer.registerPlugin(UniverSheetsPlugin, {
@@ -98,7 +91,6 @@ univer.registerPlugin(UniverRPCMainThreadPlugin, {
univer.registerPlugin(UniverSheetsHyperLinkUIPlugin);
// find replace
univer.registerPlugin(UniverFindReplacePlugin);
univer.registerPlugin(UniverSheetsFindReplacePlugin);
// data validation
@@ -112,9 +104,6 @@ univer.registerPlugin(UniverSheetsFilterPlugin);
univer.registerPlugin(UniverSheetsConditionalFormattingUIPlugin);
// drawing
univer.registerPlugin(UniverDocsDrawingPlugin);
univer.registerPlugin(UniverSheetsDrawingPlugin);
univer.registerPlugin(UniverDrawingUIPlugin);
univer.registerPlugin(UniverSheetsDrawingUIPlugin);
// create univer sheet instance
@@ -151,9 +140,10 @@ class CustomMentionDataService implements IThreadCommentMentionDataService {
}
}
univer.registerPlugin(UniverSheetsThreadCommentPlugin, {
univer.registerPlugin(UniverThreadCommentUIPlugin, {
overrides: [[IThreadCommentMentionDataService, { useClass: CustomMentionDataService }]],
});
univer.registerPlugin(UniverSheetsThreadCommentPlugin);
// debugger plugin
univer.registerPlugin(UniverDebuggerPlugin);
+1 -2
View File
@@ -20,7 +20,6 @@ export { DEFAULT_DOCUMENT_SUB_COMPONENT_ID } from './docs/data-model/subdocument
export { type UnitType, UnitModel, UniverInstanceType } from './common/unit';
export { Registry, RegistryAsMap } from './common/registry';
export { Univer } from './univer';
export { PluginHolder } from './services/plugin/plugin-holder';
export { shallowEqual, isRangesEqual, isUnitRangesEqual } from './common/equal';
export { isNumeric, isSafeNumeric } from './common/number';
export { isBooleanString } from './common/boolean';
@@ -55,7 +54,7 @@ export type { JSONXActions, JSONXPath } from './docs/data-model/json-x/json-x';
export { replaceInDocumentBody } from './docs/data-model/replacement';
export * from './observer';
export { Plugin } from './services/plugin/plugin';
export { PluginService } from './services/plugin/plugin.service';
export { PluginService, DependentOn } from './services/plugin/plugin.service';
export {
type CommandListener,
CommandService,
@@ -1,111 +0,0 @@
/**
* Copyright 2023-present DreamNum Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* eslint-disable ts/no-explicit-any */
import type { Ctor } from '@wendellhu/redi';
import { Inject, Injector } from '@wendellhu/redi';
import { finalize } from 'rxjs';
import { LifecycleStages } from '../lifecycle/lifecycle';
import { LifecycleInitializerService, LifecycleService } from '../lifecycle/lifecycle.service';
import { Disposable } from '../../shared/lifecycle';
import { ILogService } from '../log/log.service';
import { type Plugin, type PluginCtor, PluginRegistry, PluginStore } from './plugin';
export class PluginHolder extends Disposable {
protected _started: boolean = false;
get started(): boolean { return this._started; }
protected readonly _pluginRegistered = new Set<string>();
protected readonly _pluginStore = new PluginStore();
protected readonly _pluginRegistry = new PluginRegistry();
constructor(
@ILogService protected readonly _logService: ILogService,
@Inject(Injector) protected readonly _injector: Injector,
@Inject(LifecycleService) protected readonly _lifecycleService: LifecycleService,
@Inject(LifecycleInitializerService) protected readonly _lifecycleInitializerService: LifecycleInitializerService
) {
super();
}
override dispose(): void {
super.dispose();
this._pluginStore.forEachPlugin((plugin) => plugin.dispose());
this._pluginStore.removePlugins();
this._pluginRegistry.removePlugins();
this._pluginRegistered.clear();
}
registerPlugin<T extends PluginCtor<Plugin>>(pluginCtor: T, config?: ConstructorParameters<T>[0]): void {
const { pluginName } = pluginCtor;
if (this._pluginRegistered.has(pluginName)) {
this._logService.warn('[PluginService]', `plugin ${pluginName} has already been registered. This registration will be ignored.`);
return;
}
this._pluginRegistered.add(pluginName);
this._pluginRegistry.registerPlugin(pluginCtor, config);
}
start(): void {
if (this._started) return;
this._started = true;
this.flush();
}
flush(): void {
if (!this._started) return;
const plugins = this._pluginRegistry.getRegisterPlugins().map(({ plugin, options }) => this._initPlugin(plugin, options));
this._pluginRegistry.removePlugins();
const subscription = this.disposeWithMe(this._lifecycleService.subscribeWithPrevious()
// It has to been async because the finalize may execute synchronously after we
// make the subscription. For example, the lifecycle service is already in stage "steady".
.pipe(finalize(() => { Promise.resolve().then(() => subscription.dispose()); }))
.subscribe((stage) => { this._pluginsRunLifecycle(plugins, stage); }));
}
protected _pluginsRunLifecycle(plugins: Plugin[], lifecycle: LifecycleStages): void {
plugins.forEach((p) => {
switch (lifecycle) {
case LifecycleStages.Starting:
p.onStarting(this._injector);
break;
case LifecycleStages.Ready:
p.onReady();
break;
case LifecycleStages.Rendered:
p.onRendered();
break;
case LifecycleStages.Steady:
p.onSteady();
break;
}
});
this._lifecycleInitializerService.initModulesOnStage(lifecycle);
}
protected _initPlugin<T extends Plugin>(plugin: PluginCtor<T>, options: any): Plugin {
const pluginInstance: Plugin = this._injector.createInstance(plugin as unknown as Ctor<any>, options);
return pluginInstance;
}
}
@@ -14,25 +14,53 @@
* limitations under the License.
*/
import type { IDisposable } from '@wendellhu/redi';
import type { Ctor, IDisposable } from '@wendellhu/redi';
import { Inject, Injector } from '@wendellhu/redi';
import { finalize } from 'rxjs';
import { Disposable } from '../../shared/lifecycle';
import { type UnitType, UniverInstanceType } from '../../common/unit';
import { PluginHolder } from './plugin-holder';
import type { Plugin, PluginCtor } from './plugin';
import { LifecycleStages } from '../lifecycle/lifecycle';
import { LifecycleInitializerService, LifecycleService } from '../lifecycle/lifecycle.service';
import { ILogService } from '../log/log.service';
import { DependentOnSymbol, type Plugin, type PluginCtor, PluginRegistry, PluginStore } from './plugin';
const INIT_LAZY_PLUGINS_TIMEOUT = 4;
/**
* Use this decorator to declare dependencies among plugins. If a dependent plugin is not registered yet,
* Univer will automatically register it with no configuration.
*
* For example:
*
* ```ts
* ⁣@DependentOn(UniverDrawingPlugin, UniverDrawingUIPlugin, UniverSheetsDrawingPlugin)
* export class UniverSheetsDrawingUIPlugin extends Plugin {
* }
* ```
*/
export function DependentOn(...plugins: PluginCtor<Plugin>[]) {
return function (target: PluginCtor<Plugin>) {
target[DependentOnSymbol] = plugins;
};
}
/**
* This service manages plugin registration.
*/
export class PluginService implements IDisposable {
private readonly _pluginHolderForUniver: PluginHolder;
private readonly _pluginHoldersForTypes = new Map<UnitType, PluginHolder>();
private readonly _seenPlugins = new Set<string>();
constructor(
@Inject(Injector) private readonly _injector: Injector
) {
this._pluginHolderForUniver = this._injector.createInstance(PluginHolder);
this._pluginHolderForUniver = this._injector.createInstance(PluginHolder,
this._checkPluginSeen.bind(this),
this._immediateInitPlugin.bind(this)
);
this._pluginHolderForUniver.start();
}
@@ -47,19 +75,18 @@ export class PluginService implements IDisposable {
}
/** Register a plugin into univer. */
registerPlugin<T extends PluginCtor<Plugin>>(plugin: T, config?: ConstructorParameters<T>[0]): void {
this._assertPluginValid(plugin);
registerPlugin<T extends PluginCtor>(ctor: T, config?: ConstructorParameters<T>[0]): void {
this._assertPluginValid(ctor);
this._scheduleInitPlugin();
const { type } = plugin;
const { type } = ctor;
if (type === UniverInstanceType.UNIVER_UNKNOWN) {
this._pluginHolderForUniver.registerPlugin(plugin, config);
this._pluginHolderForUniver.register(ctor, config);
this._pluginHolderForUniver.flush();
} else {
// If it's type is for specific document, we should run them at specific time.
const holder = this._ensurePluginHolderForType(type);
holder.registerPlugin(plugin, config);
holder.register(ctor, config);
}
}
@@ -68,9 +95,12 @@ export class PluginService implements IDisposable {
holder.start();
}
_ensurePluginHolderForType(type: UnitType): PluginHolder {
private _ensurePluginHolderForType(type: UnitType): PluginHolder {
if (!this._pluginHoldersForTypes.has(type)) {
const pluginHolder = this._injector.createInstance(PluginHolder);
const pluginHolder = this._injector.createInstance(PluginHolder,
this._checkPluginSeen.bind(this),
this._immediateInitPlugin.bind(this)
);
this._pluginHoldersForTypes.set(type, pluginHolder);
return pluginHolder;
}
@@ -78,16 +108,33 @@ export class PluginService implements IDisposable {
return this._pluginHoldersForTypes.get(type)!;
}
private _assertPluginValid(plugin: PluginCtor<Plugin>): void {
const { type, pluginName } = plugin;
private _immediateInitPlugin(ctor: PluginCtor): void {
this._seenPlugins.add(ctor.pluginName);
const holder = this._ensurePluginHolderForType(ctor.type);
holder.immediateInitPlugin(ctor);
}
private _checkPluginSeen(ctor: PluginCtor<Plugin>): boolean {
return this._seenPlugins.has(ctor.pluginName);
}
private _assertPluginValid(ctor: PluginCtor<Plugin>): void {
const { type, pluginName } = ctor;
if (type === UniverInstanceType.UNRECOGNIZED) {
throw new Error(`[PluginService]: invalid plugin type for ${plugin}. Please assign a "type" to your plugin.`);
throw new Error(`[PluginService]: invalid plugin type for ${ctor}. Please assign a "type" to your plugin.`);
}
if (pluginName === '') {
throw new Error(`[PluginService]: no plugin name for ${plugin}. Please assign a "pluginName" to your plugin.`);
throw new Error(`[PluginService]: no plugin name for ${ctor}. Please assign a "pluginName" to your plugin.`);
}
if (this._seenPlugins.has(pluginName)) {
throw new Error(`[PluginService]: duplicate plugin name for "${pluginName}".`);
}
this._seenPlugins.add(ctor.pluginName);
}
private _flushTimer?: number;
@@ -123,3 +170,118 @@ export class PluginService implements IDisposable {
}
}
}
export class PluginHolder extends Disposable {
protected _started: boolean = false;
get started(): boolean { return this._started; }
/** Plugin constructors waiting to be initialized. */
protected readonly _pluginRegistry = new PluginRegistry();
/** Stores initialized plugin instances. */
protected readonly _pluginStore = new PluginStore();
constructor(
private _checkPluginRegistered: (pluginCtor: PluginCtor) => boolean,
private _registerPlugin: <T extends PluginCtor>(plugin: T, config?: ConstructorParameters<T>[0]) => void,
@ILogService protected readonly _logService: ILogService,
@Inject(Injector) protected readonly _injector: Injector,
@Inject(LifecycleService) protected readonly _lifecycleService: LifecycleService,
@Inject(LifecycleInitializerService) protected readonly _lifecycleInitializerService: LifecycleInitializerService
) {
super();
}
override dispose(): void {
super.dispose();
this._pluginStore.forEachPlugin((plugin) => plugin.dispose());
this._pluginStore.removePlugins();
this._pluginRegistry.removePlugins();
}
register<T extends PluginCtor<Plugin>>(pluginCtor: T, config?: ConstructorParameters<T>[0]): void {
this._pluginRegistry.registerPlugin(pluginCtor, config);
}
immediateInitPlugin<T extends Plugin>(plugin: PluginCtor<T>): void {
const p = this._initPlugin(plugin, undefined);
this._pluginsRunLifecycle([p]);
}
start(): void {
if (this._started) return;
this._started = true;
this.flush();
}
flush(): void {
if (!this._started) {
return;
};
const plugins = this._pluginRegistry.getRegisterPlugins().map(({ plugin, options }) => this._initPlugin(plugin, options));
this._pluginsRunLifecycle(plugins);
this._pluginRegistry.removePlugins();
}
// eslint-disable-next-line ts/no-explicit-any
private _initPlugin<T extends Plugin>(plugin: PluginCtor<T>, options: any): Plugin {
const dependents = plugin[DependentOnSymbol];
if (dependents) {
const exhaustUnregisteredDependents = () => {
const NotRegistered = dependents.find((d) => !this._checkPluginRegistered(d));
if (NotRegistered) {
this._logService.warn(
'[PluginService]',
`plugin "${plugin.pluginName}" depends on "${NotRegistered.pluginName}" which is not registered. Univer will automatically register it with default configuration.`
);
this._registerPlugin(NotRegistered, undefined);
return true;
}
return false;
};
while (exhaustUnregisteredDependents()) {
continue;
}
}
// eslint-disable-next-line ts/no-explicit-any
const pluginInstance: Plugin = this._injector.createInstance(plugin as unknown as Ctor<any>, options);
this._pluginStore.addPlugin(pluginInstance);
return pluginInstance;
}
protected _pluginsRunLifecycle(plugins: Plugin[]): void {
const run = (lifecycle: LifecycleStages) => {
plugins.forEach((p) => {
switch (lifecycle) {
case LifecycleStages.Starting:
p.onStarting(this._injector);
break;
case LifecycleStages.Ready:
p.onReady();
break;
case LifecycleStages.Rendered:
p.onRendered();
break;
case LifecycleStages.Steady:
p.onSteady();
break;
}
this._lifecycleInitializerService.initModulesOnStage(lifecycle);
});
};
const subscription = this.disposeWithMe(this._lifecycleService.subscribeWithPrevious()
// It has to been async because the finalize may execute synchronously after we
// make the subscription. For example, the lifecycle service is already in stage "steady".
.pipe(finalize(() => { Promise.resolve().then(() => subscription.dispose()); }))
.subscribe((stage) => { run(stage); }));
}
}
+9 -2
View File
@@ -18,7 +18,13 @@ import type { Ctor, Injector } from '@wendellhu/redi';
import { Disposable } from '../../shared';
import { UniverInstanceType } from '../../common/unit';
export type PluginCtor<T extends Plugin> = Ctor<T> & { type: UniverInstanceType; pluginName: string };
export const DependentOnSymbol = Symbol('DependentOn');
export type PluginCtor<T extends Plugin = Plugin> = Ctor<T> & {
type: UniverInstanceType;
pluginName: string;
[DependentOnSymbol]?: PluginCtor[];
};
/**
* Plug-in base class, all plug-ins must inherit from this base class. Provide basic methods.
@@ -30,7 +36,8 @@ export abstract class Plugin extends Disposable {
protected abstract _injector: Injector;
onStarting(_injector: Injector): void {
// eslint-disable-next-line unused-imports/no-unused-vars
onStarting(injector: Injector): void {
// empty
}
+1 -1
View File
@@ -24,7 +24,7 @@ import { AddDataValidationMutation, RemoveDataValidationMutation, UpdateDataVali
import { DataValidationResourceController } from './controllers/dv-resource.controller';
import { DataValidationSheetController } from './controllers/dv-sheet.controller';
const PLUGIN_NAME = 'data-validation';
const PLUGIN_NAME = 'UNIVER_DATA_VALIDATION_PLUGIN';
export class UniverDataValidationPlugin extends Plugin {
static override pluginName = PLUGIN_NAME;
+1 -1
View File
@@ -25,7 +25,7 @@ import { IRenderManagerService, RenderManagerService } from './render-manager/re
*/
export const IRenderingEngine = createIdentifier<Engine>('univer.render-engine');
const PLUGIN_NAME = 'render-engine';
const PLUGIN_NAME = 'RENDER_ENGINE_PLUGIN';
export class UniverRenderEnginePlugin extends Plugin {
static override pluginName = PLUGIN_NAME;
+2 -2
View File
@@ -288,6 +288,8 @@ export class FUniver {
});
}
// #endregion
/**
* Execute command
* @param id Command id
@@ -368,6 +370,4 @@ export class FUniver {
);
}, 10);
}
// @endregion
}
@@ -14,8 +14,11 @@
* limitations under the License.
*/
import { ICommandService, LocaleService, Plugin, Tools, UniverInstanceType } from '@univerjs/core';
import { DependentOn, ICommandService, LocaleService, Plugin, Tools, UniverInstanceType } from '@univerjs/core';
import { type Dependency, Inject, Injector } from '@wendellhu/redi';
import { UniverDataValidationPlugin } from '@univerjs/data-validation';
import { UniverSheetsPlugin } from '@univerjs/sheets';
import { UniverSheetsUIPlugin } from '@univerjs/sheets-ui';
import type { IUniverSheetsDataValidation } from './controllers/dv-render.controller';
import { DataValidationRenderController, DefaultSheetsDataValidation } from './controllers/dv-render.controller';
import { DataValidationController } from './controllers/dv.controller';
@@ -37,6 +40,7 @@ import { DataValidationPanelService } from './services/data-validation-panel.ser
import { DataValidationFormulaController } from './controllers/dv-formula.controller';
import { DataValidationPermissionController } from './controllers/dv-permission.controller';
@DependentOn(UniverDataValidationPlugin, UniverSheetsPlugin, UniverSheetsUIPlugin)
export class UniverSheetsDataValidationPlugin extends Plugin {
static override pluginName = DATA_VALIDATION_PLUGIN_NAME;
static override type = UniverInstanceType.UNIVER_SHEET;
+6 -2
View File
@@ -14,9 +14,12 @@
* limitations under the License.
*/
import { LocaleService, Plugin, Tools, UniverInstanceType } from '@univerjs/core';
import { DependentOn, LocaleService, Plugin, Tools, UniverInstanceType } from '@univerjs/core';
import type { Dependency } from '@wendellhu/redi';
import { Inject, Injector } from '@wendellhu/redi';
import { UniverDrawingUIPlugin } from '@univerjs/drawing-ui';
import { UniverSheetsDrawingPlugin } from '@univerjs/sheets-drawing';
import { UniverDrawingPlugin } from '@univerjs/drawing';
import { DrawingPopupMenuController } from './controllers/drawing-popup-menu.controller';
import { SheetDrawingUpdateController } from './controllers/sheet-drawing-update.controller';
import type { IUniverSheetsDrawingConfig } from './controllers/sheet-drawing.controller';
@@ -24,8 +27,9 @@ import { DefaultSheetsDrawingConfig, SheetDrawingUIController } from './controll
import { SheetDrawingTransformAffectedController } from './controllers/sheet-drawing-transform-affected.controller';
import { SheetCanvasFloatDomManagerService } from './services/canvas-float-dom-manager.service';
const PLUGIN_NAME = 'SHEETS_IMAGE_UI_PLUGIN';
const PLUGIN_NAME = 'SHEET_IMAGE_UI_PLUGIN';
@DependentOn(UniverDrawingPlugin, UniverDrawingUIPlugin, UniverSheetsDrawingPlugin)
export class UniverSheetsDrawingUIPlugin extends Plugin {
static override type = UniverInstanceType.UNIVER_SHEET;
static override pluginName = PLUGIN_NAME;
+1
View File
@@ -25,6 +25,7 @@ export class UniverSheetsDrawingPlugin extends Plugin {
static override type = UniverInstanceType.UNIVER_SHEET;
constructor(
private readonly _config: unknown,
@Inject(Injector) override readonly _injector: Injector
) {
super();
+3 -1
View File
@@ -14,9 +14,10 @@
* limitations under the License.
*/
import { LocaleService, Plugin, Tools, UniverInstanceType } from '@univerjs/core';
import { DependentOn, LocaleService, Plugin, Tools, UniverInstanceType } from '@univerjs/core';
import type { Dependency } from '@wendellhu/redi';
import { Inject, Injector } from '@wendellhu/redi';
import { UniverSheetsFilterPlugin } from '@univerjs/sheets-filter';
import type { IUniverSheetsFilterUIConfig } from './controllers/sheets-filter-ui.controller';
import { DefaultSheetFilterUiConfig, SheetsFilterUIController } from './controllers/sheets-filter-ui.controller';
@@ -25,6 +26,7 @@ import { SheetsFilterPermissionController } from './controllers/sheets-filter-pe
const NAME = 'SHEET_FILTER_UI_PLUGIN';
@DependentOn(UniverSheetsFilterPlugin)
export class UniverSheetsFilterUIPlugin extends Plugin {
static override type = UniverInstanceType.UNIVER_SHEET;
static override pluginName = NAME;
+4 -5
View File
@@ -14,26 +14,25 @@
* limitations under the License.
*/
import { Plugin, PluginService, UniverInstanceType } from '@univerjs/core';
import { DependentOn, Plugin, UniverInstanceType } from '@univerjs/core';
import type { Dependency } from '@wendellhu/redi';
import { Inject, Injector } from '@wendellhu/redi';
import { UniverFindReplacePlugin } from '@univerjs/find-replace';
import { UniverSheetsPlugin } from '@univerjs/sheets';
import { SheetsFindReplaceController } from './controllers/sheet-find-replace.controller';
const NAME = 'SHEET_FIND_REPLACE_PLUGIN';
@DependentOn(UniverSheetsPlugin, UniverSheetsPlugin, UniverFindReplacePlugin)
export class UniverSheetsFindReplacePlugin extends Plugin {
static override pluginName = NAME;
static override type = UniverInstanceType.UNIVER_SHEET;
constructor(
_config: unknown,
@Inject(Injector) protected readonly _injector: Injector,
@Inject(PluginService) private readonly _pluginService: PluginService
@Inject(Injector) protected readonly _injector: Injector
) {
super();
this._pluginService.registerPlugin(UniverFindReplacePlugin);
}
override onStarting(injector: Injector): void {
@@ -14,10 +14,11 @@
* limitations under the License.
*/
import { LocaleService, Plugin, Tools, UniverInstanceType } from '@univerjs/core';
import { DependentOn, LocaleService, Plugin, Tools, UniverInstanceType } from '@univerjs/core';
import type { Dependency } from '@wendellhu/redi';
import { Inject, Injector } from '@wendellhu/redi';
import { UniverFormulaEnginePlugin } from '@univerjs/engine-formula';
import { FORMULA_UI_PLUGIN_NAME } from './common/plugin-name';
import { ActiveDirtyController } from './controllers/active-dirty.controller';
import { ArrayFormulaDisplayController } from './controllers/array-formula-display.controller';
@@ -46,6 +47,7 @@ import { FormulaRenderController } from './controllers/formula-render.controller
/**
* The configuration of the formula UI plugin.
*/
@DependentOn(UniverFormulaEnginePlugin)
export class UniverSheetsFormulaPlugin extends Plugin {
static override pluginName = FORMULA_UI_PLUGIN_NAME;
static override type = UniverInstanceType.UNIVER_SHEET;
@@ -20,7 +20,7 @@ import { AddHyperLinkMutation, HyperLinkModel, RemoveHyperLinkMutation } from '@
import type { IAutoFillLocation, ISheetAutoFillHook } from '@univerjs/sheets-ui';
import { APPLY_TYPE, getAutoFillRepeatRange, IAutoFillService, virtualizeDiscreteRanges } from '@univerjs/sheets-ui';
import { Inject } from '@wendellhu/redi';
import { SHEETS_HYPER_LINK_UI_PLUGIN } from '../types/const';
import { SHEET_HYPER_LINK_UI_PLUGIN } from '../types/const';
@OnLifecycle(LifecycleStages.Ready, SheetsHyperLinkAutoFillController)
export class SheetsHyperLinkAutoFillController extends Disposable {
@@ -145,7 +145,7 @@ export class SheetsHyperLinkAutoFillController extends Disposable {
};
};
const hook: ISheetAutoFillHook = {
id: SHEETS_HYPER_LINK_UI_PLUGIN,
id: SHEET_HYPER_LINK_UI_PLUGIN,
onFillData: (location, direction, applyType) => {
if (
applyType === APPLY_TYPE.COPY ||
@@ -21,7 +21,7 @@ import type { IDiscreteRange, ISheetDiscreteRangeLocation } from '@univerjs/shee
import { COPY_TYPE, getRepeatRange, ISheetClipboardService, PREDEFINED_HOOK_NAME, rangeToDiscreteRange, virtualizeDiscreteRanges } from '@univerjs/sheets-ui';
import { Inject, Injector } from '@wendellhu/redi';
import { SPECIAL_PASTE_FORMULA } from '@univerjs/sheets-formula';
import { SHEETS_HYPER_LINK_UI_PLUGIN } from '../types/const';
import { SHEET_HYPER_LINK_UI_PLUGIN } from '../types/const';
import { isLegalLink, serializeUrl } from '../common/util';
import { SheetsHyperLinkResolverService } from '../services/resolver.service';
@@ -46,7 +46,7 @@ export class SheetsHyperLinkCopyPasteController extends Disposable {
// eslint-disable-next-line max-lines-per-function
private _initCopyPaste() {
this._sheetClipboardService.addClipboardHook({
id: SHEETS_HYPER_LINK_UI_PLUGIN,
id: SHEET_HYPER_LINK_UI_PLUGIN,
onBeforeCopy: (unitId, subUnitId, range) => this._collect(unitId, subUnitId, range),
onPasteCells: (pasteFrom, pasteTo, data, payload) => {
const { copyType = COPY_TYPE.COPY, pasteType } = payload;
+6 -6
View File
@@ -16,7 +16,7 @@
import type { Dependency } from '@wendellhu/redi';
import { Inject, Injector } from '@wendellhu/redi';
import { UniverInstanceType } from '@univerjs/core';
import { DependentOn, Plugin, UniverInstanceType } from '@univerjs/core';
import { UniverSheetsHyperLinkPlugin } from '@univerjs/sheets-hyper-link';
import { SheetsHyperLinkRemoveSheetController } from './controllers/remove-sheet.controller';
import { SheetsHyperLinkRefRangeController } from './controllers/ref-range.controller';
@@ -27,25 +27,25 @@ import { SheetHyperLinkSetRangeController } from './controllers/set-range.contro
import { SheetsHyperLinkPopupController } from './controllers/popup.controller';
import type { IUniverSheetsHyperLinkUIConfig } from './controllers/ui.controller';
import { SheetsHyperLinkUIController } from './controllers/ui.controller';
import { SHEETS_HYPER_LINK_UI_PLUGIN } from './types/const';
import { SHEET_HYPER_LINK_UI_PLUGIN } from './types/const';
import { SheetsHyperLinkAutoFillController } from './controllers/auto-fill.controller';
import { SheetsHyperLinkCopyPasteController } from './controllers/copy-paste.controller';
import { SheetHyperLinkUrlController } from './controllers/url.controller';
import { SheetsHyperLinkPermissionController } from './controllers/hyper-link-permission.controller';
export class UniverSheetsHyperLinkUIPlugin extends UniverSheetsHyperLinkPlugin {
static override pluginName: string = SHEETS_HYPER_LINK_UI_PLUGIN;
@DependentOn(UniverSheetsHyperLinkPlugin)
export class UniverSheetsHyperLinkUIPlugin extends Plugin {
static override pluginName: string = SHEET_HYPER_LINK_UI_PLUGIN;
static override type = UniverInstanceType.UNIVER_SHEET;
constructor(
private _config: IUniverSheetsHyperLinkUIConfig,
@Inject(Injector) protected override _injector: Injector
) {
super(_config, _injector);
super();
}
override onStarting(injector: Injector): void {
super.onStarting(injector);
const dependencies: Dependency[] = [
[SheetsHyperLinkResolverService],
[SheetsHyperLinkPopupService],
@@ -14,6 +14,6 @@
* limitations under the License.
*/
export const SHEETS_HYPER_LINK_UI_PLUGIN = 'SHEETS_HYPER_LINK_UI_PLUGIN';
export const SHEET_HYPER_LINK_UI_PLUGIN = 'SHEET_HYPER_LINK_UI_PLUGIN';
export const ERROR_RANGE = 'err';
+4 -1
View File
@@ -14,9 +14,11 @@
* limitations under the License.
*/
import { Plugin, Tools, UniverInstanceType } from '@univerjs/core';
import { DependentOn, Plugin, Tools, UniverInstanceType } from '@univerjs/core';
import { Inject, Injector } from '@wendellhu/redi';
import { UniverSheetsPlugin } from '@univerjs/sheets';
import { UniverSheetsUIPlugin } from '@univerjs/sheets-ui';
import { SHEET_NUMFMT_PLUGIN } from './base/const/PLUGIN_NAME';
import { NumfmtCellContent } from './controllers/numfmt.cell-content.controller';
import { NumfmtController } from './controllers/numfmt.controller';
@@ -27,6 +29,7 @@ import { DefaultSheetNumfmtConfig, NumfmtMenuController } from './controllers/nu
import { INumfmtController } from './controllers/type';
import { UserHabitController } from './controllers/user-habit.controller';
@DependentOn(UniverSheetsPlugin, UniverSheetsUIPlugin)
export class UniverSheetsNumfmtPlugin extends Plugin {
static override pluginName = SHEET_NUMFMT_PLUGIN;
static override type = UniverInstanceType.UNIVER_SHEET;
+6 -6
View File
@@ -16,7 +16,7 @@
import type { Dependency } from '@wendellhu/redi';
import { Inject, Injector } from '@wendellhu/redi';
import { ICommandService, Tools, UniverInstanceType } from '@univerjs/core';
import { DependentOn, ICommandService, Plugin, Tools, UniverInstanceType } from '@univerjs/core';
import { UniverThreadCommentUIPlugin } from '@univerjs/thread-comment-ui';
import type { IUniverSheetsThreadCommentConfig } from './controllers/sheets-thread-comment.controller';
import { DefaultSheetsThreadCommentConfig, SheetsThreadCommentController } from './controllers/sheets-thread-comment.controller';
@@ -30,7 +30,8 @@ import { SheetsThreadCommentCopyPasteController } from './controllers/sheets-thr
import { SheetsThreadCommentHoverController } from './controllers/sheets-thread-comment-hover.controller';
import { ThreadCommentRemoveSheetsController } from './controllers/sheets-thread-comment-remove.controller';
export class UniverSheetsThreadCommentPlugin extends UniverThreadCommentUIPlugin {
@DependentOn(UniverThreadCommentUIPlugin)
export class UniverSheetsThreadCommentPlugin extends Plugin {
static override pluginName = SHEETS_THREAD_COMMENT;
static override type = UniverInstanceType.UNIVER_SHEET;
@@ -39,15 +40,14 @@ export class UniverSheetsThreadCommentPlugin extends UniverThreadCommentUIPlugin
constructor(
config: Partial<IUniverSheetsThreadCommentConfig> = {},
@Inject(Injector) protected override _injector: Injector,
@Inject(ICommandService) protected override _commandService: ICommandService
@Inject(ICommandService) protected _commandService: ICommandService
) {
super(config, _injector, _commandService);
super();
this._pluginConfig = Tools.deepMerge({}, DefaultSheetsThreadCommentConfig, config);
}
override onStarting(injector: Injector): void {
super.onStarting(injector);
([
[SheetsThreadCommentModel],
[
@@ -63,7 +63,7 @@ export class UniverSheetsThreadCommentPlugin extends UniverThreadCommentUIPlugin
[ThreadCommentRemoveSheetsController],
[SheetsThreadCommentPopupService],
] as Dependency[]).forEach((dep) => {
this._injector.add(dep);
injector.add(dep);
});
[ShowAddSheetCommentModalOperation].forEach((command) => {
+4 -2
View File
@@ -15,13 +15,14 @@
*/
import type { Workbook } from '@univerjs/core';
import { IUniverInstanceService, LocaleService, Plugin, Tools, UniverInstanceType } from '@univerjs/core';
import { DependentOn, IUniverInstanceService, LocaleService, Plugin, Tools, UniverInstanceType } from '@univerjs/core';
import type { Dependency } from '@wendellhu/redi';
import { Inject, Injector } from '@wendellhu/redi';
import { filter } from 'rxjs/operators';
import { IRenderManagerService } from '@univerjs/engine-render';
import { WorksheetProtectionRenderService } from '@univerjs/sheets';
import { UniverSheetsPlugin, WorksheetProtectionRenderService } from '@univerjs/sheets';
import { UniverUIPlugin } from '@univerjs/ui';
import { ActiveWorksheetController } from './controllers/active-worksheet/active-worksheet.controller';
import { AutoHeightController } from './controllers/auto-height.controller';
import { SheetClipboardController } from './controllers/clipboard/clipboard.controller';
@@ -84,6 +85,7 @@ import { SheetPermissionPanelModel } from './services/permission/sheet-permissio
import { SheetPermissionUserManagerService } from './services/permission/sheet-permission-user-list.service';
import { PermissionRenderService } from './services/permission/permission-render.service';
@DependentOn(UniverSheetsPlugin, UniverUIPlugin)
export class UniverSheetsUIPlugin extends Plugin {
static override pluginName = 'SHEET_UI_PLUGIN';
static override type = UniverInstanceType.UNIVER_SHEET;
+3 -1
View File
@@ -15,10 +15,11 @@
*/
import type { DependencyOverride } from '@univerjs/core';
import { ICommandService, IConfigService, LocaleService, mergeOverrideWithDependencies, Plugin, UniverInstanceType } from '@univerjs/core';
import { DependentOn, ICommandService, IConfigService, LocaleService, mergeOverrideWithDependencies, Plugin, UniverInstanceType } from '@univerjs/core';
import type { Dependency } from '@wendellhu/redi';
import { Inject, Injector } from '@wendellhu/redi';
import { UniverFormulaEnginePlugin } from '@univerjs/engine-formula';
import { BasicWorksheetController } from './controllers/basic-worksheet.controller';
import { CalculateResultApplyController } from './controllers/calculate-result-apply.controller';
import { FeatureCalculationController } from './controllers/feature-calculation.controller';
@@ -56,6 +57,7 @@ export interface IUniverSheetsConfig {
/**
* The main sheet base, construct the sheet container and layout, mount the rendering engine
*/
@DependentOn(UniverFormulaEnginePlugin)
export class UniverSheetsPlugin extends Plugin {
static override pluginName = PLUGIN_NAME;
static override type = UniverInstanceType.UNIVER_SHEET;
+7 -13
View File
@@ -16,7 +16,7 @@
import { UniverThreadCommentPlugin } from '@univerjs/thread-comment';
import type { DependencyOverride } from '@univerjs/core';
import { ICommandService, mergeOverrideWithDependencies, UniverInstanceType } from '@univerjs/core';
import { DependentOn, ICommandService, mergeOverrideWithDependencies, Plugin, UniverInstanceType } from '@univerjs/core';
import type { Dependency } from '@wendellhu/redi';
import { Inject, Injector } from '@wendellhu/redi';
import { PLUGIN_NAME } from './types/const';
@@ -29,31 +29,25 @@ export interface IUniverThreadCommentUIConfig {
overrides?: DependencyOverride;
}
export class UniverThreadCommentUIPlugin extends UniverThreadCommentPlugin {
@DependentOn(UniverThreadCommentPlugin)
export class UniverThreadCommentUIPlugin extends Plugin {
static override pluginName = PLUGIN_NAME;
static override type = UniverInstanceType.UNIVER_UNKNOWN;
private _config1: IUniverThreadCommentUIConfig;
constructor(
config: IUniverThreadCommentUIConfig,
private readonly _config: IUniverThreadCommentUIConfig | undefined,
@Inject(Injector) protected override _injector: Injector,
@ICommandService protected override _commandService: ICommandService
@ICommandService protected _commandService: ICommandService
) {
super(
config,
_injector,
_commandService
);
this._config1 = config;
super();
}
override onStarting(injector: Injector): void {
super.onStarting(injector);
(mergeOverrideWithDependencies([
[ThreadCommentUIController],
[ThreadCommentPanelService],
[IThreadCommentMentionDataService, { useClass: ThreadCommentMentionDataService }],
], this._config1.overrides) as Dependency[]).forEach((dep) => {
], this._config?.overrides) as Dependency[]).forEach((dep) => {
injector.add(dep);
});
@@ -18,4 +18,4 @@ export const THREAD_COMMENT_POPUP = 'thread-comment-popup';
export const THREAD_COMMENT_PANEL = 'thread-comment-panel';
export const PLUGIN_NAME = 'thread-comment-ui-plugin';
export const PLUGIN_NAME = 'THREAD_COMMENT_UI_PLUGIN';
+3 -1
View File
@@ -14,9 +14,10 @@
* limitations under the License.
*/
import { IContextService, ILocalStorageService, LocaleService, mergeOverrideWithDependencies, Plugin, Tools } from '@univerjs/core';
import { DependentOn, IContextService, ILocalStorageService, LocaleService, mergeOverrideWithDependencies, Plugin, Tools } from '@univerjs/core';
import type { Dependency } from '@wendellhu/redi';
import { Inject, Injector } from '@wendellhu/redi';
import { UniverRenderEnginePlugin } from '@univerjs/engine-render';
import { CanvasPopupService, ICanvasPopupService } from './services/popup/canvas-popup.service';
import { DesktopGlobalZoneService } from './services/global-zone/desktop-global-zone.service';
@@ -65,6 +66,7 @@ export const DISABLE_AUTO_FOCUS_KEY = 'DISABLE_AUTO_FOCUS';
/**
* UI plugin provides basic interaction with users. Including workbench (menus, UI parts, notifications etc.), copy paste, shortcut.
*/
@DependentOn(UniverRenderEnginePlugin)
export class UniverUIPlugin extends Plugin {
static override pluginName = PLUGIN_NAME;