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

Side by Side Diff: chrome/test/data/webui/md_bookmarks/dnd_manager_test.js

Issue 2746363013: [MD Bookmarks] Add a drag and drop indicator to bookmarks. (Closed)
Patch Set: fix nit Created 3 years, 8 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
OLDNEW
(Empty)
1 // Copyright 2017 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 suite('drag and drop', function() {
6 var app;
7 var list;
8 var sidebar;
9 var store;
10 var dndManager;
11 var draggedIds;
12
13 var DRAG_STYLE = {
14 NONE: 0,
15 ON: 1,
16 ABOVE: 2,
17 BELOW: 3,
18 };
19
20 function getFolderNode(id) {
21 var nodes = [sidebar];
22 var node;
23 while (nodes.length) {
24 node = nodes.pop();
25 if (node.itemId == id)
26 return node;
27
28 node.root.querySelectorAll('bookmarks-folder-node')
29 .forEach((x) => {nodes.unshift(x)});
30 }
31 }
32
33 function getListItem(id) {
34 var items = list.root.querySelectorAll('bookmarks-item');
35 for (var i = 0; i < items.length; i++) {
36 if (items[i].itemId == id)
37 return items[i];
38 }
39 }
40
41 function dispatchDragEvent(type, node, xy) {
42 xy = xy || MockInteractions.middleOfNode(node);
43 var props = {
44 bubbles: true,
45 cancelable: true,
46 clientX: xy.x,
47 clientY: xy.y,
48 // Make this a primary input.
49 buttons: 1,
50 };
51 var e = new DragEvent(type, props);
52 node.dispatchEvent(e);
53 }
54
55 function assertDragStyle(bookmarkElement, style) {
56 var dragStyles = {};
57 dragStyles[DRAG_STYLE.ON] = 'drag-on';
58 dragStyles[DRAG_STYLE.ABOVE] = 'drag-above';
59 dragStyles[DRAG_STYLE.BELOW] = 'drag-below';
60
61 var classList = bookmarkElement.getDropTarget().classList;
62 Object.keys(dragStyles).forEach(dragStyle => {
63 assertEquals(
64 dragStyle == style, classList.contains(dragStyles[dragStyle]),
65 dragStyles[dragStyle] + (dragStyle == style ? ' missing' : ' found') +
66 ' in classList ' + classList);
67 });
68 }
69
70 function createDragData(ids, sameProfile) {
71 return {
72 elements: ids.map(id => store.data.nodes[id]),
73 sameProfile: sameProfile == undefined ? true : sameProfile,
74 };
75 }
76
77 setup(function() {
78 store = new bookmarks.TestStore({
79 nodes: testTree(
80 createFolder(
81 '1',
82 [
83 createFolder(
84 '11',
85 [
86 createFolder(
87 '111',
88 [
89 createItem('1111'),
90 ]),
91 createFolder('112', []),
92 ]),
93 createItem('12'),
94 createItem('13'),
95 createFolder('14', []),
96 createFolder('15', []),
97 ]),
98 createFolder('2', [])),
99 selectedFolder: '1',
100 });
101 bookmarks.Store.instance_ = store;
102
103 chrome.bookmarkManagerPrivate.startDrag = function(nodes, isTouch) {
104 draggedIds = nodes;
105 };
106
107 app = document.createElement('bookmarks-app');
108 replaceBody(app);
109 list = app.$$('bookmarks-list');
110 sidebar = app.$$('bookmarks-sidebar');
111 dndManager = app.dndManager_;
112 dndManager.dropIndicator_.disableTimeoutForTesting();
113 Polymer.dom.flush();
114 });
115
116 test('dragInfo isDraggingFolderToDescendant', function() {
117 var dragInfo = new bookmarks.DragInfo();
118 var nodes = store.data.nodes;
119 dragInfo.handleChromeDragEnter(createDragData(['11']));
120 assertTrue(dragInfo.isDraggingFolderToDescendant('111', nodes));
121 assertFalse(dragInfo.isDraggingFolderToDescendant('1', nodes));
122 assertFalse(dragInfo.isDraggingFolderToDescendant('2', nodes));
123
124 dragInfo.handleChromeDragEnter(createDragData(['1']));
125 assertTrue(dragInfo.isDraggingFolderToDescendant('14', nodes));
126 assertTrue(dragInfo.isDraggingFolderToDescendant('111', nodes));
127 assertFalse(dragInfo.isDraggingFolderToDescendant('2', nodes));
128 });
129
130 test('drag in list', function() {
131 var dragElement = getListItem('13');
132 var dragTarget = getListItem('12');
133
134 dispatchDragEvent('dragstart', dragElement);
135 assertDeepEquals(['13'], draggedIds);
136 dndManager.dragInfo_.handleChromeDragEnter(createDragData(draggedIds));
137
138 // Bookmark items cannot be dragged onto other items.
139 dispatchDragEvent(
140 'dragover', dragTarget, MockInteractions.topLeftOfNode(dragTarget));
141 assertEquals(
142 DropPosition.ABOVE,
143 dndManager.calculateValidDropPositions_(dragTarget));
144 assertDragStyle(dragTarget, DRAG_STYLE.ABOVE);
145
146 dispatchDragEvent('dragleave', dragTarget);
147 assertDragStyle(dragTarget, DRAG_STYLE.NONE);
148
149 // Bookmark items can be dragged onto folders.
150 dragTarget = getListItem('11');
151 dispatchDragEvent('dragover', dragTarget);
152 assertEquals(
153 DropPosition.ON | DropPosition.ABOVE | DropPosition.BELOW,
154 dndManager.calculateValidDropPositions_(dragTarget));
155 assertDragStyle(dragTarget, DRAG_STYLE.ON);
156
157 // There are no valid drop locations for dragging an item onto itself.
158 assertEquals(
159 DropPosition.NONE,
160 dndManager.calculateValidDropPositions_(dragElement));
161 dispatchDragEvent('dragleave', dragTarget);
162 dispatchDragEvent('dragover', dragElement);
163
164 assertDragStyle(dragTarget, DRAG_STYLE.NONE);
165 assertDragStyle(dragElement, DRAG_STYLE.NONE);
166 });
167
168 test('reorder folder nodes', function() {
169 var dragElement = getFolderNode('112');
170 var dragTarget = getFolderNode('111');
171 dispatchDragEvent('dragstart', dragElement);
172 dndManager.dragInfo_.handleChromeDragEnter(createDragData(draggedIds));
173
174 assertEquals(
175 DropPosition.ON | DropPosition.ABOVE,
176 dndManager.calculateValidDropPositions_(dragTarget));
177
178 dispatchDragEvent(
179 'dragover', dragTarget, MockInteractions.topLeftOfNode(dragTarget));
180 assertDragStyle(dragTarget, DRAG_STYLE.ABOVE);
181 });
182
183 test('drag an item into a sidebar folder', function() {
184 var dragElement = getListItem('13');
185 var dragTarget = getFolderNode('2');
186 dispatchDragEvent('dragstart', dragElement);
187 dndManager.dragInfo_.handleChromeDragEnter(createDragData(draggedIds));
188
189 // Items can only be dragged onto sidebar folders, not above or below.
190 assertEquals(
191 DropPosition.ON, dndManager.calculateValidDropPositions_(dragTarget));
192
193 dispatchDragEvent('dragover', dragTarget);
194 assertDragStyle(dragTarget, DRAG_STYLE.ON);
195
196 // Items cannot be dragged onto their parent folders.
197 dragTarget = getFolderNode('1');
198 dispatchDragEvent('dragover', dragTarget);
199 assertDragStyle(dragTarget, DRAG_STYLE.NONE);
200 });
201
202 test('drag a folder into a descendant', function() {
203 var dragElement = getFolderNode('11');
204 var dragTarget = getFolderNode('112');
205
206 // Folders cannot be dragged into their descendants.
207 dispatchDragEvent('dragstart', dragElement);
208 dndManager.dragInfo_.handleChromeDragEnter(createDragData(draggedIds));
209 assertEquals(
210 DropPosition.NONE,
211 dndManager.calculateValidDropPositions_(dragTarget));
212
213 dispatchDragEvent('dragover', dragTarget);
214
215 assertDragStyle(dragTarget, DRAG_STYLE.NONE);
216 });
217
218 test('drag item into sidebar folder with descendants', function() {
219 var dragElement = getFolderNode('15');
220 var dragTarget = getFolderNode('11');
221 dispatchDragEvent('dragstart', dragElement);
222 dndManager.dragInfo_.handleChromeDragEnter(createDragData(draggedIds));
223
224 // Drags below an open folder are not allowed.
225 assertEquals(
226 DropPosition.ON | DropPosition.ABOVE,
227 dndManager.calculateValidDropPositions_(dragTarget));
228
229 dispatchDragEvent('dragover', dragTarget);
230
231 assertDragStyle(dragTarget, DRAG_STYLE.ON);
232
233 dispatchDragEvent('dragend', dragElement);
234 assertDragStyle(dragTarget, DRAG_STYLE.NONE);
235
236 store.data.closedFolders['11'] = true;
237
238 dispatchDragEvent('dragstart', dragElement);
239 dndManager.dragInfo_.handleChromeDragEnter(createDragData(draggedIds));
240
241 // Drags below a closed folder are allowed.
242 assertEquals(
243 DropPosition.ON | DropPosition.ABOVE | DropPosition.BELOW,
244 dndManager.calculateValidDropPositions_(dragTarget));
245 });
246
247 test('drag multiple list items', function() {
248 // Dragging multiple items.
249 store.data.selection.items = {'13': true, '15': true};
250 dispatchDragEvent('dragstart', getListItem('13'));
251 assertDeepEquals(['13', '15'], draggedIds);
252 dndManager.dragInfo_.handleChromeDragEnter(createDragData(draggedIds));
253
254 // The dragged items should not be allowed to be dragged around any selected
255 // item.
256 assertEquals(
257 DropPosition.NONE,
258 dndManager.calculateValidDropPositions_(getListItem('13')));
259 assertEquals(
260 DropPosition.ON,
261 dndManager.calculateValidDropPositions_(getListItem('14')));
262 assertEquals(
263 DropPosition.NONE,
264 dndManager.calculateValidDropPositions_(getListItem('15')));
265
266 // Dragging an unselected item should only drag the unselected item.
267 dispatchDragEvent('dragstart', getListItem('14'));
268 assertDeepEquals(['14'], draggedIds);
269
270 // Dragging a folder node should only drag the node.
271 dispatchDragEvent('dragstart', getListItem('11'));
272 assertDeepEquals(['11'], draggedIds);
273 });
274
275 test('bookmarks from different profiles', function() {
276 dndManager.dragInfo_.handleChromeDragEnter(createDragData(['11'], false));
277
278 // All positions should be allowed even with the same bookmark id if the
279 // drag element is from a different profile.
280 assertEquals(
281 DropPosition.ON | DropPosition.ABOVE | DropPosition.BELOW,
282 dndManager.calculateValidDropPositions_(getListItem('11')));
283
284 // Folders from other profiles should be able to be dragged into
285 // descendants in this profile.
286 assertEquals(
287 DropPosition.ON | DropPosition.ABOVE | DropPosition.BELOW,
288 dndManager.calculateValidDropPositions_(getFolderNode('112')));
289 });
290
291 test('drag from sidebar to list', function() {
292 var dragElement = getFolderNode('112');
293 var dragTarget = getListItem('13');
294
295 // Drag a folder onto the list.
296 dispatchDragEvent('dragstart', dragElement);
297 assertDeepEquals(['112'], draggedIds);
298 dndManager.dragInfo_.handleChromeDragEnter(createDragData(draggedIds));
299
300 dispatchDragEvent(
301 'dragover', dragTarget, MockInteractions.topLeftOfNode(dragTarget));
302 assertDragStyle(dragTarget, DRAG_STYLE.ABOVE);
303
304 dispatchDragEvent('dragend', dragTarget);
305
306 // Folders should not be able to dragged onto themselves in the list.
307 dndManager.dragInfo_.handleChromeDragEnter(createDragData(['11']));
308 assertEquals(
309 DropPosition.NONE,
310 dndManager.calculateValidDropPositions_(getListItem('11')));
311
312 // Ancestors should not be able to be dragged onto descendant
313 // displayed lists.
314 store.data.selectedFolder = '111';
315 store.notifyObservers();
316 Polymer.dom.flush();
317
318 dndManager.dragInfo_.handleChromeDragEnter(createDragData(['11']));
319 assertEquals(
320 DropPosition.NONE,
321 dndManager.calculateValidDropPositions_(getListItem('1111')));
322 });
323
324 test('drags with search', function() {
325 store.data.search.term = 'Asgore';
326 store.data.search.results = ['11', '13', '2'];
327 store.data.selectedFolder = null;
328 store.notifyObservers();
329
330 // Search results should not be able to be dragged onto, but can be dragged
331 // from.
332 dndManager.dragInfo_.handleChromeDragEnter(createDragData(['2']));
333 assertEquals(
334 DropPosition.NONE,
335 dndManager.calculateValidDropPositions_(getListItem('13')));
336
337 // Drags onto folders should work as per usual.
338 assertEquals(
339 DropPosition.ON | DropPosition.ABOVE | DropPosition.BELOW,
340 dndManager.calculateValidDropPositions_(getFolderNode('112')));
341 });
342 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698