Browse Source

Move Droppable to TS

pull/4695/head
Artur Arseniev 3 years ago
parent
commit
c190913807
  1. 102
      src/utils/Droppable.ts

102
src/utils/Droppable.js → src/utils/Droppable.ts

@ -1,29 +1,44 @@
/*
This class makes the canvas droppable
*/
import { bindAll, indexOf } from 'underscore';
import CanvasModule from '../canvas';
import EditorModel from '../editor/model/Editor';
import { on, off } from './mixins';
// TODO move in sorter
type SorterOptions = {
sorter: any;
event: any;
};
type DragStop = (cancel?: boolean) => void;
type DragContent = (content: any) => void;
/**
* This class makes the canvas droppable
*/
export default class Droppable {
constructor(em, rootEl) {
em: EditorModel;
canvas: CanvasModule;
el: HTMLElement;
counter: number;
sortOpts?: Record<string, any> | null;
over?: boolean;
dragStop?: DragStop;
dragContent?: DragContent;
sorter?: any;
constructor(em: EditorModel, rootEl?: HTMLElement) {
this.em = em;
const el =
rootEl ||
em
.get('Canvas')
.getFrames()
.map(frame => frame.getComponent().getEl());
this.canvas = em.get('Canvas');
const el = rootEl || this.canvas.getFrames().map(frame => frame.getComponent().getEl());
const els = Array.isArray(el) ? el : [el];
this.el = el;
this.el = els[0];
this.counter = 0;
bindAll(this, 'handleDragEnter', 'handleDragOver', 'handleDrop', 'handleDragLeave');
els.forEach(el => this.toggleEffects(el, 1));
return this;
els.forEach(el => this.toggleEffects(el, true));
}
toggleEffects(el, enable) {
toggleEffects(el: HTMLElement, enable: boolean) {
const methods = { on, off };
const method = enable ? 'on' : 'off';
methods[method](el, 'dragenter', this.handleDragEnter);
@ -32,19 +47,19 @@ export default class Droppable {
methods[method](el, 'dragleave', this.handleDragLeave);
}
__customTglEff(enable) {
__customTglEff(enable: boolean) {
const method = enable ? on : off;
const doc = this.el.ownerDocument;
const frameEl = doc.defaultView.frameElement;
const frameEl = doc.defaultView?.frameElement as HTMLIFrameElement;
this.sortOpts = enable
? {
onStart({ sorter }) {
onStart({ sorter }: SorterOptions) {
on(frameEl, 'pointermove', sorter.onMove);
},
onEnd({ sorter }) {
onEnd({ sorter }: SorterOptions) {
off(frameEl, 'pointermove', sorter.onMove);
},
customTarget({ event }) {
customTarget({ event }: SorterOptions) {
return doc.elementFromPoint(event.clientX, event.clientY);
},
}
@ -63,11 +78,11 @@ export default class Droppable {
this.__customTglEff(true);
}
endCustom(cancel) {
endCustom(cancel?: boolean) {
this.over ? this.endDrop(cancel) : this.__customTglEff(false);
}
endDrop(cancel, ev) {
endDrop(cancel?: boolean, ev?: Event) {
const { em, dragStop } = this;
this.counter = 0;
dragStop && dragStop(cancel);
@ -75,28 +90,29 @@ export default class Droppable {
em.trigger('canvas:dragend', ev);
}
handleDragLeave(ev) {
handleDragLeave(ev: Event) {
this.updateCounter(-1, ev);
}
updateCounter(value, ev) {
updateCounter(value: number, ev: Event) {
this.counter += value;
this.counter === 0 && this.endDrop(1, ev);
this.counter === 0 && this.endDrop(true, ev);
}
handleDragEnter(ev) {
handleDragEnter(ev: DragEvent | Event) {
const { em } = this;
const dt = ev.dataTransfer;
const dt = (ev as DragEvent).dataTransfer;
this.updateCounter(1, ev);
if (this.over) return;
this.over = 1;
this.over = true;
const utils = em.get('Utils');
const canvas = em.get('Canvas');
// For security reason I can't read the drag data on dragenter, but
// as I need it for the Sorter context I will use `dragContent` or just
// any not empty element
let content = em.get('dragContent') || '<br>';
let dragStop, dragContent;
let dragStop: DragStop;
let dragContent;
em.stopDefault();
// Select the right drag provider
@ -108,7 +124,7 @@ export default class Droppable {
guidesInfo: 1,
center: 1,
target,
onEnd: (ev, dragger, { cancelled }) => {
onEnd: (ev: any, dragger: any, { cancelled }: any) => {
let comp;
if (!cancelled) {
comp = wrapper.append(content)[0];
@ -124,8 +140,8 @@ export default class Droppable {
target.remove();
},
});
dragStop = cancel => dragger.stop(ev, { cancel });
dragContent = cnt => (content = cnt);
dragStop = (cancel?: boolean) => dragger.stop(ev, { cancel });
dragContent = (cnt: any) => (content = cnt);
} else {
const sorter = new utils.Sorter({
em,
@ -138,18 +154,18 @@ export default class Droppable {
containerSel: '*',
itemSel: '*',
pfx: 'gjs-',
onEndMove: model => this.handleDragEnd(model, dt),
onEndMove: (model: any) => this.handleDragEnd(model, dt),
document: this.el.ownerDocument,
...(this.sortOpts || {}),
});
sorter.setDropContent(content);
sorter.startSort();
this.sorter = sorter;
dragStop = cancel => {
dragStop = (cancel?: boolean) => {
cancel && (sorter.moved = 0);
sorter.endMove();
};
dragContent = content => sorter.setDropContent(content);
dragContent = (content: any) => sorter.setDropContent(content);
}
this.dragStop = dragStop;
@ -157,9 +173,9 @@ export default class Droppable {
em.trigger('canvas:dragenter', dt, content);
}
handleDragEnd(model, dt) {
handleDragEnd(model: any, dt: any) {
const { em } = this;
this.over = 0;
this.over = false;
if (model) {
em.set('dragResult', model);
em.trigger('canvas:drop', dt, model);
@ -171,7 +187,7 @@ export default class Droppable {
* Always need to have this handler active for enabling the drop
* @param {Event} ev
*/
handleDragOver(ev) {
handleDragOver(ev: Event) {
ev.preventDefault();
this.em.trigger('canvas:dragover', ev);
}
@ -180,17 +196,17 @@ export default class Droppable {
* WARNING: This function might fail to run on drop, for example, when the
* drop, accidentally, happens on some external element (DOM not inside the iframe)
*/
handleDrop(ev) {
handleDrop(ev: Event | DragEvent) {
ev.preventDefault();
const { dragContent } = this;
const dt = ev.dataTransfer;
const dt = (ev as DragEvent).dataTransfer;
const content = this.getContentByData(dt).content;
ev.target.style.border = '';
(ev.target as HTMLElement).style.border = '';
content && dragContent && dragContent(content);
this.endDrop(!content, ev);
}
getContentByData(dt) {
getContentByData(dt: any) {
const em = this.em;
const types = dt && dt.types;
const files = (dt && dt.files) || [];
Loading…
Cancel
Save