forked from aosabook/500lines
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdrag.js
More file actions
97 lines (88 loc) · 3.93 KB
/
Copy pathdrag.js
File metadata and controls
97 lines (88 loc) · 3.93 KB
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
(function(global){
'use strict';
var dragTarget = null; // Block we're dragging
var dragType = null; // Are we dragging from the menu or from the script?
var scriptBlocks = []; // Blocks in the script, sorted by position
function dragStart(evt){
if (!matches(evt.target, '.block')) return;
if (matches(evt.target, '.menu .block')){
dragType = 'menu';
}else{
dragType = 'script';
}
evt.target.classList.add('dragging');
dragTarget = evt.target;
scriptBlocks = [].slice.call(document.querySelectorAll('.script .block:not(.dragging)'));
// For dragging to take place in Firefox, we have to set this, even if we don't use it
evt.dataTransfer.setData('text/html', evt.target.outerHTML);
if (matches(evt.target, '.menu .block')){
evt.dataTransfer.effectAllowed = 'copy';
}else{
evt.dataTransfer.effectAllowed = 'move';
}
}
function dragEnter(evt){
if (matches(evt.target, '.menu, .script, .content')){
evt.target.classList.add('over');
if (evt.preventDefault) { evt.preventDefault(); }// Necessary. Allows us to drop.
}else{
if (!matches(evt.target, '.menu *, .script *')){
_findAndRemoveClass('over');
evt.target.classList.remove('over');
}
}
return false;
}
function dragOver(evt){
if (!matches(evt.target, '.menu, .menu *, .script, .script *, .content')) return;
if (evt.preventDefault) { evt.preventDefault(); } // Necessary. Allows us to drop.
if (dragType === 'menu'){
evt.dataTransfer.dropEffect = 'copy'; // See the section on the DataTransfer object.
}else{
evt.dataTransfer.dropEffect = 'move';
}
return false;
}
function drop(evt){
if (!matches(evt.target, '.menu, .menu *, .script, .script *')) return;
var dropTarget = closest(evt.target, '.script .container, .script .block, .menu, .script');
var dropType = 'script';
if (matches(dropTarget, '.menu')){ dropType = 'menu'; }
if (evt.stopPropagation) { evt.stopPropagation(); } // stops the browser from redirecting.
if (dragType === 'script' && dropType === 'menu'){
trigger('blockRemoved', dragTarget.parentElement, dragTarget);
dragTarget.parentElement.removeChild(dragTarget);
}else if (dragType ==='script' && dropType === 'script'){
if (matches(dropTarget, '.block')){
dropTarget.parentElement.insertBefore(dragTarget, dropTarget.nextSibling);
}else{
dropTarget.insertBefore(dragTarget, dropTarget.firstChildElement);
}
trigger('blockMoved', dropTarget, dragTarget);
}else if (dragType === 'menu' && dropType === 'script'){
var newNode = dragTarget.cloneNode(true);
newNode.classList.remove('dragging');
if (matches(dropTarget, '.block')){
dropTarget.parentElement.insertBefore(newNode, dropTarget.nextSibling);
}else{
dropTarget.insertBefore(newNode, dropTarget.firstChildElement);
}
trigger('blockAdded', dropTarget, newNode);
}
}
function _findAndRemoveClass(klass){
var elem = document.querySelector('.' + klass);
if (elem){ elem.classList.remove(klass); }
}
function dragEnd(evt){
_findAndRemoveClass('dragging');
_findAndRemoveClass('over');
_findAndRemoveClass('next');
}
document.addEventListener('dragstart', dragStart, false);
document.addEventListener('dragenter', dragEnter, false);
document.addEventListener('dragover', dragOver, false);
document.addEventListener('drag', function(){}, false);
document.addEventListener('drop', drop, false);
document.addEventListener('dragend', dragEnd, false);
})(window);