OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 cr.define('dnd', function() { | 5 cr.define('dnd', function() { |
6 'use strict'; | 6 'use strict'; |
7 | 7 |
8 /** @const */ var BookmarkList = bmm.BookmarkList; | 8 /** @const */ var BookmarkList = bmm.BookmarkList; |
9 /** @const */ var ListItem = cr.ui.ListItem; | 9 /** @const */ var ListItem = cr.ui.ListItem; |
10 /** @const */ var TreeItem = cr.ui.TreeItem; | 10 /** @const */ var TreeItem = cr.ui.TreeItem; |
(...skipping 29 matching lines...) Expand all Loading... | |
40 | 40 |
41 /** | 41 /** |
42 * The element that had a style applied it to indicate the drop location. | 42 * The element that had a style applied it to indicate the drop location. |
43 * This is used to easily remove the style when necessary. | 43 * This is used to easily remove the style when necessary. |
44 * @type {Element} | 44 * @type {Element} |
45 */ | 45 */ |
46 var lastIndicatorElement; | 46 var lastIndicatorElement; |
47 | 47 |
48 /** | 48 /** |
49 * The style that was applied to indicate the drop location. | 49 * The style that was applied to indicate the drop location. |
50 * @type {string} | 50 * @type {?string} |
51 */ | 51 */ |
52 var lastIndicatorClassName; | 52 var lastIndicatorClassName; |
53 | 53 |
54 var dropIndicator = { | 54 var dropIndicator = { |
55 /** | 55 /** |
56 * Applies the drop indicator style on the target element and stores that | 56 * Applies the drop indicator style on the target element and stores that |
57 * information to easily remove the style in the future. | 57 * information to easily remove the style in the future. |
58 */ | 58 */ |
59 addDropIndicatorStyle: function(indicatorElement, position) { | 59 addDropIndicatorStyle: function(indicatorElement, position) { |
60 var indicatorStyleName = position == DropPosition.ABOVE ? 'drag-above' : | 60 var indicatorStyleName = position == DropPosition.ABOVE ? 'drag-above' : |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
187 return dragData && dragData.elements.some(function(node) { | 187 return dragData && dragData.elements.some(function(node) { |
188 var dragFolder = bmm.treeLookup[node.id]; | 188 var dragFolder = bmm.treeLookup[node.id]; |
189 var dragFolderNode = dragFolder && dragFolder.bookmarkNode; | 189 var dragFolderNode = dragFolder && dragFolder.bookmarkNode; |
190 return dragFolderNode && bmm.contains(dragFolderNode, bookmarkNode); | 190 return dragFolderNode && bmm.contains(dragFolderNode, bookmarkNode); |
191 }); | 191 }); |
192 } | 192 } |
193 }; | 193 }; |
194 | 194 |
195 /** | 195 /** |
196 * External function to select folders or bookmarks after a drop action. | 196 * External function to select folders or bookmarks after a drop action. |
197 * @type {function} | 197 * @type {?Function} |
198 */ | 198 */ |
199 var selectItemsAfterUserAction = null; | 199 var selectItemsAfterUserAction = null; |
200 | 200 |
201 function getBookmarkElement(el) { | 201 function getBookmarkElement(el) { |
202 while (el && !el.bookmarkNode) { | 202 while (el && !el.bookmarkNode) { |
203 el = el.parentNode; | 203 el = el.parentNode; |
204 } | 204 } |
205 return el; | 205 return el; |
206 } | 206 } |
207 | 207 |
208 // If we are over the list and the list is showing search result, we cannot | 208 // If we are over the list and the list is showing search result, we cannot |
209 // drop. | 209 // drop. |
210 function isOverSearch(overElement) { | 210 function isOverSearch(overElement) { |
211 return list.isSearch() && list.contains(overElement); | 211 return $('list').isSearch() && $('list').contains(overElement); |
Dan Beam
2014/09/25 04:27:18
can you use bmm.list instead?
Vitaly Pavlenko
2014/09/25 15:37:15
Done.
| |
212 } | 212 } |
213 | 213 |
214 /** | 214 /** |
215 * Determines the valid drop positions for the given target element. | 215 * Determines the valid drop positions for the given target element. |
216 * @param {!HTMLElement} overElement The element that we are currently | 216 * @param {!HTMLElement} overElement The element that we are currently |
217 * dragging over. | 217 * dragging over. |
218 * @return {DropPosition} An bit field enumeration of valid drop locations. | 218 * @return {DropPosition} An bit field enumeration of valid drop locations. |
219 */ | 219 */ |
220 function calculateValidDropTargets(overElement) { | 220 function calculateValidDropTargets(overElement) { |
221 // Don't allow dropping if there is an ephemeral item being edited. | 221 // Don't allow dropping if there is an ephemeral item being edited. |
222 if (list.hasEphemeral()) | 222 if ($('list').hasEphemeral()) |
223 return DropPosition.NONE; | 223 return DropPosition.NONE; |
224 | 224 |
225 if (!dragInfo.isDragValid() || isOverSearch(overElement)) | 225 if (!dragInfo.isDragValid() || isOverSearch(overElement)) |
226 return DropPosition.NONE; | 226 return DropPosition.NONE; |
227 | 227 |
228 if (dragInfo.isSameProfile() && | 228 if (dragInfo.isSameProfile() && |
229 (dragInfo.isDraggingBookmark(overElement.bookmarkNode.id) || | 229 (dragInfo.isDraggingBookmark(overElement.bookmarkNode.id) || |
230 dragInfo.isDraggingFolderToDescendant(overElement.bookmarkNode))) { | 230 dragInfo.isDraggingFolderToDescendant(overElement.bookmarkNode))) { |
231 return DropPosition.NONE; | 231 return DropPosition.NONE; |
232 } | 232 } |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
295 if (!bmm.isFolder(overElement.bookmarkNode)) | 295 if (!bmm.isFolder(overElement.bookmarkNode)) |
296 return false; | 296 return false; |
297 | 297 |
298 if (!dragInfo.isSameProfile()) | 298 if (!dragInfo.isSameProfile()) |
299 return true; | 299 return true; |
300 | 300 |
301 if (overElement instanceof BookmarkList) { | 301 if (overElement instanceof BookmarkList) { |
302 // We are trying to drop an item past the last item. This is | 302 // We are trying to drop an item past the last item. This is |
303 // only allowed if dragged item is different from the last item | 303 // only allowed if dragged item is different from the last item |
304 // in the list. | 304 // in the list. |
305 var listItems = list.items; | 305 var listItems = $('list').items; |
306 var len = listItems.length; | 306 var len = listItems.length; |
307 if (!len || !dragInfo.isDraggingBookmark(listItems[len - 1].bookmarkId)) | 307 if (!len || !dragInfo.isDraggingBookmark(listItems[len - 1].bookmarkId)) |
308 return true; | 308 return true; |
309 } | 309 } |
310 | 310 |
311 return !dragInfo.isDraggingChildBookmark(overElement.bookmarkNode.id); | 311 return !dragInfo.isDraggingChildBookmark(overElement.bookmarkNode.id); |
312 } | 312 } |
313 | 313 |
314 /** | 314 /** |
315 * Callback for the dragstart event. | 315 * Callback for the dragstart event. |
(...skipping 10 matching lines...) Expand all Loading... | |
326 draggedNodes = target.parentNode.selectedItems; | 326 draggedNodes = target.parentNode.selectedItems; |
327 } else if (target instanceof TreeItem) { | 327 } else if (target instanceof TreeItem) { |
328 draggedNodes.push(target.bookmarkNode); | 328 draggedNodes.push(target.bookmarkNode); |
329 } | 329 } |
330 | 330 |
331 // We manage starting the drag by using the extension API. | 331 // We manage starting the drag by using the extension API. |
332 e.preventDefault(); | 332 e.preventDefault(); |
333 | 333 |
334 // Do not allow dragging if there is an ephemeral item being edited at the | 334 // Do not allow dragging if there is an ephemeral item being edited at the |
335 // moment. | 335 // moment. |
336 if (list.hasEphemeral()) | 336 if ($('list').hasEphemeral()) |
337 return; | 337 return; |
338 | 338 |
339 if (draggedNodes.length) { | 339 if (draggedNodes.length) { |
340 // If we are dragging a single link, we can do the *Link* effect. | 340 // If we are dragging a single link, we can do the *Link* effect. |
341 // Otherwise, we only allow copy and move. | 341 // Otherwise, we only allow copy and move. |
342 e.dataTransfer.effectAllowed = draggedNodes.length == 1 && | 342 e.dataTransfer.effectAllowed = draggedNodes.length == 1 && |
343 !bmm.isFolder(draggedNodes[0]) ? 'copyMoveLink' : 'copyMove'; | 343 !bmm.isFolder(draggedNodes[0]) ? 'copyMoveLink' : 'copyMove'; |
344 | 344 |
345 chrome.bookmarkManagerPrivate.startDrag(draggedNodes.map(function(node) { | 345 chrome.bookmarkManagerPrivate.startDrag(draggedNodes.map(function(node) { |
346 return node.id; | 346 return node.id; |
(...skipping 17 matching lines...) Expand all Loading... | |
364 e.preventDefault(); | 364 e.preventDefault(); |
365 | 365 |
366 // Set to none. This will get set to something if we can do the drop. | 366 // Set to none. This will get set to something if we can do the drop. |
367 e.dataTransfer.dropEffect = 'none'; | 367 e.dataTransfer.dropEffect = 'none'; |
368 } | 368 } |
369 | 369 |
370 if (!dragInfo.isDragValid()) | 370 if (!dragInfo.isDragValid()) |
371 return; | 371 return; |
372 | 372 |
373 var overElement = getBookmarkElement(e.target) || | 373 var overElement = getBookmarkElement(e.target) || |
374 (e.target == list ? list : null); | 374 (e.target == $('list') ? $('list') : null); |
375 if (!overElement) | 375 if (!overElement) |
376 return; | 376 return; |
377 | 377 |
378 updateAutoExpander(e.timeStamp, overElement); | 378 updateAutoExpander(e.timeStamp, overElement); |
379 | 379 |
380 var canDropInfo = calculateValidDropTargets(overElement); | 380 var canDropInfo = calculateValidDropTargets(overElement); |
381 if (canDropInfo == DropPosition.NONE) | 381 if (canDropInfo == DropPosition.NONE) |
382 return; | 382 return; |
383 | 383 |
384 // Now we know that we can drop. Determine if we will drop above, on or | 384 // Now we know that we can drop. Determine if we will drop above, on or |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
443 index: -1, | 443 index: -1, |
444 relatedIndex: -1 | 444 relatedIndex: -1 |
445 }; | 445 }; |
446 | 446 |
447 // Try to find the index in the dataModel so we don't have to always keep | 447 // Try to find the index in the dataModel so we don't have to always keep |
448 // the index for the list items up to date. | 448 // the index for the list items up to date. |
449 var overElement = getBookmarkElement(eventTarget); | 449 var overElement = getBookmarkElement(eventTarget); |
450 if (overElement instanceof ListItem) { | 450 if (overElement instanceof ListItem) { |
451 dropInfoResult.relatedIndex = | 451 dropInfoResult.relatedIndex = |
452 overElement.parentNode.dataModel.indexOf(relatedNode); | 452 overElement.parentNode.dataModel.indexOf(relatedNode); |
453 dropInfoResult.selectTarget = list; | 453 dropInfoResult.selectTarget = $('list'); |
454 } else if (overElement instanceof BookmarkList) { | 454 } else if (overElement instanceof BookmarkList) { |
455 dropInfoResult.relatedIndex = overElement.dataModel.length - 1; | 455 dropInfoResult.relatedIndex = overElement.dataModel.length - 1; |
456 dropInfoResult.selectTarget = list; | 456 dropInfoResult.selectTarget = $('list'); |
457 } else { | 457 } else { |
458 // Tree | 458 // Tree |
459 dropInfoResult.relatedIndex = relatedNode.index; | 459 dropInfoResult.relatedIndex = relatedNode.index; |
460 dropInfoResult.selectTarget = tree; | 460 dropInfoResult.selectTarget = $('tree'); |
461 dropInfoResult.selectedTreeId = | 461 dropInfoResult.selectedTreeId = |
462 tree.selectedItem ? tree.selectedItem.bookmarkId : null; | 462 $('tree').selectedItem ? $('tree').selectedItem.bookmarkId : null; |
463 } | 463 } |
464 | 464 |
465 if (dropPos == DropPosition.ABOVE) | 465 if (dropPos == DropPosition.ABOVE) |
466 dropInfoResult.index = dropInfoResult.relatedIndex; | 466 dropInfoResult.index = dropInfoResult.relatedIndex; |
467 else if (dropPos == DropPosition.BELOW) | 467 else if (dropPos == DropPosition.BELOW) |
468 dropInfoResult.index = dropInfoResult.relatedIndex + 1; | 468 dropInfoResult.index = dropInfoResult.relatedIndex + 1; |
469 | 469 |
470 return dropInfoResult; | 470 return dropInfoResult; |
471 } | 471 } |
472 | 472 |
(...skipping 28 matching lines...) Expand all Loading... | |
501 currentTouchTarget = null; | 501 currentTouchTarget = null; |
502 } | 502 } |
503 | 503 |
504 function clearDragData() { | 504 function clearDragData() { |
505 dragInfo.clearDragData(); | 505 dragInfo.clearDragData(); |
506 dropDestination = null; | 506 dropDestination = null; |
507 } | 507 } |
508 | 508 |
509 function init(selectItemsAfterUserActionFunction) { | 509 function init(selectItemsAfterUserActionFunction) { |
510 function deferredClearData() { | 510 function deferredClearData() { |
511 setTimeout(clearDragData); | 511 setTimeout(clearDragData, 0); |
512 } | 512 } |
513 | 513 |
514 selectItemsAfterUserAction = selectItemsAfterUserActionFunction; | 514 selectItemsAfterUserAction = selectItemsAfterUserActionFunction; |
515 | 515 |
516 document.addEventListener('dragstart', handleDragStart); | 516 document.addEventListener('dragstart', handleDragStart); |
517 document.addEventListener('dragenter', handleDragEnter); | 517 document.addEventListener('dragenter', handleDragEnter); |
518 document.addEventListener('dragover', handleDragOver); | 518 document.addEventListener('dragover', handleDragOver); |
519 document.addEventListener('dragleave', handleDragLeave); | 519 document.addEventListener('dragleave', handleDragLeave); |
520 document.addEventListener('drop', handleDrop); | 520 document.addEventListener('drop', handleDrop); |
521 document.addEventListener('dragend', deferredClearData); | 521 document.addEventListener('dragend', deferredClearData); |
522 document.addEventListener('mouseup', deferredClearData); | 522 document.addEventListener('mouseup', deferredClearData); |
523 document.addEventListener('mousedown', clearCurrentTouchTarget); | 523 document.addEventListener('mousedown', clearCurrentTouchTarget); |
524 document.addEventListener('touchcancel', clearCurrentTouchTarget); | 524 document.addEventListener('touchcancel', clearCurrentTouchTarget); |
525 document.addEventListener('touchend', clearCurrentTouchTarget); | 525 document.addEventListener('touchend', clearCurrentTouchTarget); |
526 document.addEventListener('touchstart', setCurrentTouchTarget); | 526 document.addEventListener('touchstart', setCurrentTouchTarget); |
527 | 527 |
528 chrome.bookmarkManagerPrivate.onDragEnter.addListener( | 528 chrome.bookmarkManagerPrivate.onDragEnter.addListener( |
529 dragInfo.handleChromeDragEnter); | 529 dragInfo.handleChromeDragEnter); |
530 chrome.bookmarkManagerPrivate.onDragLeave.addListener(deferredClearData); | 530 chrome.bookmarkManagerPrivate.onDragLeave.addListener(deferredClearData); |
531 chrome.bookmarkManagerPrivate.onDrop.addListener(deferredClearData); | 531 chrome.bookmarkManagerPrivate.onDrop.addListener(deferredClearData); |
532 } | 532 } |
533 return {init: init}; | 533 return {init: init}; |
534 }); | 534 }); |
OLD | NEW |