UNPKG

jodit

Version:

Jodit is awesome and usefully wysiwyg editor with filebrowser

179 lines (144 loc) 4.09 kB
/*! * Jodit Editor (https://xdsoft.net/jodit/) * Licensed under GNU General Public License version 2 or later or a commercial license or MIT; * For GPL see LICENSE-GPL.txt in the project root for license information. * For MIT see LICENSE-MIT.txt in the project root for license information. * For commercial licenses see https://xdsoft.net/jodit/commercial/ * Copyright (c) 2013-2019 Valeriy Chupurnov. All rights reserved. https://xdsoft.net */ import { Config } from '../Config'; import { css, ctrlKey, dataBind, setTimeout, splitArray, throttle } from '../modules/helpers/'; import { Plugin } from '../modules/Plugin'; import { Dom } from '../modules/Dom'; declare module '../Config' { interface Config { draggableTags: string | string[]; } } /** * Draggable elements */ Config.prototype.draggableTags = ['img', 'a', 'jodit-media', 'jodit']; /** * Process drag and drop image or another element inside the editor */ export class DragAndDropElement extends Plugin { private dragList: string[] = []; private isCopyMode: boolean = false; private draggable: HTMLElement | null = null; private wasMoved: boolean = false; private timeout: number = 0; private onDrag = throttle((event: DragEvent) => { if (!this.draggable) { return; } this.wasMoved = true; this.jodit.events.fire('hidePopup hideResizer'); if (!this.draggable.parentNode) { this.jodit.ownerDocument.body.appendChild(this.draggable); } css(this.draggable, { left: event.clientX + 20, top: event.clientY + 20 }); this.jodit.selection.insertCursorAtPoint(event.clientX, event.clientY); }, this.jodit.defaultTimeout); private onDragStart = (event: DragEvent) => { let target: Node | null = event.target as Node, last: HTMLElement | null = null; if (!this.dragList.length) { return; } do { if (this.dragList.indexOf(target.nodeName.toLowerCase()) !== -1) { if ( !last || (target.firstChild === last && target.lastChild === last) ) { last = target as HTMLElement; } } target = target.parentNode; } while (target && target !== this.jodit.editor); if (!last) { return; } this.isCopyMode = ctrlKey(event); // we can move only element from editor this.onDragEnd(); this.timeout = setTimeout( (lastNode?: HTMLElement) => { if (!lastNode) { return; } this.draggable = lastNode.cloneNode(true) as HTMLElement; dataBind(this.draggable, 'target', lastNode); css(this.draggable, { 'z-index': 100000000000000, 'pointer-events': 'none', position: 'fixed', display: 'inlin-block', left: event.clientX, top: event.clientY, width: lastNode.offsetWidth, height: lastNode.offsetHeight }); }, this.jodit.defaultTimeout, last ); event.preventDefault(); }; private onDragEnd = () => { window.clearTimeout(this.timeout); if (this.draggable) { Dom.safeRemove(this.draggable); this.draggable = null; this.wasMoved = false; } }; private onDrop = () => { if (!this.draggable || !this.wasMoved) { this.onDragEnd(); return; } let fragment: HTMLElement = dataBind(this.draggable, 'target'); this.onDragEnd(); if (this.isCopyMode) { fragment = fragment.cloneNode(true) as HTMLElement; } this.jodit.selection.insertNode(fragment, true, false); if (fragment.nodeName === 'IMG' && this.jodit.events) { this.jodit.events.fire('afterInsertImage', fragment); } this.jodit.events.fire('synchro'); }; public afterInit() { this.dragList = this.jodit.options.draggableTags ? splitArray(this.jodit.options.draggableTags) .filter(item => item) .map((item: string) => item.toLowerCase()) : []; if (!this.dragList.length) { return; } this.jodit.events .on(this.jodit.editor, 'mousemove touchmove', this.onDrag) .on( this.jodit.editor, 'mousedown touchstart dragstart', this.onDragStart ) .on('mouseup touchend', this.onDrop) .on(window, 'mouseup touchend', this.onDragEnd); } public beforeDestruct() { this.onDragEnd(); } }