Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
|
Aaron Boodman
2011/01/22 23:42:57
Seems like this file should be called drag_drop_co
jstritar
2011/01/24 01:00:42
Done.
| |
| 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 // dimensions --> | |
| 16 // property that specifies the dimensions of the items | |
| 17 // The object should contain the following properties: | |
| 18 // itemHeight, itemWidth, marginWidth, marginHeight, borderWidth | |
|
Aaron Boodman
2011/01/22 23:42:57
Why does this class care about marginWidth/height
jstritar
2011/01/24 01:00:42
I removed the dependency on the dimensions.
| |
| 19 // | |
| 20 // getItem(e) --> | |
| 21 // get's the item that is under the mouse event |e| | |
| 22 // | |
| 23 // canDropOn(position) --> | |
| 24 // returns true if the position index is a valid place to drop an item | |
| 25 // | |
| 26 // setDragPlaceholder(position) --> | |
| 27 // tells the delegate that the dragged item is currently above | |
| 28 // |position| | |
| 29 // | |
| 30 // saveDrag() --> | |
| 31 // tells the delegate that the drag is done. move the item to the | |
| 32 // position last specified by setDragPlaceholder. (e.g., commit changes) | |
| 33 // | |
| 34 | |
| 35 function DragAndDropController(delegate) { | |
| 36 this.delegate = delegate; | |
|
Aaron Boodman
2011/01/22 23:42:57
this.delegate_ ?
jstritar
2011/01/24 01:00:42
Done.
| |
| 37 | |
| 38 this.installHandlers_(); | |
| 39 } | |
| 40 | |
| 41 DragAndDropController.prototype = { | |
| 42 startX_: 0, | |
| 43 startY_: 0, | |
| 44 startScreenX_: 0, | |
| 45 startScreenY_: 0, | |
| 46 | |
| 47 installHandlers_: function() { | |
| 48 var el = this.delegate.dragContainer; | |
| 49 el.addEventListener('dragstart', this.handleDragStart_.bind(this)); | |
| 50 el.addEventListener('dragenter', this.handleDragEnter_.bind(this)); | |
| 51 el.addEventListener('dragover', this.handleDragOver_.bind(this)); | |
| 52 el.addEventListener('dragleave', this.handleDragLeave_.bind(this)); | |
| 53 el.addEventListener('drop', this.handleDrop_.bind(this)); | |
| 54 el.addEventListener('dragend', this.handleDragEnd_.bind(this)); | |
| 55 el.addEventListener('drag', this.handleDrag_.bind(this)); | |
| 56 el.addEventListener('mousedown', this.handleMouseDown_.bind(this)); | |
| 57 }, | |
| 58 | |
| 59 isDragging: function() { | |
| 60 return !!this.delegate.dragItem; | |
|
Aaron Boodman
2011/01/22 23:42:57
Nit: prefer Boolean(this.delegate.dragItem) or thi
jstritar
2011/01/24 01:00:42
I realized I wasn't using this method, so I yanked
| |
| 61 }, | |
| 62 | |
| 63 getIndexAt_: function(e) { | |
|
Aaron Boodman
2011/01/22 23:42:57
Design nit: I think that knowledge of layout shoul
jstritar
2011/01/24 01:00:42
Great idea-- I think that's what felt off about th
| |
| 64 var del = this.delegate; | |
|
Aaron Boodman
2011/01/22 23:42:57
Careful with your abbreviations again. Since deleg
jstritar
2011/01/24 01:00:42
Done. Cleaned this up throughout the class.
| |
| 65 var el = del.dragContainer; | |
|
Aaron Boodman
2011/01/22 23:42:57
This variable is only used once, might as well jus
jstritar
2011/01/24 01:00:42
Done.
| |
| 66 var rect = el.getBoundingClientRect(); | |
| 67 var d = del.dimensions; | |
| 68 var availableWidth = el.offsetWidth; | |
| 69 | |
| 70 var clientX = e.clientX + window.scrollX - rect.left; | |
| 71 var clientY = e.clientY + window.scrollY - rect.top; | |
| 72 | |
| 73 var w = d.itemWidth + 2 * d.borderWidth + 2 * d.marginWidth; | |
| 74 var h = d.itemHeight + 2 * d.borderWidth + 2 * d.marginHeight; | |
| 75 | |
| 76 var rtl = isRtl(); | |
| 77 if (rtl) | |
| 78 clientX = availableWidth - clientX; | |
| 79 | |
| 80 var row = Math.floor(clientY / h); | |
| 81 var col = Math.floor(clientX / w); | |
| 82 var index = Math.floor(availableWidth / w) * row + col; | |
| 83 | |
| 84 return index; | |
| 85 }, | |
| 86 | |
| 87 // Listen to mousedown to get the relative position of the cursor when | |
| 88 // starting drag and drop. | |
| 89 handleMouseDown_: function(e) { | |
| 90 var item = this.delegate.getItem(e); | |
| 91 if (item) { | |
|
Aaron Boodman
2011/01/22 23:42:57
Invert check and return early. Multiple places in
jstritar
2011/01/24 01:00:42
Done.
| |
| 92 this.startX_ = item.offsetLeft; | |
| 93 this.startY_ = item.offsetTop; | |
| 94 this.startScreenX_ = e.screenX; | |
| 95 this.startScreenY_ = e.screenY; | |
| 96 | |
| 97 // We don't want to focus the item on mousedown. However, to prevent | |
| 98 // focus one has to call preventDefault but this also prevents the drag | |
| 99 // and drop (sigh) so we only prevent it when the user is not doing a | |
| 100 // left mouse button drag. | |
| 101 if (e.button != 0) // LEFT | |
| 102 e.preventDefault(); | |
| 103 } | |
| 104 }, | |
| 105 | |
| 106 handleDragStart_: function(e) { | |
| 107 var item = this.delegate.getItem(e); | |
| 108 if (item) { | |
| 109 // Don't set data since HTML5 does not allow setting the name for | |
| 110 // url-list. Instead, we just rely on the dragging of link behavior. | |
| 111 this.delegate.dragItem = item; | |
| 112 item.classList.add('dragging'); | |
| 113 item.style.zIndex = 2; | |
| 114 | |
| 115 e.dataTransfer.effectAllowed = 'copyLinkMove'; | |
| 116 } | |
| 117 }, | |
| 118 | |
| 119 handleDragEnter_: function(e) { | |
| 120 if (this.delegate.canDropOn(this.getIndexAt_(e))) | |
| 121 e.preventDefault(); | |
| 122 }, | |
| 123 | |
| 124 handleDragOver_: function(e) { | |
| 125 var del = this.delegate; | |
| 126 var position = this.getIndexAt_(e); | |
| 127 if (del.canDropOn(position)) { | |
| 128 del.setDragPlaceholder(position); | |
| 129 e.preventDefault(); | |
| 130 e.dataTransfer.dropEffect = 'move'; | |
| 131 } | |
| 132 }, | |
| 133 | |
| 134 handleDragLeave_: function(e) { | |
| 135 if (this.delegate.canDropOn(this.getIndexAt_(e))) | |
| 136 e.preventDefault(); | |
| 137 }, | |
| 138 | |
| 139 handleDrop_: function(e) { | |
| 140 var del = this.delegate; | |
| 141 var dragItem = del.dragItem; | |
| 142 if (dragItem) { | |
| 143 dragItem.classList.remove('dragging'); | |
| 144 del.dragItem = null; | |
| 145 del.invalidate(); | |
|
Aaron Boodman
2011/01/22 23:42:57
Seems like these two methods should be del.saveDra
jstritar
2011/01/24 01:00:42
Done.
| |
| 146 del.layout(); | |
| 147 | |
| 148 setTimeout(function() { | |
| 149 dragItem.style.pointerEvents = ''; | |
| 150 dragItem.style.zIndex = ''; | |
| 151 }, this.delegate.transitionsDuration + 10); | |
| 152 } | |
| 153 }, | |
| 154 | |
| 155 handleDragEnd_: function(e) { | |
| 156 return this.handleDrop_(e); | |
| 157 }, | |
| 158 | |
| 159 handleDrag_: function(e) { | |
| 160 // Moves the drag item making sure that it is not displayed outside the | |
| 161 // browser viewport. | |
| 162 var del = this.delegate; | |
| 163 var dragItem = del.dragItem; | |
| 164 var rect = del.dragContainer.getBoundingClientRect(); | |
| 165 | |
| 166 var x = this.startX_ + e.screenX - this.startScreenX_; | |
| 167 var y = this.startY_ + e.screenY - this.startScreenY_; | |
| 168 | |
| 169 // The position of the item is relative to #apps so we need to | |
| 170 // subtract that when calculating the allowed position. | |
| 171 x = Math.max(x, -rect.left); | |
| 172 x = Math.min(x, document.body.clientWidth - rect.left - | |
| 173 dragItem.offsetWidth - 2); | |
| 174 | |
| 175 // The shadow is 2px | |
| 176 y = Math.max(-rect.top, y); | |
| 177 y = Math.min(y, document.body.clientHeight - rect.top - | |
| 178 dragItem.offsetHeight - 2); | |
| 179 | |
| 180 // Override right in case of RTL. | |
| 181 dragItem.style.right = 'auto'; | |
|
Aaron Boodman
2011/01/22 23:42:57
Don't think this line is needed.
jstritar
2011/01/24 01:00:42
Done.
| |
| 182 dragItem.style.left = x + 'px'; | |
| 183 dragItem.style.top = y + 'px'; | |
| 184 dragItem.style.zIndex = 2; | |
| 185 } | |
| 186 }; | |
| OLD | NEW |