OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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('options.browser_options', function() { | 5 cr.define('options.browser_options', function() { |
6 const AutocompleteList = options.AutocompleteList; | 6 const AutocompleteList = options.AutocompleteList; |
7 const InlineEditableItem = options.InlineEditableItem; | 7 const InlineEditableItem = options.InlineEditableItem; |
8 const InlineEditableItemList = options.InlineEditableItemList; | 8 const InlineEditableItemList = options.InlineEditableItemList; |
9 | 9 |
10 /** | 10 /** |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 | 73 |
74 this.addEventListener('commitedit', this.onEditCommitted_); | 74 this.addEventListener('commitedit', this.onEditCommitted_); |
75 | 75 |
76 var self = this; | 76 var self = this; |
77 urlField.addEventListener('focus', function(event) { | 77 urlField.addEventListener('focus', function(event) { |
78 self.parentNode.autocompleteList.attachToInput(urlField); | 78 self.parentNode.autocompleteList.attachToInput(urlField); |
79 }); | 79 }); |
80 urlField.addEventListener('blur', function(event) { | 80 urlField.addEventListener('blur', function(event) { |
81 self.parentNode.autocompleteList.detach(); | 81 self.parentNode.autocompleteList.detach(); |
82 }); | 82 }); |
| 83 this.draggable = true; |
83 }, | 84 }, |
84 | 85 |
85 /** @inheritDoc */ | 86 /** @inheritDoc */ |
86 get currentInputIsValid() { | 87 get currentInputIsValid() { |
87 return this.urlField_.validity.valid; | 88 return this.urlField_.validity.valid; |
88 }, | 89 }, |
89 | 90 |
90 /** @inheritDoc */ | 91 /** @inheritDoc */ |
91 get hasBeenEdited() { | 92 get hasBeenEdited() { |
92 return this.urlField_.value != this.pageInfo_['url']; | 93 return this.urlField_.value != this.pageInfo_['url']; |
(...skipping 17 matching lines...) Expand all Loading... |
110 | 111 |
111 StartupPageList.prototype = { | 112 StartupPageList.prototype = { |
112 __proto__: InlineEditableItemList.prototype, | 113 __proto__: InlineEditableItemList.prototype, |
113 | 114 |
114 /** | 115 /** |
115 * An autocomplete suggestion list for URL editing. | 116 * An autocomplete suggestion list for URL editing. |
116 * @type {AutocompleteList} | 117 * @type {AutocompleteList} |
117 */ | 118 */ |
118 autocompleteList: null, | 119 autocompleteList: null, |
119 | 120 |
| 121 /** |
| 122 * The drop position information: "below" or "above". |
| 123 */ |
| 124 dropPos: null, |
| 125 |
| 126 /** @inheritDoc */ |
| 127 decorate: function() { |
| 128 InlineEditableItemList.prototype.decorate.call(this); |
| 129 |
| 130 // Listen to drag and drop events. |
| 131 this.addEventListener('dragstart', this.handleDragStart_.bind(this)); |
| 132 this.addEventListener('dragenter', this.handleDragEnter_.bind(this)); |
| 133 this.addEventListener('dragover', this.handleDragOver_.bind(this)); |
| 134 this.addEventListener('drop', this.handleDrop_.bind(this)); |
| 135 this.addEventListener('dragleave', this.handleDragLeave_.bind(this)); |
| 136 }, |
| 137 |
120 /** @inheritDoc */ | 138 /** @inheritDoc */ |
121 createItem: function(pageInfo) { | 139 createItem: function(pageInfo) { |
122 var item = new StartupPageListItem(pageInfo); | 140 var item = new StartupPageListItem(pageInfo); |
123 item.urlField_.disabled = this.disabled; | 141 item.urlField_.disabled = this.disabled; |
124 return item; | 142 return item; |
125 }, | 143 }, |
126 | 144 |
127 /** @inheritDoc */ | 145 /** @inheritDoc */ |
128 deleteItemAtIndex: function(index) { | 146 deleteItemAtIndex: function(index) { |
129 chrome.send('removeStartupPages', [String(index)]); | 147 chrome.send('removeStartupPages', [String(index)]); |
130 }, | 148 }, |
| 149 |
| 150 /* |
| 151 * Computes the target item of drop event. |
| 152 * @param {Event} e The drop or dragover event. |
| 153 * @private |
| 154 */ |
| 155 getTargetFromDropEvent_ : function(e) { |
| 156 var target = e.target; |
| 157 // e.target may be an inner element of the list item |
| 158 while (target != null && !(target instanceof StartupPageListItem)) { |
| 159 target = target.parentNode; |
| 160 } |
| 161 return target; |
| 162 }, |
| 163 |
| 164 /* |
| 165 * Handles the dragstart event. |
| 166 * @param {Event} e The dragstart event. |
| 167 * @private |
| 168 */ |
| 169 handleDragStart_: function(e) { |
| 170 var target = e.target; |
| 171 // StartupPageListItem should be the only draggable element type in the |
| 172 // page but let's make sure. |
| 173 if (target instanceof StartupPageListItem) { |
| 174 this.draggedItem = target; |
| 175 this.draggedItem.editable = false; |
| 176 e.dataTransfer.effectAllowed = 'move'; |
| 177 // We need to put some kind of data in the drag or it will be |
| 178 // ignored. Use the URL in case the user drags to a text field or the |
| 179 // desktop. |
| 180 e.dataTransfer.setData('text/plain', target.urlField_.value); |
| 181 } |
| 182 }, |
| 183 |
| 184 /* |
| 185 * Handles the dragenter event. |
| 186 * @param {Event} e The dragenter event. |
| 187 * @private |
| 188 */ |
| 189 handleDragEnter_: function(e) { |
| 190 e.preventDefault(); |
| 191 }, |
| 192 |
| 193 /* |
| 194 * Handles the dragover event. |
| 195 * @param {Event} e The dragover event. |
| 196 * @private |
| 197 */ |
| 198 handleDragOver_: function(e) { |
| 199 var dropTarget = this.getTargetFromDropEvent_(e); |
| 200 // Determines whether the drop target is to accept the drop. |
| 201 // The drop is only successful on another StartupPageListItem. |
| 202 if (!(dropTarget instanceof StartupPageListItem) || |
| 203 dropTarget == this.draggedItem || dropTarget.isPlaceholder) { |
| 204 this.hideDropMarker_(); |
| 205 return; |
| 206 } |
| 207 // Compute the drop postion. Should we move the dragged item to |
| 208 // below or above the drop target? |
| 209 var rect = dropTarget.getBoundingClientRect(); |
| 210 var dy = e.clientY - rect.top; |
| 211 var yRatio = dy / rect.height; |
| 212 var dropPos = yRatio <= .5 ? 'above' : 'below'; |
| 213 this.dropPos = dropPos; |
| 214 this.showDropMarker_(dropTarget, dropPos); |
| 215 e.preventDefault(); |
| 216 }, |
| 217 |
| 218 /* |
| 219 * Handles the drop event. |
| 220 * @param {Event} e The drop event. |
| 221 * @private |
| 222 */ |
| 223 handleDrop_: function(e) { |
| 224 var dropTarget = this.getTargetFromDropEvent_(e); |
| 225 this.hideDropMarker_(); |
| 226 |
| 227 // Insert the selection at the new position. |
| 228 var newIndex = this.dataModel.indexOf(dropTarget.pageInfo_); |
| 229 if (this.dropPos == 'below') |
| 230 newIndex += 1; |
| 231 |
| 232 var selected = this.selectionModel.selectedIndexes; |
| 233 var stringized_selected = []; |
| 234 for (var j = 0; j < selected.length; j++) |
| 235 stringized_selected.push(String(selected[j])); |
| 236 |
| 237 chrome.send('dragDropStartupPage', |
| 238 [String(newIndex), stringized_selected] ); |
| 239 }, |
| 240 |
| 241 /* |
| 242 * Handles the dragleave event. |
| 243 * @param {Event} e The dragleave event |
| 244 * @private |
| 245 */ |
| 246 handleDragLeave_ : function(e) { |
| 247 this.hideDropMarker_(); |
| 248 }, |
| 249 |
| 250 /* |
| 251 * Shows and positions the marker to indicate the drop target. |
| 252 * @param {HTMLElement} target The current target list item of drop |
| 253 * @param {string} pos 'below' or 'above' |
| 254 * @private |
| 255 */ |
| 256 showDropMarker_ : function(target, pos) { |
| 257 window.clearTimeout(this.hideDropMarkerTimer_); |
| 258 var marker = $('startupPagesListDropmarker'); |
| 259 var rect = target.getBoundingClientRect(); |
| 260 var markerHeight = 6; |
| 261 if (pos == 'above') { |
| 262 marker.style.top = (rect.top - markerHeight/2) + 'px'; |
| 263 } else { |
| 264 marker.style.top = (rect.bottom - markerHeight/2) + 'px'; |
| 265 } |
| 266 marker.style.width = rect.width + 'px'; |
| 267 marker.style.left = rect.left + 'px'; |
| 268 marker.style.display = 'block'; |
| 269 }, |
| 270 |
| 271 /* |
| 272 * Hides the drop marker. |
| 273 * @private |
| 274 */ |
| 275 hideDropMarker_ : function() { |
| 276 // Hide the marker in a timeout to reduce flickering as we move between |
| 277 // valid drop targets. |
| 278 window.clearTimeout(this.hideDropMarkerTimer_); |
| 279 this.hideDropMarkerTimer_ = window.setTimeout(function() { |
| 280 $('startupPagesListDropmarker').style.display = ''; |
| 281 }, 100); |
| 282 }, |
131 }; | 283 }; |
132 | 284 |
133 return { | 285 return { |
134 StartupPageList: StartupPageList | 286 StartupPageList: StartupPageList |
135 }; | 287 }; |
136 }); | 288 }); |
OLD | NEW |