dockview
Version:
Zero dependency layout manager supporting tabs, grids and splitviews with ReactJS support
110 lines (109 loc) • 3.8 kB
JavaScript
import { addDisposableListener, Emitter } from '../events';
import { CompositeDisposable } from '../lifecycle';
import { LocalSelectionTransfer } from './dataTransfer';
export class DragAndDropObserver extends CompositeDisposable {
constructor(element, callbacks) {
super();
this.element = element;
this.callbacks = callbacks;
// A helper to fix issues with repeated DRAG_ENTER / DRAG_LEAVE
// calls see https://github.com/microsoft/vscode/issues/14470
// when the element has child elements where the events are fired
// repeadedly.
this.counter = 0;
this.registerListeners();
}
registerListeners() {
this.addDisposables(addDisposableListener(this.element, 'dragenter', (e) => {
this.counter++;
this.callbacks.onDragEnter(e);
}));
this.addDisposables(addDisposableListener(this.element, 'dragover', (e) => {
e.preventDefault(); // needed so that the drop event fires (https://stackoverflow.com/questions/21339924/drop-event-not-firing-in-chrome)
if (this.callbacks.onDragOver) {
this.callbacks.onDragOver(e);
}
}));
this.addDisposables(addDisposableListener(this.element, 'dragleave', (e) => {
this.counter--;
if (this.counter === 0) {
this.callbacks.onDragLeave(e);
}
}));
this.addDisposables(addDisposableListener(this.element, 'dragend', (e) => {
this.counter = 0;
this.callbacks.onDragEnd(e);
}));
this.addDisposables(addDisposableListener(this.element, 'drop', (e) => {
this.counter = 0;
this.callbacks.onDrop(e);
}));
}
}
class DockviewIdentifier {
constructor(data) {
this.data = data;
//
}
}
export class DragAndDrop extends CompositeDisposable {
constructor() {
super();
this._onDragStart = new Emitter();
this._onDragEnd = new Emitter();
this.transferData = LocalSelectionTransfer.getInstance();
this.addDisposables(this._onDragStart, this._onDragEnd);
}
static get INSTANCE() {
if (!DragAndDrop._instance) {
DragAndDrop._instance = new DragAndDrop();
}
return DragAndDrop._instance;
}
registerTarget(element, callbacks) {
const disposables = new CompositeDisposable();
disposables.addDisposables(new DragAndDropObserver(element, {
onDragEnd: (e) => {
// no-op
},
onDragEnter: (e) => {
e.preventDefault();
},
onDragLeave: (e) => {
//
},
onDrop: (e) => {
//
},
onDragOver: (e) => {
//
},
}));
return disposables;
}
registerDraggable(element, draggedItemProvider, callbacks) {
element.draggable = true;
const disposables = new CompositeDisposable();
disposables.addDisposables(addDisposableListener(element, 'dragstart', (e) => {
this._onDragStart.fire({ event: e });
}));
disposables.addDisposables(new DragAndDropObserver(element, {
onDragEnd: (e) => {
// no-op
},
onDragEnter: (e) => {
//
},
onDragLeave: (e) => {
//
},
onDrop: (e) => {
//
},
onDragOver: (e) => {
//
},
}));
return disposables;
}
}