Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(337)

Side by Side Diff: chrome/browser/resources/ntp/drag_drop_controller.js

Issue 6297013: [NTP] Allow reordering of apps via drag and drop. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: incorporate feedback Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // The delegate interface:
6 // dragContainer -->
7 // element containing the draggable items
8 //
9 // transitionsDuration -->
10 // length of time of transitions in ms
11 //
12 // dragItem -->
13 // get / set property containing the item being dragged
14 //
15 // getItem(e) -->
16 // get's the item that is under the mouse event |e|
17 //
18 // canDropOn(coordinates) -->
19 // returns true if the coordinates (relative to the drag container)
20 // point to a valid place to drop an item
21 //
22 // setDragPlaceholder(coordinates) -->
23 // tells the delegate that the dragged item is currently above
24 // the specified coordinates.
25 //
26 // saveDrag() -->
27 // tells the delegate that the drag is done. move the item to the
28 // position last specified by setDragPlaceholder. (e.g., commit changes)
29 //
30
31 function DragAndDropController(delegate) {
32 this.delegate_ = delegate;
33
34 this.installHandlers_();
35 }
36
37 DragAndDropController.prototype = {
38 startX_: 0,
39 startY_: 0,
40 startScreenX_: 0,
41 startScreenY_: 0,
42
43 installHandlers_: function() {
44 var el = this.delegate_.dragContainer;
45 el.addEventListener('dragstart', this.handleDragStart_.bind(this));
46 el.addEventListener('dragenter', this.handleDragEnter_.bind(this));
47 el.addEventListener('dragover', this.handleDragOver_.bind(this));
48 el.addEventListener('dragleave', this.handleDragLeave_.bind(this));
49 el.addEventListener('drop', this.handleDrop_.bind(this));
50 el.addEventListener('dragend', this.handleDragEnd_.bind(this));
51 el.addEventListener('drag', this.handleDrag_.bind(this));
52 el.addEventListener('mousedown', this.handleMouseDown_.bind(this));
53 },
54
55 getCoordinates_: function(e) {
56 var rect = this.delegate_.dragContainer.getBoundingClientRect();
57 var coordinates = {
58 x: e.clientX + window.scrollX - rect.left,
59 y: e.clientY + window.scrollY - rect.top
60 };
61
62 // If we're in an RTL language, reflect the coordinates so the delegate
63 // doesn't need to worry about it.
64 if (isRtl())
65 coordinates.x = this.delegate_.dragContainer.offsetWidth - coordinates.x;
66
67 return coordinates;
68 },
69
70 // Listen to mousedown to get the relative position of the cursor when
71 // starting drag and drop.
72 handleMouseDown_: function(e) {
73 var item = this.delegate_.getItem(e);
74 if (!item)
75 return;
76
77 this.startX_ = item.offsetLeft;
78 this.startY_ = item.offsetTop;
79 this.startScreenX_ = e.screenX;
80 this.startScreenY_ = e.screenY;
81
82 // We don't want to focus the item on mousedown. However, to prevent
83 // focus one has to call preventDefault but this also prevents the drag
84 // and drop (sigh) so we only prevent it when the user is not doing a
85 // left mouse button drag.
86 if (e.button != 0) // LEFT
87 e.preventDefault();
88 },
89
90 handleDragStart_: function(e) {
91 var item = this.delegate_.getItem(e);
92 if (!item)
93 return;
94
95 // Don't set data since HTML5 does not allow setting the name for
96 // url-list. Instead, we just rely on the dragging of link behavior.
97 this.delegate_.dragItem = item;
98 item.classList.add('dragging');
99
100 e.dataTransfer.effectAllowed = 'copyLinkMove';
101 },
102
103 handleDragEnter_: function(e) {
104 if (this.delegate_.canDropOn(this.getCoordinates_(e)))
105 e.preventDefault();
106 },
107
108 handleDragOver_: function(e) {
109 var coordinates = this.getCoordinates_(e);
110 if (!this.delegate_.canDropOn(coordinates))
111 return;
112
113 this.delegate_.setDragPlaceholder(coordinates);
114 e.preventDefault();
115 e.dataTransfer.dropEffect = 'move';
116 },
117
118 handleDragLeave_: function(e) {
119 if (this.delegate_.canDropOn(this.getCoordinates_(e)))
120 e.preventDefault();
121 },
122
123 handleDrop_: function(e) {
124 var dragItem = this.delegate_.dragItem;
125 if (!dragItem)
126 return;
127
128 this.delegate_.dragItem = null;
129 this.delegate_.saveDrag();
130
131 setTimeout(function() {
132 dragItem.classList.remove('dragging');
133 }, this.delegate_.transitionsDuration + 10);
134 },
135
136 handleDragEnd_: function(e) {
137 return this.handleDrop_(e);
138 },
139
140 handleDrag_: function(e) {
141 // Moves the drag item making sure that it is not displayed outside the
142 // browser viewport.
143 var dragItem = this.delegate_.dragItem;
144 var rect = this.delegate_.dragContainer.getBoundingClientRect();
145
146 var x = this.startX_ + e.screenX - this.startScreenX_;
147 var y = this.startY_ + e.screenY - this.startScreenY_;
148
149 // The position of the item is relative to #apps so we need to
150 // subtract that when calculating the allowed position.
151 x = Math.max(x, -rect.left);
152 x = Math.min(x, document.body.clientWidth - rect.left -
153 dragItem.offsetWidth - 2);
154
155 // The shadow is 2px
156 y = Math.max(-rect.top, y);
157 y = Math.min(y, document.body.clientHeight - rect.top -
158 dragItem.offsetHeight - 2);
159
160 // Override right in case of RTL.
161 dragItem.style.left = x + 'px';
162 dragItem.style.top = y + 'px';
163 }
164 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698