Browse Source

Refactor PasteComponent

typed-command-runs
Artur Arseniev 5 months ago
parent
commit
19652cee26
  1. 12
      packages/core/src/commands/index.ts
  2. 4
      packages/core/src/commands/registry.ts
  3. 1
      packages/core/src/commands/view/CopyComponent.ts
  4. 23
      packages/core/src/commands/view/PasteComponent.ts
  5. 53
      packages/core/test/specs/commands/view/PasteComponent.ts

12
packages/core/src/commands/index.ts

@ -36,12 +36,7 @@
*/
import { isFunction, includes } from 'underscore';
import CommandAbstract, {
Command,
CommandConstructor,
CommandOptions,
CommandStored,
} from './view/CommandAbstract';
import CommandAbstract, { Command, CommandConstructor, CommandOptions, CommandStored } from './view/CommandAbstract';
import CanvasClear from './view/CanvasClear';
import CanvasMove from './view/CanvasMove';
import ComponentDelete from './view/ComponentDelete';
@ -336,7 +331,10 @@ export default class CommandsModule extends Module<CommandsConfig & { pStylePref
* }
* });
* */
extend<const TId extends string>(id: TId, cmd: CommandObjectById<TId, ObjectAny> = {} as CommandObjectById<TId, ObjectAny>) {
extend<const TId extends string>(
id: TId,
cmd: CommandObjectById<TId, ObjectAny> = {} as CommandObjectById<TId, ObjectAny>,
) {
const command = this.get(id);
if (command) {

4
packages/core/src/commands/registry.ts

@ -10,6 +10,7 @@ import type { FullscreenCommandRegistryRun, FullscreenCommandRegistryStop } from
import type { PreviewCommandRegistryRun, PreviewCommandRegistryStop } from './view/Preview';
import type { ResizeCommandRegistryRun, ResizeCommandRegistryStop } from './view/Resize';
import type { CopyComponentCommandRegistryRun } from './view/CopyComponent';
import type { PasteComponentCommandRegistryRun } from './view/PasteComponent';
type CommandRegistryHandler = (...args: any[]) => any;
type CommandRegistryEntry<TRegistry, TId extends string> = TId extends keyof TRegistry
@ -22,7 +23,8 @@ export interface CommandRegistryRun
extends FullscreenCommandRegistryRun,
PreviewCommandRegistryRun,
ResizeCommandRegistryRun,
CopyComponentCommandRegistryRun {}
CopyComponentCommandRegistryRun,
PasteComponentCommandRegistryRun {}
export interface CommandRegistryStop
extends FullscreenCommandRegistryStop,

1
packages/core/src/commands/view/CopyComponent.ts

@ -4,7 +4,6 @@ import CommandAbstract from './CommandAbstract';
export interface CopyComponentCommandRegistryRun {
'core:copy': CommandPublicFnFromHandler<CommandCopyComponent['run']>;
copy: CommandPublicFnFromHandler<CommandCopyComponent['run']>;
}
export default class CommandCopyComponent extends CommandAbstract {

23
packages/core/src/commands/view/PasteComponent.ts

@ -1,11 +1,20 @@
import { isArray, contains } from 'underscore';
import { contains, isArray } from 'underscore';
import Component from '../../dom_components/model/Component';
import { ComponentsEvents } from '../../dom_components/types';
import { CommandObject } from './CommandAbstract';
import Editor from '../../editor';
import type { CommandPublicFnFromHandler } from '../registryHelpers';
import CommandAbstract from './CommandAbstract';
export default {
run(ed, s, opts = {}) {
export interface PasteComponentOptions {
action?: string;
}
export interface PasteComponentCommandRegistryRun {
'core:paste': CommandPublicFnFromHandler<CommandPasteComponent['run']>;
}
export default class CommandPasteComponent extends CommandAbstract<PasteComponentOptions> {
run(ed: Editor, _sender: any, opts: PasteComponentOptions = {}) {
const em = ed.getModel();
const clp: Component[] | null = em.get('clipboard');
const lastSelected = ed.getSelected();
@ -25,8 +34,6 @@ export default {
added = doAdd(ed, clp, selected.parent()!, addOpts);
}
} else {
// Page body is selected
// Paste at the end of the body
const pageBody = em.Pages.getSelected()?.getMainComponent();
const addOpts = { at: pageBody?.components().length || 0, action: opts.action || 'paste-component' };
@ -39,8 +46,8 @@ export default {
lastSelected.emitUpdate();
}
},
} as CommandObject;
}
}
function doAdd(ed: Editor, clp: Component[], parent: Component, addOpts: any): Component[] | Component {
const copyable = clp.filter((cop) => cop.get('copyable'));

53
packages/core/test/specs/commands/view/PasteComponent.ts

@ -0,0 +1,53 @@
import { ComponentsEvents } from '../../../../src/dom_components/types';
import PasteComponent from '../../../../src/commands/view/PasteComponent';
describe('PasteComponent command', () => {
test('should paste a clone into the selected collection and emit paste event', () => {
const command = new PasteComponent({});
const added = { id: 'added' };
const collection = {
add: jest.fn(() => added),
};
const selected = {
collection,
index: jest.fn(() => 2),
get: jest.fn((key: string) => (key === 'copyable' ? true : undefined)),
clone: jest.fn(() => ({ id: 'clone' })),
parent: jest.fn(),
};
const clipboard = [selected];
const emitUpdate = jest.fn();
const trigger = jest.fn();
const editor = {
getModel: jest.fn(() => ({
get: jest.fn((key: string) => (key === 'clipboard' ? clipboard : undefined)),
})),
getSelected: jest.fn(() => ({ emitUpdate })),
getSelectedAll: jest.fn(() => [selected]),
trigger,
} as any;
command.run(editor, null, { action: 'clone-component' });
expect(collection.add).toHaveBeenCalled();
expect(trigger).toHaveBeenCalledWith(ComponentsEvents.paste, added);
expect(emitUpdate).toHaveBeenCalledTimes(1);
});
test('should do nothing without clipboard content or selection', () => {
const command = new PasteComponent({});
const trigger = jest.fn();
const editor = {
getModel: jest.fn(() => ({
get: jest.fn(() => null),
})),
getSelected: jest.fn(() => null),
getSelectedAll: jest.fn(() => []),
trigger,
} as any;
command.run(editor, null);
expect(trigger).not.toHaveBeenCalled();
});
});
Loading…
Cancel
Save