Title: [109107] trunk
Revision
109107
Author
[email protected]
Date
2012-02-28 08:18:58 -0800 (Tue, 28 Feb 2012)

Log Message

Web Inspector: move filtering of the timeline records into the presentation model.
https://bugs.webkit.org/show_bug.cgi?id=79789

Reviewed by Yury Semikhatsky.

Source/WebCore:

* inspector/front-end/TimelineModel.js:
* inspector/front-end/TimelineOverviewPane.js:
(WebInspector.TimelineOverviewPane):
(WebInspector.TimelineOverviewPane.prototype.setStartAtZero):
(WebInspector.TimelineOverviewPane.prototype.scrollWindow):
(WebInspector.TimelineOverviewPane.prototype.accept):
(WebInspector.TimelineOverviewPane.prototype._setWindowIndices):
(WebInspector.TimelineStartAtZeroOverview):
(WebInspector.TimelineStartAtZeroOverview.prototype._onWindowChanged):
* inspector/front-end/TimelinePanel.js:
(WebInspector.TimelinePanel):
(WebInspector.TimelinePanel.prototype._createStatusbarButtons):
(WebInspector.TimelinePanel.prototype._updateRecordsCounter):
(WebInspector.TimelinePanel.prototype._glueParentButtonClicked):
(WebInspector.TimelinePanel.prototype._toggleStartAtZeroButtonClicked):
(WebInspector.TimelinePanel.prototype._innerAddRecordToTimeline):
(WebInspector.TimelinePanel.prototype._resetPanel):
(WebInspector.TimelinePanel.prototype._refresh):
(WebInspector.TimelinePanel.prototype.revealRecordAt):
(WebInspector.TimelinePanel.prototype._refreshRecords):
(WebInspector.TimelineExpandableElement.prototype._update):
(WebInspector.TimelineCategoryFilter):
(WebInspector.TimelineCategoryFilter.prototype.accept):
(WebInspector.TimelineIsLongFilter):
(WebInspector.TimelineIsLongFilter.prototype.accept):
* inspector/front-end/TimelinePresentationModel.js:
(WebInspector.TimelinePresentationModel):
(WebInspector.TimelinePresentationModel.prototype.addFilter):
(WebInspector.TimelinePresentationModel.prototype.reset):
(WebInspector.TimelinePresentationModel.prototype.minimumRecordTime):
(WebInspector.TimelinePresentationModel.prototype.maximumRecordTime):
(WebInspector.TimelinePresentationModel.prototype.addRecord):
(WebInspector.TimelinePresentationModel.prototype._updateBoundaries):
(WebInspector.TimelinePresentationModel.prototype._findParentRecord):
(WebInspector.TimelinePresentationModel.prototype.setGlueRecords):
(WebInspector.TimelinePresentationModel.prototype.fireWindowChanged):
(WebInspector.TimelinePresentationModel.prototype.get _recordStyles):
(WebInspector.TimelinePresentationModel.prototype.filteredRecords):
(WebInspector.TimelinePresentationModel.prototype._filterRecords):
(WebInspector.TimelinePresentationModel.Record.prototype.get visibleChildrenCount):
(WebInspector.TimelinePresentationModel.Record.prototype.get invisibleChildrenCount):
(WebInspector.TimelinePresentationModel.Filter):
(WebInspector.TimelinePresentationModel.Filter.prototype.accept):

LayoutTests:

* inspector/timeline/timeline-enum-stability-expected.txt:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (109106 => 109107)


--- trunk/LayoutTests/ChangeLog	2012-02-28 16:11:56 UTC (rev 109106)
+++ trunk/LayoutTests/ChangeLog	2012-02-28 16:18:58 UTC (rev 109107)
@@ -1,3 +1,12 @@
+2012-02-28  Pavel Feldman  <[email protected]>
+
+        Web Inspector: move filtering of the timeline records into the presentation model.
+        https://bugs.webkit.org/show_bug.cgi?id=79789
+
+        Reviewed by Yury Semikhatsky.
+
+        * inspector/timeline/timeline-enum-stability-expected.txt:
+
 2012-02-28  Florin Malita  <[email protected]>
 
         Percent width/height SVG not always scaled on window resize

Modified: trunk/LayoutTests/inspector/timeline/timeline-enum-stability-expected.txt (109106 => 109107)


--- trunk/LayoutTests/inspector/timeline/timeline-enum-stability-expected.txt	2012-02-28 16:11:56 UTC (rev 109106)
+++ trunk/LayoutTests/inspector/timeline/timeline-enum-stability-expected.txt	2012-02-28 16:18:58 UTC (rev 109107)
@@ -3,6 +3,7 @@
 Applications outside of WebKit depend on the stability of the mapping of these types to these specific values.
 
 {
+    Root : "Root"
     EventDispatch : "EventDispatch"
     Layout : "Layout"
     RecalculateStyles : "RecalculateStyles"

Modified: trunk/Source/WebCore/ChangeLog (109106 => 109107)


--- trunk/Source/WebCore/ChangeLog	2012-02-28 16:11:56 UTC (rev 109106)
+++ trunk/Source/WebCore/ChangeLog	2012-02-28 16:18:58 UTC (rev 109107)
@@ -1,3 +1,54 @@
+2012-02-28  Pavel Feldman  <[email protected]>
+
+        Web Inspector: move filtering of the timeline records into the presentation model.
+        https://bugs.webkit.org/show_bug.cgi?id=79789
+
+        Reviewed by Yury Semikhatsky.
+
+        * inspector/front-end/TimelineModel.js:
+        * inspector/front-end/TimelineOverviewPane.js:
+        (WebInspector.TimelineOverviewPane):
+        (WebInspector.TimelineOverviewPane.prototype.setStartAtZero):
+        (WebInspector.TimelineOverviewPane.prototype.scrollWindow):
+        (WebInspector.TimelineOverviewPane.prototype.accept):
+        (WebInspector.TimelineOverviewPane.prototype._setWindowIndices):
+        (WebInspector.TimelineStartAtZeroOverview):
+        (WebInspector.TimelineStartAtZeroOverview.prototype._onWindowChanged):
+        * inspector/front-end/TimelinePanel.js:
+        (WebInspector.TimelinePanel):
+        (WebInspector.TimelinePanel.prototype._createStatusbarButtons):
+        (WebInspector.TimelinePanel.prototype._updateRecordsCounter):
+        (WebInspector.TimelinePanel.prototype._glueParentButtonClicked):
+        (WebInspector.TimelinePanel.prototype._toggleStartAtZeroButtonClicked):
+        (WebInspector.TimelinePanel.prototype._innerAddRecordToTimeline):
+        (WebInspector.TimelinePanel.prototype._resetPanel):
+        (WebInspector.TimelinePanel.prototype._refresh):
+        (WebInspector.TimelinePanel.prototype.revealRecordAt):
+        (WebInspector.TimelinePanel.prototype._refreshRecords):
+        (WebInspector.TimelineExpandableElement.prototype._update):
+        (WebInspector.TimelineCategoryFilter):
+        (WebInspector.TimelineCategoryFilter.prototype.accept):
+        (WebInspector.TimelineIsLongFilter):
+        (WebInspector.TimelineIsLongFilter.prototype.accept):
+        * inspector/front-end/TimelinePresentationModel.js:
+        (WebInspector.TimelinePresentationModel):
+        (WebInspector.TimelinePresentationModel.prototype.addFilter):
+        (WebInspector.TimelinePresentationModel.prototype.reset):
+        (WebInspector.TimelinePresentationModel.prototype.minimumRecordTime):
+        (WebInspector.TimelinePresentationModel.prototype.maximumRecordTime):
+        (WebInspector.TimelinePresentationModel.prototype.addRecord):
+        (WebInspector.TimelinePresentationModel.prototype._updateBoundaries):
+        (WebInspector.TimelinePresentationModel.prototype._findParentRecord):
+        (WebInspector.TimelinePresentationModel.prototype.setGlueRecords):
+        (WebInspector.TimelinePresentationModel.prototype.fireWindowChanged):
+        (WebInspector.TimelinePresentationModel.prototype.get _recordStyles):
+        (WebInspector.TimelinePresentationModel.prototype.filteredRecords):
+        (WebInspector.TimelinePresentationModel.prototype._filterRecords):
+        (WebInspector.TimelinePresentationModel.Record.prototype.get visibleChildrenCount):
+        (WebInspector.TimelinePresentationModel.Record.prototype.get invisibleChildrenCount):
+        (WebInspector.TimelinePresentationModel.Filter):
+        (WebInspector.TimelinePresentationModel.Filter.prototype.accept):
+
 2012-02-28  Florin Malita  <[email protected]>
 
         Percent width/height SVG not always scaled on window resize

Modified: trunk/Source/WebCore/inspector/front-end/TimelineModel.js (109106 => 109107)


--- trunk/Source/WebCore/inspector/front-end/TimelineModel.js	2012-02-28 16:11:56 UTC (rev 109106)
+++ trunk/Source/WebCore/inspector/front-end/TimelineModel.js	2012-02-28 16:18:58 UTC (rev 109107)
@@ -41,6 +41,7 @@
 }
 
 WebInspector.TimelineModel.RecordType = {
+    Root: "Root",
     EventDispatch: "EventDispatch",
     Layout: "Layout",
     RecalculateStyles: "RecalculateStyles",

Modified: trunk/Source/WebCore/inspector/front-end/TimelineOverviewPane.js (109106 => 109107)


--- trunk/Source/WebCore/inspector/front-end/TimelineOverviewPane.js	2012-02-28 16:11:56 UTC (rev 109106)
+++ trunk/Source/WebCore/inspector/front-end/TimelineOverviewPane.js	2012-02-28 16:18:58 UTC (rev 109107)
@@ -31,6 +31,7 @@
 /**
  * @constructor
  * @extends {WebInspector.Object}
+ * @implements {WebInspector.TimelinePresentationModel.Filter}
  */
 WebInspector.TimelineOverviewPane = function(presentationModel)
 {
@@ -38,6 +39,9 @@
     this.element.className = "fill";
 
     this._startAtZero = false;
+    this._topLevelRecordIndex = 0;
+    this._windowIndexLeft = 0;
+    this._windowIndexRight = null;
 
     this._presentationModel = presentationModel;
 
@@ -139,7 +143,7 @@
             if (this._heapGraph.visible)
                 this._showTimelines();
             this.element.addStyleClass("timeline-start-at-zero");
-            this._startAtZeroOverview = new WebInspector.TimelineStartAtZeroOverview(this._presentationModel);
+            this._startAtZeroOverview = new WebInspector.TimelineStartAtZeroOverview(this);
             this._startAtZeroOverview.show(this.element);
             this._startAtZeroOverview.update(this._records);
         } else {
@@ -163,6 +167,7 @@
 
     update: function(records, showShortEvents)
     {
+        this._topLevelRecordIndex = 0;
         this._records = records;
         this._showShortEvents = showShortEvents;
         // Clear summary bars.
@@ -261,6 +266,32 @@
     scrollWindow: function(event)
     {
         this._overviewWindow.scrollWindow(event);
+    },
+
+    /**
+     * @param {WebInspector.TimelinePresentationModel.Record} record
+     */
+    accept: function(record)
+    {
+        if (this._startAtZeroOverview) {
+            if (record.parent === this._presentationModel.rootRecord())
+                ++this._topLevelRecordIndex;
+            return this._topLevelRecordIndex > this._windowIndexLeft &&
+                (typeof this._windowIndexRight !== "number" || this._topLevelRecordIndex <= this._windowIndexRight);
+        } else {
+            var absoluteMin = this._presentationModel.minimumRecordTime();
+            var absoluteMax = this._presentationModel.maximumRecordTime();
+            var windowLeft = absoluteMin + (absoluteMax - absoluteMin) * this._overviewWindow.windowLeft;
+            var windowRight = absoluteMin + (absoluteMax - absoluteMin) * this._overviewWindow.windowRight;
+            return record.endTime >= windowLeft && record.startTime <= windowRight;
+        }
+    },
+
+    _setWindowIndices: function(indexLeft, indexRight)
+    {
+        this._windowIndexLeft = indexLeft;
+        this._windowIndexRight = indexRight;
+        this._presentationModel.fireWindowChanged();
     }
 }
 
@@ -721,12 +752,12 @@
 
 /**
  * @constructor
- * @param {WebInspector.TimelinePresentationModel} model
+ * @param {WebInspector.TimelineOverviewPane} pane
  * @extends {WebInspector.View}
  */
-WebInspector.TimelineStartAtZeroOverview = function(model) {
+WebInspector.TimelineStartAtZeroOverview = function(pane) {
     WebInspector.View.call(this);
-    this._presentationModel = model;
+    this._pane = pane;
     this.element.className = "timeline-overview-start-at-zero fill";
     this._overviewElement = this.element.createChild("div", "timeline-overview-start-at-zero-bars fill");
     this._overviewWindow = new WebInspector.TimelineOverviewWindow(this.element);
@@ -810,7 +841,7 @@
         var leftIndex = Math.floor((leftOffset - offset0) / barWidth * this._recordsPerBar);
         var rightIndex = rightOffset + barWidth >= this.element.clientWidth ? null : Math.ceil((rightOffset - offset0 - 2) / barWidth * this._recordsPerBar);
 
-        this._presentationModel.setWindowIndices(leftIndex, rightIndex);
+        this._pane._setWindowIndices(leftIndex, rightIndex);
     }
 }
 

Modified: trunk/Source/WebCore/inspector/front-end/TimelinePanel.js (109106 => 109107)


--- trunk/Source/WebCore/inspector/front-end/TimelinePanel.js	2012-02-28 16:11:56 UTC (rev 109106)
+++ trunk/Source/WebCore/inspector/front-end/TimelinePanel.js	2012-02-28 16:18:58 UTC (rev 109107)
@@ -123,8 +123,11 @@
 
     this._registerShortcuts();
 
-    this._visibleRecordsCount = 0;
     this._allRecordsCount = 0;
+
+    this._presentationModel.addFilter(this._overviewPane);
+    this._presentationModel.addFilter(new WebInspector.TimelineCategoryFilter()); 
+    this._presentationModel.addFilter(new WebInspector.TimelineIsLongFilter(this)); 
 }
 
 // Define row height, should be in sync with styles for timeline graphs.
@@ -221,6 +224,7 @@
 
         this._glueParentButton = new WebInspector.StatusBarButton(WebInspector.UIString("Glue asynchronous events to causes"), "glue-async-status-bar-item");
         this._glueParentButton.toggled = true;
+        this._presentationModel.setGlueRecords(true);
         this._glueParentButton.addEventListener("click", this._glueParentButtonClicked, this);
 
         this.statusBarFilters = document.createElement("div");
@@ -322,9 +326,9 @@
         return this._presentationModel.rootRecord();
     },
 
-    _updateRecordsCounter: function()
+    _updateRecordsCounter: function(recordsInWindowCount)
     {
-        this.recordsCounter.textContent = WebInspector.UIString("%d of %d captured records are visible", this._visibleRecordsCount, this._allRecordsCount);
+        this.recordsCounter.textContent = WebInspector.UIString("%d of %d captured records are visible", recordsInWindowCount, this._allRecordsCount);
     },
 
     _updateEventDividers: function()
@@ -416,6 +420,7 @@
     _glueParentButtonClicked: function()
     {
         this._glueParentButton.toggled = !this._glueParentButton.toggled;
+        this._presentationModel.setGlueRecords(this._glueParentButton.toggled && !this.toggleStartAtZeroButton.toggled);
         this._repopulateRecords();
     },
 
@@ -425,6 +430,7 @@
         this._glueParentButton.disabled = toggled;
         this.toggleStartAtZeroButton.toggled = toggled;
         this._calculator = toggled ? new WebInspector.TimelineStartAtZeroCalculator() : new WebInspector.TimelineCalculator();
+        this._presentationModel.setGlueRecords(this._glueParentButton.toggled && !this.toggleStartAtZeroButton.toggled);
         this._repopulateRecords();
         this._overviewPane.setStartAtZero(toggled);
     },
@@ -454,77 +460,11 @@
 
     _innerAddRecordToTimeline: function(record, parentRecord)
     {
-        var connectedToOldRecord = false;
+        var formattedRecord = this._presentationModel.addRecord(record, parentRecord);
+        ++this._allRecordsCount;
         var recordTypes = WebInspector.TimelineModel.RecordType;
-
-        if (record.type === recordTypes.MarkDOMContent || record.type === recordTypes.MarkLoad)
-            parentRecord = null; // No bar entry for load events.
-        else if (!this._startAtZero &&
-                    this._glueParentButton.toggled &&
-                    (parentRecord === this._rootRecord() ||
-                    record.type === recordTypes.ResourceReceiveResponse ||
-                    record.type === recordTypes.ResourceFinish ||
-                    record.type === recordTypes.ResourceReceivedData)) {
-            var newParentRecord = this._presentationModel.findParentRecord(record);
-            if (newParentRecord) {
-                parentRecord = newParentRecord;
-                connectedToOldRecord = true;
-            }
-        }
-
-        var children = record.children;
-        var scriptDetails;
-        if (record.data && record.data["scriptName"]) {
-            scriptDetails = {
-                scriptName: record.data["scriptName"],
-                scriptLine: record.data["scriptLine"]
-            }
-        };
-
-        if ((record.type === recordTypes.TimerFire || record.type === recordTypes.FireAnimationFrame) && children && children.length) {
-            var childRecord = children[0];
-            if (childRecord.type === recordTypes.FunctionCall) {
-                scriptDetails = {
-                    scriptName: childRecord.data["scriptName"],
-                    scriptLine: childRecord.data["scriptLine"]
-                };
-                children = childRecord.children.concat(children.slice(1));
-            }
-        }
-
-        var formattedRecord = this._presentationModel.createFormattedRecord(record, parentRecord, scriptDetails);
-
-        if (record.type === recordTypes.MarkDOMContent || record.type === recordTypes.MarkLoad) {
+        if (record.type === recordTypes.MarkDOMContent || record.type === recordTypes.MarkLoad || record.type === recordTypes.TimeStamp)
             this._timeStampRecords.push(formattedRecord);
-            return;
-        }
-
-        ++this._allRecordsCount;
-        formattedRecord.collapsed = (parentRecord === this._rootRecord());
-
-        var childrenCount = children ? children.length : 0;
-        for (var i = 0; i < childrenCount; ++i)
-            this._innerAddRecordToTimeline(children[i], formattedRecord);
-
-        formattedRecord.calculateAggregatedStats(this._presentationModel.categories);
-
-        if (connectedToOldRecord) {
-            record = formattedRecord;
-            do {
-                var parent = record.parent;
-                if (parent.lastChildEndTime < record.lastChildEndTime)
-                    parent.lastChildEndTime = record.lastChildEndTime;
-                for (var category in formattedRecord.aggregatedStats)
-                    parent.aggregatedStats[category] += formattedRecord.aggregatedStats[category];
-                record = parent;
-            } while (record.parent);
-        } else {
-            if (parentRecord !== this._rootRecord())
-                parentRecord.selfTime -= formattedRecord.endTime - formattedRecord.startTime;
-        }
-        // Keep bar entry for mark timeline since nesting might be interesting to the user.
-        if (record.type === recordTypes.TimeStamp)
-            this._timeStampRecords.push(formattedRecord);
     },
 
     sidebarResized: function(event)
@@ -565,7 +505,6 @@
         this._overviewPane.reset();
         this._adjustScrollPosition(0);
         this._closeRecordDetails();
-        this._visibleRecordsCount = 0;
         this._allRecordsCount = 0;
     },
 
@@ -624,8 +563,8 @@
 
         if (!this._boundariesAreValid)
             this._updateBoundaries();
-        this._refreshRecords(!this._boundariesAreValid);
-        this._updateRecordsCounter();
+        var recordsInWindowCount = this._refreshRecords(!this._boundariesAreValid);
+        this._updateRecordsCounter(recordsInWindowCount);
         if(!this._boundariesAreValid)
             this._updateEventDividers();
         if (this._memoryStatistics && this._memoryStatistics.visible())
@@ -645,60 +584,18 @@
         this._calculator.calculateWindow();
     },
 
-    _filterRecords: function()
-    {
-        var recordsInWindow = [];
-        var filter = this._startAtZero ? new WebInspector.TimelineStartAtZeroRecordFilter(this._presentationModel, this._rootRecord(), this._showShortEvents)
-            : new WebInspector.TimelineRecordFilter(this._calculator, this._showShortEvents);
-        this._visibleRecordsCount = 0;
-
-        var stack = [{children: this._rootRecord().children, index: 0, parentIsCollapsed: false}];
-        while (stack.length) {
-            var entry = stack[stack.length - 1];
-            var records = entry.children;
-            if (records && entry.index < records.length) {
-                 var record = records[entry.index];
-                 ++entry.index;
-
-                 if (filter.accept(record)) {
-                     ++this._visibleRecordsCount;
-                     ++record.parent._invisibleChildrenCount;
-                     if (!entry.parentIsCollapsed)
-                         recordsInWindow.push(record);
-                 }
-
-                 record._invisibleChildrenCount = 0;
-
-                 stack.push({children: record.children,
-                             index: 0,
-                             parentIsCollapsed: (entry.parentIsCollapsed || record.collapsed),
-                             parentRecord: record,
-                             windowLengthBeforeChildrenTraversal: recordsInWindow.length});
-            } else {
-                stack.pop();
-                if (entry.parentRecord)
-                    entry.parentRecord._visibleChildrenCount = recordsInWindow.length - entry.windowLengthBeforeChildrenTraversal;
-            }
-        }
-
-        return recordsInWindow;
-    },
-
     revealRecordAt: function(time)
     {
         if (this._startAtZero)
             return;
-        var filter = new WebInspector.TimelineRecordFilter(this._calculator, this._showShortEvents);
+        var recordsInWindow = this._presentationModel.filteredRecords();
         var recordToReveal;
-        function recordFinder(record)
-        {
-            if (filter.accept(record) && record.containsTime(time)) {
-                recordToReveal = record;
-                return true;
+        for (var i = 0; i < recordsInWindow.length; ++i) {
+            if (recordsInWindow[i].containsTime(time)) {
+                recordToReveal = recordsInWindow[i];
+                break;
             }
-            return false;
         }
-        WebInspector.TimelinePanel.forAllRecords(this._rootRecord().children, recordFinder);
 
         // The record ends before the window left bound so scroll to the top.
         if (!recordToReveal) {
@@ -709,14 +606,13 @@
         // Expand all ancestors.
         for (var parent = recordToReveal.parent; parent !== this._rootRecord(); parent = parent.parent)
             parent.collapsed = false;
-        var recordsInWindow = this._filterRecords();
         var index = recordsInWindow.indexOf(recordToReveal);
         this._containerElement.scrollTop = index * WebInspector.TimelinePanel.rowHeight;
     },
 
     _refreshRecords: function(updateBoundaries)
     {
-        var recordsInWindow = this._filterRecords();
+        var recordsInWindow = this._presentationModel.filteredRecords();
 
         // Calculate the visible area.
         this._scrollTop = this._containerElement.scrollTop;
@@ -750,7 +646,7 @@
             var isEven = !(i % 2);
 
             if (i < startIndex) {
-                var lastChildIndex = i + record._visibleChildrenCount;
+                var lastChildIndex = i + record.visibleChildrenCount;
                 if (lastChildIndex >= startIndex && lastChildIndex < endIndex) {
                     var expandElement = new WebInspector.TimelineExpandableElement(this._expandElements);
                     expandElement._update(record, i, this._calculator.computeBarGraphWindowPosition(record, width - this._expandOffset));
@@ -792,6 +688,8 @@
         if (updateBoundaries)
             this._timelineGrid.updateDividers(true, this._calculator, this.timelinePaddingLeft);
         this._adjustScrollPosition((recordsInWindow.length + 1) * rowHeight);
+
+        return recordsInWindow.length;
     },
 
     get timelinePaddingLeft()
@@ -1159,12 +1057,12 @@
     _update: function(record, index, barPosition)
     {
         const rowHeight = WebInspector.TimelinePanel.rowHeight;
-        if (record._visibleChildrenCount || record._invisibleChildrenCount) {
+        if (record.visibleChildrenCount || record.invisibleChildrenCount) {
             this._element.style.top = index * rowHeight + "px";
             this._element.style.left = barPosition.left + "px";
             this._element.style.width = Math.max(12, barPosition.width + 25) + "px";
             if (!record.collapsed) {
-                this._element.style.height = (record._visibleChildrenCount + 1) * rowHeight + "px";
+                this._element.style.height = (record.visibleChildrenCount + 1) * rowHeight + "px";
                 this._element.addStyleClass("timeline-expandable-expanded");
                 this._element.removeStyleClass("timeline-expandable-collapsed");
             } else {
@@ -1185,58 +1083,38 @@
 
 /**
  * @constructor
- * @param {WebInspector.TimelineCalculator} calculator
- * @param {boolean} showShortEvents
+ * @implements {WebInspector.TimelinePresentationModel.Filter}
  */
-WebInspector.TimelineRecordFilter = function(calculator, showShortEvents)
+WebInspector.TimelineCategoryFilter = function()
 {
-    this._calculator = calculator;
-    this._showShortEvents = showShortEvents;
 }
 
-WebInspector.TimelineRecordFilter.prototype = {
+WebInspector.TimelineCategoryFilter.prototype = {
     /**
      * @param {WebInspector.TimelinePresentationModel.Record} record
      */
     accept: function(record)
     {
-        if (record.category.hidden)
-            return false;
-        if (!this._showShortEvents && !record.isLong())
-            return false;
-        var percentages = this._calculator.computeBarGraphPercentages(record);
-        return percentages.start <= 100 && percentages.endWithChildren >= 0;
+        return !record.category.hidden;
     }
 }
 
 /**
+ * @param {WebInspector.TimelinePanel} panel
  * @constructor
- * @param {WebInspector.TimelinePresentationModel} model
- * @param {Object} rootRecord
- * @param {boolean} showShortEvents
+ * @implements {WebInspector.TimelinePresentationModel.Filter}
  */
-WebInspector.TimelineStartAtZeroRecordFilter = function(model, rootRecord, showShortEvents)
+WebInspector.TimelineIsLongFilter = function(panel)
 {
-    this._windowIndexLeft = model.windowIndexLeft;
-    this._windowIndexRight = model.windowIndexRight;
-    this._rootRecord = rootRecord;
-    this._topLevelRecordIndex = 0;
-    this._showShortEvents = showShortEvents;
+    this._panel = panel;
 }
 
-WebInspector.TimelineStartAtZeroRecordFilter.prototype = {
+WebInspector.TimelineIsLongFilter.prototype = {
     /**
      * @param {WebInspector.TimelinePresentationModel.Record} record
      */
     accept: function(record)
     {
-        if (record.category.hidden)
-            return false;
-        if (record.parent === this._rootRecord)
-            ++this._topLevelRecordIndex;
-        if (!this._showShortEvents && !record.isLong())
-            return false;
-        return this._topLevelRecordIndex > this._windowIndexLeft &&
-            (typeof this._windowIndexRight !== "number" || this._topLevelRecordIndex <= this._windowIndexRight);
+        return this._panel._showShortEvents || record.isLong();
     }
 }

Modified: trunk/Source/WebCore/inspector/front-end/TimelinePresentationModel.js (109106 => 109107)


--- trunk/Source/WebCore/inspector/front-end/TimelinePresentationModel.js	2012-02-28 16:11:56 UTC (rev 109106)
+++ trunk/Source/WebCore/inspector/front-end/TimelinePresentationModel.js	2012-02-28 16:18:58 UTC (rev 109107)
@@ -39,6 +39,8 @@
     this._addCategory(new WebInspector.TimelineCategory("scripting", WebInspector.UIString("Scripting"), "rgb(157,231,119)"));
     this._addCategory(new WebInspector.TimelineCategory("rendering", WebInspector.UIString("Rendering"), "rgb(164,60,255)"));
     this._linkifier = WebInspector.debuggerPresentationModel.createLinkifier();
+    this._glueRecords = false;
+    this._filters = [];
     this.reset();
 }
 
@@ -50,19 +52,14 @@
 WebInspector.TimelinePresentationModel.shortRecordThreshold = 0.015;
 
 WebInspector.TimelinePresentationModel.prototype = {
-    createFormattedRecord: function(record, parentRecord, scriptDetails)
+    /**
+     * @param {WebInspector.TimelinePresentationModel.Filter} filter
+     */
+    addFilter: function(filter)
     {
-        return new WebInspector.TimelinePresentationModel.Record(this, record, parentRecord, scriptDetails);
+        this._filters.push(filter);
     },
 
-    _createRootRecord: function()
-    {
-        var rootRecord = {};
-        rootRecord.children = [];
-        rootRecord.aggregatedStats = {};
-        return rootRecord;
-    },
-
     rootRecord: function()
     {
         return this._rootRecord;
@@ -71,18 +68,105 @@
     reset: function()
     {
         this._linkifier.reset();
-        this._rootRecord = this._createRootRecord();
+        this._rootRecord = new WebInspector.TimelinePresentationModel.Record(this, { type: WebInspector.TimelineModel.RecordType.Root }, null, null);
         this._sendRequestRecords = {};
         this._scheduledResourceRequests = {};
         this._timerRecords = {};
         this._requestAnimationFrameRecords = {};
-
+        this._minimumRecordTime = -1;
+        this._maximumRecordTime = -1;
         this._resetWindow();
     },
 
-    findParentRecord: function(record)
+    minimumRecordTime: function()
     {
+        return this._minimumRecordTime;
+    },
+
+    maximumRecordTime: function()
+    {
+        return this._maximumRecordTime;
+    },
+
+    addRecord: function(record, parentRecord)
+    {
+        var connectedToOldRecord = false;
         var recordTypes = WebInspector.TimelineModel.RecordType;
+
+        if (record.type === recordTypes.MarkDOMContent || record.type === recordTypes.MarkLoad)
+            parentRecord = null; // No bar entry for load events.
+        else {
+            var newParentRecord = this._findParentRecord(record);
+            if (newParentRecord) {
+                parentRecord = newParentRecord;
+                connectedToOldRecord = true;
+            }
+        }
+
+        var children = record.children;
+        var scriptDetails;
+        if (record.data && record.data["scriptName"]) {
+            scriptDetails = {
+                scriptName: record.data["scriptName"],
+                scriptLine: record.data["scriptLine"]
+            }
+        };
+
+        if ((record.type === recordTypes.TimerFire || record.type === recordTypes.FireAnimationFrame) && children && children.length) {
+            var childRecord = children[0];
+            if (childRecord.type === recordTypes.FunctionCall) {
+                scriptDetails = {
+                    scriptName: childRecord.data["scriptName"],
+                    scriptLine: childRecord.data["scriptLine"]
+                };
+                children = childRecord.children.concat(children.slice(1));
+            }
+        }
+
+        var formattedRecord = new WebInspector.TimelinePresentationModel.Record(this, record, parentRecord, scriptDetails);
+        this._updateBoundaries(formattedRecord);    
+
+        if (record.type === recordTypes.MarkDOMContent || record.type === recordTypes.MarkLoad)
+            return formattedRecord;
+
+        formattedRecord.collapsed = (parentRecord === this._rootRecord);
+
+        var childrenCount = children ? children.length : 0;
+        for (var i = 0; i < childrenCount; ++i)
+            this.addRecord(children[i], formattedRecord);
+
+        formattedRecord.calculateAggregatedStats(this._categories);
+
+        if (connectedToOldRecord) {
+            record = formattedRecord;
+            do {
+                var parent = record.parent;
+                if (parent.lastChildEndTime < record.lastChildEndTime)
+                    parent.lastChildEndTime = record.lastChildEndTime;
+                for (var category in formattedRecord.aggregatedStats)
+                    parent.aggregatedStats[category] += formattedRecord.aggregatedStats[category];
+                record = parent;
+            } while (record.parent);
+        } else {
+            if (parentRecord !== this._rootRecord)
+                parentRecord.selfTime -= formattedRecord.endTime - formattedRecord.startTime;
+        }
+        return formattedRecord;
+    },
+
+    _updateBoundaries: function(formattedRecord)
+    {
+        if (this._minimumRecordTime === -1 || formattedRecord.startTime < this._minimumRecordTime)
+            this._minimumRecordTime = formattedRecord.startTime;
+        if (this._maximumRecordTime === -1 || formattedRecord.endTime > this._maximumRecordTime)
+            this._maximumRecordTime = formattedRecord.endTime;
+    },
+
+    _findParentRecord: function(record)
+    {
+        if (!this._glueRecords)
+            return null;
+        var recordTypes = WebInspector.TimelineModel.RecordType;
         var parentRecord;
         if (record.type === recordTypes.ResourceReceiveResponse ||
             record.type === recordTypes.ResourceFinish ||
@@ -105,6 +189,11 @@
         this.windowIndexRight = null;
     },
 
+    setGlueRecords: function(glue)
+    {
+        this._glueRecords = glue;
+    },
+
     get categories()
     {
         return this._categories;
@@ -129,14 +218,8 @@
         this.dispatchEventToListeners(WebInspector.TimelinePresentationModel.Events.WindowChanged);
     },
 
-    /**
-     * @param {number} left
-     * @param {?number} right
-     */
-    setWindowIndices: function(left, right)
+    fireWindowChanged: function()
     {
-        this.windowIndexLeft = left;
-        this.windowIndexRight = right;
         this.dispatchEventToListeners(WebInspector.TimelinePresentationModel.Events.WindowChanged);
     },
 
@@ -157,6 +240,7 @@
             var categories = this._categories;
 
             var recordStyles = {};
+            recordStyles[recordTypes.Root] = { title: "#root", category: categories["loading"] };
             recordStyles[recordTypes.EventDispatch] = { title: WebInspector.UIString("Event"), category: categories["scripting"] };
             recordStyles[recordTypes.Layout] = { title: WebInspector.UIString("Layout"), category: categories["rendering"] };
             recordStyles[recordTypes.RecalculateStyles] = { title: WebInspector.UIString("Recalculate Style"), category: categories["rendering"] };
@@ -184,6 +268,54 @@
             this._recordStylesArray = recordStyles;
         }
         return this._recordStylesArray;
+    },
+
+    filteredRecords: function()
+    {
+        function filter(record)
+        {
+            for (var i = 0; i < this._filters.length; ++i) {
+                if (!this._filters[i].accept(record))
+                    return false;
+            }
+            return true;
+        }
+        return this._filterRecords(filter.bind(this));
+    },
+
+    _filterRecords: function(filter)
+    {
+        var recordsInWindow = [];
+
+        var stack = [{children: this._rootRecord.children, index: 0, parentIsCollapsed: false}];
+        while (stack.length) {
+            var entry = stack[stack.length - 1];
+            var records = entry.children;
+            if (records && entry.index < records.length) {
+                 var record = records[entry.index];
+                 ++entry.index;
+
+                 if (filter(record)) {
+                     ++record.parent._invisibleChildrenCount;
+                     if (!entry.parentIsCollapsed)
+                         recordsInWindow.push(record);
+                 }
+
+                 record._invisibleChildrenCount = 0;
+
+                 stack.push({children: record.children,
+                             index: 0,
+                             parentIsCollapsed: (entry.parentIsCollapsed || record.collapsed),
+                             parentRecord: record,
+                             windowLengthBeforeChildrenTraversal: recordsInWindow.length});
+            } else {
+                stack.pop();
+                if (entry.parentRecord)
+                    entry.parentRecord._visibleChildrenCount = recordsInWindow.length - entry.windowLengthBeforeChildrenTraversal;
+            }
+        }
+
+        return recordsInWindow;
     }
 }
 
@@ -300,6 +432,16 @@
         return this._children;
     },
 
+    get visibleChildrenCount()
+    {
+        return this._visibleChildrenCount || 0;
+    },
+
+    get invisibleChildrenCount()
+    {
+        return this._invisibleChildrenCount || 0;
+    },
+
     containsTime: function(time)
     {
         return this.startTime <= time && time <= this.endTime;
@@ -574,3 +716,17 @@
         this._appendElementRow(title, framesTable, "timeline-stacktrace-title");
     }
 }
+
+/**
+ * @interface
+ */
+WebInspector.TimelinePresentationModel.Filter = function()
+{
+}
+
+WebInspector.TimelinePresentationModel.Filter.prototype = {
+    /**
+     * @param {WebInspector.TimelinePresentationModel.Record} record
+     */
+    accept: function(record) { return false; }
+}
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to