-
Notifications
You must be signed in to change notification settings - Fork 30.4k
/
Copy pathdnd.ts
115 lines (90 loc) · 2.79 KB
/
dnd.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { addDisposableListener } from 'vs/base/browser/dom';
import { Disposable } from 'vs/base/common/lifecycle';
import { Mimes } from 'vs/base/common/mime';
/**
* A helper that will execute a provided function when the provided HTMLElement receives
* dragover event for 800ms. If the drag is aborted before, the callback will not be triggered.
*/
export class DelayedDragHandler extends Disposable {
private timeout: any;
constructor(container: HTMLElement, callback: () => void) {
super();
this._register(addDisposableListener(container, 'dragover', e => {
e.preventDefault(); // needed so that the drop event fires (https://stackoverflow.com/questions/21339924/drop-event-not-firing-in-chrome)
if (!this.timeout) {
this.timeout = setTimeout(() => {
callback();
this.timeout = null;
}, 800);
}
}));
['dragleave', 'drop', 'dragend'].forEach(type => {
this._register(addDisposableListener(container, type, () => {
this.clearDragTimeout();
}));
});
}
private clearDragTimeout(): void {
if (this.timeout) {
clearTimeout(this.timeout);
this.timeout = null;
}
}
override dispose(): void {
super.dispose();
this.clearDragTimeout();
}
}
// Common data transfers
export const DataTransfers = {
/**
* Application specific resource transfer type
*/
RESOURCES: 'ResourceURLs',
/**
* Browser specific transfer type to download
*/
DOWNLOAD_URL: 'DownloadURL',
/**
* Browser specific transfer type for files
*/
FILES: 'Files',
/**
* Typically transfer type for copy/paste transfers.
*/
TEXT: Mimes.text
};
export function applyDragImage(event: DragEvent, label: string | null, clazz: string): void {
const dragImage = document.createElement('div');
dragImage.className = clazz;
dragImage.textContent = label;
if (event.dataTransfer) {
document.body.appendChild(dragImage);
event.dataTransfer.setDragImage(dragImage, -10, -10);
// Removes the element when the DND operation is done
setTimeout(() => document.body.removeChild(dragImage), 0);
}
}
export interface IDragAndDropData {
update(dataTransfer: DataTransfer): void;
getData(): unknown;
}
export class DragAndDropData<T> implements IDragAndDropData {
constructor(private data: T) { }
update(): void {
// noop
}
getData(): T {
return this.data;
}
}
export interface IStaticDND {
CurrentDragAndDropData: IDragAndDropData | undefined;
}
export const StaticDND: IStaticDND = {
CurrentDragAndDropData: undefined
};