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

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

Issue 2466123002: DevTools: reformat front-end code to match chromium style. (Closed)
Patch Set: all done Created 4 years, 1 month 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/ViewportControl.js
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/ViewportControl.js b/third_party/WebKit/Source/devtools/front_end/ui/ViewportControl.js
index f8586e755e4db9f881812696ee9da2e67cc7e491..57bb46df5c027133149af537450d626402f50da9 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/ViewportControl.js
+++ b/third_party/WebKit/Source/devtools/front_end/ui/ViewportControl.js
@@ -27,32 +27,33 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-
/**
- * @constructor
- * @param {!WebInspector.ViewportControl.Provider} provider
+ * @unrestricted
*/
-WebInspector.ViewportControl = function(provider)
-{
- this.element = createElement("div");
- this.element.style.overflow = "auto";
- this._topGapElement = this.element.createChild("div");
- this._topGapElement.style.height = "0px";
- this._topGapElement.style.color = "transparent";
- this._contentElement = this.element.createChild("div");
- this._bottomGapElement = this.element.createChild("div");
- this._bottomGapElement.style.height = "0px";
- this._bottomGapElement.style.color = "transparent";
+WebInspector.ViewportControl = class {
+ /**
+ * @param {!WebInspector.ViewportControl.Provider} provider
+ */
+ constructor(provider) {
+ this.element = createElement('div');
+ this.element.style.overflow = 'auto';
+ this._topGapElement = this.element.createChild('div');
+ this._topGapElement.style.height = '0px';
+ this._topGapElement.style.color = 'transparent';
+ this._contentElement = this.element.createChild('div');
+ this._bottomGapElement = this.element.createChild('div');
+ this._bottomGapElement.style.height = '0px';
+ this._bottomGapElement.style.color = 'transparent';
// Text content needed for range intersection checks in _updateSelectionModel.
// Use Unicode ZERO WIDTH NO-BREAK SPACE, which avoids contributing any height to the element's layout overflow.
- this._topGapElement.textContent = "\uFEFF";
- this._bottomGapElement.textContent = "\uFEFF";
+ this._topGapElement.textContent = '\uFEFF';
+ this._bottomGapElement.textContent = '\uFEFF';
this._provider = provider;
- this.element.addEventListener("scroll", this._onScroll.bind(this), false);
- this.element.addEventListener("copy", this._onCopy.bind(this), false);
- this.element.addEventListener("dragstart", this._onDragStart.bind(this), false);
+ this.element.addEventListener('scroll', this._onScroll.bind(this), false);
+ this.element.addEventListener('copy', this._onCopy.bind(this), false);
+ this.element.addEventListener('dragstart', this._onDragStart.bind(this), false);
this._firstActiveIndex = 0;
this._lastActiveIndex = -1;
@@ -65,605 +66,592 @@ WebInspector.ViewportControl = function(provider)
// that items updated asynchronously will not break stick-to-bottom behavior
// if they change the scroll height.
this._observer = new MutationObserver(this.refresh.bind(this));
- this._observerConfig = { childList: true, subtree: true };
-};
-
-/**
- * @interface
- */
-WebInspector.ViewportControl.Provider = function()
-{
-};
-
-WebInspector.ViewportControl.Provider.prototype = {
- /**
- * @param {number} index
- * @return {number}
- */
- fastHeight: function(index) { return 0; },
-
- /**
- * @return {number}
- */
- itemCount: function() { return 0; },
-
- /**
- * @return {number}
- */
- minimumRowHeight: function() { return 0; },
-
- /**
- * @param {number} index
- * @return {?WebInspector.ViewportElement}
- */
- itemElement: function(index) { return null; }
-};
-
-/**
- * @interface
- */
-WebInspector.ViewportElement = function() { };
-WebInspector.ViewportElement.prototype = {
- willHide: function() { },
-
- wasShown: function() { },
-
- /**
- * @return {!Element}
- */
- element: function() { },
-};
-
-/**
- * @constructor
- * @implements {WebInspector.ViewportElement}
- * @param {!Element} element
- */
-WebInspector.StaticViewportElement = function(element)
-{
- this._element = element;
-};
-
-WebInspector.StaticViewportElement.prototype = {
- /**
- * @override
- */
- willHide: function() { },
+ this._observerConfig = {childList: true, subtree: true};
+ }
+
+ /**
+ * @return {boolean}
+ */
+ stickToBottom() {
+ return this._stickToBottom;
+ }
+
+ /**
+ * @param {boolean} value
+ */
+ setStickToBottom(value) {
+ this._stickToBottom = value;
+ if (this._stickToBottom)
+ this._observer.observe(this._contentElement, this._observerConfig);
+ else
+ this._observer.disconnect();
+ }
+
+ /**
+ * @param {!Event} event
+ */
+ _onCopy(event) {
+ var text = this._selectedText();
+ if (!text)
+ return;
+ event.preventDefault();
+ event.clipboardData.setData('text/plain', text);
+ }
+
+ /**
+ * @param {!Event} event
+ */
+ _onDragStart(event) {
+ var text = this._selectedText();
+ if (!text)
+ return false;
+ event.dataTransfer.clearData();
+ event.dataTransfer.setData('text/plain', text);
+ event.dataTransfer.effectAllowed = 'copy';
+ return true;
+ }
+
+ /**
+ * @return {!Element}
+ */
+ contentElement() {
+ return this._contentElement;
+ }
+
+ invalidate() {
+ delete this._cumulativeHeights;
+ delete this._cachedProviderElements;
+ this._itemCount = this._provider.itemCount();
+ this.refresh();
+ }
+
+ /**
+ * @param {number} index
+ * @return {?WebInspector.ViewportElement}
+ */
+ _providerElement(index) {
+ if (!this._cachedProviderElements)
+ this._cachedProviderElements = new Array(this._itemCount);
+ var element = this._cachedProviderElements[index];
+ if (!element) {
+ element = this._provider.itemElement(index);
+ this._cachedProviderElements[index] = element;
+ }
+ return element;
+ }
+
+ _rebuildCumulativeHeightsIfNeeded() {
+ if (this._cumulativeHeights)
+ return;
+ if (!this._itemCount)
+ return;
+ var firstActiveIndex = this._firstActiveIndex;
+ var lastActiveIndex = this._lastActiveIndex;
+ var height = 0;
+ this._cumulativeHeights = new Int32Array(this._itemCount);
+ for (var i = 0; i < this._itemCount; ++i) {
+ if (firstActiveIndex <= i && i <= lastActiveIndex)
+ height += this._renderedItems[i - firstActiveIndex].element().offsetHeight;
+ else
+ height += this._provider.fastHeight(i);
+ this._cumulativeHeights[i] = height;
+ }
+ }
+
+ /**
+ * @param {number} index
+ * @return {number}
+ */
+ _cachedItemHeight(index) {
+ return index === 0 ? this._cumulativeHeights[0] :
+ this._cumulativeHeights[index] - this._cumulativeHeights[index - 1];
+ }
+
+ /**
+ * @param {?Selection} selection
+ * @suppressGlobalPropertiesCheck
+ */
+ _isSelectionBackwards(selection) {
+ if (!selection || !selection.rangeCount)
+ return false;
+ var range = document.createRange();
+ range.setStart(selection.anchorNode, selection.anchorOffset);
+ range.setEnd(selection.focusNode, selection.focusOffset);
+ return range.collapsed;
+ }
+
+ /**
+ * @param {number} itemIndex
+ * @param {!Node} node
+ * @param {number} offset
+ * @return {!{item: number, node: !Node, offset: number}}
+ */
+ _createSelectionModel(itemIndex, node, offset) {
+ return {item: itemIndex, node: node, offset: offset};
+ }
+
+ /**
+ * @param {?Selection} selection
+ */
+ _updateSelectionModel(selection) {
+ var range = selection && selection.rangeCount ? selection.getRangeAt(0) : null;
+ if (!range || selection.isCollapsed || !this.element.hasSelection()) {
+ this._headSelection = null;
+ this._anchorSelection = null;
+ return false;
+ }
- /**
- * @override
- */
- wasShown: function() { },
+ var firstSelected = Number.MAX_VALUE;
+ var lastSelected = -1;
+
+ var hasVisibleSelection = false;
+ for (var i = 0; i < this._renderedItems.length; ++i) {
+ if (range.intersectsNode(this._renderedItems[i].element())) {
+ var index = i + this._firstActiveIndex;
+ firstSelected = Math.min(firstSelected, index);
+ lastSelected = Math.max(lastSelected, index);
+ hasVisibleSelection = true;
+ }
+ }
+ if (hasVisibleSelection) {
+ firstSelected =
+ this._createSelectionModel(firstSelected, /** @type {!Node} */ (range.startContainer), range.startOffset);
+ lastSelected =
+ this._createSelectionModel(lastSelected, /** @type {!Node} */ (range.endContainer), range.endOffset);
+ }
+ var topOverlap = range.intersectsNode(this._topGapElement) && this._topGapElement._active;
+ var bottomOverlap = range.intersectsNode(this._bottomGapElement) && this._bottomGapElement._active;
+ if (!topOverlap && !bottomOverlap && !hasVisibleSelection) {
+ this._headSelection = null;
+ this._anchorSelection = null;
+ return false;
+ }
- /**
- * @override
- * @return {!Element}
- */
- element: function()
- {
- return this._element;
- },
-};
+ if (!this._anchorSelection || !this._headSelection) {
+ this._anchorSelection = this._createSelectionModel(0, this.element, 0);
+ this._headSelection = this._createSelectionModel(this._itemCount - 1, this.element, this.element.children.length);
+ this._selectionIsBackward = false;
+ }
-WebInspector.ViewportControl.prototype = {
- /**
- * @return {boolean}
- */
- stickToBottom: function()
- {
- return this._stickToBottom;
- },
+ var isBackward = this._isSelectionBackwards(selection);
+ var startSelection = this._selectionIsBackward ? this._headSelection : this._anchorSelection;
+ var endSelection = this._selectionIsBackward ? this._anchorSelection : this._headSelection;
+ if (topOverlap && bottomOverlap && hasVisibleSelection) {
+ firstSelected = firstSelected.item < startSelection.item ? firstSelected : startSelection;
+ lastSelected = lastSelected.item > endSelection.item ? lastSelected : endSelection;
+ } else if (!hasVisibleSelection) {
+ firstSelected = startSelection;
+ lastSelected = endSelection;
+ } else if (topOverlap)
+ firstSelected = isBackward ? this._headSelection : this._anchorSelection;
+ else if (bottomOverlap)
+ lastSelected = isBackward ? this._anchorSelection : this._headSelection;
+
+ if (isBackward) {
+ this._anchorSelection = lastSelected;
+ this._headSelection = firstSelected;
+ } else {
+ this._anchorSelection = firstSelected;
+ this._headSelection = lastSelected;
+ }
+ this._selectionIsBackward = isBackward;
+ return true;
+ }
+
+ /**
+ * @param {?Selection} selection
+ */
+ _restoreSelection(selection) {
+ var anchorElement = null;
+ var anchorOffset;
+ if (this._firstActiveIndex <= this._anchorSelection.item && this._anchorSelection.item <= this._lastActiveIndex) {
+ anchorElement = this._anchorSelection.node;
+ anchorOffset = this._anchorSelection.offset;
+ } else {
+ if (this._anchorSelection.item < this._firstActiveIndex)
+ anchorElement = this._topGapElement;
+ else if (this._anchorSelection.item > this._lastActiveIndex)
+ anchorElement = this._bottomGapElement;
+ anchorOffset = this._selectionIsBackward ? 1 : 0;
+ }
- /**
- * @param {boolean} value
- */
- setStickToBottom: function(value)
- {
- this._stickToBottom = value;
- if (this._stickToBottom)
- this._observer.observe(this._contentElement, this._observerConfig);
- else
- this._observer.disconnect();
- },
+ var headElement = null;
+ var headOffset;
+ if (this._firstActiveIndex <= this._headSelection.item && this._headSelection.item <= this._lastActiveIndex) {
+ headElement = this._headSelection.node;
+ headOffset = this._headSelection.offset;
+ } else {
+ if (this._headSelection.item < this._firstActiveIndex)
+ headElement = this._topGapElement;
+ else if (this._headSelection.item > this._lastActiveIndex)
+ headElement = this._bottomGapElement;
+ headOffset = this._selectionIsBackward ? 0 : 1;
+ }
- /**
- * @param {!Event} event
- */
- _onCopy: function(event)
- {
- var text = this._selectedText();
- if (!text)
- return;
- event.preventDefault();
- event.clipboardData.setData("text/plain", text);
- },
+ selection.setBaseAndExtent(anchorElement, anchorOffset, headElement, headOffset);
+ }
+
+ refresh() {
+ this._observer.disconnect();
+ this._innerRefresh();
+ if (this._stickToBottom)
+ this._observer.observe(this._contentElement, this._observerConfig);
+ }
+
+ _innerRefresh() {
+ if (!this._visibleHeight())
+ return; // Do nothing for invisible controls.
+
+ if (!this._itemCount) {
+ for (var i = 0; i < this._renderedItems.length; ++i)
+ this._renderedItems[i].willHide();
+ this._renderedItems = [];
+ this._contentElement.removeChildren();
+ this._topGapElement.style.height = '0px';
+ this._bottomGapElement.style.height = '0px';
+ this._firstActiveIndex = -1;
+ this._lastActiveIndex = -1;
+ return;
+ }
- /**
- * @param {!Event} event
- */
- _onDragStart: function(event)
- {
- var text = this._selectedText();
- if (!text)
- return false;
- event.dataTransfer.clearData();
- event.dataTransfer.setData("text/plain", text);
- event.dataTransfer.effectAllowed = "copy";
- return true;
- },
+ var selection = this.element.getComponentSelection();
+ var shouldRestoreSelection = this._updateSelectionModel(selection);
- /**
- * @return {!Element}
- */
- contentElement: function()
- {
- return this._contentElement;
- },
+ var visibleFrom = this.element.scrollTop;
+ var visibleHeight = this._visibleHeight();
+ var isInvalidating = !this._cumulativeHeights;
- invalidate: function()
- {
+ for (var i = 0; i < this._renderedItems.length; ++i) {
+ // Tolerate 1-pixel error due to double-to-integer rounding errors.
+ if (this._cumulativeHeights &&
+ Math.abs(this._cachedItemHeight(this._firstActiveIndex + i) - this._renderedItems[i].element().offsetHeight) >
+ 1)
delete this._cumulativeHeights;
- delete this._cachedProviderElements;
- this._itemCount = this._provider.itemCount();
- this.refresh();
- },
-
- /**
- * @param {number} index
- * @return {?WebInspector.ViewportElement}
- */
- _providerElement: function(index)
- {
- if (!this._cachedProviderElements)
- this._cachedProviderElements = new Array(this._itemCount);
- var element = this._cachedProviderElements[index];
- if (!element) {
- element = this._provider.itemElement(index);
- this._cachedProviderElements[index] = element;
- }
- return element;
- },
-
- _rebuildCumulativeHeightsIfNeeded: function()
- {
- if (this._cumulativeHeights)
- return;
- if (!this._itemCount)
- return;
- var firstActiveIndex = this._firstActiveIndex;
- var lastActiveIndex = this._lastActiveIndex;
- var height = 0;
- this._cumulativeHeights = new Int32Array(this._itemCount);
- for (var i = 0; i < this._itemCount; ++i) {
- if (firstActiveIndex <= i && i <= lastActiveIndex)
- height += this._renderedItems[i - firstActiveIndex].element().offsetHeight;
- else
- height += this._provider.fastHeight(i);
- this._cumulativeHeights[i] = height;
- }
- },
-
- /**
- * @param {number} index
- * @return {number}
- */
- _cachedItemHeight: function(index)
- {
- return index === 0 ? this._cumulativeHeights[0] : this._cumulativeHeights[index] - this._cumulativeHeights[index - 1];
- },
-
- /**
- * @param {?Selection} selection
- * @suppressGlobalPropertiesCheck
- */
- _isSelectionBackwards: function(selection)
- {
- if (!selection || !selection.rangeCount)
- return false;
- var range = document.createRange();
- range.setStart(selection.anchorNode, selection.anchorOffset);
- range.setEnd(selection.focusNode, selection.focusOffset);
- return range.collapsed;
- },
-
- /**
- * @param {number} itemIndex
- * @param {!Node} node
- * @param {number} offset
- * @return {!{item: number, node: !Node, offset: number}}
- */
- _createSelectionModel: function(itemIndex, node, offset)
- {
- return {
- item: itemIndex,
- node: node,
- offset: offset
- };
- },
+ }
+ this._rebuildCumulativeHeightsIfNeeded();
+ var oldFirstActiveIndex = this._firstActiveIndex;
+ var oldLastActiveIndex = this._lastActiveIndex;
+ var activeHeight = visibleHeight * 2;
+ // When the viewport is scrolled to the bottom, using the cumulative heights estimate is not
+ // precise enough to determine next visible indices. This stickToBottom check avoids extra
+ // calls to refresh in those cases.
+ if (this._stickToBottom) {
+ this._firstActiveIndex =
+ Math.max(this._itemCount - Math.ceil(activeHeight / this._provider.minimumRowHeight()), 0);
+ this._lastActiveIndex = this._itemCount - 1;
+ } else {
+ this._firstActiveIndex = Math.max(
+ Array.prototype.lowerBound.call(
+ this._cumulativeHeights, visibleFrom + 1 - (activeHeight - visibleHeight) / 2),
+ 0);
+ // Proactively render more rows in case some of them will be collapsed without triggering refresh. @see crbug.com/390169
+ this._lastActiveIndex = this._firstActiveIndex + Math.ceil(activeHeight / this._provider.minimumRowHeight()) - 1;
+ this._lastActiveIndex = Math.min(this._lastActiveIndex, this._itemCount - 1);
+ }
- /**
- * @param {?Selection} selection
- */
- _updateSelectionModel: function(selection)
- {
- var range = selection && selection.rangeCount ? selection.getRangeAt(0) : null;
- if (!range || selection.isCollapsed || !this.element.hasSelection()) {
- this._headSelection = null;
- this._anchorSelection = null;
- return false;
- }
-
- var firstSelected = Number.MAX_VALUE;
- var lastSelected = -1;
-
- var hasVisibleSelection = false;
- for (var i = 0; i < this._renderedItems.length; ++i) {
- if (range.intersectsNode(this._renderedItems[i].element())) {
- var index = i + this._firstActiveIndex;
- firstSelected = Math.min(firstSelected, index);
- lastSelected = Math.max(lastSelected, index);
- hasVisibleSelection = true;
- }
- }
- if (hasVisibleSelection) {
- firstSelected = this._createSelectionModel(firstSelected, /** @type {!Node} */(range.startContainer), range.startOffset);
- lastSelected = this._createSelectionModel(lastSelected, /** @type {!Node} */(range.endContainer), range.endOffset);
- }
- var topOverlap = range.intersectsNode(this._topGapElement) && this._topGapElement._active;
- var bottomOverlap = range.intersectsNode(this._bottomGapElement) && this._bottomGapElement._active;
- if (!topOverlap && !bottomOverlap && !hasVisibleSelection) {
- this._headSelection = null;
- this._anchorSelection = null;
- return false;
- }
-
- if (!this._anchorSelection || !this._headSelection) {
- this._anchorSelection = this._createSelectionModel(0, this.element, 0);
- this._headSelection = this._createSelectionModel(this._itemCount - 1, this.element, this.element.children.length);
- this._selectionIsBackward = false;
- }
-
- var isBackward = this._isSelectionBackwards(selection);
- var startSelection = this._selectionIsBackward ? this._headSelection : this._anchorSelection;
- var endSelection = this._selectionIsBackward ? this._anchorSelection : this._headSelection;
- if (topOverlap && bottomOverlap && hasVisibleSelection) {
- firstSelected = firstSelected.item < startSelection.item ? firstSelected : startSelection;
- lastSelected = lastSelected.item > endSelection.item ? lastSelected : endSelection;
- } else if (!hasVisibleSelection) {
- firstSelected = startSelection;
- lastSelected = endSelection;
- } else if (topOverlap)
- firstSelected = isBackward ? this._headSelection : this._anchorSelection;
- else if (bottomOverlap)
- lastSelected = isBackward ? this._anchorSelection : this._headSelection;
-
- if (isBackward) {
- this._anchorSelection = lastSelected;
- this._headSelection = firstSelected;
- } else {
- this._anchorSelection = firstSelected;
- this._headSelection = lastSelected;
- }
- this._selectionIsBackward = isBackward;
- return true;
- },
+ var topGapHeight = this._cumulativeHeights[this._firstActiveIndex - 1] || 0;
+ var bottomGapHeight =
+ this._cumulativeHeights[this._cumulativeHeights.length - 1] - this._cumulativeHeights[this._lastActiveIndex];
/**
- * @param {?Selection} selection
+ * @this {WebInspector.ViewportControl}
*/
- _restoreSelection: function(selection)
- {
- var anchorElement = null;
- var anchorOffset;
- if (this._firstActiveIndex <= this._anchorSelection.item && this._anchorSelection.item <= this._lastActiveIndex) {
- anchorElement = this._anchorSelection.node;
- anchorOffset = this._anchorSelection.offset;
- } else {
- if (this._anchorSelection.item < this._firstActiveIndex)
- anchorElement = this._topGapElement;
- else if (this._anchorSelection.item > this._lastActiveIndex)
- anchorElement = this._bottomGapElement;
- anchorOffset = this._selectionIsBackward ? 1 : 0;
- }
-
- var headElement = null;
- var headOffset;
- if (this._firstActiveIndex <= this._headSelection.item && this._headSelection.item <= this._lastActiveIndex) {
- headElement = this._headSelection.node;
- headOffset = this._headSelection.offset;
- } else {
- if (this._headSelection.item < this._firstActiveIndex)
- headElement = this._topGapElement;
- else if (this._headSelection.item > this._lastActiveIndex)
- headElement = this._bottomGapElement;
- headOffset = this._selectionIsBackward ? 0 : 1;
- }
-
- selection.setBaseAndExtent(anchorElement, anchorOffset, headElement, headOffset);
- },
-
- refresh: function()
- {
- this._observer.disconnect();
- this._innerRefresh();
- if (this._stickToBottom)
- this._observer.observe(this._contentElement, this._observerConfig);
- },
-
- _innerRefresh: function()
- {
- if (!this._visibleHeight())
- return; // Do nothing for invisible controls.
-
- if (!this._itemCount) {
- for (var i = 0; i < this._renderedItems.length; ++i)
- this._renderedItems[i].willHide();
- this._renderedItems = [];
- this._contentElement.removeChildren();
- this._topGapElement.style.height = "0px";
- this._bottomGapElement.style.height = "0px";
- this._firstActiveIndex = -1;
- this._lastActiveIndex = -1;
- return;
- }
-
- var selection = this.element.getComponentSelection();
- var shouldRestoreSelection = this._updateSelectionModel(selection);
-
- var visibleFrom = this.element.scrollTop;
- var visibleHeight = this._visibleHeight();
- var isInvalidating = !this._cumulativeHeights;
-
- for (var i = 0; i < this._renderedItems.length; ++i) {
- // Tolerate 1-pixel error due to double-to-integer rounding errors.
- if (this._cumulativeHeights && Math.abs(this._cachedItemHeight(this._firstActiveIndex + i) - this._renderedItems[i].element().offsetHeight) > 1)
- delete this._cumulativeHeights;
- }
- this._rebuildCumulativeHeightsIfNeeded();
- var oldFirstActiveIndex = this._firstActiveIndex;
- var oldLastActiveIndex = this._lastActiveIndex;
- var activeHeight = visibleHeight * 2;
- // When the viewport is scrolled to the bottom, using the cumulative heights estimate is not
- // precise enough to determine next visible indices. This stickToBottom check avoids extra
- // calls to refresh in those cases.
- if (this._stickToBottom) {
- this._firstActiveIndex = Math.max(this._itemCount - Math.ceil(activeHeight / this._provider.minimumRowHeight()), 0);
- this._lastActiveIndex = this._itemCount - 1;
- } else {
- this._firstActiveIndex = Math.max(Array.prototype.lowerBound.call(this._cumulativeHeights, visibleFrom + 1 - (activeHeight - visibleHeight) / 2), 0);
- // Proactively render more rows in case some of them will be collapsed without triggering refresh. @see crbug.com/390169
- this._lastActiveIndex = this._firstActiveIndex + Math.ceil(activeHeight / this._provider.minimumRowHeight()) - 1;
- this._lastActiveIndex = Math.min(this._lastActiveIndex, this._itemCount - 1);
- }
-
- var topGapHeight = this._cumulativeHeights[this._firstActiveIndex - 1] || 0;
- var bottomGapHeight = this._cumulativeHeights[this._cumulativeHeights.length - 1] - this._cumulativeHeights[this._lastActiveIndex];
-
- /**
- * @this {WebInspector.ViewportControl}
- */
- function prepare()
- {
- this._topGapElement.style.height = topGapHeight + "px";
- this._bottomGapElement.style.height = bottomGapHeight + "px";
- this._topGapElement._active = !!topGapHeight;
- this._bottomGapElement._active = !!bottomGapHeight;
- this._contentElement.style.setProperty("height", "10000000px");
- }
-
- if (isInvalidating)
- this._fullViewportUpdate(prepare.bind(this));
- else
- this._partialViewportUpdate(oldFirstActiveIndex, oldLastActiveIndex, prepare.bind(this));
- this._contentElement.style.removeProperty("height");
- // Should be the last call in the method as it might force layout.
- if (shouldRestoreSelection)
- this._restoreSelection(selection);
- if (this._stickToBottom)
- this.element.scrollTop = 10000000;
- },
+ function prepare() {
+ this._topGapElement.style.height = topGapHeight + 'px';
+ this._bottomGapElement.style.height = bottomGapHeight + 'px';
+ this._topGapElement._active = !!topGapHeight;
+ this._bottomGapElement._active = !!bottomGapHeight;
+ this._contentElement.style.setProperty('height', '10000000px');
+ }
- /**
- * @param {function()} prepare
- */
- _fullViewportUpdate: function(prepare)
- {
- for (var i = 0; i < this._renderedItems.length; ++i)
- this._renderedItems[i].willHide();
- prepare();
- this._renderedItems = [];
- this._contentElement.removeChildren();
- for (var i = this._firstActiveIndex; i <= this._lastActiveIndex; ++i) {
- var viewportElement = this._providerElement(i);
- this._contentElement.appendChild(viewportElement.element());
- this._renderedItems.push(viewportElement);
- }
- for (var i = 0; i < this._renderedItems.length; ++i)
- this._renderedItems[i].wasShown();
- },
+ if (isInvalidating)
+ this._fullViewportUpdate(prepare.bind(this));
+ else
+ this._partialViewportUpdate(oldFirstActiveIndex, oldLastActiveIndex, prepare.bind(this));
+ this._contentElement.style.removeProperty('height');
+ // Should be the last call in the method as it might force layout.
+ if (shouldRestoreSelection)
+ this._restoreSelection(selection);
+ if (this._stickToBottom)
+ this.element.scrollTop = 10000000;
+ }
+
+ /**
+ * @param {function()} prepare
+ */
+ _fullViewportUpdate(prepare) {
+ for (var i = 0; i < this._renderedItems.length; ++i)
+ this._renderedItems[i].willHide();
+ prepare();
+ this._renderedItems = [];
+ this._contentElement.removeChildren();
+ for (var i = this._firstActiveIndex; i <= this._lastActiveIndex; ++i) {
+ var viewportElement = this._providerElement(i);
+ this._contentElement.appendChild(viewportElement.element());
+ this._renderedItems.push(viewportElement);
+ }
+ for (var i = 0; i < this._renderedItems.length; ++i)
+ this._renderedItems[i].wasShown();
+ }
+
+ /**
+ * @param {number} oldFirstActiveIndex
+ * @param {number} oldLastActiveIndex
+ * @param {function()} prepare
+ */
+ _partialViewportUpdate(oldFirstActiveIndex, oldLastActiveIndex, prepare) {
+ var willBeHidden = [];
+ for (var i = 0; i < this._renderedItems.length; ++i) {
+ var index = oldFirstActiveIndex + i;
+ if (index < this._firstActiveIndex || this._lastActiveIndex < index)
+ willBeHidden.push(this._renderedItems[i]);
+ }
+ for (var i = 0; i < willBeHidden.length; ++i)
+ willBeHidden[i].willHide();
+ prepare();
+ for (var i = 0; i < willBeHidden.length; ++i)
+ willBeHidden[i].element().remove();
- /**
- * @param {number} oldFirstActiveIndex
- * @param {number} oldLastActiveIndex
- * @param {function()} prepare
- */
- _partialViewportUpdate: function(oldFirstActiveIndex, oldLastActiveIndex, prepare)
- {
- var willBeHidden = [];
- for (var i = 0; i < this._renderedItems.length; ++i) {
- var index = oldFirstActiveIndex + i;
- if (index < this._firstActiveIndex || this._lastActiveIndex < index)
- willBeHidden.push(this._renderedItems[i]);
- }
- for (var i = 0; i < willBeHidden.length; ++i)
- willBeHidden[i].willHide();
- prepare();
- for (var i = 0; i < willBeHidden.length; ++i)
- willBeHidden[i].element().remove();
-
- this._renderedItems = [];
- var anchor = this._contentElement.firstChild;
- var wasShown = [];
- for (var i = this._firstActiveIndex; i <= this._lastActiveIndex; ++i) {
- var viewportElement = this._providerElement(i);
- var element = viewportElement.element();
- if (element !== anchor) {
- this._contentElement.insertBefore(element, anchor);
- wasShown.push(viewportElement);
- } else {
- anchor = anchor.nextSibling;
- }
- this._renderedItems.push(viewportElement);
- }
- for (var i = 0; i < wasShown.length; ++i)
- wasShown[i].wasShown();
- },
+ this._renderedItems = [];
+ var anchor = this._contentElement.firstChild;
+ var wasShown = [];
+ for (var i = this._firstActiveIndex; i <= this._lastActiveIndex; ++i) {
+ var viewportElement = this._providerElement(i);
+ var element = viewportElement.element();
+ if (element !== anchor) {
+ this._contentElement.insertBefore(element, anchor);
+ wasShown.push(viewportElement);
+ } else {
+ anchor = anchor.nextSibling;
+ }
+ this._renderedItems.push(viewportElement);
+ }
+ for (var i = 0; i < wasShown.length; ++i)
+ wasShown[i].wasShown();
+ }
+
+ /**
+ * @return {?string}
+ */
+ _selectedText() {
+ this._updateSelectionModel(this.element.getComponentSelection());
+ if (!this._headSelection || !this._anchorSelection)
+ return null;
+
+ var startSelection = null;
+ var endSelection = null;
+ if (this._selectionIsBackward) {
+ startSelection = this._headSelection;
+ endSelection = this._anchorSelection;
+ } else {
+ startSelection = this._anchorSelection;
+ endSelection = this._headSelection;
+ }
- /**
- * @return {?string}
- */
- _selectedText: function()
- {
- this._updateSelectionModel(this.element.getComponentSelection());
- if (!this._headSelection || !this._anchorSelection)
- return null;
-
- var startSelection = null;
- var endSelection = null;
- if (this._selectionIsBackward) {
- startSelection = this._headSelection;
- endSelection = this._anchorSelection;
- } else {
- startSelection = this._anchorSelection;
- endSelection = this._headSelection;
- }
-
- var textLines = [];
- for (var i = startSelection.item; i <= endSelection.item; ++i)
- textLines.push(this._providerElement(i).element().deepTextContent());
-
- var endSelectionElement = this._providerElement(endSelection.item).element();
- if (endSelection.node && endSelection.node.isSelfOrDescendant(endSelectionElement)) {
- var itemTextOffset = this._textOffsetInNode(endSelectionElement, endSelection.node, endSelection.offset);
- textLines[textLines.length - 1] = textLines.peekLast().substring(0, itemTextOffset);
- }
-
- var startSelectionElement = this._providerElement(startSelection.item).element();
- if (startSelection.node && startSelection.node.isSelfOrDescendant(startSelectionElement)) {
- var itemTextOffset = this._textOffsetInNode(startSelectionElement, startSelection.node, startSelection.offset);
- textLines[0] = textLines[0].substring(itemTextOffset);
- }
-
- return textLines.join("\n");
- },
+ var textLines = [];
+ for (var i = startSelection.item; i <= endSelection.item; ++i)
+ textLines.push(this._providerElement(i).element().deepTextContent());
- /**
- * @param {!Element} itemElement
- * @param {!Node} container
- * @param {number} offset
- * @return {number}
- */
- _textOffsetInNode: function(itemElement, container, offset)
- {
- var chars = 0;
- var node = itemElement;
- while ((node = node.traverseNextTextNode()) && !node.isSelfOrDescendant(container))
- chars += node.textContent.length;
- return chars + offset;
- },
+ var endSelectionElement = this._providerElement(endSelection.item).element();
+ if (endSelection.node && endSelection.node.isSelfOrDescendant(endSelectionElement)) {
+ var itemTextOffset = this._textOffsetInNode(endSelectionElement, endSelection.node, endSelection.offset);
+ textLines[textLines.length - 1] = textLines.peekLast().substring(0, itemTextOffset);
+ }
- /**
- * @param {!Event} event
- */
- _onScroll: function(event)
- {
- this.refresh();
- },
+ var startSelectionElement = this._providerElement(startSelection.item).element();
+ if (startSelection.node && startSelection.node.isSelfOrDescendant(startSelectionElement)) {
+ var itemTextOffset = this._textOffsetInNode(startSelectionElement, startSelection.node, startSelection.offset);
+ textLines[0] = textLines[0].substring(itemTextOffset);
+ }
- /**
- * @return {number}
- */
- firstVisibleIndex: function()
- {
- var firstVisibleIndex = Math.max(Array.prototype.lowerBound.call(this._cumulativeHeights, this.element.scrollTop + 1), 0);
- return Math.max(firstVisibleIndex, this._firstActiveIndex);
- },
+ return textLines.join('\n');
+ }
+
+ /**
+ * @param {!Element} itemElement
+ * @param {!Node} container
+ * @param {number} offset
+ * @return {number}
+ */
+ _textOffsetInNode(itemElement, container, offset) {
+ var chars = 0;
+ var node = itemElement;
+ while ((node = node.traverseNextTextNode()) && !node.isSelfOrDescendant(container))
+ chars += node.textContent.length;
+ return chars + offset;
+ }
+
+ /**
+ * @param {!Event} event
+ */
+ _onScroll(event) {
+ this.refresh();
+ }
+
+ /**
+ * @return {number}
+ */
+ firstVisibleIndex() {
+ var firstVisibleIndex =
+ Math.max(Array.prototype.lowerBound.call(this._cumulativeHeights, this.element.scrollTop + 1), 0);
+ return Math.max(firstVisibleIndex, this._firstActiveIndex);
+ }
+
+ /**
+ * @return {number}
+ */
+ lastVisibleIndex() {
+ var lastVisibleIndex;
+ if (this._stickToBottom)
+ lastVisibleIndex = this._itemCount - 1;
+ else
+ lastVisibleIndex =
+ this.firstVisibleIndex() + Math.ceil(this._visibleHeight() / this._provider.minimumRowHeight()) - 1;
+ return Math.min(lastVisibleIndex, this._lastActiveIndex);
+ }
+
+ /**
+ * @return {?Element}
+ */
+ renderedElementAt(index) {
+ if (index < this._firstActiveIndex)
+ return null;
+ if (index > this._lastActiveIndex)
+ return null;
+ return this._renderedItems[index - this._firstActiveIndex].element();
+ }
+
+ /**
+ * @param {number} index
+ * @param {boolean=} makeLast
+ */
+ scrollItemIntoView(index, makeLast) {
+ var firstVisibleIndex = this.firstVisibleIndex();
+ var lastVisibleIndex = this.lastVisibleIndex();
+ if (index > firstVisibleIndex && index < lastVisibleIndex)
+ return;
+ if (makeLast)
+ this.forceScrollItemToBeLast(index);
+ else if (index <= firstVisibleIndex)
+ this.forceScrollItemToBeFirst(index);
+ else if (index >= lastVisibleIndex)
+ this.forceScrollItemToBeLast(index);
+ }
+
+ /**
+ * @param {number} index
+ */
+ forceScrollItemToBeFirst(index) {
+ this.setStickToBottom(false);
+ this._rebuildCumulativeHeightsIfNeeded();
+ this.element.scrollTop = index > 0 ? this._cumulativeHeights[index - 1] : 0;
+ if (this.element.isScrolledToBottom())
+ this.setStickToBottom(true);
+ this.refresh();
+ }
+
+ /**
+ * @param {number} index
+ */
+ forceScrollItemToBeLast(index) {
+ this.setStickToBottom(false);
+ this._rebuildCumulativeHeightsIfNeeded();
+ this.element.scrollTop = this._cumulativeHeights[index] - this._visibleHeight();
+ if (this.element.isScrolledToBottom())
+ this.setStickToBottom(true);
+ this.refresh();
+ }
+
+ /**
+ * @return {number}
+ */
+ _visibleHeight() {
+ // Use offsetHeight instead of clientHeight to avoid being affected by horizontal scroll.
+ return this.element.offsetHeight;
+ }
+};
- /**
- * @return {number}
- */
- lastVisibleIndex: function()
- {
- var lastVisibleIndex;
- if (this._stickToBottom)
- lastVisibleIndex = this._itemCount - 1;
- else
- lastVisibleIndex = this.firstVisibleIndex() + Math.ceil(this._visibleHeight() / this._provider.minimumRowHeight()) - 1;
- return Math.min(lastVisibleIndex, this._lastActiveIndex);
- },
+/**
+ * @interface
+ */
+WebInspector.ViewportControl.Provider = function() {};
- /**
- * @return {?Element}
- */
- renderedElementAt: function(index)
- {
- if (index < this._firstActiveIndex)
- return null;
- if (index > this._lastActiveIndex)
- return null;
- return this._renderedItems[index - this._firstActiveIndex].element();
- },
+WebInspector.ViewportControl.Provider.prototype = {
+ /**
+ * @param {number} index
+ * @return {number}
+ */
+ fastHeight: function(index) {
+ return 0;
+ },
+
+ /**
+ * @return {number}
+ */
+ itemCount: function() {
+ return 0;
+ },
+
+ /**
+ * @return {number}
+ */
+ minimumRowHeight: function() {
+ return 0;
+ },
+
+ /**
+ * @param {number} index
+ * @return {?WebInspector.ViewportElement}
+ */
+ itemElement: function(index) {
+ return null;
+ }
+};
- /**
- * @param {number} index
- * @param {boolean=} makeLast
- */
- scrollItemIntoView: function(index, makeLast)
- {
- var firstVisibleIndex = this.firstVisibleIndex();
- var lastVisibleIndex = this.lastVisibleIndex();
- if (index > firstVisibleIndex && index < lastVisibleIndex)
- return;
- if (makeLast)
- this.forceScrollItemToBeLast(index);
- else if (index <= firstVisibleIndex)
- this.forceScrollItemToBeFirst(index);
- else if (index >= lastVisibleIndex)
- this.forceScrollItemToBeLast(index);
- },
+/**
+ * @interface
+ */
+WebInspector.ViewportElement = function() {};
+WebInspector.ViewportElement.prototype = {
+ willHide: function() {},
- /**
- * @param {number} index
- */
- forceScrollItemToBeFirst: function(index)
- {
- this.setStickToBottom(false);
- this._rebuildCumulativeHeightsIfNeeded();
- this.element.scrollTop = index > 0 ? this._cumulativeHeights[index - 1] : 0;
- if (this.element.isScrolledToBottom())
- this.setStickToBottom(true);
- this.refresh();
- },
+ wasShown: function() {},
- /**
- * @param {number} index
- */
- forceScrollItemToBeLast: function(index)
- {
- this.setStickToBottom(false);
- this._rebuildCumulativeHeightsIfNeeded();
- this.element.scrollTop = this._cumulativeHeights[index] - this._visibleHeight();
- if (this.element.isScrolledToBottom())
- this.setStickToBottom(true);
- this.refresh();
- },
+ /**
+ * @return {!Element}
+ */
+ element: function() {},
+};
- /**
- * @return {number}
- */
- _visibleHeight: function()
- {
- // Use offsetHeight instead of clientHeight to avoid being affected by horizontal scroll.
- return this.element.offsetHeight;
- }
+/**
+ * @implements {WebInspector.ViewportElement}
+ * @unrestricted
+ */
+WebInspector.StaticViewportElement = class {
+ /**
+ * @param {!Element} element
+ */
+ constructor(element) {
+ this._element = element;
+ }
+
+ /**
+ * @override
+ */
+ willHide() {
+ }
+
+ /**
+ * @override
+ */
+ wasShown() {
+ }
+
+ /**
+ * @override
+ * @return {!Element}
+ */
+ element() {
+ return this._element;
+ }
};
« no previous file with comments | « third_party/WebKit/Source/devtools/front_end/ui/View.js ('k') | third_party/WebKit/Source/devtools/front_end/ui/Widget.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698