UNPKG

grapesjs_codeapps

Version:

Free and Open Source Web Builder Framework/SC Modification

233 lines (214 loc) 6.27 kB
import _ from 'underscore'; import Backbone from 'backbone'; const SelectPosition = require('./SelectPosition'); const $ = Backbone.$; module.exports = _.extend({}, SelectPosition, { init(opt) { _.bindAll(this, 'startDraw', 'draw', 'endDraw', 'rollback'); this.config = opt || {}; this.hType = this.config.newFixedH ? 'height' : 'min-height'; this.allowDraw = 1; }, /** * Start with enabling to select position and listening to start drawing * @private * */ enable(...args) { SelectPosition.enable.apply(this, args); this.$wr.css('cursor', 'crosshair'); if (this.allowDraw) this.$wr.on('mousedown', this.startDraw); this.ghost = this.canvas.getGhostEl(); }, /** * Start drawing component * @param {Object} e Event * @private * */ startDraw(e) { e.preventDefault(); this.stopSelectPosition(); this.ghost.style.display = 'block'; this.frameOff = this.getOffsetDim(); this.startPos = { top: e.pageY + this.frameOff.top, left: e.pageX + this.frameOff.left }; this.isDragged = false; this.tempComponent = { style: {} }; this.beforeDraw(this.tempComponent); this.updateSize(this.startPos.top, this.startPos.left, 0, 0); this.toggleEvents(1); }, /** * Enable/Disable events * @param {Boolean} enable */ toggleEvents(enable) { var method = enable ? 'on' : 'off'; this.$wr[method]('mousemove', this.draw); this.$wr[method]('mouseup', this.endDraw); this.$canvas[method]('mousemove', this.draw); $(document)[method]('mouseup', this.endDraw); $(document)[method]('keypress', this.rollback); }, /** * While drawing the component * @param {Object} e Event * @private * */ draw(e) { this.isDragged = true; this.updateComponentSize(e); }, /** * End drawing component * @param {Object} e Event * @private * */ endDraw(e) { this.toggleEvents(); var model = {}; // Only if the mouse was moved if (this.isDragged) { this.updateComponentSize(e); this.setRequirements(this.tempComponent); var lp = this.sorter.lastPos; model = this.create( this.sorter.target, this.tempComponent, lp.index, lp.method ); this.sorter.prevTarget = null; } this.ghost.style.display = 'none'; this.startSelectPosition(); this.afterDraw(model); }, /** * Create new component inside the target * @param {Object} target Tha target collection * @param {Object} component New component to create * @param {number} index Index inside the collection, 0 if no children inside * @param {string} method Before or after of the children * @param {Object} opts Options */ create(target, component, index, method, opts) { index = method === 'after' ? index + 1 : index; var opt = opts || {}; var $trg = $(target); var trgModel = $trg.data('model'); var trgCollection = $trg.data('collection'); var droppable = trgModel ? trgModel.get('droppable') : 1; opt.at = index; if (trgCollection && droppable) return trgCollection.add(component, opt); else console.warn('Invalid target position'); }, /** * Check and set basic requirements for the component * @param {Object} component New component to be created * @return {Object} Component updated * @private * */ setRequirements(component) { var c = this.config; var compStl = component.style; // Check min width if (compStl.width.replace(/\D/g, '') < c.minComponentW) compStl.width = c.minComponentW + 'px'; // Check min height if (compStl[this.hType].replace(/\D/g, '') < c.minComponentH) compStl[this.hType] = c.minComponentH + 'px'; // Set overflow in case of fixed height if (c.newFixedH) compStl.overflow = 'auto'; if (!this.absoluteMode) { delete compStl.left; delete compStl.top; } else compStl.position = 'absolute'; var lp = this.sorter.lastPos; if (this.nearFloat(lp.index, lp.method, this.sorter.lastDims)) compStl.float = 'left'; if ( this.config.firstCentered && this.getCanvasWrapper() == this.sorter.target ) { compStl.margin = '0 auto'; } return component; }, /** * Update new component size while drawing * @param {Object} e Event * @private * */ updateComponentSize(e) { var y = e.pageY + this.frameOff.top; var x = e.pageX + this.frameOff.left; var start = this.startPos; var top = start.top; var left = start.left; var height = y - top; var width = x - left; if (x < left) { left = x; width = start.left - x; } if (y < top) { top = y; height = start.top - y; } this.updateSize(top, left, width, height); }, /** * Update size * @private */ updateSize(top, left, width, height) { var u = 'px'; var ghStl = this.ghost.style; var compStl = this.tempComponent.style; ghStl.top = compStl.top = top + u; ghStl.left = compStl.left = left + u; ghStl.width = compStl.width = width + u; ghStl[this.hType] = compStl[this.hType] = height + u; }, /** * Used to bring the previous situation before event started * @param {Object} e Event * @param {Boolean} forse Indicates if rollback in anycase * @private * */ rollback(e, force) { var key = e.which || e.keyCode; if (key == this.config.ESCAPE_KEY || force) { this.isDragged = false; this.endDraw(); } return; }, /** * This event is triggered at the beginning of a draw operation * @param {Object} component Object component before creation * @private * */ beforeDraw(component) { component.editable = false; //set this component editable }, /** * This event is triggered at the end of a draw operation * @param {Object} model Component model created * @private * */ afterDraw(model) {}, run(editor, sender, opts) { this.editor = editor; this.sender = sender; this.$wr = this.$wrapper; this.enable(); }, stop() { this.stopSelectPosition(); this.$wrapper.css('cursor', ''); this.$wrapper.unbind(); } });