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

Unified Diff: third_party/WebKit/Source/devtools/front_end/ui/ListControl.js

Issue 2609363002: [DevTools] Tweak ListControl API. (Closed)
Patch Set: fixed review comments Created 3 years, 11 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 side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/devtools/front_end/ui/ListControl.js
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/ListControl.js b/third_party/WebKit/Source/devtools/front_end/ui/ListControl.js
index f97f8d9db4d5d5f9397adc3b9febfb8263b63d4a..f05dd175e1590738a337c1778b898641b80a4dbc 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/ListControl.js
+++ b/third_party/WebKit/Source/devtools/front_end/ui/ListControl.js
@@ -16,6 +16,8 @@ UI.ListDelegate.prototype = {
createElementForItem(item) {},
/**
+ * This method is not called in NonViewport mode.
+ * Return zero to make list measure the item (only works in SameHeight mode).
* @param {T} item
* @return {number}
*/
@@ -38,10 +40,9 @@ UI.ListDelegate.prototype = {
/** @enum {symbol} */
UI.ListMode = {
- Grow: Symbol('UI.ListMode.Grow'),
- ViewportFixedItems: Symbol('UI.ListMode.ViewportFixedItems'),
- ViewportFixedItemsMeasured: Symbol('UI.ListMode.ViewportFixedItemsMeasured'),
- ViewportVariableItems: Symbol('UI.ListMode.ViewportVariableItems')
+ NonViewport: Symbol('UI.ListMode.NonViewport'),
+ EqualHeightItems: Symbol('UI.ListMode.EqualHeightItems'),
+ VariousHeightItems: Symbol('UI.ListMode.VariousHeightItems')
};
/**
@@ -69,37 +70,19 @@ UI.ListControl = class {
this._itemToElement = new Map();
this._selectedIndex = -1;
- this._boundKeyDown = event => {
- if (this.onKeyDown(event))
- event.consume(true);
- };
- this._boundClick = event => {
- if (this.onClick(event))
- event.consume(true);
- };
- this._boundScroll = event => {
- this._updateViewport(this.element.scrollTop, this.element.offsetHeight);
- };
+ this.element.addEventListener('click', this._onClick.bind(this), false);
+ this.element.addEventListener('keydown', this._onKeyDown.bind(this), false);
this._delegate = delegate;
- this._mode = mode || UI.ListMode.ViewportFixedItemsMeasured;
+ this._mode = mode || UI.ListMode.EqualHeightItems;
this._fixedHeight = 0;
this._variableOffsets = new Int32Array(0);
this._clearContents();
- if (this._mode !== UI.ListMode.Grow)
- this.element.addEventListener('scroll', this._boundScroll, false);
- }
- /**
- * @param {boolean} handleInput
- */
- setHandleInput(handleInput) {
- if (handleInput) {
- this.element.addEventListener('keydown', this._boundKeyDown, false);
- this.element.addEventListener('click', this._boundClick, false);
- } else {
- this.element.removeEventListener('keydown', this._boundKeyDown, false);
- this.element.removeEventListener('click', this._boundClick, false);
+ if (this._mode !== UI.ListMode.NonViewport) {
+ this.element.addEventListener('scroll', () => {
+ this._updateViewport(this.element.scrollTop, this.element.offsetHeight);
+ }, false);
}
}
@@ -197,7 +180,7 @@ UI.ListControl = class {
}
viewportResized() {
- if (this._mode === UI.ListMode.Grow)
+ if (this._mode === UI.ListMode.NonViewport)
return;
// TODO(dgozman): try to keep visible scrollTop the same.
var scrollTop = this.element.scrollTop;
@@ -206,9 +189,9 @@ UI.ListControl = class {
this._updateViewport(Number.constrain(scrollTop, 0, this._totalHeight() - viewportHeight), viewportHeight);
}
- fixedHeightChanged() {
- if (this._mode !== UI.ListMode.ViewportFixedItemsMeasured && this._mode !== UI.ListMode.ViewportFixedItems)
- throw 'Only supported in fixed height items modes';
+ invalidateItemHeight() {
+ if (this._mode !== UI.ListMode.EqualHeightItems)
+ throw 'Only supported in equal height items mode';
this._fixedHeight = 0;
if (this._items.length) {
this._itemToElement.clear();
@@ -217,81 +200,114 @@ UI.ListControl = class {
}
/**
- * @param {number} index
+ * @param {!Element} element
+ * @return {?T}
*/
- scrollItemAtIndexIntoView(index) {
- if (this._mode === UI.ListMode.Grow) {
- this._elementAtIndex(index).scrollIntoViewIfNeeded(false);
- return;
- }
- var top = this._offsetAtIndex(index);
- var bottom = this._offsetAtIndex(index + 1);
- var scrollTop = this.element.scrollTop;
- var viewportHeight = this.element.offsetHeight;
- if (top < scrollTop)
- this._updateViewport(top, viewportHeight);
- else if (bottom > scrollTop + viewportHeight)
- this._updateViewport(bottom - viewportHeight, viewportHeight);
+ itemForElement(element) {
+ var index = this._items.findIndex(item => this._itemToElement.get(item) === element);
+ return index !== -1 ? this._items[index] : null;
}
/**
- * @param {number} index
- * @param {boolean=} scrollIntoView
+ * @param {T} item
+ * @param {boolean=} center
+ */
+ scrollItemIntoView(item, center) {
+ var index = this._items.indexOf(item);
+ if (index === -1)
+ throw 'Attempt to scroll onto missing item';
+ this._scrollIntoView(index, center);
+ }
+
+ /**
+ * @return {?T}
+ */
+ selectedItem() {
+ return this._selectedIndex === -1 ? null : this._items[this._selectedIndex];
+ }
+
+ /**
+ * @param {?T} item
+ * @param {boolean=} center
*/
- selectItemAtIndex(index, scrollIntoView) {
- if (index !== -1 && !this._delegate.isItemSelectable(this._items[index]))
- throw 'Attempt to select non-selectable item';
+ selectItem(item, center) {
+ var index = -1;
+ if (item !== null) {
+ index = this._items.indexOf(item);
+ if (index === -1)
+ throw 'Attempt to select missing item';
+ if (!this._delegate.isItemSelectable(item))
+ throw 'Attempt to select non-selectable item';
+ }
this._select(index);
- if (index !== -1 && !!scrollIntoView)
- this.scrollItemAtIndexIntoView(index);
+ if (index !== -1)
+ this._scrollIntoView(index, center);
}
/**
- * @return {number}
+ * @param {boolean=} canWrap
+ * @param {boolean=} center
+ * @return {boolean}
*/
- selectedIndex() {
- return this._selectedIndex;
+ selectPreviousItem(canWrap, center) {
+ if (this._selectedIndex === -1 && !canWrap)
+ return false;
+ var index = this._selectedIndex === -1 ? this._items.length - 1 : this._selectedIndex - 1;
+ index = this._findFirstSelectable(index, -1, !!canWrap);
+ if (index !== -1) {
+ this._scrollIntoView(index, center);
+ this._select(index);
+ return true;
+ }
+ return false;
}
/**
- * @return {?T}
+ * @param {boolean=} canWrap
+ * @param {boolean=} center
+ * @return {boolean}
*/
- selectedItem() {
- return this._selectedIndex === -1 ? null : this._items[this._selectedIndex];
+ selectNextItem(canWrap, center) {
+ if (this._selectedIndex === -1 && !canWrap)
+ return false;
+ var index = this._selectedIndex === -1 ? 0 : this._selectedIndex + 1;
+ index = this._findFirstSelectable(index, +1, !!canWrap);
+ if (index !== -1) {
+ this._scrollIntoView(index, center);
+ this._select(index);
+ return true;
+ }
+ return false;
}
/**
- * @param {!Event} event
+ * @param {boolean=} center
* @return {boolean}
*/
- onKeyDown(event) {
- var index = -1;
- switch (event.key) {
- case 'ArrowUp':
- index = this._selectedIndex === -1 ? this._items.length - 1 : this._selectedIndex - 1;
- index = this._findFirstSelectable(index, -1, true);
- break;
- case 'ArrowDown':
- index = this._selectedIndex === -1 ? 0 : this._selectedIndex + 1;
- index = this._findFirstSelectable(index, +1, true);
- break;
- case 'PageUp':
- if (this._mode === UI.ListMode.Grow)
- return false;
- index = this._selectedIndex === -1 ? this._items.length - 1 : this._selectedIndex;
- index = this._findPageSelectable(index, -1);
- break;
- case 'PageDown':
- if (this._mode === UI.ListMode.Grow)
- return false;
- index = this._selectedIndex === -1 ? 0 : this._selectedIndex;
- index = this._findPageSelectable(index, +1);
- break;
- default:
- return false;
+ selectItemPreviousPage(center) {
+ if (this._mode === UI.ListMode.NonViewport)
+ return false;
+ var index = this._selectedIndex === -1 ? this._items.length - 1 : this._selectedIndex;
+ index = this._findPageSelectable(index, -1);
+ if (index !== -1) {
+ this._scrollIntoView(index, center);
+ this._select(index);
+ return true;
}
+ return false;
+ }
+
+ /**
+ * @param {boolean=} center
+ * @return {boolean}
+ */
+ selectItemNextPage(center) {
+ if (this._mode === UI.ListMode.NonViewport)
+ return false;
+ var index = this._selectedIndex === -1 ? 0 : this._selectedIndex;
+ index = this._findPageSelectable(index, +1);
if (index !== -1) {
- this.scrollItemAtIndexIntoView(index);
+ this._scrollIntoView(index, center);
this._select(index);
return true;
}
@@ -299,20 +315,67 @@ UI.ListControl = class {
}
/**
+ * @param {number} index
+ * @param {boolean=} center
+ */
+ _scrollIntoView(index, center) {
+ if (this._mode === UI.ListMode.NonViewport) {
+ this._elementAtIndex(index).scrollIntoViewIfNeeded(!!center);
+ return;
+ }
+
+ var top = this._offsetAtIndex(index);
+ var bottom = this._offsetAtIndex(index + 1);
+ var viewportHeight = this.element.offsetHeight;
+ if (center) {
+ var scrollTo = (top + bottom) / 2 - viewportHeight / 2;
+ this._updateViewport(Number.constrain(scrollTo, 0, this._totalHeight() - viewportHeight), viewportHeight);
+ return;
+ }
+
+ var scrollTop = this.element.scrollTop;
+ if (top < scrollTop)
+ this._updateViewport(top, viewportHeight);
+ else if (bottom > scrollTop + viewportHeight)
+ this._updateViewport(bottom - viewportHeight, viewportHeight);
+ }
+
+ /**
* @param {!Event} event
- * @return {boolean}
*/
- onClick(event) {
+ _onClick(event) {
var node = event.target;
while (node && node.parentNodeOrShadowHost() !== this.element)
node = node.parentNodeOrShadowHost();
if (!node)
- return false;
- var index = this._items.findIndex(item => this._itemToElement.get(item) === node);
- if (index === -1 || !this._delegate.isItemSelectable(this._items[index]))
- return false;
- this._select(index);
- return true;
+ return;
+ var element = /** @type {!Element} */ (node);
+ var item = this.itemForElement(element);
+ if (item)
+ this.selectItem(item);
+ }
+
+ /**
+ * @param {!Event} event
+ */
+ _onKeyDown(event) {
+ var selected = false;
+ switch (event.key) {
+ case 'ArrowUp':
+ selected = this.selectPreviousItem(true, false);
+ break;
+ case 'ArrowDown':
+ selected = this.selectNextItem(true, false);
+ break;
+ case 'PageUp':
+ selected = this.selectItemPreviousPage(false);
+ break;
+ case 'PageDown':
+ selected = this.selectItemNextPage(false);
+ break;
+ }
+ if (selected)
+ event.consume();
}
/**
@@ -327,11 +390,11 @@ UI.ListControl = class {
* @return {number}
*/
_indexAtOffset(offset) {
- if (this._mode === UI.ListMode.Grow)
- throw 'There should be no offset conversions in grow mode';
+ if (this._mode === UI.ListMode.NonViewport)
+ throw 'There should be no offset conversions in non-viewport mode';
if (!this._items.length || offset < 0)
return 0;
- if (this._mode === UI.ListMode.ViewportVariableItems) {
+ if (this._mode === UI.ListMode.VariousHeightItems) {
return Math.min(
this._items.length - 1, this._variableOffsets.lowerBound(offset, undefined, 0, this._items.length));
}
@@ -359,11 +422,11 @@ UI.ListControl = class {
* @return {number}
*/
_offsetAtIndex(index) {
- if (this._mode === UI.ListMode.Grow)
- throw 'There should be no offset conversions in grow mode';
+ if (this._mode === UI.ListMode.NonViewport)
+ throw 'There should be no offset conversions in non-viewport mode';
if (!this._items.length)
return 0;
- if (this._mode === UI.ListMode.ViewportVariableItems)
+ if (this._mode === UI.ListMode.VariousHeightItems)
return this._variableOffsets[index];
if (!this._fixedHeight)
this._measureHeight();
@@ -371,10 +434,9 @@ UI.ListControl = class {
}
_measureHeight() {
- if (this._mode === UI.ListMode.ViewportFixedItemsMeasured)
+ this._fixedHeight = this._delegate.heightForItem(this._items[0]);
+ if (!this._fixedHeight)
this._fixedHeight = UI.measurePreferredSize(this._elementAtIndex(0), this.element).height;
- else
- this._fixedHeight = this._delegate.heightForItem(this._items[0]);
}
/**
@@ -459,12 +521,12 @@ UI.ListControl = class {
* @param {number} inserted
*/
_invalidate(from, to, inserted) {
- if (this._mode === UI.ListMode.Grow) {
- this._invalidateGrowMode(from, to - from, inserted);
+ if (this._mode === UI.ListMode.NonViewport) {
+ this._invalidateNonViewportMode(from, to - from, inserted);
return;
}
- if (this._mode === UI.ListMode.ViewportVariableItems) {
+ if (this._mode === UI.ListMode.VariousHeightItems) {
this._reallocateVariableOffsets(this._items.length + 1, from + 1);
for (var i = from + 1; i <= this._items.length; i++)
this._variableOffsets[i] = this._variableOffsets[i - 1] + this._delegate.heightForItem(this._items[i - 1]);
@@ -512,7 +574,7 @@ UI.ListControl = class {
* @param {number} remove
* @param {number} add
*/
- _invalidateGrowMode(start, remove, add) {
+ _invalidateNonViewportMode(start, remove, add) {
var startElement = this._topElement;
for (var index = 0; index < start; index++)
startElement = startElement.nextElementSibling;
@@ -523,8 +585,8 @@ UI.ListControl = class {
}
_clearViewport() {
- if (this._mode === UI.ListMode.Grow)
- throw 'There should be no viewport updates in grow mode';
+ if (this._mode === UI.ListMode.NonViewport)
+ throw 'There should be no viewport updates in non-viewport mode';
this._firstIndex = 0;
this._lastIndex = 0;
this._renderedHeight = 0;
@@ -548,8 +610,8 @@ UI.ListControl = class {
*/
_updateViewport(scrollTop, viewportHeight) {
// Note: this method should not force layout. Be careful.
- if (this._mode === UI.ListMode.Grow)
- throw 'There should be no viewport updates in grow mode';
+ if (this._mode === UI.ListMode.NonViewport)
+ throw 'There should be no viewport updates in non-viewport mode';
var totalHeight = this._totalHeight();
if (!totalHeight) {

Powered by Google App Engine
This is Rietveld 408576698