Browse Source

Refactor MoveComponent

typed-command-runs
Artur Arseniev 5 months ago
parent
commit
270c6534ef
  1. 3
      packages/core/src/commands/registry.ts
  2. 106
      packages/core/src/commands/view/MoveComponent.ts
  3. 42
      packages/core/test/specs/commands/view/MoveComponent.ts

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

@ -17,6 +17,7 @@ import type { ExportTemplateCommandRegistryRun, ExportTemplateCommandRegistrySto
import type { OpenAssetsCommandRegistryRun, OpenAssetsCommandRegistryStop } from './view/OpenAssets'; import type { OpenAssetsCommandRegistryRun, OpenAssetsCommandRegistryStop } from './view/OpenAssets';
import type { OpenLayersCommandRegistryRun, OpenLayersCommandRegistryStop } from './view/OpenLayers'; import type { OpenLayersCommandRegistryRun, OpenLayersCommandRegistryStop } from './view/OpenLayers';
import type { OpenBlocksCommandRegistryRun, OpenBlocksCommandRegistryStop } from './view/OpenBlocks'; import type { OpenBlocksCommandRegistryRun, OpenBlocksCommandRegistryStop } from './view/OpenBlocks';
import type { MoveComponentCommandRegistryRun, MoveComponentCommandRegistryStop } from './view/MoveComponent';
import type { ShowOffsetCommandRegistryRun, ShowOffsetCommandRegistryStop } from './view/ShowOffset'; import type { ShowOffsetCommandRegistryRun, ShowOffsetCommandRegistryStop } from './view/ShowOffset';
import type { SwitchVisibilityCommandRegistryRun, SwitchVisibilityCommandRegistryStop } from './view/SwitchVisibility'; import type { SwitchVisibilityCommandRegistryRun, SwitchVisibilityCommandRegistryStop } from './view/SwitchVisibility';
import type { import type {
@ -44,6 +45,7 @@ export interface CommandRegistryRun
CanvasMoveCommandRegistryRun, CanvasMoveCommandRegistryRun,
CanvasClearCommandRegistryRun, CanvasClearCommandRegistryRun,
ExportTemplateCommandRegistryRun, ExportTemplateCommandRegistryRun,
MoveComponentCommandRegistryRun,
OpenAssetsCommandRegistryRun, OpenAssetsCommandRegistryRun,
OpenBlocksCommandRegistryRun, OpenBlocksCommandRegistryRun,
OpenLayersCommandRegistryRun, OpenLayersCommandRegistryRun,
@ -58,6 +60,7 @@ export interface CommandRegistryStop
ResizeCommandRegistryStop, ResizeCommandRegistryStop,
CanvasMoveCommandRegistryStop, CanvasMoveCommandRegistryStop,
ExportTemplateCommandRegistryStop, ExportTemplateCommandRegistryStop,
MoveComponentCommandRegistryStop,
OpenAssetsCommandRegistryStop, OpenAssetsCommandRegistryStop,
OpenBlocksCommandRegistryStop, OpenBlocksCommandRegistryStop,
OpenLayersCommandRegistryStop, OpenLayersCommandRegistryStop,

106
packages/core/src/commands/view/MoveComponent.ts

@ -1,38 +1,55 @@
import { bindAll, extend } from 'underscore'; import { bindAll } from 'underscore';
import { $ } from '../../common'; import { $ } from '../../common';
import Component from '../../dom_components/model/Component'; import type Component from '../../dom_components/model/Component';
import { off, on } from '../../utils/dom'; import { off, on } from '../../utils/dom';
import { CommandObject } from './CommandAbstract'; import type { CommandPublicFnFromHandler } from '../registryHelpers';
import CommandAbstract from './CommandAbstract';
import SelectComponent from './SelectComponent'; import SelectComponent from './SelectComponent';
import SelectPosition from './SelectPosition'; import SelectPosition from './SelectPosition';
export default extend({}, SelectPosition, SelectComponent, { export interface MoveComponentCommandRegistryRun {
'core:component-move': CommandPublicFnFromHandler<CommandMoveComponent['run']>;
'move-comp': CommandPublicFnFromHandler<CommandMoveComponent['run']>;
}
export interface MoveComponentCommandRegistryStop {
'core:component-move': CommandPublicFnFromHandler<CommandMoveComponent['stop']>;
'move-comp': CommandPublicFnFromHandler<CommandMoveComponent['stop']>;
}
export default class CommandMoveComponent extends CommandAbstract {
[key: string]: any;
init(o: any) { init(o: any) {
SelectComponent.init.apply(this, arguments); (SelectComponent.init as any).apply(this, arguments as any);
bindAll(this, 'initSorter', 'rollback', 'onEndMove'); bindAll(this, 'initSorter', 'rollback', 'onEndMove');
this.opt = o; this.opt = o;
this.hoverClass = this.ppfx + 'highlighter-warning'; this.hoverClass = `${this.ppfx}highlighter-warning`;
this.badgeClass = this.ppfx + 'badge-warning'; this.badgeClass = `${this.ppfx}badge-warning`;
this.noSelClass = this.ppfx + 'no-select'; this.noSelClass = `${this.ppfx}no-select`;
}, }
run(...args: any[]) {
return (SelectPosition.run as any).apply(this, args);
}
enable(...args: any) { enable(...args: any[]) {
SelectComponent.enable.apply(this, args); SelectComponent.enable.apply(this, args);
this.getBadgeEl().addClass(this.badgeClass); this.getBadgeEl().addClass(this.badgeClass);
this.getHighlighterEl().addClass(this.hoverClass); this.getHighlighterEl().addClass(this.hoverClass);
var wp = this.$wrapper; const wp = this.$wrapper;
wp.css('cursor', 'move'); wp.css('cursor', 'move');
wp.on('mousedown', this.initSorter); wp.on('mousedown', this.initSorter);
// Avoid strange moving behavior // Avoid strange moving behavior
wp.addClass(this.noSelClass); wp.addClass(this.noSelClass);
}, }
/** /**
* Overwrite for doing nothing * Overwrite for doing nothing
* @private * @private
*/ */
toggleClipboard() {}, toggleClipboard() {}
/** /**
* Delegate sorting * Delegate sorting
@ -40,8 +57,8 @@ export default extend({}, SelectPosition, SelectComponent, {
* @private * @private
* */ * */
initSorter(e: any) { initSorter(e: any) {
var el = $(e.target).data('model'); const el = $(e.target).data('model');
var drag = el.get('draggable'); const drag = el.get('draggable');
if (!drag) return; if (!drag) return;
// Avoid badge showing on move // Avoid badge showing on move
@ -52,7 +69,7 @@ export default extend({}, SelectPosition, SelectComponent, {
this.stopSelectComponent(); this.stopSelectComponent();
this.$wrapper.off('mousedown', this.initSorter); this.$wrapper.off('mousedown', this.initSorter);
on(this.getContentWindow(), 'keydown', this.rollback); on(this.getContentWindow(), 'keydown', this.rollback);
}, }
/** /**
* Init sorter from model * Init sorter from model
@ -60,27 +77,18 @@ export default extend({}, SelectPosition, SelectComponent, {
* @private * @private
*/ */
initSorterFromModel(model: Component) { initSorterFromModel(model: Component) {
var drag = model.get('draggable'); const drag = model.get('draggable');
if (!drag) return; if (!drag) return;
// Avoid badge showing on move // Avoid badge showing on move
this.cacheEl = null; this.cacheEl = null;
// @ts-ignore const el = model.view?.el;
var el = model.view.el; if (!el) return;
this.startSelectPosition(el, this.frameEl.contentDocument); this.startSelectPosition(el, this.frameEl.contentDocument);
this.sorter.draggable = drag; this.sorter.draggable = drag;
this.sorter.eventHandlers.legacyOnEndMove = this.onEndMoveFromModel.bind(this); this.sorter.eventHandlers.legacyOnEndMove = this.onEndMoveFromModel.bind(this);
/*
this.sorter.setDragHelper(el);
var dragHelper = this.sorter.dragHelper;
dragHelper.className = this.ppfx + 'drag-helper';
dragHelper.innerHTML = '';
dragHelper.backgroundColor = 'white';
*/
this.stopSelectComponent(); this.stopSelectComponent();
on(this.getContentWindow(), 'keydown', this.rollback); on(this.getContentWindow(), 'keydown', this.rollback);
}, }
/** /**
* Init sorter from models * Init sorter from models
@ -101,11 +109,11 @@ export default extend({}, SelectPosition, SelectComponent, {
this.sorter.eventHandlers.legacyOnEndMove = this.onEndMoveFromModel.bind(this); this.sorter.eventHandlers.legacyOnEndMove = this.onEndMoveFromModel.bind(this);
this.stopSelectComponent(); this.stopSelectComponent();
on(this.getContentWindow(), 'keydown', this.rollback); on(this.getContentWindow(), 'keydown', this.rollback);
}, }
onEndMoveFromModel() { onEndMoveFromModel() {
off(this.getContentWindow(), 'keydown', this.rollback); off(this.getContentWindow(), 'keydown', this.rollback);
}, }
/** /**
* Callback after sorting * Callback after sorting
@ -114,7 +122,7 @@ export default extend({}, SelectPosition, SelectComponent, {
onEndMove() { onEndMove() {
this.enable(); this.enable();
off(this.getContentWindow(), 'keydown', this.rollback); off(this.getContentWindow(), 'keydown', this.rollback);
}, }
/** /**
* Say what to do after the component was selected (selectComponent) * Say what to do after the component was selected (selectComponent)
@ -122,7 +130,7 @@ export default extend({}, SelectPosition, SelectComponent, {
* @param {Object} Selected element * @param {Object} Selected element
* @private * @private
* */ * */
onSelect(e: any, el: any) {}, onSelect(e: any, el: any) {}
/** /**
* Used to bring the previous situation before start moving the component * Used to bring the previous situation before start moving the component
@ -130,13 +138,13 @@ export default extend({}, SelectPosition, SelectComponent, {
* @param {Boolean} Indicates if rollback in anycase * @param {Boolean} Indicates if rollback in anycase
* @private * @private
* */ * */
rollback(e: any, force: boolean) { rollback(e: any, force?: boolean) {
var key = e.which || e.keyCode; const key = e.which || e.keyCode;
if (key == 27 || force) { if (key == 27 || force) {
this.sorter.cancelDrag(); this.sorter.cancelDrag();
} }
return; return;
}, }
/** /**
* Returns badge element * Returns badge element
@ -146,7 +154,7 @@ export default extend({}, SelectPosition, SelectComponent, {
getBadgeEl() { getBadgeEl() {
if (!this.$badge) this.$badge = $(this.getBadge()); if (!this.$badge) this.$badge = $(this.getBadge());
return this.$badge; return this.$badge;
}, }
/** /**
* Returns highlighter element * Returns highlighter element
@ -156,14 +164,24 @@ export default extend({}, SelectPosition, SelectComponent, {
getHighlighterEl() { getHighlighterEl() {
if (!this.$hl) this.$hl = $(this.canvas.getHighlighter()); if (!this.$hl) this.$hl = $(this.canvas.getHighlighter());
return this.$hl; return this.$hl;
}, }
stop(...args) { stop(...args: any[]) {
// @ts-ignore (SelectComponent.stop as any).apply(this, args);
SelectComponent.stop.apply(this, args);
this.getBadgeEl().removeClass(this.badgeClass); this.getBadgeEl().removeClass(this.badgeClass);
this.getHighlighterEl().removeClass(this.hoverClass); this.getHighlighterEl().removeClass(this.hoverClass);
var wp = this.$wrapper; const wp = this.$wrapper;
wp.css('cursor', '').unbind().removeClass(this.noSelClass); wp.css('cursor', '').unbind().removeClass(this.noSelClass);
}, }
} as CommandObject<{}, { [k: string]: any }>); }
[
SelectPosition as Record<string, unknown>,
SelectComponent as Record<string, unknown>,
].forEach((source) => {
Object.keys(source).forEach((key) => {
if (!(key in CommandMoveComponent.prototype)) {
(CommandMoveComponent.prototype as Record<string, unknown>)[key] = source[key];
}
});
});

42
packages/core/test/specs/commands/view/MoveComponent.ts

@ -0,0 +1,42 @@
import MoveComponent from '../../../../src/commands/view/MoveComponent';
describe('MoveComponent command', () => {
test('rollback should cancel drag on escape', () => {
const command = new MoveComponent({});
const cancelDrag = jest.fn();
command.sorter = { cancelDrag };
command.rollback({ which: 27 }, false);
expect(cancelDrag).toHaveBeenCalledTimes(1);
});
test('stop should reset wrapper and remove helper classes', () => {
const command = new MoveComponent({});
const wrapper: any = {};
wrapper.css = jest.fn(() => wrapper);
wrapper.unbind = jest.fn(() => wrapper);
wrapper.removeClass = jest.fn(() => wrapper);
const removeBadgeClass = jest.fn();
const removeHighlighterClass = jest.fn();
command.$wrapper = wrapper;
command.$badge = { removeClass: removeBadgeClass };
command.$hl = { removeClass: removeHighlighterClass };
command.badgeClass = 'badge-warning';
command.hoverClass = 'highlighter-warning';
command.noSelClass = 'no-select';
command.onHovered = jest.fn();
command.stopSelectComponent = jest.fn();
command.em = { setSelected: jest.fn() } as any;
command.toggleToolsEl = jest.fn();
command.editor = { stopCommand: jest.fn() };
command.stop();
expect(removeBadgeClass).toHaveBeenCalledWith('badge-warning');
expect(removeHighlighterClass).toHaveBeenCalledWith('highlighter-warning');
expect(wrapper.css).toHaveBeenCalledWith('cursor', '');
expect(wrapper.unbind).toHaveBeenCalledTimes(1);
expect(wrapper.removeClass).toHaveBeenCalledWith('no-select');
});
});
Loading…
Cancel
Save