Diff
Modified: trunk/Source/WebCore/ChangeLog (117968 => 117969)
--- trunk/Source/WebCore/ChangeLog 2012-05-22 14:04:23 UTC (rev 117968)
+++ trunk/Source/WebCore/ChangeLog 2012-05-22 14:06:47 UTC (rev 117969)
@@ -1,3 +1,31 @@
+2012-05-22 Andrey Kosyakov <[email protected]>
+
+ Web Inspector: use canvas to render timeline category strips in overview pane
+ https://bugs.webkit.org/show_bug.cgi?id=87109
+
+ Reviewed by Pavel Feldman.
+
+ - use canvas, not DOM to represent timeline category strips in the default overview mode
+
+ * inspector/front-end/TimelineOverviewPane.js:
+ (WebInspector.TimelineOverviewPane):
+ (WebInspector.TimelineOverviewPane.prototype._setVerticalOverview): propagate to TimelineCategoryStrips;
+ (WebInspector.TimelineOverviewPane.prototype._onCategoryVisibilityChanged): force update of category strips;
+ (WebInspector.TimelineOverviewPane.prototype._update):
+ (WebInspector.TimelineOverviewPane.prototype.setShowShortEvents):
+ (WebInspector.TimelineCategoryStrips):
+ (WebInspector.TimelineCategoryStrips.prototype.update.appendRecord): process one record;
+ (WebInspector.TimelineCategoryStrips.prototype.update): re-draw everything;
+ (WebInspector.TimelineCategoryStrips.prototype.setShowShortEvents):
+ (WebInspector.TimelineCategoryStrips.prototype._renderBar): render single bar;
+ (WebInspector.TimelineVerticalOverview):
+ (WebInspector.TimelineVerticalOverview.prototype._renderBar):
+ * inspector/front-end/TimelinePresentationModel.js:
+ (WebInspector.TimelinePresentationModel.categories):
+ (WebInspector.TimelinePresentationModel.createFillStyle): utility methods to create gradients for category bars;
+ (WebInspector.TimelinePresentationModel.createFillStyleForCategory):
+ (WebInspector.TimelineCategory):
+
2012-05-22 Pavel Feldman <[email protected]>
Web Inspector: [regression] dynamically created script tab is bound to the document resource.
Modified: trunk/Source/WebCore/inspector/front-end/TimelineOverviewPane.js (117968 => 117969)
--- trunk/Source/WebCore/inspector/front-end/TimelineOverviewPane.js 2012-05-22 14:04:23 UTC (rev 117968)
+++ trunk/Source/WebCore/inspector/front-end/TimelineOverviewPane.js 2012-05-22 14:06:47 UTC (rev 117969)
@@ -88,21 +88,16 @@
this._overviewWindow = new WebInspector.TimelineOverviewWindow(this._overviewContainer);
this._overviewWindow.addEventListener(WebInspector.TimelineOverviewWindow.Events.WindowChanged, this._onWindowChanged, this);
- this._overviewContainer.appendChild(this._overviewGrid.element);
-
var separatorElement = document.createElement("div");
separatorElement.id = "timeline-overview-separator";
this.element.appendChild(separatorElement);
+
+ this._categoryStrips = new WebInspector.TimelineCategoryStrips(this._model);
+ this._overviewGrid.itemsGraphsElement.appendChild(this._categoryStrips.element);
- this._categoryGraphs = {};
- var i = 0;
var categories = WebInspector.TimelinePresentationModel.categories();
- for (var category in categories) {
- var categoryGraph = new WebInspector.TimelineCategoryGraph(categories[category], i++ % 2);
- this._categoryGraphs[category] = categoryGraph;
- this._overviewGrid.itemsGraphsElement.appendChild(categoryGraph.graphElement);
+ for (var category in categories)
categories[category].addEventListener(WebInspector.TimelineCategory.Events.VisibilityChanged, this._onCategoryVisibilityChanged, this);
- }
this._overviewGrid.setScrollAndDividerTop(0, 0);
this._overviewCalculator = new WebInspector.TimelineOverviewCalculator();
@@ -134,6 +129,11 @@
this._update();
},
+ onResize: function()
+ {
+ this._update();
+ },
+
_showEvents: function()
{
if (this._currentMode === WebInspector.TimelineOverviewPane.Mode.EventsHorizontal)
@@ -182,15 +182,14 @@
this._verticalOverview.detach();
this._verticalOverview = null;
this._overviewGrid.itemsGraphsElement.removeStyleClass("hidden");
- this._updateCategoryStrips();
+ this._categoryStrips.update();
}
},
_onCategoryVisibilityChanged: function(event)
{
- var category = event.data;
- this._categoryGraphs[category.name].dimmed = category.hidden;
- this._update();
+ if (this._currentMode === WebInspector.TimelineOverviewPane.Mode.EventsHorizontal)
+ this._categoryStrips.update();
},
_update: function()
@@ -205,61 +204,12 @@
else if (this._verticalOverview)
this._verticalOverview.update();
else
- this._updateCategoryStrips();
+ this._categoryStrips.update();
this._overviewGrid.updateDividers(this._overviewCalculator);
this._updateEventDividers();
},
- _updateCategoryStrips: function()
- {
- // Clear summary bars.
- var timelines = {};
- var categories = WebInspector.TimelinePresentationModel.categories();
- for (var category in categories) {
- timelines[category] = [];
- this._categoryGraphs[category].clearChunks();
- }
-
- // Create sparse arrays with 101 cells each to fill with chunks for a given category.
- function markPercentagesForRecord(record)
- {
- var isLong = WebInspector.TimelineModel.durationInSeconds(record) > WebInspector.TimelinePresentationModel.shortRecordThreshold;
- if (!(this._showShortEvents || isLong))
- return;
- var percentages = this._overviewCalculator.computeBarGraphPercentages(record);
-
- var end = Math.round(percentages.end);
- var categoryName = WebInspector.TimelinePresentationModel.categoryForRecord(record).name;
- for (var j = Math.round(percentages.start); j <= end; ++j)
- timelines[categoryName][j] = true;
- }
- var records = this._model.records;
- WebInspector.TimelinePresentationModel.forAllRecords(records, markPercentagesForRecord.bind(this));
-
- // Convert sparse arrays to continuous segments, render graphs for each.
- for (var category in categories) {
- var timeline = timelines[category];
- window.timelineSaved = timeline;
- var chunkStart = -1;
- for (var j = 0; j < 101; ++j) {
- if (timeline[j]) {
- if (chunkStart === -1)
- chunkStart = j;
- } else {
- if (chunkStart !== -1) {
- this._categoryGraphs[category].addChunk(chunkStart, j);
- chunkStart = -1;
- }
- }
- }
- if (chunkStart !== -1) {
- this._categoryGraphs[category].addChunk(chunkStart, 100);
- chunkStart = -1;
- }
- }
- },
-
_updateEventDividers: function()
{
var records = this._eventDividers;
@@ -374,10 +324,12 @@
this.dispatchEventToListeners(WebInspector.TimelineOverviewPane.Events.WindowChanged);
},
+ /**
+ * @param {boolean} value
+ */
setShowShortEvents: function(value)
{
- this._showShortEvents = value;
- this._update();
+ this._categoryStrips.setShowShortEvents(value);
},
_scheduleRefresh: function()
@@ -675,50 +627,6 @@
/**
* @constructor
*/
-WebInspector.TimelineCategoryGraph = function(category, isEven)
-{
- this._category = category;
-
- this._graphElement = document.createElement("div");
- this._graphElement.className = "timeline-graph-side timeline-overview-graph-side" + (isEven ? " even" : "");
-
- this._barAreaElement = document.createElement("div");
- this._barAreaElement.className = "timeline-graph-bar-area timeline-category-" + category.name;
- this._graphElement.appendChild(this._barAreaElement);
-}
-
-WebInspector.TimelineCategoryGraph.prototype = {
- get graphElement()
- {
- return this._graphElement;
- },
-
- addChunk: function(start, end)
- {
- var chunk = document.createElement("div");
- chunk.className = "timeline-graph-bar";
- this._barAreaElement.appendChild(chunk);
- chunk.style.setProperty("left", start + "%");
- chunk.style.setProperty("width", (end - start) + "%");
- },
-
- clearChunks: function()
- {
- this._barAreaElement.removeChildren();
- },
-
- set dimmed(dimmed)
- {
- if (dimmed)
- this._barAreaElement.removeStyleClass("timeline-category-" + this._category.name);
- else
- this._barAreaElement.addStyleClass("timeline-category-" + this._category.name);
- }
-}
-
-/**
- * @constructor
- */
WebInspector.TimelineOverviewPane.WindowSelector = function(parent, position)
{
this._startPosition = position;
@@ -892,10 +800,104 @@
},
}
+/**
+ * @constructor
+ * @param {WebInspector.TimelineModel} model
+ */
WebInspector.TimelineCategoryStrips = function(model)
{
+ this._model = model;
+ this.element = document.createElement("canvas");
+ this._context = this.element.getContext("2d");
+
+ this._fillStyles = {};
+ var categories = WebInspector.TimelinePresentationModel.categories();
+ for (var category in categories)
+ this._fillStyles[category] = WebInspector.TimelinePresentationModel.createFillStyleForCategory(this._context, 0, WebInspector.TimelineCategoryStrips._innerStripHeight, categories[category]);
+
+ this._disabledCategoryFillStyle = WebInspector.TimelinePresentationModel.createFillStyle(this._context, 0, WebInspector.TimelineCategoryStrips._innerStripHeight,
+ "rgb(218, 218, 218)", "rgb(170, 170, 170)", "rgb(143, 143, 143)");
+
+ this._disabledCategoryBorderStyle = "rgb(143, 143, 143)";
}
+/** @const */
+WebInspector.TimelineCategoryStrips._canvasHeight = 60;
+/** @const */
+WebInspector.TimelineCategoryStrips._numberOfStrips = 3;
+/** @const */
+WebInspector.TimelineCategoryStrips._stripHeight = Math.round(WebInspector.TimelineCategoryStrips._canvasHeight / WebInspector.TimelineCategoryStrips._numberOfStrips);
+/** @const */
+WebInspector.TimelineCategoryStrips._stripPadding = 4;
+/** @const */
+WebInspector.TimelineCategoryStrips._innerStripHeight = WebInspector.TimelineCategoryStrips._stripHeight - 2 * WebInspector.TimelineCategoryStrips._stripPadding;
+
+WebInspector.TimelineCategoryStrips.prototype = {
+ update: function()
+ {
+ // Use real world, 1:1 coordinates in canvas. This will also take care of clearing it.
+ this.element.width = this.element.parentElement.clientWidth;
+ this.element.height = WebInspector.TimelineCategoryStrips._canvasHeight;
+
+ var timeOffset = this._model.minimumRecordTime();
+ var timeSpan = this._model.maximumRecordTime() - timeOffset;
+ var scale = this.element.width / timeSpan;
+
+ var barsByCategory = {};
+
+ this._context.fillStyle = "rgba(0, 0, 0, 0.05)";
+ for (var i = 1; i < WebInspector.TimelineCategoryStrips._numberOfStrips; i += 2)
+ this._context.fillRect(0.5, i * WebInspector.TimelineCategoryStrips._stripHeight + 0.5, this.element.width, WebInspector.TimelineCategoryStrips._stripHeight);
+
+ function appendRecord(record)
+ {
+ var isLong = WebInspector.TimelineModel.durationInSeconds(record) > WebInspector.TimelinePresentationModel.shortRecordThreshold;
+ if (!(this._showShortEvents || isLong))
+ return;
+ var recordStart = Math.floor((WebInspector.TimelineModel.startTimeInSeconds(record) - timeOffset)* scale);
+ var recordEnd = Math.ceil((WebInspector.TimelineModel.endTimeInSeconds(record) - timeOffset) * scale);
+ var category = WebInspector.TimelinePresentationModel.categoryForRecord(record);
+ var bar = barsByCategory[category.name];
+ // This bar may be merged with previous -- so just adjust the previous bar.
+ const barsMergeThreshold = 2;
+ if (bar && bar.end + barsMergeThreshold >= recordStart) {
+ bar.end = recordEnd;
+ return;
+ }
+ if (bar)
+ this._renderBar(bar.start, bar.end, category);
+ barsByCategory[category.name] = { start: recordStart, end: recordEnd };
+ }
+ WebInspector.TimelinePresentationModel.forAllRecords(this._model.records, appendRecord.bind(this));
+ for (var category in barsByCategory)
+ this._renderBar(barsByCategory[category].start, barsByCategory[category].end, WebInspector.TimelinePresentationModel.categories()[category]);
+ },
+
+ /**
+ * @param {boolean} value
+ */
+ setShowShortEvents: function(value)
+ {
+ this._showShortEvents = value;
+ this.update();
+ },
+
+ _renderBar: function(begin, end, category)
+ {
+ var x = begin + 0.5;
+ var y = category.overviewStripGroupIndex * WebInspector.TimelineCategoryStrips._stripHeight + WebInspector.TimelineCategoryStrips._stripPadding + 0.5;
+ var width = Math.max(end - begin, 1);
+
+ this._context.save();
+ this._context.translate(x, y);
+ this._context.fillStyle = category.hidden ? this._disabledCategoryFillStyle : this._fillStyles[category.name];
+ this._context.fillRect(0, 0, width, WebInspector.TimelineCategoryStrips._innerStripHeight);
+ this._context.strokeStyle = category.hidden ? this._disabledCategoryBorderStyle : category.borderColor;
+ this._context.strokeRect(0, 0, width, WebInspector.TimelineCategoryStrips._innerStripHeight);
+ this._context.restore();
+ }
+}
+
/**
* @constructor
* @extends {WebInspector.View}
@@ -920,12 +922,8 @@
this._fillStyles = {};
var categories = WebInspector.TimelinePresentationModel.categories();
- for (var category in categories) {
- var fillStyle = this._context.createLinearGradient(0, 0, this._maxInnerBarWidth, 0);
- fillStyle.addColorStop(0, categories[category].fillColorStop0);
- fillStyle.addColorStop(1, categories[category].fillColorStop1);
- this._fillStyles[category] = fillStyle;
- }
+ for (var category in categories)
+ this._fillStyles[category] = WebInspector.TimelinePresentationModel.createFillStyleForCategory(this._context, this._maxInnerBarWidth, 0, categories[category]);
}
WebInspector.TimelineVerticalOverview.prototype = {
@@ -1047,7 +1045,7 @@
this._context.fillRect(0, y, this._maxInnerBarWidth, Math.floor(height));
this._context.restore();
- this._context.strokeStyle = WebInspector.TimelinePresentationModel.categories()[category];
+ this._context.strokeStyle = WebInspector.TimelinePresentationModel.categories()[category].borderColor;
this._context.strokeRect(x, y, width, Math.floor(height));
bottomOffset -= height - 1;
}
Modified: trunk/Source/WebCore/inspector/front-end/TimelinePresentationModel.js (117968 => 117969)
--- trunk/Source/WebCore/inspector/front-end/TimelinePresentationModel.js 2012-05-22 14:04:23 UTC (rev 117968)
+++ trunk/Source/WebCore/inspector/front-end/TimelinePresentationModel.js 2012-05-22 14:06:47 UTC (rev 117969)
@@ -47,9 +47,9 @@
if (WebInspector.TimelinePresentationModel._categories)
return WebInspector.TimelinePresentationModel._categories;
WebInspector.TimelinePresentationModel._categories = {
- loading: new WebInspector.TimelineCategory("loading", WebInspector.UIString("Loading"), "rgb(106, 152, 213)", "rgb(201, 220, 245)", "rgb(109, 157, 222)"),
- scripting: new WebInspector.TimelineCategory("scripting", WebInspector.UIString("Scripting"), "rgb(223, 175, 77)", "rgb(251, 222, 168)", "rgb(234, 182, 77)"),
- rendering: new WebInspector.TimelineCategory("rendering", WebInspector.UIString("Rendering"), "rgb(130, 59, 190)", "rgb(213, 185, 236)", "rgb(137, 62, 200)")
+ loading: new WebInspector.TimelineCategory("loading", WebInspector.UIString("Loading"), 0, "rgb(80, 135, 207)", "rgb(191, 214, 243)", "rgb(112, 162, 227)"),
+ scripting: new WebInspector.TimelineCategory("scripting", WebInspector.UIString("Scripting"), 1, "rgb(220, 163, 49)", "rgb(253, 217, 144)", "rgb(253, 191, 68)"),
+ rendering: new WebInspector.TimelineCategory("rendering", WebInspector.UIString("Rendering"), 2, "rgb(148, 88, 199)", "rgb(219, 195, 239)", "rgb(175, 120, 221)")
};
return WebInspector.TimelinePresentationModel._categories;
};
@@ -754,6 +754,35 @@
}
/**
+ * @param {CanvasRenderingContext2D} context
+ * @param {number} width
+ * @param {number} height
+ * @param {string} color0
+ * @param {string} color1
+ * @param {string} color2
+ */
+WebInspector.TimelinePresentationModel.createFillStyle = function(context, width, height, color0, color1, color2)
+{
+ var gradient = context.createLinearGradient(0, 0, width, height);
+ gradient.addColorStop(0, color0);
+ gradient.addColorStop(0.3, color1);
+ gradient.addColorStop(0.7, color1);
+ gradient.addColorStop(1, color2);
+ return gradient;
+}
+
+/**
+ * @param {CanvasRenderingContext2D} context
+ * @param {number} width
+ * @param {number} height
+ * @param {WebInspector.TimelineCategory} category
+ */
+WebInspector.TimelinePresentationModel.createFillStyleForCategory = function(context, width, height, category)
+{
+ return WebInspector.TimelinePresentationModel.createFillStyle(context, width, height, category.fillColorStop0, category.fillColorStop1, category.borderColor);
+}
+
+/**
* @interface
*/
WebInspector.TimelinePresentationModel.Filter = function()
@@ -772,14 +801,16 @@
* @extends {WebInspector.Object}
* @param {string} name
* @param {string} title
+ * @param {number} overviewStripGroupIndex
* @param {string} borderColor
* @param {string} fillColorStop0
* @param {string} fillColorStop1
*/
-WebInspector.TimelineCategory = function(name, title, borderColor, fillColorStop0, fillColorStop1)
+WebInspector.TimelineCategory = function(name, title, overviewStripGroupIndex, borderColor, fillColorStop0, fillColorStop1)
{
this.name = name;
this.title = title;
+ this.overviewStripGroupIndex = overviewStripGroupIndex;
this.borderColor = borderColor;
this.fillColorStop0 = fillColorStop0;
this.fillColorStop1 = fillColorStop1;
Modified: trunk/Source/WebCore/inspector/front-end/timelinePanel.css (117968 => 117969)
--- trunk/Source/WebCore/inspector/front-end/timelinePanel.css 2012-05-22 14:04:23 UTC (rev 117968)
+++ trunk/Source/WebCore/inspector/front-end/timelinePanel.css 2012-05-22 14:06:47 UTC (rev 117969)
@@ -307,16 +307,6 @@
pointer-events: none;
}
-.timeline-overview-graph-side {
- height: 20px;
- z-index: 170;
- pointer-events: none;
-}
-
-.timeline-overview-graph-side .timeline-graph-bar {
- height: 13px;
-}
-
.timeline-graph-bar-area {
position: absolute;
top: 0;