diff --git a/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js b/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js
index 6770170ba098b..01ba42848ac4a 100644
Binary files a/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js and b/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js differ
diff --git a/Source/WebInspectorUI/UserInterface/DataGrid.js b/Source/WebInspectorUI/UserInterface/DataGrid.js
index d09808ab08516..e423cc08546a3 100644
--- a/Source/WebInspectorUI/UserInterface/DataGrid.js
+++ b/Source/WebInspectorUI/UserInterface/DataGrid.js
@@ -1303,7 +1303,7 @@ WebInspector.DataGridNode = function(data, hasChildren)
this._data = data || {};
this.hasChildren = hasChildren || false;
this.children = [];
- this.dataGrid = this.dataGrid || null;
+ this.dataGrid = null;
this.parent = null;
this.previousSibling = null;
this.nextSibling = null;
diff --git a/Source/WebInspectorUI/UserInterface/Images/TimelineBarGreen.png b/Source/WebInspectorUI/UserInterface/Images/TimelineBarGreen.png
new file mode 100644
index 0000000000000..06a89e28ceb70
Binary files /dev/null and b/Source/WebInspectorUI/UserInterface/Images/TimelineBarGreen.png differ
diff --git a/Source/WebInspectorUI/UserInterface/Images/TimelineBarGreen@2x.png b/Source/WebInspectorUI/UserInterface/Images/TimelineBarGreen@2x.png
new file mode 100644
index 0000000000000..d5b36ec1cda42
Binary files /dev/null and b/Source/WebInspectorUI/UserInterface/Images/TimelineBarGreen@2x.png differ
diff --git a/Source/WebInspectorUI/UserInterface/InstrumentIcons.css b/Source/WebInspectorUI/UserInterface/InstrumentIcons.css
index 6ccde5b2ccb96..7e17595d6c5cb 100644
--- a/Source/WebInspectorUI/UserInterface/InstrumentIcons.css
+++ b/Source/WebInspectorUI/UserInterface/InstrumentIcons.css
@@ -31,6 +31,10 @@
content: -webkit-image-set(url(Images/Colors.png) 1x, url(Images/Colors@2x.png) 2x);
}
+.screenshot-icon .icon {
+ content: -webkit-image-set(url(Images/Log.png) 1x, url(Images/Log@2x.png) 2x);
+}
+
.script-icon .icon {
content: -webkit-image-set(url(Images/Script.png) 1x, url(Images/Script@2x.png) 2x);
}
diff --git a/Source/WebInspectorUI/UserInterface/InstrumentSidebarPanel.css b/Source/WebInspectorUI/UserInterface/InstrumentSidebarPanel.css
index a6b7b2373cf90..e110b3d2dd366 100644
--- a/Source/WebInspectorUI/UserInterface/InstrumentSidebarPanel.css
+++ b/Source/WebInspectorUI/UserInterface/InstrumentSidebarPanel.css
@@ -56,7 +56,7 @@
outline: none;
color: transparent;
overflow: hidden;
-
+
-webkit-appearance: none;
background-color: transparent;
@@ -98,7 +98,7 @@
top: 22px;
left: 0;
right: 0;
- height: 78px;
+ height: 104px;
}
.sidebar > .panel.instrument > .navigation-sidebar-panel-content-tree-outline.timelines .item:not(:first-child):not(.selected) {
@@ -110,7 +110,7 @@
}
.sidebar > .panel.instrument > .title-bar.profiles {
- top: 100px;
+ top: 126px;
border-top: 1px solid rgb(179, 179, 179);
height: 23px;
}
diff --git a/Source/WebInspectorUI/UserInterface/InstrumentSidebarPanel.js b/Source/WebInspectorUI/UserInterface/InstrumentSidebarPanel.js
index b57c4f6a997fe..46c5f19f23a14 100644
--- a/Source/WebInspectorUI/UserInterface/InstrumentSidebarPanel.js
+++ b/Source/WebInspectorUI/UserInterface/InstrumentSidebarPanel.js
@@ -75,10 +75,16 @@ WebInspector.InstrumentSidebarPanel = function()
scriptTimelineTreeElement.twoLine = true;
this._timelinesTreeOutline.appendChild(scriptTimelineTreeElement);
+ var screenshotTimelineTreeElement = new WebInspector.GeneralTreeElement(WebInspector.InstrumentSidebarPanel.ScreenshotIconStyleClass, WebInspector.UIString("Screenshots"), null, WebInspector.TimelineRecord.Type.Screenshot);
+ screenshotTimelineTreeElement.small = true;
+ screenshotTimelineTreeElement.twoLine = true;
+ this._timelinesTreeOutline.appendChild(screenshotTimelineTreeElement);
+
this._timelineTreeElementMap = {};
this._timelineTreeElementMap[WebInspector.TimelineRecord.Type.Network] = networkTimelineTreeElement;
this._timelineTreeElementMap[WebInspector.TimelineRecord.Type.Layout] = layoutTimelineTreeElement;
this._timelineTreeElementMap[WebInspector.TimelineRecord.Type.Script] = scriptTimelineTreeElement;
+ this._timelineTreeElementMap[WebInspector.TimelineRecord.Type.Screenshot] = screenshotTimelineTreeElement;
var profilesTitleBarElement = document.createElement("div");
profilesTitleBarElement.textContent = WebInspector.UIString("Profiles");
@@ -132,6 +138,8 @@ WebInspector.InstrumentSidebarPanel = function()
WebInspector.profileManager.addEventListener(WebInspector.ProfileManager.Event.ProfilingEnded, this._profilingEnded, this);
WebInspector.profileManager.addEventListener(WebInspector.ProfileManager.Event.ProfilingInterrupted, this._profilingInterrupted, this);
+ this._isCapturingScreenshots = true;
+
this.emptyContentPlaceholder = WebInspector.UIString("No Recorded Profiles");
// Maps from profile titles -> tree elements.
@@ -154,6 +162,7 @@ WebInspector.InstrumentSidebarPanel.NetworkIconStyleClass = "network-icon";
WebInspector.InstrumentSidebarPanel.ColorsIconStyleClass = "colors-icon";
WebInspector.InstrumentSidebarPanel.ScriptIconStyleClass = "script-icon";
WebInspector.InstrumentSidebarPanel.ProfileIconStyleClass = "profile-icon";
+WebInspector.InstrumentSidebarPanel.ScreenshotIconStyleClass = "screenshot-icon";
WebInspector.InstrumentSidebarPanel.StartJavaScriptProfileValue = "start-javascript-profile";
WebInspector.InstrumentSidebarPanel.StartCSSSelectorProfileValue = "start-css-selector-profile";
WebInspector.InstrumentSidebarPanel.StartCanvasProfileValue = "start-canvas-profile";
@@ -411,10 +420,15 @@ WebInspector.InstrumentSidebarPanel.prototype = {
// Add forced class to prevent the glyph from showing a confusing status after click.
this._recordGlyphElement.classList.add(WebInspector.InstrumentSidebarPanel.RecordGlyphRecordingForcedStyleClass);
- if (WebInspector.timelineManager.recording)
+ if (WebInspector.timelineManager.recording) {
WebInspector.timelineManager.stopRecording();
- else
+ if (this._isCapturingScreenshots)
+ WebInspector.timelineManager.clearScreenshotInterval();
+ } else {
WebInspector.timelineManager.startRecording();
+ if (this._isCapturingScreenshots)
+ WebInspector.timelineManager.setScreenshotInterval();
+ }
},
_titleForProfile: function(profile)
diff --git a/Source/WebInspectorUI/UserInterface/Main.html b/Source/WebInspectorUI/UserInterface/Main.html
index 5f6ee410e07f7..11bfcefe46a8e 100644
--- a/Source/WebInspectorUI/UserInterface/Main.html
+++ b/Source/WebInspectorUI/UserInterface/Main.html
@@ -351,6 +351,7 @@
+
@@ -358,6 +359,8 @@
+
+
diff --git a/Source/WebInspectorUI/UserInterface/ScreenshotTimelineDataGrid.js b/Source/WebInspectorUI/UserInterface/ScreenshotTimelineDataGrid.js
new file mode 100644
index 0000000000000..9b2226a19939e
--- /dev/null
+++ b/Source/WebInspectorUI/UserInterface/ScreenshotTimelineDataGrid.js
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2013 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * 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
+ * HOLDER 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.
+ */
+
+ WebInspector.ScreenshotTimelineDataGrid = function(columns)
+{
+ WebInspector.TimelineDataGrid.call(this, columns);
+
+ this.element.classList.add(WebInspector.ScreenshotTimelineDataGrid.ScreenshotDataGridStyleClassName);
+}
+
+WebInspector.ScreenshotTimelineDataGrid.ScreenshotDataGridStyleClassName = "screenshot-data-grid";
+
+WebInspector.ScreenshotTimelineDataGrid.prototype = {
+ constructor: WebInspector.ScreenshotTimelineDataGrid,
+ __proto__: WebInspector.TimelineDataGrid.prototype,
+
+ // Protected
+
+ callFramePopoverAnchorElement: function()
+ {
+ return this.selectedNode.elementWithColumnIdentifier("image");
+ }
+}
diff --git a/Source/WebInspectorUI/UserInterface/ScreenshotTimelineDataGridNode.js b/Source/WebInspectorUI/UserInterface/ScreenshotTimelineDataGridNode.js
new file mode 100644
index 0000000000000..4af5f128492b5
--- /dev/null
+++ b/Source/WebInspectorUI/UserInterface/ScreenshotTimelineDataGridNode.js
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2013 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * 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
+ * HOLDER 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.
+ */
+
+ WebInspector.ScreenshotTimelineDataGridNode = function(screenshotTimelineRecord, baseStartTime)
+{
+ WebInspector.DataGridNode.call(this, {});
+
+ this._record = screenshotTimelineRecord;
+ this._baseStartTime = baseStartTime || 0;
+};
+
+WebInspector.Object.addConstructorFunctions(WebInspector.ScreenshotTimelineDataGridNode);
+
+WebInspector.ScreenshotTimelineDataGridNode.IconStyleClassName = "icon";
+WebInspector.ScreenshotTimelineDataGridNode.SubtitleStyleClassName = "subtitle";
+WebInspector.ScreenshotTimelineDataGridNode.EmptyImagePlaceholder = "Images/DocumentImage.png";
+WebInspector.ScreenshotTimelineDataGridNode.EmptyStringPlaceholder = "\u2014";
+WebInspector.ScreenshotTimelineDataGridNode.ScreenshotStyleClassName = "screenshot";
+WebInspector.ScreenshotTimelineDataGridNode.EmptyScreenshotStyleClassName = "empty";
+
+WebInspector.ScreenshotTimelineDataGridNode.prototype = {
+ constructor: WebInspector.ScreenshotTimelineDataGridNode,
+ __proto__: WebInspector.DataGridNode.prototype,
+
+ // Public
+
+ get record()
+ {
+ return this._record;
+ },
+
+ get data()
+ {
+ return this._record;
+ },
+
+ createCellContent: function(columnIdentifier, cell)
+ {
+ var emptyString = WebInspector.ScreenshotTimelineDataGridNode.EmptyStringPlaceholder;
+ var value = this.data[columnIdentifier];
+
+ switch (columnIdentifier) {
+ case "eventType":
+ return WebInspector.ScreenshotTimelineRecord.EventType.displayName(value);
+
+ case "image":
+ var source = value;
+ var image = document.createElement("img");
+ image.classList.add(WebInspector.ScreenshotTimelineDataGridNode.ScreenshotStyleClassName);
+
+ if (!source) {
+ image.src = WebInspector.ScreenshotTimelineDataGridNode.EmptyImagePlaceholder;
+ image.classList.add(WebInspector.ScreenshotTimelineDataGridNode.EmptyScreenshotStyleClassName);
+ } else {
+ image.src = source;
+ }
+
+ return image;
+
+ case "x":
+ case "y":
+ return isNaN(value) ? emptyString : WebInspector.UIString("%d").format(value);
+
+ case "width":
+ case "height":
+ return isNaN(value) ? emptyString : WebInspector.UIString("%fpx").format(value);
+
+ case "area":
+ return isNaN(value) ? emptyString : WebInspector.UIString("%fpx²").format(value);
+
+ case "startTime":
+ return isNaN(value) ? emptyString : Number.secondsToString(value - this._baseStartTime);
+ }
+
+ return WebInspector.DataGridNode.prototype.createCellContent.call(this, columnIdentifier);
+ }
+}
diff --git a/Source/WebInspectorUI/UserInterface/ScreenshotTimelineRecord.js b/Source/WebInspectorUI/UserInterface/ScreenshotTimelineRecord.js
new file mode 100644
index 0000000000000..c254d9300d2ce
--- /dev/null
+++ b/Source/WebInspectorUI/UserInterface/ScreenshotTimelineRecord.js
@@ -0,0 +1,94 @@
+
+/*
+ * Copyright (C) 2013 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * 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
+ * HOLDER 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.
+ */
+
+ WebInspector.ScreenshotTimelineRecord = function(startTime, image, x, y, width, height)
+{
+ WebInspector.TimelineRecord.call(this, WebInspector.TimelineRecord.Type.Screenshot, startTime, startTime);
+
+ this._startTime = startTime || NaN;
+ this._x = x || NaN;
+ this._y = y || NaN;
+ this._width = width || NaN;
+ this._height = height || NaN;
+ this._image = image;
+};
+
+WebInspector.ScreenshotTimelineRecord.EventType = {
+ ImageCaptured: "screenshot-image-captured"
+};
+
+WebInspector.ScreenshotTimelineRecord.EventType.displayName = function(eventType)
+{
+ return WebInspector.UIString("Image Captured");
+};
+
+WebInspector.ScreenshotTimelineRecord.prototype = {
+ constructor: WebInspector.ScreenshotTimelineRecord,
+
+ // Public
+
+ get eventType()
+ {
+ return WebInspector.ScreenshotTimelineRecord.EventType.ImageCaptured;
+ },
+
+ get startTime()
+ {
+ return this._startTime;
+ },
+
+ get x()
+ {
+ return this._x;
+ },
+
+ get y()
+ {
+ return this._y;
+ },
+
+ get width()
+ {
+ return this._width;
+ },
+
+ get height()
+ {
+ return this._height;
+ },
+
+ get area()
+ {
+ return this._width * this._height;
+ },
+
+ get image()
+ {
+ return this._image;
+ }
+};
+
+WebInspector.ScreenshotTimelineRecord.prototype.__proto__ = WebInspector.TimelineRecord.prototype;
diff --git a/Source/WebInspectorUI/UserInterface/TimelineDecorations.css b/Source/WebInspectorUI/UserInterface/TimelineDecorations.css
index 01c465c0528fc..55898d3c15e3d 100644
--- a/Source/WebInspectorUI/UserInterface/TimelineDecorations.css
+++ b/Source/WebInspectorUI/UserInterface/TimelineDecorations.css
@@ -31,7 +31,7 @@
.timeline-decorations > .header {
border-top: 1px solid rgb(200, 200, 200);
- height: 22px;
+ height: 23px;
position: relative;
}
diff --git a/Source/WebInspectorUI/UserInterface/TimelineManager.js b/Source/WebInspectorUI/UserInterface/TimelineManager.js
index c5fb8d6fb6aff..5ddaad701cd9e 100644
--- a/Source/WebInspectorUI/UserInterface/TimelineManager.js
+++ b/Source/WebInspectorUI/UserInterface/TimelineManager.js
@@ -50,6 +50,7 @@ WebInspector.TimelineManager.Event = {
WebInspector.TimelineManager.MaximumAutoRecordDuration = 90000; // 90 seconds
WebInspector.TimelineManager.MaximumAutoRecordDurationAfterLoadEvent = 10000; // 10 seconds
WebInspector.TimelineManager.DeadTimeRequiredToStopAutoRecordingEarly = 2000; // 2 seconds
+WebInspector.TimelineManager.ScreenshotTimeIntervalDelay = 1000; // 1 second
WebInspector.TimelineManager.prototype = {
constructor: WebInspector.TimelineManager,
@@ -299,6 +300,14 @@ WebInspector.TimelineManager.prototype = {
this._loadEventTime = timestamp;
},
+ setScreenshotInterval: function() {
+ this._timeInvervalIdentifier = setInterval(this._recordScreenshot.bind(this), WebInspector.TimelineManager.ScreenshotTimeIntervalDelay);
+ },
+
+ clearScreenshotInterval: function() {
+ clearInterval(this._timeInvervalIdentifier);
+ },
+
// Private
_clear: function()
@@ -434,6 +443,14 @@ WebInspector.TimelineManager.prototype = {
return;
this._addRecord(new WebInspector.ResourceTimelineRecord(event.data.resource));
+ },
+
+ _recordScreenshot: function()
+ {
+ PageAgent.snapshotRect(0, 0, document.width, document.height, "Viewport", function(error, dataURL) {
+ if (!error)
+ this._addRecord(new WebInspector.ScreenshotTimelineRecord((new Date().getTime()) / 1000, dataURL, 0, 0, document.width, document.height));
+ }.bind(this));
}
};
diff --git a/Source/WebInspectorUI/UserInterface/TimelineOverview.css b/Source/WebInspectorUI/UserInterface/TimelineOverview.css
index be237e3cdf960..fe30719858b45 100644
--- a/Source/WebInspectorUI/UserInterface/TimelineOverview.css
+++ b/Source/WebInspectorUI/UserInterface/TimelineOverview.css
@@ -66,6 +66,10 @@
border-image-source: -webkit-image-set(url(Images/TimelineBarOrange.png) 1x, url(Images/TimelineBarOrange@2x.png) 2x);
}
+.timeline-overview > .timeline.timeline-record-type-screenshot .bar {
+ border-image-source: -webkit-image-set(url(Images/TimelineBarGreen.png) 1x, url(Images/TimelineBarGreen@2x.png) 2x);
+}
+
.timeline-overview .timeline-decorations > .event-markers {
height: 78px;
bottom: 22px;
diff --git a/Source/WebInspectorUI/UserInterface/TimelineRecord.js b/Source/WebInspectorUI/UserInterface/TimelineRecord.js
index 06388eee40fc4..f89b9bc9b6f0a 100644
--- a/Source/WebInspectorUI/UserInterface/TimelineRecord.js
+++ b/Source/WebInspectorUI/UserInterface/TimelineRecord.js
@@ -44,6 +44,7 @@ WebInspector.TimelineRecord.Event = {
WebInspector.TimelineRecord.Type = {
Network: "timeline-record-type-network",
Layout: "timeline-record-type-layout",
+ Screenshot: "timeline-record-type-screenshot",
Script: "timeline-record-type-script"
};
diff --git a/Source/WebInspectorUI/UserInterface/TimelinesContentView.css b/Source/WebInspectorUI/UserInterface/TimelinesContentView.css
index 93720719d134d..5d0e2a3cb6f54 100644
--- a/Source/WebInspectorUI/UserInterface/TimelinesContentView.css
+++ b/Source/WebInspectorUI/UserInterface/TimelinesContentView.css
@@ -28,12 +28,12 @@
top: 0;
left: 0;
right: 0;
- height: 100px;
+ height: 125px;
}
.content-view.timelines > .data-grid {
position: absolute;
- top: 100px;
+ top: 126px;
left: 0;
right: 0;
bottom: 0;
@@ -245,3 +245,21 @@
border-bottom: 1px solid rgb(179, 179, 179);
background-color: white;
}
+
+.content-view.timelines > .data-grid img.screenshot {
+ height: 300px;
+}
+
+.content-view.timelines > .data-grid.screenshot-data-grid tr.offscreen {
+ height: 300px;
+}
+
+.content-view.timelines > .data-grid.screenshot-data-grid tr.offscreen td {
+ display: block;
+}
+
+.content-view.timelines > .data-grid.screenshot-data-grid table.data {
+ background-size: auto 600px;
+ background-image: -webkit-linear-gradient(top, #ccc, #ccc 50%, rgb(90%, 90%, 90%) 50%, rgb(90%, 90%, 90%));
+
+}
diff --git a/Source/WebInspectorUI/UserInterface/TimelinesContentView.js b/Source/WebInspectorUI/UserInterface/TimelinesContentView.js
index 6a9b31af2548c..4a3cfc57c4048 100644
--- a/Source/WebInspectorUI/UserInterface/TimelinesContentView.js
+++ b/Source/WebInspectorUI/UserInterface/TimelinesContentView.js
@@ -29,7 +29,7 @@ WebInspector.TimelinesContentView = function(representedObject)
this.element.classList.add(WebInspector.TimelinesContentView.StyleClassName);
- this._timelineOverview = new WebInspector.TimelineOverview(this, [WebInspector.TimelineRecord.Type.Network, WebInspector.TimelineRecord.Type.Layout, WebInspector.TimelineRecord.Type.Script]);
+ this._timelineOverview = new WebInspector.TimelineOverview(this, [WebInspector.TimelineRecord.Type.Network, WebInspector.TimelineRecord.Type.Layout, WebInspector.TimelineRecord.Type.Script, WebInspector.TimelineRecord.Type.Screenshot]);
this.element.appendChild(this._timelineOverview.element);
function createPathComponent(displayName, className, representedObject)
@@ -42,11 +42,15 @@ WebInspector.TimelinesContentView = function(representedObject)
var networkPathComponent = createPathComponent.call(this, WebInspector.UIString("Network Requests"), WebInspector.InstrumentSidebarPanel.NetworkIconStyleClass, WebInspector.TimelineRecord.Type.Network);
var layoutPathComponent = createPathComponent.call(this, WebInspector.UIString("Layout & Rendering"), WebInspector.InstrumentSidebarPanel.ColorsIconStyleClass, WebInspector.TimelineRecord.Type.Layout);
var scriptPathComponent = createPathComponent.call(this, WebInspector.UIString("JavaScript & Events"), WebInspector.InstrumentSidebarPanel.ScriptIconStyleClass, WebInspector.TimelineRecord.Type.Script);
+ var screenshotPathComponent = createPathComponent.call(this, WebInspector.UIString("Screenshots"), WebInspector.InstrumentSidebarPanel.ScreenshotIconStyleClass, WebInspector.TimelineRecord.Type.Screenshot);
networkPathComponent.nextSibling = layoutPathComponent;
layoutPathComponent.previousSibling = networkPathComponent;
layoutPathComponent.nextSibling = scriptPathComponent;
scriptPathComponent.previousSibling = layoutPathComponent;
+ scriptPathComponent.nextSibling = screenshotPathComponent;
+ screenshotPathComponent.previousSibling = scriptPathComponent;
+
this._currentRecordType = null;
this._currentRecordTypeSetting = new WebInspector.Setting("timeline-view-current-record-type", WebInspector.TimelineRecord.Type.Network);
@@ -147,6 +151,35 @@ WebInspector.TimelinesContentView = function(representedObject)
scriptDataGridColumns.duration.width = "10%";
scriptDataGridColumns.duration.aligned = "right";
+ var screenshotDataGridColumns = {eventType: {}, image: {}, x: {}, y: {}, width: {}, height: {}, area: {}, startTime: {}};
+
+ screenshotDataGridColumns.eventType.title = WebInspector.UIString("Type");
+ screenshotDataGridColumns.eventType.width = "15%";
+ screenshotDataGridColumns.eventType.scopeBar = this._makeColumnScopeBar("screenshot", WebInspector.ScreenshotTimelineRecord.EventType);
+
+ screenshotDataGridColumns.image.title = WebInspector.UIString("Image");
+ screenshotDataGridColumns.image.width = "25%";
+
+ screenshotDataGridColumns.x.title = WebInspector.UIString("X");
+ screenshotDataGridColumns.x.width = "8%";
+
+ screenshotDataGridColumns.y.title = WebInspector.UIString("Y");
+ screenshotDataGridColumns.y.width = "8%";
+
+ screenshotDataGridColumns.width.title = WebInspector.UIString("Width");
+ screenshotDataGridColumns.width.width = "8%";
+
+ screenshotDataGridColumns.height.title = WebInspector.UIString("Height");
+ screenshotDataGridColumns.width.width = "8%";
+
+ screenshotDataGridColumns.area.title = WebInspector.UIString("Area");
+ screenshotDataGridColumns.area.width = "12%";
+
+ screenshotDataGridColumns.startTime.title = WebInspector.UIString("Time");
+ screenshotDataGridColumns.startTime.width = "8%";
+ screenshotDataGridColumns.startTime.aligned = "right";
+ screenshotDataGridColumns.startTime.sort = "ascending";
+
for (var column in networkDataGridColumns)
networkDataGridColumns[column].sortable = true;
@@ -156,9 +189,13 @@ WebInspector.TimelinesContentView = function(representedObject)
for (var column in scriptDataGridColumns)
scriptDataGridColumns[column].sortable = true;
+ for (var column in screenshotDataGridColumns)
+ screenshotDataGridColumns[column].sortable = true;
+
var networkDataGrid = new WebInspector.NetworkDataGrid(networkDataGridColumns);
var layoutDataGrid = new WebInspector.LayoutTimelineDataGrid(layoutDataGridColumns);
var scriptDataGrid = new WebInspector.ScriptTimelineDataGrid(scriptDataGridColumns);
+ var screenshotDataGrid = new WebInspector.ScreenshotTimelineDataGrid(screenshotDataGridColumns);
networkDataGrid.addEventListener(WebInspector.DataGrid.Event.SelectedNodeChanged, this._selectedNodeChanged, this);
@@ -166,11 +203,13 @@ WebInspector.TimelinesContentView = function(representedObject)
this._pathComponentMap[WebInspector.TimelineRecord.Type.Network] = networkPathComponent;
this._pathComponentMap[WebInspector.TimelineRecord.Type.Layout] = layoutPathComponent;
this._pathComponentMap[WebInspector.TimelineRecord.Type.Script] = scriptPathComponent;
+ this._pathComponentMap[WebInspector.TimelineRecord.Type.Screenshot] = screenshotPathComponent;
this._dataGridMap = {};
this._dataGridMap[WebInspector.TimelineRecord.Type.Network] = networkDataGrid;
this._dataGridMap[WebInspector.TimelineRecord.Type.Layout] = layoutDataGrid;
this._dataGridMap[WebInspector.TimelineRecord.Type.Script] = scriptDataGrid;
+ this._dataGridMap[WebInspector.TimelineRecord.Type.Screenshot] = screenshotDataGrid;
for (var type in this._dataGridMap) {
var dataGrid = this._dataGridMap[type];
@@ -658,6 +697,8 @@ WebInspector.TimelinesContentView.prototype = {
return new WebInspector.LayoutTimelineDataGridNode(record, baseStartTime);
case WebInspector.TimelineRecord.Type.Script:
return new WebInspector.ScriptTimelineDataGridNode(record, baseStartTime);
+ case WebInspector.TimelineRecord.Type.Screenshot:
+ return new WebInspector.ScreenshotTimelineDataGridNode(record, baseStartTime);
}
console.error("Unknown record type: " + record.type);