From 1f8ff0687db8fee05d80288dcd96e9474a06dd3c Mon Sep 17 00:00:00 2001 From: Artur Arseniev Date: Wed, 20 May 2026 15:41:29 +0400 Subject: [PATCH] Refactor Preview --- packages/core/src/commands/registry.ts | 5 +- packages/core/src/commands/view/Preview.ts | 47 ++++++++++------ .../core/test/specs/commands/view/Preview.ts | 53 ++++++++++++------- 3 files changed, 69 insertions(+), 36 deletions(-) diff --git a/packages/core/src/commands/registry.ts b/packages/core/src/commands/registry.ts index be010e244..4ba27e096 100644 --- a/packages/core/src/commands/registry.ts +++ b/packages/core/src/commands/registry.ts @@ -7,6 +7,7 @@ import type { CommandObject, } from './view/CommandAbstract'; import type { FullscreenCommandRegistryRun, FullscreenCommandRegistryStop } from './view/Fullscreen'; +import type { PreviewCommandRegistryRun, PreviewCommandRegistryStop } from './view/Preview'; type CommandRegistryHandler = (...args: any[]) => any; type CommandRegistryEntry = TId extends keyof TRegistry @@ -15,9 +16,9 @@ type CommandRegistryEntry = TId extends keyof TRe : CommandRegistryHandler : CommandRegistryHandler; -export interface CommandRegistryRun extends FullscreenCommandRegistryRun {} +export interface CommandRegistryRun extends FullscreenCommandRegistryRun, PreviewCommandRegistryRun {} -export interface CommandRegistryStop extends FullscreenCommandRegistryStop {} +export interface CommandRegistryStop extends FullscreenCommandRegistryStop, PreviewCommandRegistryStop {} export type CommandRunKnownId = Extract; export type CommandStopKnownId = Extract; diff --git a/packages/core/src/commands/view/Preview.ts b/packages/core/src/commands/view/Preview.ts index a6bf915ac..877753925 100644 --- a/packages/core/src/commands/view/Preview.ts +++ b/packages/core/src/commands/view/Preview.ts @@ -1,23 +1,40 @@ import { each } from 'underscore'; import Editor from '../../editor'; -import { CommandObject } from './CommandAbstract'; +import type { CommandPublicFnFromHandler } from '../registryHelpers'; +import CommandAbstract from './CommandAbstract'; const cmdOutline = 'core:component-outline'; -export default { +export interface PreviewCommandRegistryRun { + 'core:preview': CommandPublicFnFromHandler; + preview: CommandPublicFnFromHandler; +} + +export interface PreviewCommandRegistryStop { + 'core:preview': CommandPublicFnFromHandler; + preview: CommandPublicFnFromHandler; +} + +export default class CommandPreview extends CommandAbstract { + helper?: HTMLSpanElement; + panels?: ReturnType; + selected?: ReturnType; + sender?: any; + shouldRunSwVisibility?: boolean; + getPanels(editor: Editor) { if (!this.panels) { this.panels = editor.Panels.getPanels(); } - return this.panels; - }, + return this.panels!; + } preventDrag(opts: any) { opts.abort = 1; - }, + } - tglEffects(on: boolean) { + tglEffects(on = false) { const { em } = this; const mthEv = on ? 'on' : 'off'; if (em) { @@ -29,9 +46,9 @@ export default { each(elP, (item) => ((item as HTMLElement).style.pointerEvents = on ? 'all' : '')); em[mthEv]('run:tlb-move:before', this.preventDrag); } - }, + } - run(editor, sender) { + run(editor: Editor, sender: any) { this.sender = sender; this.selected = [...editor.getSelectedAll()]; editor.select(); @@ -58,7 +75,7 @@ export default { this.helper.style.display = 'inline-block'; - panels.forEach((panel: any) => panel.set('visible', false)); + panels.forEach((panel) => panel.set('visible', false)); const canvasS = canvas.style; canvasS.width = '100%'; @@ -68,10 +85,10 @@ export default { canvasS.padding = '0'; canvasS.margin = '0'; editor.refresh(); - this.tglEffects(1); - }, + this.tglEffects(true); + } - stop(editor) { + stop(editor: Editor) { const { sender = {}, selected } = this; sender.set && sender.set('active', 0); const panels = this.getPanels(editor); @@ -82,7 +99,7 @@ export default { } editor.getModel().runDefault(); - panels.forEach((panel: any) => panel.set('visible', true)); + panels.forEach((panel) => panel.set('visible', true)); const canvas = editor.Canvas.getElement(); canvas.setAttribute('style', ''); @@ -95,5 +112,5 @@ export default { editor.refresh(); this.tglEffects(); - }, -} as CommandObject<{}, { [k: string]: any }>; + } +} diff --git a/packages/core/test/specs/commands/view/Preview.ts b/packages/core/test/specs/commands/view/Preview.ts index fbcccbd15..2af00e34b 100644 --- a/packages/core/test/specs/commands/view/Preview.ts +++ b/packages/core/test/specs/commands/view/Preview.ts @@ -2,12 +2,27 @@ import Panel from '../../../../src/panels/model/Panel'; import Preview from '../../../../src/commands/view/Preview'; describe('Preview command', () => { + let command: Preview; let fakePanels: Panel[]; let fakeEditor: any; let fakeIsActive: any; const obj: any = {}; beforeEach(() => { + command = new Preview({}); + command.ppfx = ''; + command.em = { + Canvas: { + getBody: jest.fn(() => ({ + querySelectorAll: jest.fn(() => []), + })), + getToolbarEl: jest.fn(() => ({ + style: {}, + })), + }, + on: jest.fn(), + off: jest.fn(), + } as any; fakePanels = [new Panel(obj, obj), new Panel(obj, obj), new Panel(obj, obj)]; fakeIsActive = false; @@ -44,63 +59,63 @@ describe('Preview command', () => { }, }; - Preview.panels = undefined; - Preview.shouldRunSwVisibility = undefined; + command.panels = undefined; + command.shouldRunSwVisibility = undefined; }); describe('.getPanels', () => { test('it should return panels set with the editor panels if not already set', () => { - Preview.getPanels(fakeEditor); - expect(Preview.panels).toBe(fakePanels); - Preview.getPanels(fakeEditor); + command.getPanels(fakeEditor); + expect(command.panels).toBe(fakePanels); + command.getPanels(fakeEditor); expect(fakeEditor.Panels.getPanels).toHaveBeenCalledTimes(1); }); }); describe('.run', () => { beforeEach(() => { - Preview.helper = { style: {} }; + command.helper = { style: {} } as any; }); it('should hide all panels', () => { fakePanels.forEach((panel) => expect(panel.get('visible')).toEqual(true)); - Preview.run!(fakeEditor, obj, obj); + command.run(fakeEditor, obj); fakePanels.forEach((panel) => expect(panel.get('visible')).toEqual(false)); }); it("should stop the 'core:component-outline' command if active", () => { - Preview.run!(fakeEditor, obj, obj); + command.run(fakeEditor, obj); expect(fakeEditor.stopCommand).not.toHaveBeenCalled(); fakeIsActive = true; - Preview.run!(fakeEditor, obj, obj); + command.run(fakeEditor, obj); expect(fakeEditor.stopCommand).toHaveBeenCalledWith('core:component-outline'); }); it('should not reset the `shouldRunSwVisibility` state once active if run multiple times', () => { - expect(Preview.shouldRunSwVisibility).toBeUndefined(); + expect(command.shouldRunSwVisibility).toBeUndefined(); fakeIsActive = true; - Preview.run!(fakeEditor, obj, obj); - expect(Preview.shouldRunSwVisibility).toEqual(true); + command.run(fakeEditor, obj); + expect(command.shouldRunSwVisibility).toEqual(true); fakeIsActive = false; - Preview.run!(fakeEditor, obj, obj); - expect(Preview.shouldRunSwVisibility).toEqual(true); + command.run(fakeEditor, obj); + expect(command.shouldRunSwVisibility).toEqual(true); }); }); describe('.stop', () => { it('should show all panels', () => { fakePanels.forEach((panel) => panel.set('visible', false)); - Preview.stop!(fakeEditor, obj, obj); + command.stop(fakeEditor); fakePanels.forEach((panel) => expect(panel.get('visible')).toEqual(true)); }); it("should run the 'core:component-outline' command if it was active before run", () => { - Preview.stop!(fakeEditor, obj, obj); + command.stop(fakeEditor); expect(fakeEditor.runCommand).not.toHaveBeenCalled(); - Preview.shouldRunSwVisibility = true; - Preview.stop!(fakeEditor, obj, obj); + command.shouldRunSwVisibility = true; + command.stop(fakeEditor); expect(fakeEditor.runCommand).toHaveBeenCalledWith('core:component-outline'); - expect(Preview.shouldRunSwVisibility).toEqual(false); + expect(command.shouldRunSwVisibility).toEqual(false); }); }); });