Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(75)

Side by Side Diff: ui/webui/resources/js/cr/ui/list.js

Issue 2597013002: Run clang-format on ui/webui/resources (Closed)
Patch Set: remove cr_shared_menu.js Created 3 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 // require: array_data_model.js 5 // require: array_data_model.js
6 // require: list_selection_model.js 6 // require: list_selection_model.js
7 // require: list_selection_controller.js 7 // require: list_selection_controller.js
8 // require: list_item.js 8 // require: list_item.js
9 9
10 /** 10 /**
(...skipping 10 matching lines...) Expand all
21 * false if the mouseevent was generated over a border or a scrollbar. 21 * false if the mouseevent was generated over a border or a scrollbar.
22 * @param {!HTMLElement} el The element to test the event with. 22 * @param {!HTMLElement} el The element to test the event with.
23 * @param {!Event} e The mouse event. 23 * @param {!Event} e The mouse event.
24 * @return {boolean} Whether the mouse event was inside the viewport. 24 * @return {boolean} Whether the mouse event was inside the viewport.
25 */ 25 */
26 function inViewport(el, e) { 26 function inViewport(el, e) {
27 var rect = el.getBoundingClientRect(); 27 var rect = el.getBoundingClientRect();
28 var x = e.clientX; 28 var x = e.clientX;
29 var y = e.clientY; 29 var y = e.clientY;
30 return x >= rect.left + el.clientLeft && 30 return x >= rect.left + el.clientLeft &&
31 x < rect.left + el.clientLeft + el.clientWidth && 31 x < rect.left + el.clientLeft + el.clientWidth &&
32 y >= rect.top + el.clientTop && 32 y >= rect.top + el.clientTop &&
33 y < rect.top + el.clientTop + el.clientHeight; 33 y < rect.top + el.clientTop + el.clientHeight;
34 } 34 }
35 35
36 function getComputedStyle(el) { 36 function getComputedStyle(el) {
37 return el.ownerDocument.defaultView.getComputedStyle(el); 37 return el.ownerDocument.defaultView.getComputedStyle(el);
38 } 38 }
39 39
40 /** 40 /**
41 * Creates a new list element. 41 * Creates a new list element.
42 * @param {Object=} opt_propertyBag Optional properties. 42 * @param {Object=} opt_propertyBag Optional properties.
43 * @constructor 43 * @constructor
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 * Function used to create grid items. 87 * Function used to create grid items.
88 * @type {function(new:cr.ui.ListItem, *)} 88 * @type {function(new:cr.ui.ListItem, *)}
89 * @private 89 * @private
90 */ 90 */
91 itemConstructor_: cr.ui.ListItem, 91 itemConstructor_: cr.ui.ListItem,
92 92
93 /** 93 /**
94 * Function used to create grid items. 94 * Function used to create grid items.
95 * @return {function(new:cr.ui.ListItem, *)} 95 * @return {function(new:cr.ui.ListItem, *)}
96 */ 96 */
97 get itemConstructor() { 97 get itemConstructor() { return this.itemConstructor_; },
98 return this.itemConstructor_;
99 },
100 set itemConstructor(func) { 98 set itemConstructor(func) {
101 if (func != this.itemConstructor_) { 99 if (func != this.itemConstructor_) {
102 this.itemConstructor_ = func; 100 this.itemConstructor_ = func;
103 this.cachedItems_ = {}; 101 this.cachedItems_ = {};
104 this.redraw(); 102 this.redraw();
105 } 103 }
106 }, 104 },
107 105
108 dataModel_: null, 106 dataModel_: null,
109 107
110 /** 108 /**
111 * The data model driving the list. 109 * The data model driving the list.
112 * @type {ArrayDataModel} 110 * @type {ArrayDataModel}
113 */ 111 */
114 set dataModel(dataModel) { 112 set dataModel(dataModel) {
115 if (this.dataModel_ == dataModel) 113 if (this.dataModel_ == dataModel)
116 return; 114 return;
117 115
118 if (!this.boundHandleDataModelPermuted_) { 116 if (!this.boundHandleDataModelPermuted_) {
119 this.boundHandleDataModelPermuted_ = 117 this.boundHandleDataModelPermuted_ =
120 this.handleDataModelPermuted_.bind(this); 118 this.handleDataModelPermuted_.bind(this);
121 this.boundHandleDataModelChange_ = 119 this.boundHandleDataModelChange_ =
122 this.handleDataModelChange_.bind(this); 120 this.handleDataModelChange_.bind(this);
123 } 121 }
124 122
125 if (this.dataModel_) { 123 if (this.dataModel_) {
126 this.dataModel_.removeEventListener( 124 this.dataModel_.removeEventListener(
127 'permuted', 125 'permuted', this.boundHandleDataModelPermuted_);
128 this.boundHandleDataModelPermuted_); 126 this.dataModel_.removeEventListener(
129 this.dataModel_.removeEventListener('change', 127 'change', this.boundHandleDataModelChange_);
130 this.boundHandleDataModelChange_);
131 } 128 }
132 129
133 this.dataModel_ = dataModel; 130 this.dataModel_ = dataModel;
134 131
135 this.cachedItems_ = {}; 132 this.cachedItems_ = {};
136 this.cachedItemHeights_ = {}; 133 this.cachedItemHeights_ = {};
137 this.selectionModel.clear(); 134 this.selectionModel.clear();
138 if (dataModel) 135 if (dataModel)
139 this.selectionModel.adjustLength(dataModel.length); 136 this.selectionModel.adjustLength(dataModel.length);
140 137
141 if (this.dataModel_) { 138 if (this.dataModel_) {
142 this.dataModel_.addEventListener( 139 this.dataModel_.addEventListener(
143 'permuted', 140 'permuted', this.boundHandleDataModelPermuted_);
144 this.boundHandleDataModelPermuted_); 141 this.dataModel_.addEventListener(
145 this.dataModel_.addEventListener('change', 142 'change', this.boundHandleDataModelChange_);
146 this.boundHandleDataModelChange_);
147 } 143 }
148 144
149 this.redraw(); 145 this.redraw();
150 this.onSetDataModelComplete(); 146 this.onSetDataModelComplete();
151 }, 147 },
152 148
153 get dataModel() { 149 get dataModel() { return this.dataModel_; },
154 return this.dataModel_;
155 },
156 150
157 /** 151 /**
158 * Override to be notified when |this.dataModel| is set. 152 * Override to be notified when |this.dataModel| is set.
159 * @protected 153 * @protected
160 */ 154 */
161 onSetDataModelComplete: function() { 155 onSetDataModelComplete: function() {},
162 },
163 156
164 /** 157 /**
165 * Cached item for measuring the default item size by measureItem(). 158 * Cached item for measuring the default item size by measureItem().
166 * @type {cr.ui.ListItem} 159 * @type {cr.ui.ListItem}
167 */ 160 */
168 cachedMeasuredItem_: null, 161 cachedMeasuredItem_: null,
169 162
170 /** 163 /**
171 * The selection model to use. 164 * The selection model to use.
172 * @type {cr.ui.ListSelectionModel} 165 * @type {cr.ui.ListSelectionModel}
173 */ 166 */
174 get selectionModel() { 167 get selectionModel() { return this.selectionModel_; },
175 return this.selectionModel_;
176 },
177 set selectionModel(sm) { 168 set selectionModel(sm) {
178 var oldSm = this.selectionModel_; 169 var oldSm = this.selectionModel_;
179 if (oldSm == sm) 170 if (oldSm == sm)
180 return; 171 return;
181 172
182 if (!this.boundHandleOnChange_) { 173 if (!this.boundHandleOnChange_) {
183 this.boundHandleOnChange_ = this.handleOnChange_.bind(this); 174 this.boundHandleOnChange_ = this.handleOnChange_.bind(this);
184 this.boundHandleLeadChange_ = this.handleLeadChange.bind(this); 175 this.boundHandleLeadChange_ = this.handleLeadChange.bind(this);
185 } 176 }
186 177
187 if (oldSm) { 178 if (oldSm) {
188 oldSm.removeEventListener('change', this.boundHandleOnChange_); 179 oldSm.removeEventListener('change', this.boundHandleOnChange_);
189 oldSm.removeEventListener('leadIndexChange', 180 oldSm.removeEventListener(
190 this.boundHandleLeadChange_); 181 'leadIndexChange', this.boundHandleLeadChange_);
191 } 182 }
192 183
193 this.selectionModel_ = sm; 184 this.selectionModel_ = sm;
194 this.selectionController_ = this.createSelectionController(sm); 185 this.selectionController_ = this.createSelectionController(sm);
195 186
196 if (sm) { 187 if (sm) {
197 sm.addEventListener('change', this.boundHandleOnChange_); 188 sm.addEventListener('change', this.boundHandleOnChange_);
198 sm.addEventListener('leadIndexChange', this.boundHandleLeadChange_); 189 sm.addEventListener('leadIndexChange', this.boundHandleLeadChange_);
199 } 190 }
200 }, 191 },
201 192
202 /** 193 /**
203 * Whether or not the list auto-expands. 194 * Whether or not the list auto-expands.
204 * @type {boolean} 195 * @type {boolean}
205 */ 196 */
206 get autoExpands() { 197 get autoExpands() { return this.autoExpands_; },
207 return this.autoExpands_;
208 },
209 set autoExpands(autoExpands) { 198 set autoExpands(autoExpands) {
210 if (this.autoExpands_ == autoExpands) 199 if (this.autoExpands_ == autoExpands)
211 return; 200 return;
212 this.autoExpands_ = autoExpands; 201 this.autoExpands_ = autoExpands;
213 this.redraw(); 202 this.redraw();
214 }, 203 },
215 204
216 /** 205 /**
217 * Whether or not the rows on list have various heights. 206 * Whether or not the rows on list have various heights.
218 * @type {boolean} 207 * @type {boolean}
219 */ 208 */
220 get fixedHeight() { 209 get fixedHeight() { return this.fixedHeight_; },
221 return this.fixedHeight_;
222 },
223 set fixedHeight(fixedHeight) { 210 set fixedHeight(fixedHeight) {
224 if (this.fixedHeight_ == fixedHeight) 211 if (this.fixedHeight_ == fixedHeight)
225 return; 212 return;
226 this.fixedHeight_ = fixedHeight; 213 this.fixedHeight_ = fixedHeight;
227 this.redraw(); 214 this.redraw();
228 }, 215 },
229 216
230 /** 217 /**
231 * Convenience alias for selectionModel.selectedItem 218 * Convenience alias for selectionModel.selectedItem
232 * @type {*} 219 * @type {*}
(...skipping 16 matching lines...) Expand all
249 }, 236 },
250 237
251 /** 238 /**
252 * Convenience alias for selectionModel.selectedItems 239 * Convenience alias for selectionModel.selectedItems
253 * @type {!Array<*>} 240 * @type {!Array<*>}
254 */ 241 */
255 get selectedItems() { 242 get selectedItems() {
256 var indexes = this.selectionModel.selectedIndexes; 243 var indexes = this.selectionModel.selectedIndexes;
257 var dataModel = this.dataModel; 244 var dataModel = this.dataModel;
258 if (dataModel) { 245 if (dataModel) {
259 return indexes.map(function(i) { 246 return indexes.map(function(i) { return dataModel.item(i); });
260 return dataModel.item(i);
261 });
262 } 247 }
263 return []; 248 return [];
264 }, 249 },
265 250
266 /** 251 /**
267 * The HTML elements representing the items. 252 * The HTML elements representing the items.
268 * @type {HTMLCollection} 253 * @type {HTMLCollection}
269 */ 254 */
270 get items() { 255 get items() {
271 return Array.prototype.filter.call(this.children, 256 return Array.prototype.filter.call(this.children, this.isItem, this);
272 this.isItem, this);
273 }, 257 },
274 258
275 /** 259 /**
276 * Returns true if the child is a list item. Subclasses may override this 260 * Returns true if the child is a list item. Subclasses may override this
277 * to filter out certain elements. 261 * to filter out certain elements.
278 * @param {Node} child Child of the list. 262 * @param {Node} child Child of the list.
279 * @return {boolean} True if a list item. 263 * @return {boolean} True if a list item.
280 */ 264 */
281 isItem: function(child) { 265 isItem: function(child) {
282 return child.nodeType == Node.ELEMENT_NODE && 266 return child.nodeType == Node.ELEMENT_NODE &&
283 child != this.beforeFiller_ && child != this.afterFiller_; 267 child != this.beforeFiller_ && child != this.afterFiller_;
284 }, 268 },
285 269
286 batchCount_: 0, 270 batchCount_: 0,
287 271
288 /** 272 /**
289 * When making a lot of updates to the list, the code could be wrapped in 273 * When making a lot of updates to the list, the code could be wrapped in
290 * the startBatchUpdates and finishBatchUpdates to increase performance. Be 274 * the startBatchUpdates and finishBatchUpdates to increase performance. Be
291 * sure that the code will not return without calling endBatchUpdates or the 275 * sure that the code will not return without calling endBatchUpdates or the
292 * list will not be correctly updated. 276 * list will not be correctly updated.
293 */ 277 */
294 startBatchUpdates: function() { 278 startBatchUpdates: function() { this.batchCount_++; },
295 this.batchCount_++;
296 },
297 279
298 /** 280 /**
299 * See startBatchUpdates. 281 * See startBatchUpdates.
300 */ 282 */
301 endBatchUpdates: function() { 283 endBatchUpdates: function() {
302 this.batchCount_--; 284 this.batchCount_--;
303 if (this.batchCount_ == 0) 285 if (this.batchCount_ == 0)
304 this.redraw(); 286 this.redraw();
305 }, 287 },
306 288
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 * the first value in the model. 376 * the first value in the model.
395 * @return {{height: number, marginTop: number, marginBottom: number, 377 * @return {{height: number, marginTop: number, marginBottom: number,
396 * width: number, marginLeft: number, marginRight: number}} 378 * width: number, marginLeft: number, marginRight: number}}
397 * The height and width of the item, taking 379 * The height and width of the item, taking
398 * margins into account, and the top, bottom, left and right margins 380 * margins into account, and the top, bottom, left and right margins
399 * themselves. 381 * themselves.
400 */ 382 */
401 measureItem: function(opt_item) { 383 measureItem: function(opt_item) {
402 var dataModel = this.dataModel; 384 var dataModel = this.dataModel;
403 if (!dataModel || !dataModel.length) { 385 if (!dataModel || !dataModel.length) {
404 return {height: 0, marginTop: 0, marginBottom: 0, 386 return {
405 width: 0, marginLeft: 0, marginRight: 0}; 387 height: 0,
388 marginTop: 0,
389 marginBottom: 0,
390 width: 0,
391 marginLeft: 0,
392 marginRight: 0
393 };
406 } 394 }
407 var item = opt_item || this.cachedMeasuredItem_ || 395 var item = opt_item || this.cachedMeasuredItem_ ||
408 this.createItem(dataModel.item(0)); 396 this.createItem(dataModel.item(0));
409 if (!opt_item) { 397 if (!opt_item) {
410 this.cachedMeasuredItem_ = item; 398 this.cachedMeasuredItem_ = item;
411 this.appendChild(item); 399 this.appendChild(item);
412 } 400 }
413 401
414 var rect = item.getBoundingClientRect(); 402 var rect = item.getBoundingClientRect();
415 var cs = getComputedStyle(item); 403 var cs = getComputedStyle(item);
(...skipping 21 matching lines...) Expand all
437 } else if (ml >= 0 && mr >= 0) { 425 } else if (ml >= 0 && mr >= 0) {
438 mh = Math.max(ml, mr); 426 mh = Math.max(ml, mr);
439 } else { 427 } else {
440 mh = ml + mr; 428 mh = ml + mr;
441 } 429 }
442 w += mh; 430 w += mh;
443 431
444 if (!opt_item) 432 if (!opt_item)
445 this.removeChild(item); 433 this.removeChild(item);
446 return { 434 return {
447 height: Math.max(0, h), 435 height: Math.max(0, h),
448 marginTop: mt, marginBottom: mb, 436 marginTop: mt,
449 width: Math.max(0, w), 437 marginBottom: mb,
450 marginLeft: ml, marginRight: mr}; 438 width: Math.max(0, w),
439 marginLeft: ml,
440 marginRight: mr
441 };
451 }, 442 },
452 443
453 /** 444 /**
454 * Callback for the double click event. 445 * Callback for the double click event.
455 * @param {Event} e The mouse event object. 446 * @param {Event} e The mouse event object.
456 * @private 447 * @private
457 */ 448 */
458 handleDoubleClick_: function(e) { 449 handleDoubleClick_: function(e) {
459 if (this.disabled) 450 if (this.disabled)
460 return; 451 return;
461 452
462 var target = /** @type {HTMLElement} */(e.target); 453 var target = /** @type {HTMLElement} */ (e.target);
463 454
464 var ancestor = this.getListItemAncestor(target); 455 var ancestor = this.getListItemAncestor(target);
465 var index = -1; 456 var index = -1;
466 if (ancestor) { 457 if (ancestor) {
467 index = this.getIndexOfListItem(ancestor); 458 index = this.getIndexOfListItem(ancestor);
468 this.activateItemAtIndex(index); 459 this.activateItemAtIndex(index);
469 } 460 }
470 461
471 var sm = this.selectionModel; 462 var sm = this.selectionModel;
472 var indexSelected = sm.getIndexSelected(index); 463 var indexSelected = sm.getIndexSelected(index);
473 if (!indexSelected) 464 if (!indexSelected)
474 this.handlePointerDownUp_(e); 465 this.handlePointerDownUp_(e);
475 }, 466 },
476 467
477 /** 468 /**
478 * Callback for mousedown and mouseup events. 469 * Callback for mousedown and mouseup events.
479 * @param {Event} e The mouse event object. 470 * @param {Event} e The mouse event object.
480 * @private 471 * @private
481 */ 472 */
482 handlePointerDownUp_: function(e) { 473 handlePointerDownUp_: function(e) {
483 if (this.disabled) 474 if (this.disabled)
484 return; 475 return;
485 476
486 var target = /** @type {HTMLElement} */(e.target); 477 var target = /** @type {HTMLElement} */ (e.target);
487 478
488 // If the target was this element we need to make sure that the user did 479 // If the target was this element we need to make sure that the user did
489 // not click on a border or a scrollbar. 480 // not click on a border or a scrollbar.
490 if (target == this) { 481 if (target == this) {
491 if (inViewport(target, e)) 482 if (inViewport(target, e))
492 this.selectionController_.handlePointerDownUp(e, -1); 483 this.selectionController_.handlePointerDownUp(e, -1);
493 return; 484 return;
494 } 485 }
495 486
496 target = this.getListItemAncestor(target); 487 target = this.getListItemAncestor(target);
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
686 } 677 }
687 return top; 678 return top;
688 } 679 }
689 }, 680 },
690 681
691 /** 682 /**
692 * @param {number} index The index of the item. 683 * @param {number} index The index of the item.
693 * @return {number} The row of the item. May vary in the case 684 * @return {number} The row of the item. May vary in the case
694 * of multiple columns. 685 * of multiple columns.
695 */ 686 */
696 getItemRow: function(index) { 687 getItemRow: function(index) { return index; },
697 return index;
698 },
699 688
700 /** 689 /**
701 * @param {number} row The row. 690 * @param {number} row The row.
702 * @return {number} The index of the first item in the row. 691 * @return {number} The index of the first item in the row.
703 */ 692 */
704 getFirstItemInRow: function(row) { 693 getFirstItemInRow: function(row) { return row; },
705 return row;
706 },
707 694
708 /** 695 /**
709 * Ensures that a given index is inside the viewport. 696 * Ensures that a given index is inside the viewport.
710 * @param {number} index The index of the item to scroll into view. 697 * @param {number} index The index of the item to scroll into view.
711 */ 698 */
712 scrollIndexIntoView: function(index) { 699 scrollIndexIntoView: function(index) {
713 var dataModel = this.dataModel; 700 var dataModel = this.dataModel;
714 if (!dataModel || index < 0 || index >= dataModel.length) 701 if (!dataModel || index < 0 || index >= dataModel.length)
715 return; 702 return;
716 703
717 var itemHeight = this.getItemHeightByIndex_(index); 704 var itemHeight = this.getItemHeightByIndex_(index);
718 var scrollTop = this.scrollTop; 705 var scrollTop = this.scrollTop;
719 var top = this.getItemTop(index); 706 var top = this.getItemTop(index);
720 var clientHeight = this.clientHeight; 707 var clientHeight = this.clientHeight;
721 708
722 var cs = getComputedStyle(this); 709 var cs = getComputedStyle(this);
723 var paddingY = parseInt(cs.paddingTop, 10) + 710 var paddingY =
724 parseInt(cs.paddingBottom, 10); 711 parseInt(cs.paddingTop, 10) + parseInt(cs.paddingBottom, 10);
725 var availableHeight = clientHeight - paddingY; 712 var availableHeight = clientHeight - paddingY;
726 713
727 var self = this; 714 var self = this;
728 // Function to adjust the tops of viewport and row. 715 // Function to adjust the tops of viewport and row.
729 function scrollToAdjustTop() { 716 function scrollToAdjustTop() { self.scrollTop = top; }
730 self.scrollTop = top;
731 }
732 // Function to adjust the bottoms of viewport and row. 717 // Function to adjust the bottoms of viewport and row.
733 function scrollToAdjustBottom() { 718 function scrollToAdjustBottom() {
734 self.scrollTop = top + itemHeight - availableHeight; 719 self.scrollTop = top + itemHeight - availableHeight;
735 } 720 }
736 721
737 // Check if the entire of given indexed row can be shown in the viewport. 722 // Check if the entire of given indexed row can be shown in the viewport.
738 if (itemHeight <= availableHeight) { 723 if (itemHeight <= availableHeight) {
739 if (top < scrollTop) 724 if (top < scrollTop)
740 scrollToAdjustTop(); 725 scrollToAdjustTop();
741 else if (scrollTop + availableHeight < top + itemHeight) 726 else if (scrollTop + availableHeight < top + itemHeight)
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
855 // If offset exceeds the height of list. 840 // If offset exceeds the height of list.
856 var lastHeight = 0; 841 var lastHeight = 0;
857 if (this.dataModel.length) { 842 if (this.dataModel.length) {
858 var h = this.getHeightsForIndex_(this.dataModel.length - 1); 843 var h = this.getHeightsForIndex_(this.dataModel.length - 1);
859 lastHeight = h.top + h.height; 844 lastHeight = h.top + h.height;
860 } 845 }
861 if (lastHeight < offset) 846 if (lastHeight < offset)
862 return this.dataModel.length; 847 return this.dataModel.length;
863 848
864 // Estimates index. 849 // Estimates index.
865 var estimatedIndex = Math.min(Math.floor(offset / itemHeight), 850 var estimatedIndex =
866 this.dataModel.length - 1); 851 Math.min(Math.floor(offset / itemHeight), this.dataModel.length - 1);
867 var isIncrementing = this.getItemTop(estimatedIndex) < offset; 852 var isIncrementing = this.getItemTop(estimatedIndex) < offset;
868 853
869 // Searchs the correct index. 854 // Searchs the correct index.
870 do { 855 do {
871 var heights = this.getHeightsForIndex_(estimatedIndex); 856 var heights = this.getHeightsForIndex_(estimatedIndex);
872 var top = heights.top; 857 var top = heights.top;
873 var height = heights.height; 858 var height = heights.height;
874 859
875 if (top <= offset && offset <= (top + height)) 860 if (top <= offset && offset <= (top + height))
876 break; 861 break;
(...skipping 22 matching lines...) Expand all
899 * @param {number} scrollTop The scroll top position. 884 * @param {number} scrollTop The scroll top position.
900 * @param {number} clientHeight The height of viewport. 885 * @param {number} clientHeight The height of viewport.
901 * @return {{first: number, length: number, last: number}} The index of 886 * @return {{first: number, length: number, last: number}} The index of
902 * first item in view port, The number of items, The item past the last. 887 * first item in view port, The number of items, The item past the last.
903 */ 888 */
904 getItemsInViewPort: function(scrollTop, clientHeight) { 889 getItemsInViewPort: function(scrollTop, clientHeight) {
905 if (this.autoExpands_) { 890 if (this.autoExpands_) {
906 return { 891 return {
907 first: 0, 892 first: 0,
908 length: this.dataModel.length, 893 length: this.dataModel.length,
909 last: this.dataModel.length}; 894 last: this.dataModel.length
895 };
910 } else { 896 } else {
911 var firstIndex = this.getIndexForListOffset_(scrollTop); 897 var firstIndex = this.getIndexForListOffset_(scrollTop);
912 var lastIndex = this.getIndexForListOffset_(scrollTop + clientHeight); 898 var lastIndex = this.getIndexForListOffset_(scrollTop + clientHeight);
913 899
914 return { 900 return {
915 first: firstIndex, 901 first: firstIndex,
916 length: lastIndex - firstIndex + 1, 902 length: lastIndex - firstIndex + 1,
917 last: lastIndex + 1}; 903 last: lastIndex + 1
904 };
918 } 905 }
919 }, 906 },
920 907
921 /** 908 /**
922 * Merges list items currently existing in the list with items in the range 909 * Merges list items currently existing in the list with items in the range
923 * [firstIndex, lastIndex). Removes or adds items if needed. 910 * [firstIndex, lastIndex). Removes or adds items if needed.
924 * Doesn't delete {@code this.pinnedItem_} if it is present (instead hides 911 * Doesn't delete {@code this.pinnedItem_} if it is present (instead hides
925 * it if it is out of the range). 912 * it if it is out of the range).
926 * @param {number} firstIndex The index of first item, inclusively. 913 * @param {number} firstIndex The index of first item, inclusively.
927 * @param {number} lastIndex The index of last item, exclusively. 914 * @param {number} lastIndex The index of last item, exclusively.
928 */ 915 */
929 mergeItems: function(firstIndex, lastIndex) { 916 mergeItems: function(firstIndex, lastIndex) {
930 var self = this; 917 var self = this;
931 var dataModel = this.dataModel; 918 var dataModel = this.dataModel;
932 var currentIndex = firstIndex; 919 var currentIndex = firstIndex;
933 920
934 function insert() { 921 function insert() {
935 var dataItem = dataModel.item(currentIndex); 922 var dataItem = dataModel.item(currentIndex);
936 var newItem = self.cachedItems_[currentIndex] || 923 var newItem =
937 self.createItem(dataItem); 924 self.cachedItems_[currentIndex] || self.createItem(dataItem);
938 newItem.listIndex = currentIndex; 925 newItem.listIndex = currentIndex;
939 self.cachedItems_[currentIndex] = newItem; 926 self.cachedItems_[currentIndex] = newItem;
940 self.insertBefore(newItem, item); 927 self.insertBefore(newItem, item);
941 currentIndex++; 928 currentIndex++;
942 } 929 }
943 930
944 function remove() { 931 function remove() {
945 var next = item.nextSibling; 932 var next = item.nextSibling;
946 if (item != self.pinnedItem_) 933 if (item != self.pinnedItem_)
947 self.removeChild(item); 934 self.removeChild(item);
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
1076 // interleave measuring with mutating dom. 1063 // interleave measuring with mutating dom.
1077 if (!this.fixedHeight_) 1064 if (!this.fixedHeight_)
1078 this.ensureAllItemSizesInCache(); 1065 this.ensureAllItemSizesInCache();
1079 1066
1080 var autoExpands = this.autoExpands_; 1067 var autoExpands = this.autoExpands_;
1081 1068
1082 var itemsInViewPort = this.getItemsInViewPort(scrollTop, clientHeight); 1069 var itemsInViewPort = this.getItemsInViewPort(scrollTop, clientHeight);
1083 // Draws the hidden rows just above/below the viewport to prevent 1070 // Draws the hidden rows just above/below the viewport to prevent
1084 // flashing in scroll. 1071 // flashing in scroll.
1085 var firstIndex = Math.max( 1072 var firstIndex = Math.max(
1086 0, 1073 0, Math.min(dataModel.length - 1, itemsInViewPort.first - 1));
1087 Math.min(dataModel.length - 1, itemsInViewPort.first - 1));
1088 var lastIndex = Math.min(itemsInViewPort.last + 1, dataModel.length); 1074 var lastIndex = Math.min(itemsInViewPort.last + 1, dataModel.length);
1089 1075
1090 var beforeFillerHeight = 1076 var beforeFillerHeight =
1091 this.autoExpands ? 0 : this.getItemTop(firstIndex); 1077 this.autoExpands ? 0 : this.getItemTop(firstIndex);
1092 var afterFillerHeight = 1078 var afterFillerHeight =
1093 this.autoExpands ? 0 : this.getAfterFillerHeight(lastIndex); 1079 this.autoExpands ? 0 : this.getAfterFillerHeight(lastIndex);
1094 1080
1095 this.beforeFiller_.style.height = beforeFillerHeight + 'px'; 1081 this.beforeFiller_.style.height = beforeFillerHeight + 'px';
1096 1082
1097 var sm = this.selectionModel; 1083 var sm = this.selectionModel;
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1181 delete this.cachedItems_[index]; 1167 delete this.cachedItems_[index];
1182 this.redraw(); 1168 this.redraw();
1183 } 1169 }
1184 }, 1170 },
1185 1171
1186 /** 1172 /**
1187 * Called when a list item is activated, currently only by a double click 1173 * Called when a list item is activated, currently only by a double click
1188 * event. 1174 * event.
1189 * @param {number} index The index of the activated item. 1175 * @param {number} index The index of the activated item.
1190 */ 1176 */
1191 activateItemAtIndex: function(index) { 1177 activateItemAtIndex: function(index) {},
1192 },
1193 1178
1194 /** 1179 /**
1195 * Returns a ListItem for the leadIndex. If the item isn't present in the 1180 * Returns a ListItem for the leadIndex. If the item isn't present in the
1196 * list creates it and inserts to the list (may be invisible if it's out of 1181 * list creates it and inserts to the list (may be invisible if it's out of
1197 * the visible range). 1182 * the visible range).
1198 * 1183 *
1199 * Item returned from this method won't be removed until it remains a lead 1184 * Item returned from this method won't be removed until it remains a lead
1200 * item or till the data model changes (unlike other items that could be 1185 * item or till the data model changes (unlike other items that could be
1201 * removed when they go out of the visible range). 1186 * removed when they go out of the visible range).
1202 * 1187 *
1203 * @return {cr.ui.ListItem} The lead item for the list. 1188 * @return {cr.ui.ListItem} The lead item for the list.
1204 */ 1189 */
1205 ensureLeadItemExists: function() { 1190 ensureLeadItemExists: function() {
1206 var index = this.selectionModel.leadIndex; 1191 var index = this.selectionModel.leadIndex;
1207 if (index < 0) 1192 if (index < 0)
1208 return null; 1193 return null;
1209 var cachedItems = this.cachedItems_ || {}; 1194 var cachedItems = this.cachedItems_ || {};
1210 1195
1211 var item = cachedItems[index] || 1196 var item =
1212 this.createItem(this.dataModel.item(index)); 1197 cachedItems[index] || this.createItem(this.dataModel.item(index));
1213 if (this.pinnedItem_ != item && this.pinnedItem_ && 1198 if (this.pinnedItem_ != item && this.pinnedItem_ &&
1214 this.pinnedItem_.hidden) { 1199 this.pinnedItem_.hidden) {
1215 this.removeChild(this.pinnedItem_); 1200 this.removeChild(this.pinnedItem_);
1216 } 1201 }
1217 this.pinnedItem_ = item; 1202 this.pinnedItem_ = item;
1218 cachedItems[index] = item; 1203 cachedItems[index] = item;
1219 item.listIndex = index; 1204 item.listIndex = index;
1220 if (item.parentNode == this) 1205 if (item.parentNode == this)
1221 return item; 1206 return item;
1222 1207
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1275 * that point even though it doesn't actually have the page focus. 1260 * that point even though it doesn't actually have the page focus.
1276 */ 1261 */
1277 cr.defineProperty(List, 'hasElementFocus', cr.PropertyKind.BOOL_ATTR); 1262 cr.defineProperty(List, 'hasElementFocus', cr.PropertyKind.BOOL_ATTR);
1278 1263
1279 /** 1264 /**
1280 * Mousedown event handler. 1265 * Mousedown event handler.
1281 * @this {cr.ui.List} 1266 * @this {cr.ui.List}
1282 * @param {Event} e The mouse event object. 1267 * @param {Event} e The mouse event object.
1283 */ 1268 */
1284 function handleMouseDown(e) { 1269 function handleMouseDown(e) {
1285 e.target = /** @type {!HTMLElement} */(e.target); 1270 e.target = /** @type {!HTMLElement} */ (e.target);
1286 var listItem = this.getListItemAncestor(e.target); 1271 var listItem = this.getListItemAncestor(e.target);
1287 var wasSelected = listItem && listItem.selected; 1272 var wasSelected = listItem && listItem.selected;
1288 this.handlePointerDownUp_(e); 1273 this.handlePointerDownUp_(e);
1289 1274
1290 if (e.defaultPrevented || e.button != 0) 1275 if (e.defaultPrevented || e.button != 0)
1291 return; 1276 return;
1292 1277
1293 // The following hack is required only if the listItem gets selected. 1278 // The following hack is required only if the listItem gets selected.
1294 if (!listItem || wasSelected || !listItem.selected) 1279 if (!listItem || wasSelected || !listItem.selected)
1295 return; 1280 return;
(...skipping 11 matching lines...) Expand all
1307 } 1292 }
1308 1293
1309 /** 1294 /**
1310 * Dragstart event handler. 1295 * Dragstart event handler.
1311 * If there is an item at starting position of drag operation and the item 1296 * If there is an item at starting position of drag operation and the item
1312 * is not selected, select it. 1297 * is not selected, select it.
1313 * @this {cr.ui.List} 1298 * @this {cr.ui.List}
1314 * @param {Event} e The event object for 'dragstart'. 1299 * @param {Event} e The event object for 'dragstart'.
1315 */ 1300 */
1316 function handleDragStart(e) { 1301 function handleDragStart(e) {
1317 e = /** @type {MouseEvent} */(e); 1302 e = /** @type {MouseEvent} */ (e);
1318 var element = e.target.ownerDocument.elementFromPoint(e.clientX, e.clientY); 1303 var element = e.target.ownerDocument.elementFromPoint(e.clientX, e.clientY);
1319 var listItem = this.getListItemAncestor(element); 1304 var listItem = this.getListItemAncestor(element);
1320 if (!listItem) 1305 if (!listItem)
1321 return; 1306 return;
1322 1307
1323 var index = this.getIndexOfListItem(listItem); 1308 var index = this.getIndexOfListItem(listItem);
1324 if (index == -1) 1309 if (index == -1)
1325 return; 1310 return;
1326 1311
1327 var isAlreadySelected = this.selectionModel_.getIndexSelected(index); 1312 var isAlreadySelected = this.selectionModel_.getIndexSelected(index);
1328 if (!isAlreadySelected) 1313 if (!isAlreadySelected)
1329 this.selectionModel_.selectedIndex = index; 1314 this.selectionModel_.selectedIndex = index;
1330 } 1315 }
1331 1316
1332 /** 1317 /**
1333 * Check if |start| or its ancestor under |root| is focusable. 1318 * Check if |start| or its ancestor under |root| is focusable.
1334 * This is a helper for handleMouseDown. 1319 * This is a helper for handleMouseDown.
1335 * @param {!Element} start An element which we start to check. 1320 * @param {!Element} start An element which we start to check.
1336 * @param {!Element} root An element which we finish to check. 1321 * @param {!Element} root An element which we finish to check.
1337 * @return {boolean} True if we found a focusable element. 1322 * @return {boolean} True if we found a focusable element.
1338 */ 1323 */
1339 function containsFocusableElement(start, root) { 1324 function containsFocusableElement(start, root) {
1340 for (var element = start; element && element != root; 1325 for (var element = start; element && element != root;
1341 element = element.parentElement) { 1326 element = element.parentElement) {
1342 if (element.tabIndex >= 0 && !element.disabled) 1327 if (element.tabIndex >= 0 && !element.disabled)
1343 return true; 1328 return true;
1344 } 1329 }
1345 return false; 1330 return false;
1346 } 1331 }
1347 1332
1348 return { 1333 return {List: List};
1349 List: List
1350 };
1351 }); 1334 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698