Chromium Code Reviews| 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} |
|
Dan Beam
2014/09/23 02:46:55
nit: ?Function
Vitaly Pavlenko
2014/09/23 22:20:55
Done.
| |
| 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/23 02:46:56
i think for now it'd probably be better to do:
Vitaly Pavlenko
2014/09/23 22:20:55
Nah, it doesn't work: at the time when the top of
| |
| 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 |