UNPKG

grapesjs_codeapps

Version:

Free and Open Source Web Builder Framework/SC Modification

130 lines (111 loc) 3.62 kB
import Backbone from 'backbone'; import { isObject } from 'underscore'; import { on, off, hasDnd } from 'utils/mixins'; module.exports = Backbone.View.extend({ events: { mousedown: 'startDrag', dragstart: 'handleDragStart', drag: 'handleDrag', dragend: 'handleDragEnd' }, initialize(o, config = {}) { const { model } = this; this.em = config.em; this.config = config; this.endDrag = this.endDrag.bind(this); this.ppfx = config.pStylePrefix || ''; this.listenTo(model, 'destroy remove', this.remove); this.listenTo(model, 'change', this.render); }, /** * Start block dragging * @private */ startDrag(e) { const config = this.config; //Right or middel click if (e.button !== 0 || !config.getSorter || this.el.draggable) return; config.em.refreshCanvas(); const sorter = config.getSorter(); sorter.setDragHelper(this.el, e); sorter.setDropContent(this.model.get('content')); sorter.startSort(this.el); on(document, 'mouseup', this.endDrag); }, handleDragStart(ev) { const { em, model } = this; const content = model.get('content'); const isObj = isObject(content); const type = isObj ? 'text/json' : 'text'; const data = isObj ? JSON.stringify(content) : content; // Note: data are not available on dragenter for security reason, // but will use dragContent as I 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); }, handleDrag(ev) { this.em.trigger('block:drag', this.model, ev); }, updateStyle(el, property, value) { const style = el.getStyle(); if (value) { style[property] = value; } else { delete style[property]; } el.setStyle(style); }, handleDragEnd() { const { em, model } = this; const result = em.get('dragResult'); this.updateStyle(result, 'position', 'absolute'); this.updateStyle(result, 'left', window.event['clientX'] - 40 + 'px'); this.updateStyle(result, 'top', window.event['clientY'] - 40 + 'px'); if (result) { const oldKey = 'activeOnRender'; const oldActive = result.get && result.get(oldKey); if (model.get('activate') || oldActive) { result.trigger('active'); result.set(oldKey, 0); } //if (model.get('select')) { em.setSelected(result); //} if (model.get('resetId')) { result.onAll(model => model.resetId()); } } em.set({ dragResult: null, dragContent: null }); em.trigger('block:drag:stop', result, model); }, /** * Drop block * @private */ endDrag(e) { off(document, 'mouseup', this.endDrag); const sorter = this.config.getSorter(); // After dropping the block in the canvas the mouseup event is not yet // triggerd on 'this.doc' and so clicking outside, the sorter, tries to move // things (throws false positives). As this method just need to drop away // the block helper I use the trick of 'moved = 0' to void those errors. sorter.moved = 0; sorter.endMove(); }, render() { const el = this.el; const pfx = this.ppfx; const className = `${pfx}block`; const label = this.model.get('label'); el.className += ` ${className} ${pfx}one-bg ${pfx}four-color-h`; el.innerHTML = `<div class="${className}-label">${label}</div>`; el.title = el.textContent.trim(); hasDnd(this.em) && el.setAttribute('draggable', true); return this; } });