OLD | NEW |
---|---|
(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, | |
tsergeant
2017/03/27 06:49:24
nit: these should align
calamity
2017/03/28 04:15:03
Obviously, it's because I forgot the semicolon on
tsergeant
2017/03/28 23:52:22
That's... interesting behavior.
| |
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 }); | |
OLD | NEW |