Title: [141258] trunk/Source/WebCore
Revision
141258
Author
[email protected]
Date
2013-01-30 04:47:39 -0800 (Wed, 30 Jan 2013)

Log Message

Web Inspector: migrate file selection dialog to the viewport.
https://bugs.webkit.org/show_bug.cgi?id=108313

Reviewed by Vsevolod Vlasov.

Otherwise it takes too long to render.

* WebCore.gypi:
* WebCore.vcproj/WebCore.vcproj:
* inspector/compile-front-end.py:
* inspector/front-end/FilteredItemSelectionDialog.js:
(WebInspector.FilteredItemSelectionDialog):
(WebInspector.FilteredItemSelectionDialog.prototype.focus):
(WebInspector.FilteredItemSelectionDialog.prototype.onEnter):
(WebInspector.FilteredItemSelectionDialog.prototype._itemsLoaded):
(WebInspector.FilteredItemSelectionDialog.prototype._createItemElement):
(WebInspector.FilteredItemSelectionDialog.prototype._filterItems):
(WebInspector.FilteredItemSelectionDialog.prototype._onKeyDown.updateSelection):
(WebInspector.FilteredItemSelectionDialog.prototype._onKeyDown):
(WebInspector.FilteredItemSelectionDialog.prototype._updateSelection):
(WebInspector.FilteredItemSelectionDialog.prototype._onClick):
(WebInspector.FilteredItemSelectionDialog.prototype._onMouseMove):
(WebInspector.FilteredItemSelectionDialog.prototype.itemCount):
(WebInspector.FilteredItemSelectionDialog.prototype.itemElement):
* inspector/front-end/ViewportControl.js: Added.
(WebInspector.ViewportControl):
(WebInspector.ViewportControl.Provider):
(WebInspector.ViewportControl.Provider.prototype.itemCount):
(WebInspector.ViewportControl.Provider.prototype.itemElement):
(WebInspector.ViewportControl.prototype.contentElement):
(WebInspector.ViewportControl.prototype.refresh):
(WebInspector.ViewportControl.prototype._onScroll):
(WebInspector.ViewportControl.prototype.rowsPerViewport):
(WebInspector.ViewportControl.prototype.firstVisibleIndex):
(WebInspector.ViewportControl.prototype.lastVisibleIndex):
(WebInspector.ViewportControl.prototype.renderedElementAt):
(WebInspector.ViewportControl.prototype.scrollItemIntoView):
* inspector/front-end/WebKit.qrc:
* inspector/front-end/filteredItemSelectionDialog.css:
(.js-outline-dialog .container div.item.selected):
(.js-outline-dialog .container div.item span.highlight):
* inspector/front-end/inspector.html:

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (141257 => 141258)


--- trunk/Source/WebCore/ChangeLog	2013-01-30 12:43:51 UTC (rev 141257)
+++ trunk/Source/WebCore/ChangeLog	2013-01-30 12:47:39 UTC (rev 141258)
@@ -1,3 +1,48 @@
+2013-01-30  Pavel Feldman  <[email protected]>
+
+        Web Inspector: migrate file selection dialog to the viewport.
+        https://bugs.webkit.org/show_bug.cgi?id=108313
+
+        Reviewed by Vsevolod Vlasov.
+
+        Otherwise it takes too long to render.
+
+        * WebCore.gypi:
+        * WebCore.vcproj/WebCore.vcproj:
+        * inspector/compile-front-end.py:
+        * inspector/front-end/FilteredItemSelectionDialog.js:
+        (WebInspector.FilteredItemSelectionDialog):
+        (WebInspector.FilteredItemSelectionDialog.prototype.focus):
+        (WebInspector.FilteredItemSelectionDialog.prototype.onEnter):
+        (WebInspector.FilteredItemSelectionDialog.prototype._itemsLoaded):
+        (WebInspector.FilteredItemSelectionDialog.prototype._createItemElement):
+        (WebInspector.FilteredItemSelectionDialog.prototype._filterItems):
+        (WebInspector.FilteredItemSelectionDialog.prototype._onKeyDown.updateSelection):
+        (WebInspector.FilteredItemSelectionDialog.prototype._onKeyDown):
+        (WebInspector.FilteredItemSelectionDialog.prototype._updateSelection):
+        (WebInspector.FilteredItemSelectionDialog.prototype._onClick):
+        (WebInspector.FilteredItemSelectionDialog.prototype._onMouseMove):
+        (WebInspector.FilteredItemSelectionDialog.prototype.itemCount):
+        (WebInspector.FilteredItemSelectionDialog.prototype.itemElement):
+        * inspector/front-end/ViewportControl.js: Added.
+        (WebInspector.ViewportControl):
+        (WebInspector.ViewportControl.Provider):
+        (WebInspector.ViewportControl.Provider.prototype.itemCount):
+        (WebInspector.ViewportControl.Provider.prototype.itemElement):
+        (WebInspector.ViewportControl.prototype.contentElement):
+        (WebInspector.ViewportControl.prototype.refresh):
+        (WebInspector.ViewportControl.prototype._onScroll):
+        (WebInspector.ViewportControl.prototype.rowsPerViewport):
+        (WebInspector.ViewportControl.prototype.firstVisibleIndex):
+        (WebInspector.ViewportControl.prototype.lastVisibleIndex):
+        (WebInspector.ViewportControl.prototype.renderedElementAt):
+        (WebInspector.ViewportControl.prototype.scrollItemIntoView):
+        * inspector/front-end/WebKit.qrc:
+        * inspector/front-end/filteredItemSelectionDialog.css:
+        (.js-outline-dialog .container div.item.selected):
+        (.js-outline-dialog .container div.item span.highlight):
+        * inspector/front-end/inspector.html:
+
 2013-01-30  Andrey Lushnikov  <[email protected]>
 
         Web Inspector: implement highlight range API

Modified: trunk/Source/WebCore/WebCore.gypi (141257 => 141258)


--- trunk/Source/WebCore/WebCore.gypi	2013-01-30 12:43:51 UTC (rev 141257)
+++ trunk/Source/WebCore/WebCore.gypi	2013-01-30 12:47:39 UTC (rev 141258)
@@ -5264,6 +5264,7 @@
             'inspector/front-end/UserMetrics.js',
             'inspector/front-end/utilities.js',
             'inspector/front-end/View.js',
+            'inspector/front-end/ViewportControl.js',
             'inspector/front-end/WorkerManager.js',
             'inspector/front-end/Workspace.js',
             'inspector/front-end/dialog.css',

Modified: trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj (141257 => 141258)


--- trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj	2013-01-30 12:43:51 UTC (rev 141257)
+++ trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj	2013-01-30 12:47:39 UTC (rev 141258)
@@ -77809,6 +77809,10 @@
 					>
 				</File>
 				<File
+					RelativePath="..\inspector\front-end\ViewportControl.js"
+					>
+				</File>
+				<File
 					RelativePath="..\inspector\front-end\WatchExpressionsSidebarPane.js"
 					>
 				</File>

Modified: trunk/Source/WebCore/inspector/compile-front-end.py (141257 => 141258)


--- trunk/Source/WebCore/inspector/compile-front-end.py	2013-01-30 12:43:51 UTC (rev 141257)
+++ trunk/Source/WebCore/inspector/compile-front-end.py	2013-01-30 12:47:39 UTC (rev 141258)
@@ -160,6 +160,7 @@
             "Toolbar.js",
             "UIUtils.js",
             "View.js",
+            "ViewportControl.js",
             "treeoutline.js",
         ]
     },

Modified: trunk/Source/WebCore/inspector/front-end/FilteredItemSelectionDialog.js (141257 => 141258)


--- trunk/Source/WebCore/inspector/front-end/FilteredItemSelectionDialog.js	2013-01-30 12:43:51 UTC (rev 141257)
+++ trunk/Source/WebCore/inspector/front-end/FilteredItemSelectionDialog.js	2013-01-30 12:47:39 UTC (rev 141258)
@@ -31,6 +31,7 @@
 /**
  * @constructor
  * @extends {WebInspector.DialogDelegate}
+ * @implements {WebInspector.ViewportControl.Provider}
  * @param {WebInspector.SelectionDialogContentProvider} delegate
  */
 WebInspector.FilteredItemSelectionDialog = function(delegate)
@@ -44,25 +45,23 @@
     this.element = document.createElement("div");
     this.element.className = "js-outline-dialog";
     this.element.addEventListener("keydown", this._onKeyDown.bind(this), false);
-    this.element.addEventListener("mousemove", this._onMouseMove.bind(this), false);
-    this.element.addEventListener("click", this._onClick.bind(this), false);
     var styleElement = this.element.createChild("style");
     styleElement.type = "text/css";
     styleElement.textContent = xhr.responseText;
 
-    this._itemElements = [];
-    this._elementIndexes = new Map();
-    this._elementHighlightChanges = new Map();
-
     this._promptElement = this.element.createChild("input", "monospace");
     this._promptElement.type = "text";
     this._promptElement.setAttribute("spellcheck", "false");
 
     this._progressElement = this.element.createChild("div", "progress");
 
-    this._itemElementsContainer = document.createElement("div");
-    this._itemElementsContainer.className = "container monospace";
-    this._itemElementsContainer.addEventListener("scroll", this._onScroll.bind(this), false);
+    this._filteredItems = [];
+    this._viewportControl = new WebInspector.ViewportControl(this);
+    this._itemElementsContainer = this._viewportControl.element;
+    this._itemElementsContainer.addStyleClass("container");
+    this._itemElementsContainer.addStyleClass("monospace");
+    this._itemElementsContainer.addEventListener("mousemove", this._onMouseMove.bind(this), false);
+    this._itemElementsContainer.addEventListener("click", this._onClick.bind(this), false);
     this.element.appendChild(this._itemElementsContainer);
 
     this._delegate = delegate;
@@ -94,6 +93,8 @@
     focus: function()
     {
         WebInspector.setCurrentFocusElement(this._promptElement);
+        if (this._filteredItems.length && !this._viewportControl.lastVisibleIndex())
+            this._viewportControl.refresh();
     },
 
     willHide: function()
@@ -107,9 +108,9 @@
 
     onEnter: function()
     {
-        if (!this._selectedElement)
+        if (typeof this._selectedIndexInFiltered !== "number")
             return;
-        this._delegate.selectItem(this._elementIndexes.get(this._selectedElement), this._promptElement.value.trim());
+        this._delegate.selectItem(this._filteredItems[this._selectedIndexInFiltered], this._promptElement.value.trim());
     },
 
     /**
@@ -120,8 +121,6 @@
      */
     _itemsLoaded: function(index, chunkLength, chunkIndex, chunkCount)
     {
-        for (var i = index; i < index + chunkLength; ++i)
-            this._itemElementsContainer.appendChild(this._createItemElement(i));
         this._filterItems();
 
         if (chunkIndex === chunkCount)
@@ -135,49 +134,37 @@
 
     /**
      * @param {number} index
+     * @return {Element}
      */
     _createItemElement: function(index)
     {
-        if (this._itemElements[index])
-            return this._itemElements[index];
-
         var itemElement = document.createElement("div");
         itemElement.className = "item";
         itemElement._titleElement = itemElement.createChild("span");
         itemElement._titleElement.textContent = this._delegate.itemTitleAt(index);
         itemElement._titleSuffixElement = itemElement.createChild("span");
+        itemElement._titleSuffixElement.textContent = this._delegate.itemSuffixAt(index);
         itemElement._subtitleElement = itemElement.createChild("span", "subtitle");
         itemElement._subtitleElement.textContent = this._delegate.itemSubtitleAt(index);
-        this._elementIndexes.put(itemElement, index);
-        this._itemElements.push(itemElement);
-        return itemElement;
-    },
+        itemElement._index = index;
 
-    /**
-     * @param {Element} itemElement
-     */
-    _hideItemElement: function(itemElement)
-    {
-        itemElement.style.display = "none";
-    },
+        var key = this._delegate.itemKeyAt(index);
+        var ranges = [];
+        var match;
+        if (this._query) {
+            var regex = this._createSearchRegExp(this._query, true);
+            while ((match = regex.exec(key)) !== null && match[0])
+                ranges.push({ offset: match.index, length: regex.lastIndex - match.index });
+            if (ranges.length)
+                WebInspector.highlightRangesWithStyleClass(itemElement, ranges, "highlight");
+        }
+        if (index === this._filteredItems[this._selectedIndexInFiltered])
+            itemElement.addStyleClass("selected");
 
-    /**
-     * @param {Element} itemElement
-     */
-    _itemElementVisible: function(itemElement)
-    {
-        return itemElement.style.display !== "none";
+        return itemElement;
     },
 
     /**
-     * @param {Element} itemElement
-     */
-    _showItemElement: function(itemElement)
-    {
-        itemElement.style.display = "";
-    },
-
-    /**
      * @param {string} query
      * @param {boolean=} isGlobal
      */
@@ -211,79 +198,57 @@
         delete this._filterTimer;
 
         var query = this._promptElement.value;
-        query = query.trim();
+        this._query = query.trim();
         var regex = this._createSearchRegExp(query);
 
-        var firstElement;
-        for (var i = 0; i < this._itemElements.length; ++i) {
-            var itemElement = this._itemElements[i];
-            itemElement._titleSuffixElement.textContent = this._delegate.itemSuffixAt(i);
+        var oldSelectedAbsoluteIndex = this._filteredItems[this._selectedIndexInFiltered];
+        this._filteredItems = [];
+        this._selectedIndexInFiltered = 0;
+        for (var i = 0; i < this._delegate.itemsCount(); ++i) {
+            var title = this._delegate.itemTitleAt(i);
             if (regex.test(this._delegate.itemKeyAt(i))) {
-                this._showItemElement(itemElement);
-                if (!firstElement)
-                    firstElement = itemElement;
-            } else
-                this._hideItemElement(itemElement);
+                if (i === oldSelectedAbsoluteIndex) 
+                    this._selectedIndexInFiltered = this._filteredItems.length;
+                this._filteredItems.push(i);
+            }
         }
 
-        if (!this._selectedElement || !this._itemElementVisible(this._selectedElement))
-            this._updateSelection(firstElement);
-
-        if (query) {
-            this._highlightItems(query);
-            this._query = query;
-        } else {
-            this._clearHighlight();
-            delete this._query;
-        }
+        this._viewportControl.refresh();
+        this._updateSelection(this._selectedIndexInFiltered);
     },
 
     _onKeyDown: function(event)
     {
-        function nextItem(itemElement, isPageScroll, forward)
-        {
-            var scrollItemsLeft = isPageScroll && this._rowsPerViewport ? this._rowsPerViewport : 1;
-            var candidate = itemElement;
-            var lastVisibleCandidate = candidate;
-            do {
-                candidate = forward ? candidate.nextSibling : candidate.previousSibling;
-                if (!candidate) {
-                    if (isPageScroll)
-                        return lastVisibleCandidate;
-                    else
-                        candidate = forward ? this._itemElementsContainer.firstChild : this._itemElementsContainer.lastChild;
-                }
-                if (!this._itemElementVisible(candidate))
-                    continue;
-                lastVisibleCandidate = candidate;
-                --scrollItemsLeft;
-            } while (scrollItemsLeft && candidate !== this._selectedElement);
+        if (typeof this._selectedIndexInFiltered === "number") {
+            var newSelectedIndex = this._selectedIndexInFiltered;
 
-            return candidate;
-        }
+            function updateSelection(makeLast)
+            {
+                this._viewportControl.scrollItemIntoView(newSelectedIndex, makeLast); 
+                this._updateSelection(newSelectedIndex);
+                event.consume(true);
+            }
 
-        if (this._selectedElement) {
-            var candidate;
             switch (event.keyCode) {
             case WebInspector.KeyboardShortcut.Keys.Down.code:
-                candidate = nextItem.call(this, this._selectedElement, false, true);
+                if (++newSelectedIndex >= this._filteredItems.length)
+                    newSelectedIndex = this._filteredItems.length - 1;
+                updateSelection.call(this, true);
                 break;
             case WebInspector.KeyboardShortcut.Keys.Up.code:
-                candidate = nextItem.call(this, this._selectedElement, false, false);
+                if (--newSelectedIndex < 0)
+                    newSelectedIndex = 0;
+                updateSelection.call(this, false);
                 break;
             case WebInspector.KeyboardShortcut.Keys.PageDown.code:
-                candidate = nextItem.call(this, this._selectedElement, true, true);
+                newSelectedIndex = Math.min(newSelectedIndex + this._viewportControl.rowsPerViewport(), this._filteredItems.length - 1);
+                updateSelection.call(this, true);
                 break;
             case WebInspector.KeyboardShortcut.Keys.PageUp.code:
-                candidate = nextItem.call(this, this._selectedElement, true, false);
+                newSelectedIndex = Math.max(newSelectedIndex - this._viewportControl.rowsPerViewport(), 0);
+                updateSelection.call(this, false);
                 break;
             }
-
-            if (candidate) {
-                this._updateSelection(candidate);
-                event.preventDefault();
-                return;
-            }
         }
 
         if (event.keyIdentifier !== "Shift" && event.keyIdentifier !== "Ctrl" && event.keyIdentifier !== "Meta" && event.keyIdentifier !== "Left" && event.keyIdentifier !== "Right")
@@ -298,24 +263,19 @@
     },
 
     /**
-     * @param {Element} newSelectedElement
+     * @param {number} index  
      */
-    _updateSelection: function(newSelectedElement)
-    {
-        if (this._selectedElement === newSelectedElement)
-            return;
-        if (this._selectedElement)
-            this._selectedElement.removeStyleClass("selected");
-
-        this._selectedElement = newSelectedElement;
-        if (newSelectedElement) {
-            newSelectedElement.addStyleClass("selected");
-            newSelectedElement.scrollIntoViewIfNeeded(false);
-            if (!this._itemHeight) {
-                this._itemHeight = newSelectedElement.offsetHeight;
-                this._rowsPerViewport = Math.floor(this._itemElementsContainer.offsetHeight / this._itemHeight);
-            }
-        }
+    _updateSelection: function(index)
+    { 
+        var element = this._viewportControl.renderedElementAt(this._selectedIndexInFiltered);
+        if (element)
+            element.removeStyleClass("selected");
+        this._selectedIndexInFiltered = index;
+        element = this._viewportControl.renderedElementAt(index); 
+        if (element)
+            element.addStyleClass("selected");
+        else
+            this._viewportControl.refresh();
     },
 
     _onClick: function(event)
@@ -323,97 +283,40 @@
         var itemElement = event.target.enclosingNodeOrSelfWithClass("item");
         if (!itemElement)
             return;
-        this._updateSelection(itemElement);
-        this._delegate.selectItem(this._elementIndexes.get(this._selectedElement), this._promptElement.value.trim());
+        this._delegate.selectItem(itemElement._index, this._promptElement.value.trim());
         WebInspector.Dialog.hide();
     },
 
     _onMouseMove: function(event)
     {
+        if (event.pageX === this._lastMouseX && event.pageY === this._lastMouseY)
+            return;
+        this._lastMouseX = event.pageX;
+        this._lastMouseY = event.pageY;
         var itemElement = event.target.enclosingNodeOrSelfWithClass("item");
         if (!itemElement)
             return;
-        this._updateSelection(itemElement);
+        this._updateSelection(itemElement._index);
     },
 
-    _onScroll: function()
-    {
-        if (this._query)
-            this._highlightItems(this._query);
-        else
-            this._clearHighlight();
-    },
-
     /**
-     * @param {string} query
+     * @return {number}
      */
-    _highlightItems: function(query)
+    itemCount: function()
     {
-        var regex = this._createSearchRegExp(query, true);
-        var elementsToHighlight = [];
-        for (var i = 0; i < this._delegate.itemsCount(); ++i) {
-            var itemElement = this._itemElements[i];
-            if (this._itemElementVisible(itemElement) && this._itemElementInViewport(itemElement))
-                elementsToHighlight.push(itemElement);
-        }
-        for (var i = 0; i < elementsToHighlight.length; ++i)
-            this._highlightItem(elementsToHighlight[i], regex);
+        return this._filteredItems.length;
     },
 
-    _clearHighlight: function()
-    {
-        for (var i = 0; i < this._delegate.itemsCount(); ++i)
-            this._clearElementHighlight(this._itemElements[i]);
-    },
-
     /**
-     * @param {Element} itemElement
+     * @param {number} index
+     * @return {Element}
      */
-    _clearElementHighlight: function(itemElement)
+    itemElement: function(index)
     {
-        var changes = this._elementHighlightChanges.get(itemElement)
-        if (changes) {
-            WebInspector.revertDomChanges(changes);
-            this._elementHighlightChanges.remove(itemElement);
-        }
+        var delegateIndex = this._filteredItems[index];
+        return this._createItemElement(delegateIndex); 
     },
 
-    /**
-     * @param {Element} itemElement
-     * @param {RegExp} regex
-     */
-    _highlightItem: function(itemElement, regex)
-    {
-        this._clearElementHighlight(itemElement);
-
-        var key = this._delegate.itemKeyAt(this._elementIndexes.get(itemElement));
-        var ranges = [];
-
-        var match;
-        while ((match = regex.exec(key)) !== null && match[0]) {
-            ranges.push({ offset: match.index, length: regex.lastIndex - match.index });
-        }
-
-        var changes = [];
-        WebInspector.highlightRangesWithStyleClass(itemElement, ranges, "highlight", changes);
-
-        if (changes.length)
-            this._elementHighlightChanges.put(itemElement, changes);
-    },
-
-    /**
-     * @param {Element} itemElement
-     * @return {boolean}
-     */
-    _itemElementInViewport: function(itemElement)
-    {
-        if (itemElement.offsetTop + this._itemHeight < this._itemElementsContainer.scrollTop)
-            return false;
-        if (itemElement.offsetTop > this._itemElementsContainer.scrollTop + this._itemHeight * (this._rowsPerViewport + 1))
-            return false;
-        return true;
-    },
-
     __proto__: WebInspector.DialogDelegate.prototype
 }
 
@@ -636,7 +539,11 @@
     {
         return uiSourceCode1.parsedURL.lastPathComponent.compareTo(uiSourceCode2.parsedURL.lastPathComponent);
     }
-    this._uiSourceCodes.sort(compareFunction);
+    if (this._uiSourceCodes.length > 1000) {
+        this._uiSourceCodes.sortRange(compareFunction, 0, this._uiSourceCodes.length - 1, 1000);
+        setTimeout(function() { this._uiSourceCodes.sort(compareFunction); }.bind(this), 0);
+    } else
+        this._uiSourceCodes.sort(compareFunction);
 }
 
 WebInspector.OpenResourceDialog.prototype = {

Added: trunk/Source/WebCore/inspector/front-end/ViewportControl.js (0 => 141258)


--- trunk/Source/WebCore/inspector/front-end/ViewportControl.js	                        (rev 0)
+++ trunk/Source/WebCore/inspector/front-end/ViewportControl.js	2013-01-30 12:47:39 UTC (rev 141258)
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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
+ */
+WebInspector.ViewportControl = function(provider)
+{
+    this.element = document.createElement("div");
+    this.element.className = "fill";
+    this.element.style.overflow = "auto";
+    this._topGapElement = this.element.createChild("div");
+    this._contentElement = this.element.createChild("div");
+    this._bottomGapElement = this.element.createChild("div");
+
+    this._provider = provider;
+    this.element.addEventListener("scroll", this._onScroll.bind(this), false);
+    this._firstVisibleIndex = 0;
+    this._lastVisibleIndex = 0;
+}
+
+/**
+ * @interface
+ */
+WebInspector.ViewportControl.Provider = function() 
+{
+}
+
+WebInspector.ViewportControl.Provider.prototype = { 
+    /**
+     * @return {number}
+     */
+    itemCount: function() { return 0; },
+
+    /**
+     * @param {number} index
+     * @return {Element}
+     */
+    itemElement: function(index) { return null; }
+}
+
+WebInspector.ViewportControl.prototype = {
+    /**
+     * @return {Element}
+     */
+    contentElement: function()
+    {
+        return this._contentElement;
+    },
+
+    refresh: function()
+    {
+        var itemCount = this._provider.itemCount();
+
+        if (!this._rowHeight) {
+            var firstElement = this._provider.itemElement(0);
+            this._rowHeight = firstElement.measurePreferredSize().height;
+        }
+
+        var visibleFrom = this.element.scrollTop;
+        var visibleTo = visibleFrom + this.element.clientHeight;
+
+        this._firstVisibleIndex = Math.floor(visibleFrom / this._rowHeight);
+        this._lastVisibleIndex = Math.max(0, Math.min(Math.ceil(visibleTo / this._rowHeight), itemCount) - 1);
+        this._topGapElement.style.height = (this._rowHeight * this._firstVisibleIndex) + "px";
+        this._bottomGapElement.style.height = (this._rowHeight * (itemCount - this._lastVisibleIndex - 1)) + "px"; 
+
+        this._contentElement.removeChildren();
+        for (var i = this._firstVisibleIndex; i <= this._lastVisibleIndex; ++i)
+            this._contentElement.appendChild(this._provider.itemElement(i));
+    },
+
+    /**
+     * @param {Event} event
+     */
+    _onScroll: function(event)
+    {
+        this.refresh();
+    },
+
+    /**
+     * @return {number}
+     */
+    rowsPerViewport: function()
+    {
+        return Math.floor(this.element.clientHeight / this._rowHeight);
+    },
+
+    /**
+     * @return {number}
+     */
+    firstVisibleIndex: function()
+    {
+        return this._firstVisibleIndex;
+    },
+
+    /**
+     * @return {number}
+     */
+    lastVisibleIndex: function()
+    {
+        return this._lastVisibleIndex;
+    },
+
+    /**
+     * @return {?Element}
+     */
+    renderedElementAt: function(index)
+    {
+        if (index < this._firstVisibleIndex)
+            return null;
+        if (index > this._lastVisibleIndex)
+            return null;
+        return this._contentElement.childNodes[index - this._firstVisibleIndex];
+    },
+
+    /**
+     * @param {number} index
+     * @param {boolean=} makeLast
+     */
+    scrollItemIntoView: function(index, makeLast)
+    {
+        if (index > this._firstVisibleIndex && index < this._lastVisibleIndex)
+            return;
+
+        if (makeLast)
+            this.element.scrollTop = this._rowHeight * (index + 1) - this.element.clientHeight;
+        else
+            this.element.scrollTop = this._rowHeight * index;
+    }
+}
Property changes on: trunk/Source/WebCore/inspector/front-end/ViewportControl.js
___________________________________________________________________

Added: svn:eol-style

Modified: trunk/Source/WebCore/inspector/front-end/WebKit.qrc (141257 => 141258)


--- trunk/Source/WebCore/inspector/front-end/WebKit.qrc	2013-01-30 12:43:51 UTC (rev 141257)
+++ trunk/Source/WebCore/inspector/front-end/WebKit.qrc	2013-01-30 12:47:39 UTC (rev 141258)
@@ -224,6 +224,7 @@
     <file>UserMetrics.js</file>
     <file>utilities.js</file>
     <file>View.js</file>
+    <file>ViewportControl.js</file>
     <file>WatchExpressionsSidebarPane.js</file>
     <file>WorkerManager.js</file>
     <file>WorkersSidebarPane.js</file>

Modified: trunk/Source/WebCore/inspector/front-end/filteredItemSelectionDialog.css (141257 => 141258)


--- trunk/Source/WebCore/inspector/front-end/filteredItemSelectionDialog.css	2013-01-30 12:43:51 UTC (rev 141257)
+++ trunk/Source/WebCore/inspector/front-end/filteredItemSelectionDialog.css	2013-01-30 12:47:39 UTC (rev 141258)
@@ -37,11 +37,11 @@
     float: right;
 }
 
-.js-outline-dialog > .container > div.item.selected {
+.js-outline-dialog .container div.item.selected {
     background-color: rgb(224, 224, 224);
 }
 
-.js-outline-dialog > .container > div.item span.highlight {
+.js-outline-dialog .container div.item span.highlight {
     color: black;
     font-weight: bold;
 }

Modified: trunk/Source/WebCore/inspector/front-end/inspector.html (141257 => 141258)


--- trunk/Source/WebCore/inspector/front-end/inspector.html	2013-01-30 12:43:51 UTC (rev 141257)
+++ trunk/Source/WebCore/inspector/front-end/inspector.html	2013-01-30 12:47:39 UTC (rev 141258)
@@ -60,6 +60,7 @@
     <script type="text/_javascript_" src=""
     <script type="text/_javascript_" src=""
     <script type="text/_javascript_" src=""
+    <script type="text/_javascript_" src="" 
     <script type="text/_javascript_" src=""
     <script type="text/_javascript_" src=""
     <script type="text/_javascript_" src=""

Modified: trunk/Source/WebCore/inspector/front-end/utilities.js (141257 => 141258)


--- trunk/Source/WebCore/inspector/front-end/utilities.js	2013-01-30 12:43:51 UTC (rev 141257)
+++ trunk/Source/WebCore/inspector/front-end/utilities.js	2013-01-30 12:47:39 UTC (rev 141258)
@@ -329,7 +329,7 @@
                 quickSortFirstK(array, comparator, pivotNewIndex + 1, right, k);
         }
 
-        if (leftBound === 0 && rightBound === (this.length - 1) && k === this.length)
+        if (leftBound === 0 && rightBound === (this.length - 1) && k >= this.length)
             this.sort(comparator);
         else
             quickSortFirstK(this, comparator, leftBound, rightBound, k);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to