From a5e53d5644f3bf6d856375ab5182fbb0ea43229a Mon Sep 17 00:00:00 2001 From: Artur Arseniev Date: Thu, 30 Sep 2021 16:11:59 +0200 Subject: [PATCH] Move D&D block logic inside the module --- src/block_manager/index.js | 73 ++++++++++++++++++++++++----- src/block_manager/view/BlockView.js | 52 ++++---------------- 2 files changed, 69 insertions(+), 56 deletions(-) diff --git a/src/block_manager/index.js b/src/block_manager/index.js index 9caa71b76..c8581c0ec 100644 --- a/src/block_manager/index.js +++ b/src/block_manager/index.js @@ -44,7 +44,7 @@ * * @module BlockManager */ -import { isElement } from 'underscore'; +import { isElement, isArray } from 'underscore'; import Module from 'common/module'; import defaults from './config/config'; import Block from './model/Block'; @@ -59,6 +59,9 @@ export const evAdd = `${evPfx}add`; export const evUpdate = `${evPfx}update`; export const evRemove = `${evPfx}remove`; export const evRemoveBefore = `${evRemove}:before`; +export const evDrag = `${evPfx}drag`; +export const evDragStart = `${evDrag}:start`; +export const evDragStop = `${evDrag}:stop`; export const evCustom = `${evPfx}custom`; export default () => { @@ -85,6 +88,9 @@ export default () => { add: evAdd, remove: evRemove, removeBefore: evRemoveBefore, + drag: evDrag, + dragStart: evDragStart, + dragEnd: evDragStop, custom: evCustom }, @@ -118,22 +124,55 @@ export default () => { bm: this, blocks: this.getAll().models, container: bhv.container, - drag: block => { - const cnt = block.getContent ? block.getContent() : block; - this.__sorterStart(cnt); - }, - dragStop: cancel => this.__sorterEnd(cancel) + dragStart: (block, ev) => this.startDrag(block, ev), + drag: ev => this.__drag(ev), + dragStop: cancel => this.endDrag(cancel) }; }, - __sorterStart(content) { - // block:drag - this.em.set('dragContent', content); - this.__getFrameViews().forEach(fv => fv.droppable.startCustom()); + __startDrag(block, ev) { + const { em, events } = this; + const content = block.getContent ? block.getContent() : block; + this._dragBlock = block; + em.set({ dragResult: null, dragContent: content }); + [em, blocks].map(i => i.trigger(events.dragStart, block, ev)); }, - __sorterEnd(cancel) { - this.__getFrameViews().forEach(fv => fv.droppable.endCustom(cancel)); + __drag(ev) { + const { em, events } = this; + const block = this._dragBlock; + [em, blocks].map(i => i.trigger(events.drag, block, ev)); + }, + + __endDrag() { + const { em, events } = this; + const block = this._dragBlock; + const cmp = em.get('dragResult'); + this._dragBlock = null; + + if (cmp) { + const oldKey = 'activeOnRender'; + const oldActive = cmp.get && cmp.get(oldKey); + const toActive = block.get('activate') || oldActive; + const toSelect = block.get('select'); + const first = isArray(cmp) ? cmp[0] : cmp; + + if (toSelect || (toActive && toSelect !== false)) { + em.setSelected(first); + } + + if (toActive) { + first.trigger('active'); + oldActive && first.unset(oldKey); + } + + if (block.get('resetId')) { + first.onAll(block => block.resetId()); + } + } + + em.set({ dragResult: null, dragContent: null }); + [em, blocks].map(i => i.trigger(events.dragEnd, cmp, block)); }, __getFrameViews() { @@ -154,6 +193,16 @@ export default () => { return this._bhv || {}; }, + startDrag(block, ev) { + this.__startDrag(block, ev); + this.__getFrameViews().forEach(fv => fv.droppable.startCustom()); + }, + + endDrag(cancel) { + this.__getFrameViews().forEach(fv => fv.droppable.endCustom(cancel)); + this.__endDrag(); + }, + /** * Get configuration object * @return {Object} diff --git a/src/block_manager/view/BlockView.js b/src/block_manager/view/BlockView.js index a8bf2e157..5a332f566 100644 --- a/src/block_manager/view/BlockView.js +++ b/src/block_manager/view/BlockView.js @@ -1,5 +1,5 @@ import Backbone from 'backbone'; -import { isFunction, isObject, isArray } from 'underscore'; +import { isFunction } from 'underscore'; import { on, off, hasDnd } from 'utils/mixins'; export default Backbone.View.extend({ @@ -21,6 +21,10 @@ export default Backbone.View.extend({ this.listenTo(model, 'change', this.render); }, + __getModule() { + return this.em.get('BlockManager'); + }, + handleClick(ev) { const { config, model, em } = this; const onClick = model.get('onClick') || config.appendOnClick; @@ -80,55 +84,15 @@ export default Backbone.View.extend({ }, handleDragStart(ev) { - const { em, model } = this; - const content = model.get('content'); - const isObj = isObject(content); - const data = isObj ? JSON.stringify(content) : content; - em.set('dragResult'); - - // Note: data are not available on dragenter for security reason, - // we have to use dragContent as we need it for the Sorter context - // IE11 supports only 'text' data type - ev.dataTransfer.setData('text', data); - em.set('dragContent', content); - em.trigger('block:drag:start', model, ev); + this.__getModule().__startDrag(this.model, ev); }, handleDrag(ev) { - this.em.trigger('block:drag', this.model, ev); + this.__getModule().__drag(ev); }, handleDragEnd() { - const { em, model } = this; - const result = em.get('dragResult'); - - if (result) { - const oldKey = 'activeOnRender'; - const oldActive = result.get && result.get(oldKey); - const toActive = model.get('activate') || oldActive; - const toSelect = model.get('select'); - const first = isArray(result) ? result[0] : result; - - if (toSelect || (toActive && toSelect !== false)) { - em.setSelected(first); - } - - if (toActive) { - first.trigger('active'); - first.unset(oldKey); - } - - if (model.get('resetId')) { - first.onAll(model => model.resetId()); - } - } - - em.set({ - dragResult: null, - dragContent: null - }); - - em.trigger('block:drag:stop', result, model); + this.__getModule().__endDrag(); }, /**