summaryrefslogtreecommitdiffstats
path: root/WebCore/inspector/front-end/TimelinePanel.js
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2009-12-17 09:55:06 -0800
committerAndroid Git Automerger <android-git-automerger@android.com>2009-12-17 09:55:06 -0800
commitb880d713c04257ca40abfef97c300afdead423b8 (patch)
tree6982576c228bcd1a7efe98afed544d840751094c /WebCore/inspector/front-end/TimelinePanel.js
parente2e7a5c57b53f01e63a0245b4420d54b454cb373 (diff)
parent643ca7872b450ea4efacab6188849e5aac2ba161 (diff)
downloadexternal_webkit-b880d713c04257ca40abfef97c300afdead423b8.zip
external_webkit-b880d713c04257ca40abfef97c300afdead423b8.tar.gz
external_webkit-b880d713c04257ca40abfef97c300afdead423b8.tar.bz2
am 643ca787: Merge webkit.org at r51976 : Initial merge by git.
Merge commit '643ca7872b450ea4efacab6188849e5aac2ba161' into eclair-mr2-plus-aosp * commit '643ca7872b450ea4efacab6188849e5aac2ba161': Merge webkit.org at r51976 : Initial merge by git.
Diffstat (limited to 'WebCore/inspector/front-end/TimelinePanel.js')
-rw-r--r--WebCore/inspector/front-end/TimelinePanel.js554
1 files changed, 411 insertions, 143 deletions
diff --git a/WebCore/inspector/front-end/TimelinePanel.js b/WebCore/inspector/front-end/TimelinePanel.js
index df63a0b..ac36fa5 100644
--- a/WebCore/inspector/front-end/TimelinePanel.js
+++ b/WebCore/inspector/front-end/TimelinePanel.js
@@ -30,19 +30,56 @@
WebInspector.TimelinePanel = function()
{
- WebInspector.AbstractTimelinePanel.call(this);
-
+ WebInspector.Panel.call(this);
this.element.addStyleClass("timeline");
- this.createInterface();
- this.summaryBar.element.id = "timeline-summary";
- this.itemsGraphsElement.id = "timeline-graphs";
+ this._overviewPane = new WebInspector.TimelineOverviewPane(this.categories);
+ this._overviewPane.addEventListener("window changed", this._scheduleRefresh, this);
+ this._overviewPane.addEventListener("filter changed", this._refresh, this);
+ this.element.appendChild(this._overviewPane.element);
- this._createStatusbarButtons();
+ this._sidebarBackgroundElement = document.createElement("div");
+ this._sidebarBackgroundElement.className = "sidebar timeline-sidebar-background";
+ this.element.appendChild(this._sidebarBackgroundElement);
+
+ this._containerElement = document.createElement("div");
+ this._containerElement.id = "timeline-container";
+ this._containerElement.addEventListener("scroll", this._onScroll.bind(this), false);
+ this.element.appendChild(this._containerElement);
+
+ this.createSidebar(this._containerElement, this._containerElement);
+ var itemsTreeElement = new WebInspector.SidebarSectionTreeElement(WebInspector.UIString("RECORDS"), {}, true);
+ itemsTreeElement.expanded = true;
+ this.sidebarTree.appendChild(itemsTreeElement);
+
+ this._sidebarListElement = document.createElement("div");
+ this.sidebarElement.appendChild(this._sidebarListElement);
+
+ this._containerContentElement = document.createElement("div");
+ this._containerContentElement.id = "resources-container-content";
+ this._containerElement.appendChild(this._containerContentElement);
+
+ this._timelineGrid = new WebInspector.TimelineGrid();
+ this._itemsGraphsElement = this._timelineGrid.itemsGraphsElement;
+ this._itemsGraphsElement.id = "timeline-graphs";
+ this._containerContentElement.appendChild(this._timelineGrid.element);
+
+ this._topGapElement = document.createElement("div");
+ this._topGapElement.className = "timeline-gap";
+ this._itemsGraphsElement.appendChild(this._topGapElement);
- this.calculator = new WebInspector.TimelineCalculator();
+ this._graphRowsElement = document.createElement("div");
+ this._itemsGraphsElement.appendChild(this._graphRowsElement);
- this.filter(this.filterAllElement, false);
+ this._bottomGapElement = document.createElement("div");
+ this._bottomGapElement.className = "timeline-gap";
+ this._itemsGraphsElement.appendChild(this._bottomGapElement);
+
+ this._createStatusbarButtons();
+
+ this._records = [];
+ this._sendRequestRecords = {};
+ this._calculator = new WebInspector.TimelineCalculator();
}
WebInspector.TimelinePanel.prototype = {
@@ -64,20 +101,12 @@ WebInspector.TimelinePanel.prototype = {
this._categories = {
loading: new WebInspector.TimelineCategory("loading", WebInspector.UIString("Loading"), "rgb(47,102,236)"),
scripting: new WebInspector.TimelineCategory("scripting", WebInspector.UIString("Scripting"), "rgb(157,231,119)"),
- rendering: new WebInspector.TimelineCategory("rendering", WebInspector.UIString("Rendering"), "rgb(164,60,255)"),
- other: new WebInspector.TimelineCategory("other", WebInspector.UIString("Other"), "rgb(186,186,186)")
+ rendering: new WebInspector.TimelineCategory("rendering", WebInspector.UIString("Rendering"), "rgb(164,60,255)")
};
}
return this._categories;
},
- populateSidebar: function()
- {
- this.itemsTreeElement = new WebInspector.SidebarSectionTreeElement(WebInspector.UIString("RECORDS"), {}, true);
- this.itemsTreeElement.expanded = true;
- this.sidebarTree.appendChild(this.itemsTreeElement);
- },
-
_createStatusbarButtons: function()
{
this.toggleTimelineButton = new WebInspector.StatusBarButton("", "record-profile-status-bar-item");
@@ -87,6 +116,14 @@ WebInspector.TimelinePanel.prototype = {
this.clearButton.addEventListener("click", this.reset.bind(this), false);
},
+ _toggleTimelineButtonClicked: function()
+ {
+ if (this.toggleTimelineButton.toggled)
+ InspectorBackend.stopTimelineProfiler();
+ else
+ InspectorBackend.startTimelineProfiler();
+ },
+
timelineWasStarted: function()
{
this.toggleTimelineButton.toggled = true;
@@ -99,7 +136,14 @@ WebInspector.TimelinePanel.prototype = {
addRecordToTimeline: function(record)
{
+ this._innerAddRecordToTimeline(record, this._records);
+ this._scheduleRefresh();
+ },
+
+ _innerAddRecordToTimeline: function(record, collection)
+ {
var formattedRecord = this._formatRecord(record);
+
// Glue subsequent records with same category and title together if they are closer than 100ms to each other.
if (this._lastRecord && (!record.children || !record.children.length) &&
this._lastRecord.category == formattedRecord.category &&
@@ -108,40 +152,25 @@ WebInspector.TimelinePanel.prototype = {
formattedRecord.startTime - this._lastRecord.endTime < 0.1) {
this._lastRecord.endTime = formattedRecord.endTime;
this._lastRecord.count++;
- this.refreshItem(this._lastRecord);
} else {
- this.addItem(formattedRecord);
-
- for (var i = 0; record.children && i < record.children.length; ++i)
- this.addRecordToTimeline(record.children[i]);
+ collection.push(formattedRecord);
+ for (var i = 0; record.children && i < record.children.length; ++i) {
+ if (!formattedRecord.children)
+ formattedRecord.children = [];
+ var formattedChild = this._innerAddRecordToTimeline(record.children[i], formattedRecord.children);
+ formattedChild.parent = formattedRecord;
+ }
this._lastRecord = record.children && record.children.length ? null : formattedRecord;
}
- },
-
- createItemTreeElement: function(item)
- {
- return new WebInspector.TimelineRecordTreeElement(item);
- },
-
- createItemGraph: function(item)
- {
- return new WebInspector.TimelineGraph(item);
- },
-
- _toggleTimelineButtonClicked: function()
- {
- if (InspectorController.timelineProfilerEnabled())
- InspectorController.stopTimelineProfiler();
- else
- InspectorController.startTimelineProfiler();
+ return formattedRecord;
},
_formatRecord: function(record)
{
+ var recordTypes = WebInspector.TimelineAgent.RecordType;
if (!this._recordStyles) {
this._recordStyles = {};
- var recordTypes = WebInspector.TimelineAgent.RecordType;
- this._recordStyles[recordTypes.DOMDispatch] = { title: WebInspector.UIString("DOM Event"), category: this.categories.scripting };
+ this._recordStyles[recordTypes.EventDispatch] = { title: WebInspector.UIString("Event"), category: this.categories.scripting };
this._recordStyles[recordTypes.Layout] = { title: WebInspector.UIString("Layout"), category: this.categories.rendering };
this._recordStyles[recordTypes.RecalculateStyles] = { title: WebInspector.UIString("Recalculate Style"), category: this.categories.rendering };
this._recordStyles[recordTypes.Paint] = { title: WebInspector.UIString("Paint"), category: this.categories.rendering };
@@ -151,13 +180,16 @@ WebInspector.TimelinePanel.prototype = {
this._recordStyles[recordTypes.TimerFire] = { title: WebInspector.UIString("Timer Fired"), category: this.categories.scripting };
this._recordStyles[recordTypes.XHRReadyStateChange] = { title: WebInspector.UIString("XHR Ready State Change"), category: this.categories.scripting };
this._recordStyles[recordTypes.XHRLoad] = { title: WebInspector.UIString("XHR Load"), category: this.categories.scripting };
- this._recordStyles[recordTypes.EvaluateScriptTag] = { title: WebInspector.UIString("Evaluate Script"), category: this.categories.scripting };
- this._recordStyles["Other"] = { title: WebInspector.UIString("Other"), icon: 0, category: this.categories.other };
+ this._recordStyles[recordTypes.EvaluateScript] = { title: WebInspector.UIString("Evaluate Script"), category: this.categories.scripting };
+ this._recordStyles[recordTypes.MarkTimeline] = { title: WebInspector.UIString("Mark"), category: this.categories.scripting };
+ this._recordStyles[recordTypes.ResourceSendRequest] = { title: WebInspector.UIString("Send Request"), category: this.categories.loading };
+ this._recordStyles[recordTypes.ResourceReceiveResponse] = { title: WebInspector.UIString("Receive Response"), category: this.categories.loading };
+ this._recordStyles[recordTypes.ResourceFinish] = { title: WebInspector.UIString("Finish Loading"), category: this.categories.loading };
}
var style = this._recordStyles[record.type];
if (!style)
- style = this._recordStyles["Other"];
+ style = this._recordStyles[recordTypes.EventDispatch];
var formattedRecord = {};
formattedRecord.category = style.category;
@@ -166,119 +198,278 @@ WebInspector.TimelinePanel.prototype = {
formattedRecord.data = record.data;
formattedRecord.count = 1;
formattedRecord.type = record.type;
- formattedRecord.details = this._getRecordDetails(record);
formattedRecord.endTime = (typeof record.endTime !== "undefined") ? record.endTime / 1000 : formattedRecord.startTime;
+ formattedRecord.record = record;
+
+ // Make resource receive record last since request was sent; make finish record last since response received.
+ if (record.type === WebInspector.TimelineAgent.RecordType.ResourceSendRequest) {
+ this._sendRequestRecords[record.data.identifier] = formattedRecord;
+ } else if (record.type === WebInspector.TimelineAgent.RecordType.ResourceReceiveResponse) {
+ var sendRequestRecord = this._sendRequestRecords[record.data.identifier];
+ if (sendRequestRecord) { // False if we started instrumentation in the middle of request.
+ sendRequestRecord._responseReceivedFormattedTime = formattedRecord.startTime;
+ formattedRecord.startTime = sendRequestRecord.startTime;
+ sendRequestRecord.details = this._getRecordDetails(record);
+ }
+ } else if (record.type === WebInspector.TimelineAgent.RecordType.ResourceFinish) {
+ var sendRequestRecord = this._sendRequestRecords[record.data.identifier];
+ if (sendRequestRecord) // False for main resource.
+ formattedRecord.startTime = sendRequestRecord._responseReceivedFormattedTime;
+ }
+ formattedRecord.details = this._getRecordDetails(record);
+
return formattedRecord;
},
-
+
_getRecordDetails: function(record)
{
switch (record.type) {
- case WebInspector.TimelineAgent.RecordType.DOMDispatch:
- return record.data.type;
+ case WebInspector.TimelineAgent.RecordType.EventDispatch:
+ return record.data ? record.data.type : "";
+ case WebInspector.TimelineAgent.RecordType.Paint:
+ return record.data.width + "\u2009\u00d7\u2009" + record.data.height;
case WebInspector.TimelineAgent.RecordType.TimerInstall:
case WebInspector.TimelineAgent.RecordType.TimerRemove:
case WebInspector.TimelineAgent.RecordType.TimerFire:
return record.data.timerId;
case WebInspector.TimelineAgent.RecordType.XHRReadyStateChange:
case WebInspector.TimelineAgent.RecordType.XHRLoad:
- case WebInspector.TimelineAgent.RecordType.EvaluateScriptTag:
- return record.data.url;
+ case WebInspector.TimelineAgent.RecordType.EvaluateScript:
+ case WebInspector.TimelineAgent.RecordType.ResourceSendRequest:
+ return WebInspector.displayNameForURL(record.data.url);
+ case WebInspector.TimelineAgent.RecordType.ResourceReceiveResponse:
+ case WebInspector.TimelineAgent.RecordType.ResourceFinish:
+ var sendRequestRecord = this._sendRequestRecords[record.data.identifier];
+ return sendRequestRecord ? WebInspector.displayNameForURL(sendRequestRecord.data.url) : "";
+ case WebInspector.TimelineAgent.RecordType.MarkTimeline:
+ return record.data.message;
default:
return "";
}
},
+ setSidebarWidth: function(width)
+ {
+ WebInspector.Panel.prototype.setSidebarWidth.call(this, width);
+ this._sidebarBackgroundElement.style.width = width + "px";
+ this._overviewPane.setSidebarWidth(width);
+ },
+
+ updateMainViewWidth: function(width)
+ {
+ this._containerContentElement.style.left = width + "px";
+ this._scheduleRefresh();
+ this._overviewPane.updateMainViewWidth(width);
+ },
+
+ resize: function() {
+ this._scheduleRefresh();
+ },
+
reset: function()
{
- WebInspector.AbstractTimelinePanel.prototype.reset.call(this);
this._lastRecord = null;
- }
-}
+ this._sendRequestRecords = {};
+ this._overviewPane.reset();
+ this._records = [];
+ this._refresh();
+ },
-WebInspector.TimelinePanel.prototype.__proto__ = WebInspector.AbstractTimelinePanel.prototype;
+ show: function()
+ {
+ WebInspector.Panel.prototype.show.call(this);
+ if (this._needsRefresh)
+ this._refresh();
+ },
-WebInspector.TimelineCategory = function(name, title, color)
-{
- WebInspector.AbstractTimelineCategory.call(this, name, title, color);
-}
+ _onScroll: function(event)
+ {
+ var scrollTop = this._containerElement.scrollTop;
+ var dividersTop = Math.max(0, scrollTop);
+ this._timelineGrid.setScrollAndDividerTop(scrollTop, dividersTop);
+ this._scheduleRefresh(true);
+ },
-WebInspector.TimelineCategory.prototype = {
-}
+ _scheduleRefresh: function(immediate)
+ {
+ if (this._needsRefresh)
+ return;
+ this._needsRefresh = true;
+
+ if (this.visible && !("_refreshTimeout" in this))
+ this._refreshTimeout = setTimeout(this._refresh.bind(this), immediate ? 0 : 100);
+ },
-WebInspector.TimelineCategory.prototype.__proto__ = WebInspector.AbstractTimelineCategory.prototype;
+ _refresh: function()
+ {
+ this._needsRefresh = false;
+ if ("_refreshTimeout" in this) {
+ clearTimeout(this._refreshTimeout);
+ delete this._refreshTimeout;
+ }
+ this._overviewPane.update(this._records);
+ this._refreshRecords();
+ },
+ _refreshRecords: function()
+ {
+ this._calculator.windowLeft = this._overviewPane.windowLeft;
+ this._calculator.windowRight = this._overviewPane.windowRight;
+ this._calculator.reset();
+
+ for (var i = 0; i < this._records.length; ++i)
+ this._calculator.updateBoundaries(this._records[i]);
+
+ var recordsInWindow = [];
+ for (var i = 0; i < this._records.length; ++i) {
+ var record = this._records[i];
+ var percentages = this._calculator.computeBarGraphPercentages(record);
+ if (percentages.start < 100 && percentages.end >= 0 && !record.category.hidden)
+ this._addToRecordsWindow(record, recordsInWindow);
+ }
-WebInspector.TimelineRecordTreeElement = function(record)
-{
- this._record = record;
+ // Calculate the visible area.
+ var visibleTop = this._containerElement.scrollTop;
+ var visibleBottom = visibleTop + this._containerElement.clientHeight;
+
+ // Define row height, should be in sync with styles for timeline graphs.
+ const rowHeight = 18;
+ const expandOffset = 15;
+
+ // Convert visible area to visible indexes. Always include top-level record for a visible nested record.
+ var startIndex = Math.max(0, Math.floor(visibleTop / rowHeight) - 1);
+ while (startIndex > 0 && recordsInWindow[startIndex].parent)
+ startIndex--;
+ var endIndex = Math.min(recordsInWindow.length, Math.ceil(visibleBottom / rowHeight));
+ while (endIndex < recordsInWindow.length - 1 && recordsInWindow[startIndex].parent)
+ endIndex++;
+
+ // Resize gaps first.
+ const top = (startIndex * rowHeight) + "px";
+ this._topGapElement.style.height = top;
+ this.sidebarElement.style.top = top;
+ this.sidebarResizeElement.style.top = top;
+ this._bottomGapElement.style.height = (recordsInWindow.length - endIndex) * rowHeight + "px";
+
+ // Update visible rows.
+ var listRowElement = this._sidebarListElement.firstChild;
+ var graphRowElement = this._graphRowsElement.firstChild;
+ var width = this._graphRowsElement.offsetWidth;
+ var scheduleRefreshCallback = this._scheduleRefresh.bind(this, true);
+ for (var i = startIndex; i < endIndex; ++i) {
+ var record = recordsInWindow[i];
+ var isEven = !(i % 2);
+
+ if (!listRowElement) {
+ listRowElement = new WebInspector.TimelineRecordListRow().element;
+ this._sidebarListElement.appendChild(listRowElement);
+ }
+ if (!graphRowElement) {
+ graphRowElement = new WebInspector.TimelineRecordGraphRow(this._itemsGraphsElement, scheduleRefreshCallback, rowHeight).element;
+ this._graphRowsElement.appendChild(graphRowElement);
+ }
+
+ listRowElement.listRow.update(record, isEven);
+ graphRowElement.graphRow.update(record, isEven, this._calculator, width, expandOffset);
+
+ listRowElement = listRowElement.nextSibling;
+ graphRowElement = graphRowElement.nextSibling;
+ }
- // Pass an empty title, the title gets made later in onattach.
- TreeElement.call(this, "", null, false);
-}
+ // Remove extra rows.
+ while (listRowElement) {
+ var nextElement = listRowElement.nextSibling;
+ listRowElement.listRow.dispose();
+ listRowElement = nextElement;
+ }
+ while (graphRowElement) {
+ var nextElement = graphRowElement.nextSibling;
+ graphRowElement.graphRow.dispose();
+ graphRowElement = nextElement;
+ }
+
+ // Reserve some room for expand / collapse controls to the left for records that start at 0ms.
+ var timelinePaddingLeft = this._calculator.windowLeft === 0 ? expandOffset : 0;
+ this._timelineGrid.updateDividers(true, this._calculator, timelinePaddingLeft);
+ this._adjustScrollPosition((recordsInWindow.length + 1) * rowHeight);
+ },
-WebInspector.TimelineRecordTreeElement.prototype = {
- onattach: function()
- {
- this.listItemElement.removeChildren();
- this.listItemElement.addStyleClass("timeline-tree-item");
- this.listItemElement.addStyleClass("timeline-category-" + this._record.category.name);
-
- var iconElement = document.createElement("span");
- iconElement.className = "timeline-tree-icon";
- this.listItemElement.appendChild(iconElement);
-
- this.typeElement = document.createElement("span");
- this.typeElement.className = "type";
- this.typeElement.textContent = this._record.title;
- this.listItemElement.appendChild(this.typeElement);
-
- if (this._record.details) {
- var separatorElement = document.createElement("span");
- separatorElement.className = "separator";
- separatorElement.textContent = " ";
-
- var dataElement = document.createElement("span");
- dataElement.className = "data";
- dataElement.textContent = "(" + this._record.details + ")";
- dataElement.addStyleClass("dimmed");
- this.listItemElement.appendChild(separatorElement);
- this.listItemElement.appendChild(dataElement);
+ _addToRecordsWindow: function(record, recordsWindow)
+ {
+ recordsWindow.push(record);
+ if (!record.collapsed) {
+ var index = recordsWindow.length;
+ for (var i = 0; record.children && i < record.children.length; ++i)
+ this._addToRecordsWindow(record.children[i], recordsWindow);
+ record.visibleChildrenCount = recordsWindow.length - index;
}
},
- refresh: function()
+ _adjustScrollPosition: function(totalHeight)
{
- if (this._record.count > 1)
- this.typeElement.textContent = this._record.title + " x " + this._record.count;
+ // Prevent the container from being scrolled off the end.
+ if ((this._containerElement.scrollTop + this._containerElement.offsetHeight) > totalHeight + 1)
+ this._containerElement.scrollTop = (totalHeight - this._containerElement.offsetHeight);
}
}
-WebInspector.TimelineRecordTreeElement.prototype.__proto__ = TreeElement.prototype;
+WebInspector.TimelinePanel.prototype.__proto__ = WebInspector.Panel.prototype;
+
+
+WebInspector.TimelineCategory = function(name, title, color)
+{
+ this.name = name;
+ this.title = title;
+ this.color = color;
+}
WebInspector.TimelineCalculator = function()
{
- WebInspector.AbstractTimelineCalculator.call(this);
+ this.windowLeft = 0.0;
+ this.windowRight = 1.0;
+ this._uiString = WebInspector.UIString.bind(WebInspector);
}
WebInspector.TimelineCalculator.prototype = {
computeBarGraphPercentages: function(record)
{
- var start = ((record.startTime - this.minimumBoundary) / this.boundarySpan) * 100;
- var end = ((record.endTime - this.minimumBoundary) / this.boundarySpan) * 100;
+ var start = (record.startTime - this.minimumBoundary) / this.boundarySpan * 100;
+ var end = (record.endTime - this.minimumBoundary) / this.boundarySpan * 100;
return {start: start, end: end};
},
- computePercentageFromEventTime: function(eventTime)
+ get minimumBoundary()
+ {
+ if (typeof this._minimumBoundary === "number")
+ return this._minimumBoundary;
+
+ if (typeof this.windowLeft === "number")
+ this._minimumBoundary = this._absoluteMinimumBoundary + this.windowLeft * (this._absoluteMaximumBoundary - this._absoluteMinimumBoundary);
+ else
+ this._minimumBoundary = this._absoluteMinimumBoundary;
+ return this._minimumBoundary;
+ },
+
+ get maximumBoundary()
{
- return ((eventTime - this.minimumBoundary) / this.boundarySpan) * 100;
+ if (typeof this._maximumBoundary === "number")
+ return this._maximumBoundary;
+
+ if (typeof this.windowLeft === "number")
+ this._maximumBoundary = this._absoluteMinimumBoundary + this.windowRight * (this._absoluteMaximumBoundary - this._absoluteMinimumBoundary);
+ else
+ this._maximumBoundary = this._absoluteMaximumBoundary;
+ return this._maximumBoundary;
},
- computeBarGraphLabels: function(record)
+ reset: function()
{
- return {tooltip: record.title};
+ delete this._absoluteMinimumBoundary;
+ delete this._absoluteMaximumBoundary;
+ delete this._minimumBoundary;
+ delete this._maximumBoundary;
},
updateBoundaries: function(record)
@@ -287,76 +478,153 @@ WebInspector.TimelineCalculator.prototype = {
var lowerBound = record.startTime;
- if (typeof this.minimumBoundary === "undefined" || lowerBound < this.minimumBoundary) {
- this.minimumBoundary = lowerBound;
+ if (typeof this._absoluteMinimumBoundary === "undefined" || lowerBound < this._absoluteMinimumBoundary) {
+ this._absoluteMinimumBoundary = lowerBound;
+ delete this._minimumBoundary;
didChange = true;
}
var upperBound = record.endTime;
- if (typeof this.maximumBoundary === "undefined" || upperBound > this.maximumBoundary) {
- this.maximumBoundary = upperBound;
+ if (typeof this._absoluteMaximumBoundary === "undefined" || upperBound > this._absoluteMaximumBoundary) {
+ this._absoluteMaximumBoundary = upperBound;
+ delete this._maximumBoundary;
didChange = true;
}
return didChange;
},
- formatValue: function(value)
+ get boundarySpan()
{
- return Number.secondsToString(value, WebInspector.UIString.bind(WebInspector));
+ return this.maximumBoundary - this.minimumBoundary;
},
+ formatValue: function(value)
+ {
+ return Number.secondsToString(value + this.minimumBoundary - this._absoluteMinimumBoundary, this._uiString);
+ }
}
-WebInspector.TimelineCalculator.prototype.__proto__ = WebInspector.AbstractTimelineCalculator.prototype;
-
-WebInspector.TimelineGraph = function(record)
+WebInspector.TimelineRecordListRow = function()
{
- this.record = record;
+ this.element = document.createElement("div");
+ this.element.listRow = this;
+ var iconElement = document.createElement("span");
+ iconElement.className = "timeline-tree-icon";
+ this.element.appendChild(iconElement);
- this._graphElement = document.createElement("div");
- this._graphElement.className = "timeline-graph-side";
+ this._typeElement = document.createElement("span");
+ this._typeElement.className = "type";
+ this.element.appendChild(this._typeElement);
- this._barAreaElement = document.createElement("div");
- this._barAreaElement.className = "timeline-graph-bar-area hidden";
- this._graphElement.appendChild(this._barAreaElement);
+ var separatorElement = document.createElement("span");
+ separatorElement.className = "separator";
+ separatorElement.textContent = " ";
- this._barElement = document.createElement("div");
- this._barElement.className = "timeline-graph-bar";
- this._barAreaElement.appendChild(this._barElement);
+ this._dataElement = document.createElement("span");
+ this._dataElement.className = "data dimmed";
+
+ this._repeatCountElement = document.createElement("span");
+ this._repeatCountElement.className = "count";
- this._graphElement.addStyleClass("timeline-category-" + record.category.name);
+ this.element.appendChild(separatorElement);
+ this.element.appendChild(this._dataElement);
+ this.element.appendChild(this._repeatCountElement);
}
-WebInspector.TimelineGraph.prototype = {
- get graphElement()
+WebInspector.TimelineRecordListRow.prototype = {
+ update: function(record, isEven)
{
- return this._graphElement;
- },
+ this.element.className = "timeline-tree-item timeline-category-" + record.category.name + (isEven ? " even" : "");
+ this._typeElement.textContent = record.title;
- refreshLabelPositions: function()
- {
+ if (record.details) {
+ this._dataElement.textContent = "(" + record.details + ")";
+ this._dataElement.title = record.details;
+ } else {
+ this._dataElement.textContent = "";
+ this._dataElement.title = "";
+ }
+
+ if (record.count > 1)
+ this._repeatCountElement.textContent = "\u2009\u00d7\u2009" + record.count;
+ else
+ this._repeatCountElement.textContent = "";
},
- refresh: function(calculator)
+ dispose: function()
{
- var percentages = calculator.computeBarGraphPercentages(this.record);
- var labels = calculator.computeBarGraphLabels(this.record);
+ this.element.parentElement.removeChild(this.element);
+ }
+}
- this._percentages = percentages;
- this._barAreaElement.removeStyleClass("hidden");
+WebInspector.TimelineRecordGraphRow = function(graphContainer, refreshCallback, rowHeight)
+{
+ this.element = document.createElement("div");
+ this.element.graphRow = this;
- if (!this._graphElement.hasStyleClass("timeline-category-" + this.record.category.name)) {
- this._graphElement.removeMatchingStyleClasses("timeline-category-\\w+");
- this._graphElement.addStyleClass("timeline-category-" + this.record.category.name);
+ this._barAreaElement = document.createElement("div");
+ this._barAreaElement.className = "timeline-graph-bar-area";
+ this.element.appendChild(this._barAreaElement);
+
+ this._barElement = document.createElement("div");
+ this._barElement.className = "timeline-graph-bar";
+ this._barAreaElement.appendChild(this._barElement);
+
+ this._expandElement = document.createElement("div");
+ this._expandElement.className = "timeline-expandable";
+ graphContainer.appendChild(this._expandElement);
+
+ var leftBorder = document.createElement("div");
+ leftBorder.className = "timeline-expandable-left";
+ this._expandElement.appendChild(leftBorder);
+
+ this._expandElement.addEventListener("click", this._onClick.bind(this));
+ this._refreshCallback = refreshCallback;
+ this._rowHeight = rowHeight;
+}
+
+WebInspector.TimelineRecordGraphRow.prototype = {
+ update: function(record, isEven, calculator, clientWidth, expandOffset)
+ {
+ this._record = record;
+ this.element.className = "timeline-graph-side timeline-category-" + record.category.name + (isEven ? " even" : "");
+ var percentages = calculator.computeBarGraphPercentages(record);
+ var left = percentages.start / 100 * clientWidth;
+ var width = (percentages.end - percentages.start) / 100 * clientWidth;
+ this._barElement.style.left = (left + expandOffset) + "px";
+ this._barElement.style.width = width + "px";
+
+ if (record.visibleChildrenCount) {
+ this._expandElement.style.top = this.element.offsetTop + "px";
+ this._expandElement.style.left = left + "px";
+ this._expandElement.style.width = Math.max(12, width + 25) + "px";
+ if (!record.collapsed) {
+ this._expandElement.style.height = (record.visibleChildrenCount + 1) * this._rowHeight + "px";
+ this._expandElement.addStyleClass("timeline-expandable-expanded");
+ this._expandElement.removeStyleClass("timeline-expandable-collapsed");
+ } else {
+ this._expandElement.style.height = this._rowHeight + "px";
+ this._expandElement.addStyleClass("timeline-expandable-collapsed");
+ this._expandElement.removeStyleClass("timeline-expandable-expanded");
+ }
+ this._expandElement.removeStyleClass("hidden");
+ } else {
+ this._expandElement.addStyleClass("hidden");
}
+ },
- this._barElement.style.setProperty("left", percentages.start + "%");
- this._barElement.style.setProperty("right", (100 - percentages.end) + "%");
+ _onClick: function(event)
+ {
+ this._record.collapsed = !this._record.collapsed;
+ this._refreshCallback();
+ },
- var tooltip = (labels.tooltip || "");
- this._barElement.title = tooltip;
+ dispose: function()
+ {
+ this.element.parentElement.removeChild(this.element);
+ this._expandElement.parentElement.removeChild(this._expandElement);
}
}