Diff
Modified: trunk/Source/WebInspectorUI/ChangeLog (241324 => 241325)
--- trunk/Source/WebInspectorUI/ChangeLog 2019-02-12 23:59:51 UTC (rev 241324)
+++ trunk/Source/WebInspectorUI/ChangeLog 2019-02-13 00:00:25 UTC (rev 241325)
@@ -1,5 +1,26 @@
2019-02-12 Joseph Pecoraro <pecor...@apple.com>
+ Web Inspector: Experimental setting for CPU Usage Timeline improvements
+ https://bugs.webkit.org/show_bug.cgi?id=194556
+
+ Reviewed by Matt Baker.
+
+ * UserInterface/Main.html:
+ * UserInterface/Views/LegacyCPUTimelineView.css: Added.
+ * UserInterface/Views/LegacyCPUTimelineView.js: Added.
+ Copy of CPUTimelineView.js/css to be used when the setting is not set.
+
+ * UserInterface/Views/ContentView.js:
+ (WI.ContentView.createFromRepresentedObject):
+ ContentView to create based on the setting.
+
+ * UserInterface/Base/Setting.js:
+ * UserInterface/Views/SettingsTabContentView.js:
+ (WI.SettingsTabContentView.prototype._createExperimentalSettingsView):
+ Experimental switch.
+
+2019-02-12 Joseph Pecoraro <pecor...@apple.com>
+
Web Inspector: Timeline.prototype.recordsInTimeRange uses a property most records do not have
https://bugs.webkit.org/show_bug.cgi?id=194549
Modified: trunk/Source/WebInspectorUI/UserInterface/Base/Setting.js (241324 => 241325)
--- trunk/Source/WebInspectorUI/UserInterface/Base/Setting.js 2019-02-12 23:59:51 UTC (rev 241324)
+++ trunk/Source/WebInspectorUI/UserInterface/Base/Setting.js 2019-02-13 00:00:25 UTC (rev 241325)
@@ -152,6 +152,7 @@
zoomFactor: new WI.Setting("zoom-factor", 1),
// Experimental
+ experimentalEnableCPUUsageEnhancements: new WI.Setting("experimental-cpu-usage", false),
experimentalEnableLayersTab: new WI.Setting("experimental-enable-layers-tab", false),
experimentalEnableNewTabBar: new WI.Setting("experimental-enable-new-tab-bar", false),
experimentalEnableAuditTab: new WI.Setting("experimental-enable-audit-tab", false),
Modified: trunk/Source/WebInspectorUI/UserInterface/Main.html (241324 => 241325)
--- trunk/Source/WebInspectorUI/UserInterface/Main.html 2019-02-12 23:59:51 UTC (rev 241324)
+++ trunk/Source/WebInspectorUI/UserInterface/Main.html 2019-02-13 00:00:25 UTC (rev 241325)
@@ -127,6 +127,7 @@
<link rel="stylesheet" href=""
<link rel="stylesheet" href=""
<link rel="stylesheet" href=""
+ <link rel="stylesheet" href=""
<link rel="stylesheet" href=""
<link rel="stylesheet" href=""
<link rel="stylesheet" href=""
@@ -702,6 +703,7 @@
<script src=""
<script src=""
<script src=""
+ <script src=""
<script src=""
<script src=""
<script src=""
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ContentView.js (241324 => 241325)
--- trunk/Source/WebInspectorUI/UserInterface/Views/ContentView.js 2019-02-12 23:59:51 UTC (rev 241324)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ContentView.js 2019-02-13 00:00:25 UTC (rev 241325)
@@ -84,7 +84,9 @@
return new WI.RenderingFrameTimelineView(representedObject, extraArguments);
if (timelineType === WI.TimelineRecord.Type.CPU)
- return new WI.CPUTimelineView(representedObject, extraArguments);
+ if (WI.settings.experimentalEnableCPUUsageEnhancements.value)
+ return new WI.CPUTimelineView(representedObject, extraArguments);
+ return new WI.LegacyCPUTimelineView(representedObject, extraArguments);
if (timelineType === WI.TimelineRecord.Type.Memory)
return new WI.MemoryTimelineView(representedObject, extraArguments);
Added: trunk/Source/WebInspectorUI/UserInterface/Views/LegacyCPUTimelineView.css (0 => 241325)
--- trunk/Source/WebInspectorUI/UserInterface/Views/LegacyCPUTimelineView.css (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/LegacyCPUTimelineView.css 2019-02-13 00:00:25 UTC (rev 241325)
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 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 APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
+ */
+
+body .timeline-view.legacy-cpu {
+ overflow: scroll;
+}
+
+.timeline-view.legacy-cpu > .content {
+ margin-top: 10px;
+}
+
+.timeline-view.legacy-cpu > .content .subtitle {
+ font-family: -webkit-system-font, sans-serif;
+ font-size: 14px;
+}
+
+.timeline-view.legacy-cpu > .content > .details {
+ position: relative;
+}
+
+.timeline-view.legacy-cpu > .content > .details > .timeline-ruler {
+ position: absolute;
+ top: 5px;
+ bottom: 0;
+ right: 0;
+ left: 0;
+
+ --cpu-timeline-view-details-timeline-ruler-offset-start: 150px;
+}
+
+body[dir=ltr] .timeline-view.legacy-cpu > .content > .details > .timeline-ruler {
+ left: var(--cpu-timeline-view-details-timeline-ruler-offset-start);
+}
+
+body[dir=rtl] .timeline-view.legacy-cpu > .content > .details > .timeline-ruler {
+ right: var(--cpu-timeline-view-details-timeline-ruler-offset-start);
+}
+
+.timeline-view.legacy-cpu > .content > .details > .subtitle {
+ padding: 0 10px 10px;
+ border-bottom: 1px solid var(--border-color);
+}
+
+.timeline-view.legacy-cpu .cpu-usage-view .line-chart > svg > path {
+ stroke: var(--cpu-stroke-color);
+ fill: var(--cpu-fill-color);
+}
Added: trunk/Source/WebInspectorUI/UserInterface/Views/LegacyCPUTimelineView.js (0 => 241325)
--- trunk/Source/WebInspectorUI/UserInterface/Views/LegacyCPUTimelineView.js (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/LegacyCPUTimelineView.js 2019-02-13 00:00:25 UTC (rev 241325)
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 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 APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
+ */
+
+WI.LegacyCPUTimelineView = class LegacyCPUTimelineView extends WI.TimelineView
+{
+ constructor(timeline, extraArguments)
+ {
+ console.assert(timeline.type === WI.TimelineRecord.Type.CPU, timeline);
+
+ super(timeline, extraArguments);
+
+ this._recording = extraArguments.recording;
+ this._maxUsage = -Infinity;
+
+ this.element.classList.add("legacy-cpu");
+
+ let contentElement = this.element.appendChild(document.createElement("div"));
+ contentElement.classList.add("content");
+
+ let detailsContainerElement = this._detailsContainerElement = contentElement.appendChild(document.createElement("div"));
+ detailsContainerElement.classList.add("details");
+
+ this._timelineRuler = new WI.TimelineRuler;
+ this.addSubview(this._timelineRuler);
+ detailsContainerElement.appendChild(this._timelineRuler.element);
+
+ let detailsSubtitleElement = detailsContainerElement.appendChild(document.createElement("div"));
+ detailsSubtitleElement.classList.add("subtitle");
+ detailsSubtitleElement.textContent = WI.UIString("CPU Usage");
+
+ this._cpuUsageView = new WI.CPUUsageView;
+ this.addSubview(this._cpuUsageView);
+ this._detailsContainerElement.appendChild(this._cpuUsageView.element);
+
+ timeline.addEventListener(WI.Timeline.Event.RecordAdded, this._cpuTimelineRecordAdded, this);
+ }
+
+ // Public
+
+ shown()
+ {
+ super.shown();
+
+ this._timelineRuler.updateLayout(WI.View.LayoutReason.Resize);
+ }
+
+ closed()
+ {
+ console.assert(this.representedObject instanceof WI.Timeline);
+ this.representedObject.removeEventListener(null, null, this);
+ }
+
+ reset()
+ {
+ super.reset();
+
+ this._maxUsage = -Infinity;
+
+ this.clear();
+ }
+
+ clear()
+ {
+ this._cpuUsageView.clear();
+ }
+
+ get scrollableElements()
+ {
+ return [this.element];
+ }
+
+ // Protected
+
+ get showsFilterBar() { return false; }
+
+ layout()
+ {
+ if (this.layoutReason === WI.View.LayoutReason.Resize)
+ return;
+
+ // Always update timeline ruler.
+ this._timelineRuler.zeroTime = this.zeroTime;
+ this._timelineRuler.startTime = this.startTime;
+ this._timelineRuler.endTime = this.endTime;
+
+ const cpuUsageViewHeight = 75; // Keep this in sync with .legacy-cpu-usage-view
+
+ let graphStartTime = this.startTime;
+ let graphEndTime = this.endTime;
+ let secondsPerPixel = this._timelineRuler.secondsPerPixel;
+ let visibleEndTime = Math.min(this.endTime, this.currentTime);
+
+ let discontinuities = this._recording.discontinuitiesInTimeRange(graphStartTime, visibleEndTime);
+
+ // Don't include the record before the graph start if the graph start is within a gap.
+ let includeRecordBeforeStart = !discontinuities.length || discontinuities[0].startTime > graphStartTime;
+ let visibleRecords = this.representedObject.recordsInTimeRange(graphStartTime, visibleEndTime, includeRecordBeforeStart);
+ if (!visibleRecords.length || (visibleRecords.length === 1 && visibleRecords[0].endTime < graphStartTime)) {
+ this.clear();
+ return;
+ }
+
+ let dataPoints = [];
+ let max = -Infinity;
+ let min = Infinity;
+ let average = 0;
+
+ for (let record of visibleRecords) {
+ let time = record.startTime;
+ let usage = record.usage;
+
+ if (discontinuities.length && discontinuities[0].endTime < time) {
+ let startDiscontinuity = discontinuities.shift();
+ let endDiscontinuity = startDiscontinuity;
+ while (discontinuities.length && discontinuities[0].endTime < time)
+ endDiscontinuity = discontinuities.shift();
+ dataPoints.push({time: startDiscontinuity.startTime, size: 0});
+ dataPoints.push({time: endDiscontinuity.endTime, size: 0});
+ dataPoints.push({time: endDiscontinuity.endTime, size: usage});
+ }
+
+ dataPoints.push({time, size: usage});
+ max = Math.max(max, usage);
+ min = Math.min(min, usage);
+ average += usage;
+ }
+
+ average /= visibleRecords.length;
+
+ // If the graph end time is inside a gap, the last data point should
+ // only be extended to the start of the discontinuity.
+ if (discontinuities.length)
+ visibleEndTime = discontinuities[0].startTime;
+
+ function layoutView(view, {dataPoints, min, max, average}) {
+ if (min === Infinity)
+ min = 0;
+ if (max === -Infinity)
+ max = 0;
+
+ // Zoom in to the top of each graph to accentuate small changes.
+ let graphMin = min * 0.95;
+ let graphMax = (max * 1.05) - graphMin;
+
+ function xScale(time) {
+ return (time - graphStartTime) / secondsPerPixel;
+ }
+
+ let size = new WI.Size(xScale(graphEndTime), cpuUsageViewHeight);
+
+ function yScale(value) {
+ return size.height - (((value - graphMin) / graphMax) * size.height);
+ }
+
+ view.updateChart(dataPoints, size, visibleEndTime, min, max, average, xScale, yScale);
+ }
+
+ layoutView(this._cpuUsageView, {dataPoints, min, max, average});
+ }
+
+ // Private
+
+ _cpuTimelineRecordAdded(event)
+ {
+ let cpuTimelineRecord = event.data.record;
+ console.assert(cpuTimelineRecord instanceof WI.CPUTimelineRecord);
+
+ this._maxUsage = Math.max(this._maxUsage, cpuTimelineRecord.usage);
+
+ if (cpuTimelineRecord.startTime >= this.startTime && cpuTimelineRecord.endTime <= this.endTime)
+ this.needsLayout();
+ }
+};
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/SettingsTabContentView.js (241324 => 241325)
--- trunk/Source/WebInspectorUI/UserInterface/Views/SettingsTabContentView.js 2019-02-12 23:59:51 UTC (rev 241324)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/SettingsTabContentView.js 2019-02-13 00:00:25 UTC (rev 241325)
@@ -261,6 +261,9 @@
experimentalSettingsView.addSetting(WI.UIString("User Interface:"), WI.settings.experimentalEnableNewTabBar, WI.UIString("Enable New Tab Bar"));
experimentalSettingsView.addSeparator();
+ experimentalSettingsView.addSetting(WI.unlocalizedString("CPU Usage:"), WI.settings.experimentalEnableCPUUsageEnhancements, WI.unlocalizedString("Enhancements"));
+ experimentalSettingsView.addSeparator();
+
let reloadInspectorButton = document.createElement("button");
reloadInspectorButton.textContent = WI.UIString("Reload Web Inspector");
reloadInspectorButton.addEventListener("click", (event) => {
@@ -285,6 +288,7 @@
listenForChange(WI.settings.experimentalEnableLayersTab);
listenForChange(WI.settings.experimentalEnableNewTabBar);
+ listenForChange(WI.settings.experimentalEnableCPUUsageEnhancements);
this.addSettingsView(experimentalSettingsView);
}