forked from codex-team/editor.js
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdragNDrop.ts
94 lines (76 loc) · 2.35 KB
/
dragNDrop.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
import SelectionUtils from '../selection';
import Module from '../__module';
export default class DragNDrop extends Module {
/**
* If drag has been started at editor, we save it
*
* @type Boolean
* @private
*/
private isStartedAtEditor = false;
/**
* Bind events
*
* @private
*/
public prepare(): void {
this.setReadOnly(this.config.readOnly);
}
/**
* Set read-only state
*
* @param {boolean} readOnlyEnabled
*/
public setReadOnly(readOnlyEnabled: boolean) {
if (readOnlyEnabled) {
this.Editor.Listeners.removeAll();
} else {
this.bindEvents();
}
}
/**
* Add drag events listeners to editor zone
* @private
*/
private bindEvents(): void {
this.Editor.Listeners.on(this.Editor.UI.nodes.holder, 'drop', this.processDrop, true);
this.Editor.Listeners.on(this.Editor.UI.nodes.holder, 'dragstart', (dragEvent: DragEvent) => {
if (SelectionUtils.isAtEditor && !SelectionUtils.isCollapsed) {
this.isStartedAtEditor = true;
}
this.Editor.InlineToolbar.close();
});
/* Prevent default browser behavior to allow drop on non-contenteditable elements */
this.Editor.Listeners.on(this.Editor.UI.nodes.holder, 'dragover', (e) => e.preventDefault(), true);
}
/**
* Handle drop event
*
* @param {DragEvent} dropEvent
*/
private processDrop = async (dropEvent: DragEvent): Promise<void> => {
const {
BlockManager,
Caret,
Paste,
} = this.Editor;
dropEvent.preventDefault();
BlockManager.blocks.forEach((block) => block.dropTarget = false);
if (SelectionUtils.isAtEditor && !SelectionUtils.isCollapsed && this.isStartedAtEditor) {
document.execCommand('delete');
}
this.isStartedAtEditor = false;
/**
* Try to set current block by drop target.
* If drop target (error will be thrown) is not part of the Block, set last Block as current.
*/
try {
const targetBlock = BlockManager.setCurrentBlockByChildNode(dropEvent.target as Node);
this.Editor.Caret.setToBlock(targetBlock, Caret.positions.END);
} catch (e) {
const targetBlock = BlockManager.setCurrentBlockByChildNode(BlockManager.lastBlock.holder);
this.Editor.Caret.setToBlock(targetBlock, Caret.positions.END);
}
Paste.processDataTransfer(dropEvent.dataTransfer, true);
}
}