Diff
Modified: trunk/Source/WebInspectorUI/ChangeLog (238483 => 238484)
--- trunk/Source/WebInspectorUI/ChangeLog 2018-11-25 21:44:43 UTC (rev 238483)
+++ trunk/Source/WebInspectorUI/ChangeLog 2018-11-25 22:11:24 UTC (rev 238484)
@@ -1,3 +1,138 @@
+2018-11-25 Devin Rousso <drou...@apple.com>
+
+ Web Inspector: Timelines: add Media timeline
+ https://bugs.webkit.org/show_bug.cgi?id=191625
+
+ Reviewed by Matt Baker.
+
+ Add a new timeline to Timelines for media related events (e.g. event/fullscreen/low-power).
+ Mimics what is visible by using the same instrumentation points as the Network tab when
+ "Group Media Requests" is enabled.
+
+ * UserInterface/Models/MediaInstrument.js: Added.
+ (WI.MediaInstrument):
+ (WI.MediaInstrument.supported):
+ (WI.MediaInstrument.prototype.get timelineRecordType):
+ (WI.MediaInstrument.prototype.startInstrumentation):
+ (WI.MediaInstrument.prototype.stopInstrumentation):
+
+ * UserInterface/Models/MediaTimelineRecord.js: Added.
+ (WI.MediaTimelineRecord):
+ (WI.MediaTimelineRecord.prototype.get eventType):
+ (WI.MediaTimelineRecord.prototype.get domNode):
+ (WI.MediaTimelineRecord.prototype.get domEvent):
+ (WI.MediaTimelineRecord.prototype.get isLowPower):
+ (WI.MediaTimelineRecord.prototype.get displayName):
+ (WI.MediaTimelineRecord.prototype.saveIdentityToCookie):
+
+ * UserInterface/Views/MediaTimelineDataGridNode.js: Added.
+ (WI.MediaTimelineDataGridNode):
+ (WI.MediaTimelineDataGridNode.prototype.get records):
+ (WI.MediaTimelineDataGridNode.prototype.get data):
+ (WI.MediaTimelineDataGridNode.prototype.createCellContent):
+ (WI.MediaTimelineDataGridNode.prototype.iconClassNames):
+ (WI.MediaTimelineDataGridNode.prototype.filterableDataForColumn):
+
+ * UserInterface/Views/MediaTimelineOverviewGraph.js: Added.
+ (WI.MediaTimelineOverviewGraph):
+ (WI.MediaTimelineOverviewGraph.prototype.reset):
+ (WI.MediaTimelineOverviewGraph.prototype.shown):
+ (WI.MediaTimelineOverviewGraph.prototype.hidden):
+ (WI.MediaTimelineOverviewGraph.prototype.layout):
+ (WI.MediaTimelineOverviewGraph.prototype.updateSelectedRecord):
+ (WI.MediaTimelineOverviewGraph.prototype._handleRecordAdded):
+ * UserInterface/Views/MediaTimelineOverviewGraph.css: Added.
+ (.timeline-overview-graph.media > .timeline-record-bar):
+ (.timeline-overview-graph.media > .timeline-record-bar > .segment):
+
+ * UserInterface/Views/MediaTimelineView.js: Added.
+ (WI.MediaTimelineView):
+ (WI.MediaTimelineView.prototype.get secondsPerPixel):
+ (WI.MediaTimelineView.prototype.get selectionPathComponents):
+ (WI.MediaTimelineView.prototype.closed):
+ (WI.MediaTimelineView.prototype.reset):
+ (WI.MediaTimelineView.prototype.dataGridSortComparator.compareDOMNodes):
+ (WI.MediaTimelineView.prototype.dataGridSortComparator.):
+ (WI.MediaTimelineView.prototype.dataGridSortComparator):
+ (WI.MediaTimelineView.prototype.layout):
+ (WI.MediaTimelineView.prototype._processPendingRecords):
+ (WI.MediaTimelineView.prototype._handleRecordAdded):
+ (WI.MediaTimelineView.prototype._handleSelectionPathComponentSiblingSelected):
+ * UserInterface/Views/MediaTimelineView.css: Added.
+ (.timeline-view.media > .data-grid):
+
+ * UserInterface/Views/DOMEventsBreakdownView.js:
+ (WI.DOMEventsBreakdownView.prototype.layout):
+ * UserInterface/Views/DOMNodeEventsContentView.js:
+ (WI.DOMNodeEventsContentView.prototype.initialLayout):
+ * UserInterface/Views/NetworkDOMNodeDetailView.js:
+ (WI.NetworkDOMNodeDetailView):
+ (WI.NetworkDOMNodeDetailView.prototype.showContentViewForIdentifier):
+ * UserInterface/Views/NetworkTableContentView.js:
+ (WI.NetworkTableContentView):
+ (WI.NetworkTableContentView.prototype.get filterNavigationItems):
+ (WI.NetworkTableContentView.prototype._populateWaterfallGraph):
+ (WI.NetworkTableContentView.prototype._showDetailView):
+ (WI.NetworkTableContentView.prototype._waterfallPopoverContentForNodeEntry):
+ Remove passing of `startTimestamp` to `WI.DOMEventsBreakdownView`, as we should be showing
+ absolute timestamps for each event, not relative to the start of the recording.
+
+ * UserInterface/Views/TimelineIcons.css:
+ (.media-icon .icon): Added.
+ (.dom-event-record .icon): Added.
+ (.dom-event-record.fullscreen .icon): Added.
+ (.low-power-record .icon): Added.
+
+ * UserInterface/Controllers/TimelineManager.js:
+ (WI.TimelineManager.availableTimelineTypes):
+ (WI.TimelineManager.prototype.capturingStarted):
+ (WI.TimelineManager.prototype.capturingStopped):
+ (WI.TimelineManager.prototype._updateAutoCaptureInstruments):
+ (WI.TimelineManager.prototype._handleDOMNodeDidFireEvent): Added.
+ (WI.TimelineManager.prototype._handleDOMNodeLowPowerChanged): Added.
+
+ * UserInterface/Views/TimelineRuler.js:
+ (WI.TimelineRuler.prototype.clearMarkers):
+ (WI.TimelineRuler.prototype._handleClick):
+ * UserInterface/Views/TimelineOverview.js:
+ (WI.TimelineOverview.prototype._timelineRulerMouseClicked):
+ * UserInterface/Models/TimelineRecording.js:
+ (WI.TimelineRecording.prototype.reset):
+ (WI.TimelineRecording.prototype.addEventMarker):
+ (WI.TimelineRecording.prototype.addRecord):
+ (WI.TimelineRecording.prototype._keyForRecord):
+ Drive-by: rework the logic for "click" event pass-through to the graph underneath.
+
+ * UserInterface/Models/Instrument.js:
+ (WI.Instrument.createForTimelineType):
+
+ * UserInterface/Models/TimelineRecord.js:
+
+ * UserInterface/Views/TimelineTabContentView.js:
+ (WI.TimelineTabContentView.displayNameForTimelineType):
+ (WI.TimelineTabContentView.iconClassNameForTimelineType):
+ (WI.TimelineTabContentView.genericClassNameForTimelineType):
+ (WI.TimelineTabContentView.iconClassNameForRecord):
+ (WI.TimelineTabContentView.displayNameForRecord):
+ * UserInterface/Views/TimelineRecordBar.css:
+ (.timeline-record-bar.timeline-record-type-media > .segment): Added.
+
+ * UserInterface/Views/ContentView.js:
+ (WI.ContentView.createFromRepresentedObject):
+ * UserInterface/Views/TimelineOverviewGraph.js:
+ (WI.TimelineOverviewGraph.createForTimeline):
+
+ * UserInterface/Models/ScriptTimelineRecord.js:
+ (WI.ScriptTimelineRecord.EventType.displayName):
+
+ * UserInterface/Main.html:
+ * UserInterface/Test.html:
+ * Localizations/en.lproj/localizedStrings.js:
+ * UserInterface/Images/DOMEvent.svg: Added.
+ * UserInterface/Images/DOMEventFullscreen.svg: Added.
+ * UserInterface/Images/LowPower.svg: Added.
+ * UserInterface/Images/MediaInstrument.svg: Added.
+
2018-11-25 Matt Baker <mattba...@apple.com>
Web Inspector: Remove parameters from TreeOutline SelectionDidChange event
Modified: trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js (238483 => 238484)
--- trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js 2018-11-25 21:44:43 UTC (rev 238483)
+++ trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js 2018-11-25 22:11:24 UTC (rev 238484)
@@ -371,6 +371,8 @@
localizedStrings["Ensure hidden=true is not present on the document body."] = "Ensure hidden=true is not present on the document body.";
localizedStrings["Ensure legend is first child in form."] = "Ensure legend is first child in form.";
localizedStrings["Ensure tabindex is a number."] = "Ensure tabindex is a number.";
+localizedStrings["Entered Full-Screen Mode"] = "Entered Full-Screen Mode";
+localizedStrings["Entered Low-Power Mode"] = "Entered Low-Power Mode";
localizedStrings["Entire Recording"] = "Entire Recording";
localizedStrings["Error"] = "Error";
localizedStrings["Error: "] = "Error: ";
@@ -385,6 +387,8 @@
localizedStrings["Events"] = "Events";
localizedStrings["Example: “%s”"] = "Example: “%s”";
localizedStrings["Exception with thrown value: %s"] = "Exception with thrown value: %s";
+localizedStrings["Exited Full-Screen Mode"] = "Exited Full-Screen Mode";
+localizedStrings["Exited Low-Power Mode"] = "Exited Low-Power Mode";
localizedStrings["Expand All"] = "Expand All";
localizedStrings["Expand columns"] = "Expand columns";
localizedStrings["Expanded"] = "Expanded";
@@ -436,8 +440,8 @@
localizedStrings["Frames %d \u2013 %d"] = "Frames %d \u2013 %d";
localizedStrings["Full Garbage Collection"] = "Full Garbage Collection";
localizedStrings["Full URL"] = "Full URL";
-localizedStrings["Fullscreen"] = "Fullscreen";
-localizedStrings["Fullscreen from “%s“"] = "Fullscreen from “%s“";
+localizedStrings["Full-Screen"] = "Full-Screen";
+localizedStrings["Full-Screen from “%s“"] = "Full-Screen from “%s“";
localizedStrings["Function"] = "Function";
localizedStrings["Function Name Variable"] = "Function Name Variable";
localizedStrings["Garbage Collection"] = "Garbage Collection";
@@ -550,7 +554,7 @@
localizedStrings["Log: "] = "Log: ";
localizedStrings["Logs"] = "Logs";
localizedStrings["Low"] = "Low";
-localizedStrings["Low Power Mode"] = "Low Power Mode";
+localizedStrings["Low-Power Mode"] = "Low-Power Mode";
localizedStrings["Lowest: %s"] = "Lowest: %s";
localizedStrings["MIME Type"] = "MIME Type";
localizedStrings["MIME Type:"] = "MIME Type:";
@@ -562,6 +566,7 @@
localizedStrings["Maximum Size: %s"] = "Maximum Size: %s";
localizedStrings["Maximum maximum memory size in this recording"] = "Maximum maximum memory size in this recording";
localizedStrings["Media"] = "Media";
+localizedStrings["Media Event"] = "Media Event";
localizedStrings["Media Logging:"] = "Media Logging:";
localizedStrings["Medium"] = "Medium";
localizedStrings["Memory"] = "Memory";
Modified: trunk/Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js (238483 => 238484)
--- trunk/Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js 2018-11-25 21:44:43 UTC (rev 238483)
+++ trunk/Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js 2018-11-25 22:11:24 UTC (rev 238484)
@@ -111,6 +111,11 @@
if (WI.HeapAllocationsInstrument.supported())
types.push(WI.TimelineRecord.Type.HeapAllocations);
+ if (WI.MediaInstrument.supported()) {
+ let insertionIndex = types.indexOf(WI.TimelineRecord.Type.Layout) + 1;
+ types.insertAtIndex(WI.TimelineRecord.Type.Media, insertionIndex || types.length);
+ }
+
return types;
}
@@ -251,6 +256,9 @@
this._webTimelineScriptRecordsExpectingScriptProfilerEvents = [];
+ WI.DOMNode.addEventListener(WI.DOMNode.Event.DidFireEvent, this._handleDOMNodeDidFireEvent, this);
+ WI.DOMNode.addEventListener(WI.DOMNode.Event.LowPowerChanged, this._handleDOMNodeLowPowerChanged, this);
+
this.dispatchEventToListeners(WI.TimelineManager.Event.CapturingStarted, {startTime});
}
@@ -261,6 +269,8 @@
if (!this._isCapturing)
return;
+ WI.DOMNode.removeEventListener(null, null, this);
+
if (this._stopCapturingTimeout) {
clearTimeout(this._stopCapturingTimeout);
this._stopCapturingTimeout = undefined;
@@ -1067,6 +1077,7 @@
case WI.TimelineRecord.Type.Network:
case WI.TimelineRecord.Type.RenderingFrame:
case WI.TimelineRecord.Type.Layout:
+ case WI.TimelineRecord.Type.Media:
instrumentSet.add(target.TimelineAgent.Instrument.Timeline);
break;
case WI.TimelineRecord.Type.Memory:
@@ -1078,6 +1089,30 @@
target.TimelineAgent.setInstruments(Array.from(instrumentSet));
}
}
+
+ _handleDOMNodeDidFireEvent(event)
+ {
+ console.assert(this._isCapturing);
+
+ let {domEvent} = event.data;
+
+ this._addRecord(new WI.MediaTimelineRecord(WI.MediaTimelineRecord.EventType.DOMEvent, domEvent.timestamp, {
+ domNode: event.target,
+ domEvent,
+ }));
+ }
+
+ _handleDOMNodeLowPowerChanged(event)
+ {
+ console.assert(this._isCapturing);
+
+ let {timestamp, isLowPower} = event.data;
+
+ this._addRecord(new WI.MediaTimelineRecord(WI.MediaTimelineRecord.EventType.LowPower, timestamp, {
+ domNode: event.target,
+ isLowPower,
+ }));
+ }
};
WI.TimelineManager.Event = {
Added: trunk/Source/WebInspectorUI/UserInterface/Images/DOMEvent.svg (0 => 238484)
--- trunk/Source/WebInspectorUI/UserInterface/Images/DOMEvent.svg (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Images/DOMEvent.svg 2018-11-25 22:11:24 UTC (rev 238484)
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright © 2018 Apple Inc. All rights reserved. -->
+<svg xmlns="http://www.w3.org/2000/svg" id="root" version="1.1" viewBox="0 0 16 16">
+ <path fill="rgb(148, 190, 164)" d="M 13 1 L 3 1 C 1.898438 1 1 1.898438 1 3 L 1 13 C 1 14.101562 1.898438 15 3 15 L 13 15 C 14.101562 15 15 14.101562 15 13 L 15 3 C 15 1.898438 14.101562 1 13 1 Z"/>
+ <path fill="rgb(101, 161, 134)" d="M 13 1 L 3 1 C 1.898438 1 1 1.898438 1 3 L 1 13 C 1 14.101562 1.898438 15 3 15 L 13 15 C 14.101562 15 15 14.101562 15 13 L 15 3 C 15 1.898438 14.101562 1 13 1 M 13 2 C 13.550781 2 14 2.449219 14 3 L 14 13 C 14 13.550781 13.550781 14 13 14 L 3 14 C 2.449219 14 2 13.550781 2 13 L 2 3 C 2 2.449219 2.449219 2 3 2 L 13 2"/>
+ <path fill="rgb(101, 161, 134)" d="M 5.503906 12.742188 C 4.949219 12.742188 4.503906 12.292969 4.503906 11.742188 L 4.503906 3.792969 C 4.503906 3.242188 4.949219 2.792969 5.503906 2.792969 L 10.472656 2.792969 C 11.023438 2.792969 11.472656 3.242188 11.472656 3.792969 L 11.472656 4.882812 C 11.472656 5.4375 11.023438 5.882812 10.472656 5.882812 C 10.472656 5.882812 9.132812 5.882812 8.15625 5.882812 C 8.15625 5.992188 8.15625 5.996094 8.15625 6.101562 C 8.957031 6.101562 9.875 6.101562 9.875 6.101562 C 10.425781 6.101562 10.875 6.550781 10.875 7.101562 L 10.875 8.164062 C 10.875 8.71875 10.425781 9.164062 9.875 9.164062 C 9.875 9.164062 8.957031 9.164062 8.15625 9.164062 C 8.15625 9.382812 8.15625 9.398438 8.15625 9.613281 C 9.191406 9.613281 10.722656 9.613281 10.722656 9.613281 C 11.277344 9.613281 11.722656 10.0625 11.722656 10.613281 L 11.722656 11.742188 C 11.722656 12.292969 11.277344 12.742188 10.722656 12.742188 L 5.503906 12.742188"/>
+ <path fill="white" d="M 5.503906 11.742188 L 5.503906 3.792969 L 10.46875 3.792969 L 10.46875 4.882812 L 7.15625 4.882812 L 7.15625 7.101562 L 9.875 7.101562 L 9.875 8.164062 L 7.15625 8.164062 L 7.15625 10.613281 L 10.722656 10.613281 L 10.722656 11.742188 Z"/>
+</svg>
Added: trunk/Source/WebInspectorUI/UserInterface/Images/DOMEventFullscreen.svg (0 => 238484)
--- trunk/Source/WebInspectorUI/UserInterface/Images/DOMEventFullscreen.svg (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Images/DOMEventFullscreen.svg 2018-11-25 22:11:24 UTC (rev 238484)
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright © 2018 Apple Inc. All rights reserved. -->
+<svg xmlns="http://www.w3.org/2000/svg" id="root" version="1.1" viewBox="0 0 16 16">
+ <path fill="rgb(148, 190, 164)" d="M 13 1 L 3 1 C 1.898438 1 1 1.898438 1 3 L 1 13 C 1 14.101562 1.898438 15 3 15 L 13 15 C 14.101562 15 15 14.101562 15 13 L 15 3 C 15 1.898438 14.101562 1 13 1 Z"/>
+ <path fill="rgb(101, 161, 134)" d="M 13 1 L 3 1 C 1.898438 1 1 1.898438 1 3 L 1 13 C 1 14.101562 1.898438 15 3 15 L 13 15 C 14.101562 15 15 14.101562 15 13 L 15 3 C 15 1.898438 14.101562 1 13 1 M 13 2 C 13.550781 2 14 2.449219 14 3 L 14 13 C 14 13.550781 13.550781 14 13 14 L 3 14 C 2.449219 14 2 13.550781 2 13 L 2 3 C 2 2.449219 2.449219 2 3 2 L 13 2"/>
+ <path fill="rgb(101, 161, 134)" d="M 12 3 L 11 3 L 5 3 L 4 3 L 4 4 L 4 12 L 4 12.962999 L 4.962 12.999 L 6.962 13.075 L 8 13.115 L 8 12.076 L 8 9 L 10 9 L 11 9 L 11 8 L 11 7 L 11 6 L 10 6 L 8 6 L 11 6 L 12 6 L 12 5 L 12 4 L 12 3 Z M 11 4 L 11 5 L 7 5 L 7 7 L 10 7 L 10 8 L 7 8 L 7 12.076 L 5 12 L 5 4 L 11 4 Z"/>
+ <path fill="white" d="M 5 12 L 5 4 L 11 4 L 11 5 L 7 5 L 7 7 L 10 7 L 10 8 L 7 8 L 7 12.076 L 5 12 Z"/>
+</svg>
Added: trunk/Source/WebInspectorUI/UserInterface/Images/LowPower.svg (0 => 238484)
--- trunk/Source/WebInspectorUI/UserInterface/Images/LowPower.svg (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Images/LowPower.svg 2018-11-25 22:11:24 UTC (rev 238484)
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright © 2018 Apple Inc. All rights reserved. -->
+<svg xmlns="http://www.w3.org/2000/svg" id="root" version="1.1" viewBox="0 0 16 16">
+ <path fill="rgb(148, 190, 164)" d="M 13 1 L 3 1 C 1.898438 1 1 1.898438 1 3 L 1 13 C 1 14.101562 1.898438 15 3 15 L 13 15 C 14.101562 15 15 14.101562 15 13 L 15 3 C 15 1.898438 14.101562 1 13 1 Z"/>
+ <path fill="rgb(101, 161, 134)" d="M 13 1 L 3 1 C 1.898438 1 1 1.898438 1 3 L 1 13 C 1 14.101562 1.898438 15 3 15 L 13 15 C 14.101562 15 15 14.101562 15 13 L 15 3 C 15 1.898438 14.101562 1 13 1 M 13 2 C 13.550781 2 14 2.449219 14 3 L 14 13 C 14 13.550781 13.550781 14 13 14 L 3 14 C 2.449219 14 2 13.550781 2 13 L 2 3 C 2 2.449219 2.449219 2 3 2 L 13 2"/>
+ <path fill="rgb(101, 161, 134)" d="M 5 13 L 6 13 L 11 13 L 12 13 L 12 12 L 12 10.8648649 L 12 9.86486486 L 11 9.86486486 L 8.57948709 9.86486483 L 8.57948718 4 L 8.57948718 3 L 7.57948718 3 L 6 3 L 5 3 L 5 4 L 5 12 L 5 13 Z M 5 13"/>
+ <path fill="white" d="M 6 4 L 7.57948718 4 L 7.57948718 10.8648649 L 11 10.8648649 L 11 12 L 6 12 L 6 4 Z M 6 4"/>
+</svg>
Added: trunk/Source/WebInspectorUI/UserInterface/Images/MediaInstrument.svg (0 => 238484)
--- trunk/Source/WebInspectorUI/UserInterface/Images/MediaInstrument.svg (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Images/MediaInstrument.svg 2018-11-25 22:11:24 UTC (rev 238484)
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright © 2018 Apple Inc. All rights reserved. -->
+<svg xmlns="http://www.w3.org/2000/svg" id="root" version="1.1" viewBox="0 0 16 16">
+ <circle cx="8" cy="8" r="7.5" id="Oval" stroke="rgb(101, 161, 134)" fill="rgb(148, 190, 164)"/>
+ <path d="M 9.05 7.38920455 L 12.375 5.5 L 12.375 10.5 L 9.05 8.61079545 L 9.05 9.5 C 9.05 10.0522847 8.60228475 10.5 8.05 10.5 L 4.25 10.5 C 3.69771525 10.5 3.25 10.0522847 3.25 9.5 L 3.25 6.5 C 3.25 5.94771525 3.69771525 5.5 4.25 5.5 L 8.05 5.5 C 8.60228475 5.5 9.05 5.94771525 9.05 6.5 L 9.05 7.38920455 Z" stroke="rgb(101, 161, 134)" fill="rgb(101, 161, 134)" stroke-width="2" stroke-linejoin="round"/>
+ <path d="M 9.05 7.38920455 L 12.375 5.5 L 12.375 10.5 L 9.05 8.61079545 L 9.05 9.5 C 9.05 10.0522847 8.60228475 10.5 8.05 10.5 L 4.25 10.5 C 3.69771525 10.5 3.25 10.0522847 3.25 9.5 L 3.25 6.5 C 3.25 5.94771525 3.69771525 5.5 4.25 5.5 L 8.05 5.5 C 8.60228475 5.5 9.05 5.94771525 9.05 6.5 L 9.05 7.38920455 Z" fill="white"/>
+</svg>
Modified: trunk/Source/WebInspectorUI/UserInterface/Main.html (238483 => 238484)
--- trunk/Source/WebInspectorUI/UserInterface/Main.html 2018-11-25 21:44:43 UTC (rev 238483)
+++ trunk/Source/WebInspectorUI/UserInterface/Main.html 2018-11-25 22:11:24 UTC (rev 238484)
@@ -124,6 +124,8 @@
<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=""
<link rel="stylesheet" href=""
@@ -396,6 +398,8 @@
<script src=""
<script src=""
<script src=""
+ <script src=""
+ <script src=""
<script src=""
<script src=""
<script src=""
@@ -684,6 +688,9 @@
<script src=""
<script src=""
<script src=""
+ <script src=""
+ <script src=""
+ <script src=""
<script src=""
<script src=""
<script src=""
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/Instrument.js (238483 => 238484)
--- trunk/Source/WebInspectorUI/UserInterface/Models/Instrument.js 2018-11-25 21:44:43 UTC (rev 238483)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/Instrument.js 2018-11-25 22:11:24 UTC (rev 238484)
@@ -42,6 +42,8 @@
return new WI.MemoryInstrument;
case WI.TimelineRecord.Type.HeapAllocations:
return new WI.HeapAllocationsInstrument;
+ case WI.TimelineRecord.Type.Media:
+ return new WI.MediaInstrument;
default:
console.error("Unknown TimelineRecord.Type: " + type);
return null;
Copied: trunk/Source/WebInspectorUI/UserInterface/Models/MediaInstrument.js (from rev 238483, trunk/Source/WebInspectorUI/UserInterface/Views/DOMNodeEventsContentView.js) (0 => 238484)
--- trunk/Source/WebInspectorUI/UserInterface/Models/MediaInstrument.js (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/MediaInstrument.js 2018-11-25 22:11:24 UTC (rev 238484)
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2018 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.MediaInstrument = class MediaInstrument extends WI.Instrument
+{
+ constructor()
+ {
+ super();
+
+ console.assert(WI.MediaInstrument.supported());
+ }
+
+ // Static
+
+ static supported()
+ {
+ // COMPATIBILITY (iOS 12): DOM.didFireEvent and DOM.videoLowPowerChanged did not exist.
+ return window.DOMAgent && DOMAgent.hasEvent("didFireEvent") && DOMAgent.hasEvent("videoLowPowerChanged");
+ }
+
+ // Protected
+
+ get timelineRecordType()
+ {
+ return WI.TimelineRecord.Type.Media;
+ }
+
+ startInstrumentation(initiatedByBackend)
+ {
+ // Nothing to do, media instrumentation is always happening.
+ }
+
+ stopInstrumentation(initiatedByBackend)
+ {
+ // Nothing to do, media instrumentation is always happening.
+ }
+};
Added: trunk/Source/WebInspectorUI/UserInterface/Models/MediaTimelineRecord.js (0 => 238484)
--- trunk/Source/WebInspectorUI/UserInterface/Models/MediaTimelineRecord.js (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/MediaTimelineRecord.js 2018-11-25 22:11:24 UTC (rev 238484)
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2018 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.MediaTimelineRecord = class MediaTimelineRecord extends WI.TimelineRecord
+{
+ constructor(eventType, timestamp, {domNode, domEvent, isLowPower} = {})
+ {
+ console.assert(Object.values(WI.MediaTimelineRecord.EventType).includes(eventType));
+
+ super(WI.TimelineRecord.Type.Media, timestamp, timestamp);
+
+ this._eventType = eventType;
+ this._domNode = domNode || null;
+ this._domEvent = domEvent || null;
+ this._isLowPower = isLowPower || false;
+ }
+
+ // Public
+
+ get eventType() { return this._eventType; }
+ get domNode() { return this._domNode; }
+ get domEvent() { return this._domEvent; }
+ get isLowPower() { return this._isLowPower; }
+
+ get displayName()
+ {
+ if (this._eventType === WI.MediaTimelineRecord.EventType.DOMEvent && this._domEvent) {
+ let eventName = this._domEvent.eventName;
+ if (eventName === "webkitfullscreenchange" && this._domEvent.data)
+ return this._domEvent.data.enabled ? WI.UIString("Entered Full-Screen Mode") : WI.UIString("Exited Full-Screen Mode");
+ return eventName;
+ }
+
+ if (this._eventType === WI.MediaTimelineRecord.EventType.LowPower)
+ return this._isLowPower ? WI.UIString("Entered Low-Power Mode") : WI.UIString("Exited Low-Power Mode");
+
+ if (this._domNode)
+ return this._domNode.displayName;
+
+ console.error("Unknown media record event type: ", this._eventType, this);
+ return WI.UIString("Media Event");
+ }
+
+ saveIdentityToCookie(cookie)
+ {
+ super.saveIdentityToCookie(cookie);
+
+ cookie["media-timeline-record-event-type"] = this._eventType;
+ if (this._domNode)
+ cookie["media-timeline-record-dom-node"] = this._domNode.path();
+ if (this._domEvent)
+ cookie["media-timeline-record-dom-event"] = this._domEvent.eventName;
+ if (this._isLowPower || (this._domEvent && this._domEvent.data && this._domEvent.data.enabled))
+ cookie["media-timeline-record-active"] = true;
+ }
+};
+
+WI.MediaTimelineRecord.EventType = {
+ DOMEvent: "dom-event",
+ LowPower: "low-power",
+};
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/ScriptTimelineRecord.js (238483 => 238484)
--- trunk/Source/WebInspectorUI/UserInterface/Models/ScriptTimelineRecord.js 2018-11-25 21:44:43 UTC (rev 238483)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/ScriptTimelineRecord.js 2018-11-25 22:11:24 UTC (rev 238484)
@@ -329,11 +329,11 @@
nameMap.set("webkitEditableContentChanged", "Editable Content Changed");
nameMap.set("webkitTransitionEnd", "Transition End");
nameMap.set("webkitaddsourcebuffer", "Add Source Buffer");
- nameMap.set("webkitbeginfullscreen", "Begin Full Screen");
+ nameMap.set("webkitbeginfullscreen", "Begin Full-Screen");
nameMap.set("webkitcurrentplaybacktargetiswirelesschanged", "Current Playback Target Is Wireless Changed");
- nameMap.set("webkitendfullscreen", "End Full Screen");
- nameMap.set("webkitfullscreenchange", "Full Screen Change");
- nameMap.set("webkitfullscreenerror", "Full Screen Error");
+ nameMap.set("webkitendfullscreen", "End Full-Screen");
+ nameMap.set("webkitfullscreenchange", "Full-Screen Change");
+ nameMap.set("webkitfullscreenerror", "Full-Screen Error");
nameMap.set("webkitkeyadded", "Key Added");
nameMap.set("webkitkeyerror", "Key Error");
nameMap.set("webkitkeymessage", "Key Message");
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/TimelineRecord.js (238483 => 238484)
--- trunk/Source/WebInspectorUI/UserInterface/Models/TimelineRecord.js 2018-11-25 21:44:43 UTC (rev 238483)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/TimelineRecord.js 2018-11-25 22:11:24 UTC (rev 238484)
@@ -160,6 +160,7 @@
RenderingFrame: "timeline-record-type-rendering-frame",
Memory: "timeline-record-type-memory",
HeapAllocations: "timeline-record-type-heap-allocations",
+ Media: "timeline-record-type-media",
};
WI.TimelineRecord.TypeIdentifier = "timeline-record";
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/TimelineRecording.js (238483 => 238484)
--- trunk/Source/WebInspectorUI/UserInterface/Models/TimelineRecording.js 2018-11-25 21:44:43 UTC (rev 238483)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/TimelineRecording.js 2018-11-25 22:11:24 UTC (rev 238484)
@@ -127,7 +127,6 @@
console.assert(!this._readonly, "Can't reset a read-only recording.");
this._sourceCodeTimelinesMap = new Map;
- this._eventMarkers = [];
this._startTime = NaN;
this._endTime = NaN;
this._discontinuities = [];
@@ -196,8 +195,6 @@
if (!this._capturing)
return;
- this._eventMarkers.push(marker);
-
this.dispatchEventToListeners(WI.TimelineRecording.Event.MarkerAdded, {marker});
}
@@ -215,7 +212,8 @@
if (record.type === WI.TimelineRecord.Type.Network
|| record.type === WI.TimelineRecord.Type.RenderingFrame
|| record.type === WI.TimelineRecord.Type.Memory
- || record.type === WI.TimelineRecord.Type.HeapAllocations)
+ || record.type === WI.TimelineRecord.Type.HeapAllocations
+ || record.type === WI.TimelineRecord.Type.Media)
return;
if (!WI.TimelineRecording.sourceCodeTimelinesSupported())
@@ -332,7 +330,7 @@
_keyForRecord(record)
{
var key = record.type;
- if (record instanceof WI.ScriptTimelineRecord || record instanceof WI.LayoutTimelineRecord)
+ if (record instanceof WI.ScriptTimelineRecord || record instanceof WI.LayoutTimelineRecord || record instanceof WI.MediaTimelineRecord)
key += ":" + record.eventType;
if (record instanceof WI.ScriptTimelineRecord && record.eventType === WI.ScriptTimelineRecord.EventType.EventDispatched)
key += ":" + record.details;
Modified: trunk/Source/WebInspectorUI/UserInterface/Test.html (238483 => 238484)
--- trunk/Source/WebInspectorUI/UserInterface/Test.html 2018-11-25 21:44:43 UTC (rev 238483)
+++ trunk/Source/WebInspectorUI/UserInterface/Test.html 2018-11-25 22:11:24 UTC (rev 238484)
@@ -158,6 +158,8 @@
<script src=""
<script src=""
<script src=""
+ <script src=""
+ <script src=""
<script src=""
<script src=""
<script src=""
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ContentView.js (238483 => 238484)
--- trunk/Source/WebInspectorUI/UserInterface/Views/ContentView.js 2018-11-25 21:44:43 UTC (rev 238483)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ContentView.js 2018-11-25 22:11:24 UTC (rev 238484)
@@ -88,6 +88,9 @@
if (timelineType === WI.TimelineRecord.Type.HeapAllocations)
return new WI.HeapAllocationsTimelineView(representedObject, extraArguments);
+
+ if (timelineType === WI.TimelineRecord.Type.Media)
+ return new WI.MediaTimelineView(representedObject, extraArguments);
}
if (representedObject instanceof WI.Breakpoint || representedObject instanceof WI.IssueMessage) {
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/DOMEventsBreakdownView.js (238483 => 238484)
--- trunk/Source/WebInspectorUI/UserInterface/Views/DOMEventsBreakdownView.js 2018-11-25 21:44:43 UTC (rev 238483)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/DOMEventsBreakdownView.js 2018-11-25 22:11:24 UTC (rev 238484)
@@ -25,7 +25,7 @@
WI.DOMEventsBreakdownView = class DOMEventsBreakdownView extends WI.View
{
- constructor(domNodeOrEvents, {includeGraph, startTimestamp} = {})
+ constructor(domNodeOrEvents, {includeGraph} = {})
{
console.assert(domNodeOrEvents instanceof WI.DOMNode || Array.isArray(domNodeOrEvents));
@@ -45,7 +45,6 @@
}
this._includeGraph = includeGraph || false;
- this._startTimestamp = startTimestamp || 0;
this._tableBodyElement = null;
@@ -134,9 +133,9 @@
fullscreenArea.style.setProperty("width", percentOfTotalTime(fullscreenRange.endTimestamp - fullscreenRange.startTimestamp) + "%");
if (fullscreenRange.originator)
- fullscreenArea.title = WI.UIString("Fullscreen from “%s“").format(fullscreenRange.originator.displayName);
+ fullscreenArea.title = WI.UIString("Full-Screen from “%s“").format(fullscreenRange.originator.displayName);
else
- fullscreenArea.title = WI.UIString("Fullscreen");
+ fullscreenArea.title = WI.UIString("Full-Screen");
}
let lowPowerRange = lowPowerRanges.find((range) => domEvent.timestamp >= range.startTimestamp && domEvent.timestamp <= range.endTimestamp);
@@ -143,7 +142,7 @@
if (lowPowerRange) {
let lowPowerArea = graphCell.appendChild(document.createElement("div"));
lowPowerArea.classList.add("area", "low-power");
- lowPowerArea.title = WI.UIString("Low Power Mode");
+ lowPowerArea.title = WI.UIString("Low-Power Mode");
lowPowerArea.style.setProperty(styleAttribute, percentOfTotalTime(lowPowerRange.startTimestamp - startTimestamp) + "%");
lowPowerArea.style.setProperty("width", percentOfTotalTime(lowPowerRange.endTimestamp - lowPowerRange.startTimestamp) + "%");
}
@@ -157,7 +156,7 @@
timeCell.classList.add("time");
const higherResolution = true;
- timeCell.textContent = Number.secondsToString(domEvent.timestamp - this._startTimestamp, higherResolution);
+ timeCell.textContent = Number.secondsToString(domEvent.timestamp, higherResolution);
let originatorCell = rowElement.appendChild(document.createElement("td"));
originatorCell.classList.add("originator");
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/DOMNodeEventsContentView.js (238483 => 238484)
--- trunk/Source/WebInspectorUI/UserInterface/Views/DOMNodeEventsContentView.js 2018-11-25 21:44:43 UTC (rev 238483)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/DOMNodeEventsContentView.js 2018-11-25 22:11:24 UTC (rev 238484)
@@ -25,7 +25,7 @@
WI.DOMNodeEventsContentView = class DOMNodeEventsContentView extends WI.ContentView
{
- constructor(domNode, {startTimestamp} = {})
+ constructor(domNode)
{
console.assert(domNode instanceof WI.DOMNode);
@@ -33,7 +33,6 @@
super(representedObject);
this._domNode = domNode;
- this._startTimestamp = startTimestamp || 0;
this.element.classList.add("dom-node-details", "dom-events");
@@ -48,7 +47,6 @@
this._breakdownView = new WI.DOMEventsBreakdownView(this._domNode, {
includeGraph: true,
- startTimestamp: this._startTimestamp,
});
this.addSubview(this._breakdownView);
}
Added: trunk/Source/WebInspectorUI/UserInterface/Views/MediaTimelineDataGridNode.js (0 => 238484)
--- trunk/Source/WebInspectorUI/UserInterface/Views/MediaTimelineDataGridNode.js (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/MediaTimelineDataGridNode.js 2018-11-25 22:11:24 UTC (rev 238484)
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2018 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.MediaTimelineDataGridNode = class MediaTimelineDataGridNode extends WI.TimelineDataGridNode
+{
+ constructor(record, graphDataSource)
+ {
+ console.assert(record instanceof WI.MediaTimelineRecord);
+
+ const includesGraph = false;
+ super(includesGraph, graphDataSource);
+
+ this._records = [record];
+ }
+
+ // Public
+
+ get records() { return this._records; }
+
+ get data()
+ {
+ if (this._cachedData)
+ return this._cachedData;
+
+ this._cachedData = super.data;
+ this._cachedData.name = this.record.displayName;
+ if (this.record.domNode)
+ this._cachedData.element = this.record.domNode;
+ this._cachedData.time = this.record.startTime - (this.graphDataSource ? this.graphDataSource.zeroTime : 0);
+ if (this.record.eventType === WI.MediaTimelineRecord.EventType.DOMEvent && this.record.domEvent.originator)
+ this._cachedData.originator = this.record.domEvent.originator;
+ return this._cachedData;
+ }
+
+ createCellContent(columnIdentifier, cell)
+ {
+ let value = this.data[columnIdentifier];
+
+ switch (columnIdentifier) {
+ case "name":
+ cell.classList.add(...this.iconClassNames());
+ return value;
+
+ case "element":
+ return value ? WI.linkifyNodeReference(value) : emDash;
+
+ case "time": {
+ const higherResolution = true;
+ return Number.secondsToString(value, higherResolution);
+ }
+
+ case "originator":
+ return value ? WI.linkifyNodeReference(value) : zeroWidthSpace;
+ }
+
+ return super.createCellContent(columnIdentifier, cell);
+ }
+
+ iconClassNames()
+ {
+ let iconClassNames = super.iconClassNames();
+ if (this.record.eventType === WI.MediaTimelineRecord.EventType.DOMEvent && this.record.domEvent.eventName === "webkitfullscreenchange")
+ iconClassNames.push("fullscreen");
+ return iconClassNames;
+ }
+
+ // Protected
+
+ filterableDataForColumn(columnIdentifier)
+ {
+ if (columnIdentifier === "element") {
+ if (this.record.domNode)
+ return this.record.domNode.displayName;
+ }
+
+ if (columnIdentifier === "originator") {
+ if (this.record.eventType === WI.MediaTimelineRecord.EventType.DOMEvent && this.record.domEvent.originator)
+ return this.record.domEvent.originator.displayName;
+ }
+
+ return super.filterableDataForColumn(columnIdentifier);
+ }
+};
Copied: trunk/Source/WebInspectorUI/UserInterface/Views/MediaTimelineOverviewGraph.css (from rev 238483, trunk/Source/WebInspectorUI/UserInterface/Views/DOMNodeEventsContentView.js) (0 => 238484)
--- trunk/Source/WebInspectorUI/UserInterface/Views/MediaTimelineOverviewGraph.css (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/MediaTimelineOverviewGraph.css 2018-11-25 22:11:24 UTC (rev 238484)
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+.timeline-overview-graph.media > .timeline-record-bar {
+ margin-top: 8px;
+ height: 20px;
+}
+
+.timeline-overview-graph.media > .timeline-record-bar > .segment {
+ border-radius: 2px;
+}
Added: trunk/Source/WebInspectorUI/UserInterface/Views/MediaTimelineOverviewGraph.js (0 => 238484)
--- trunk/Source/WebInspectorUI/UserInterface/Views/MediaTimelineOverviewGraph.js (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/MediaTimelineOverviewGraph.js 2018-11-25 22:11:24 UTC (rev 238484)
@@ -0,0 +1,120 @@
+
+/*
+ * Copyright (C) 2018 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.MediaTimelineOverviewGraph = class MediaTimelineOverviewGraph extends WI.TimelineOverviewGraph
+{
+ constructor(timeline, timelineOverview)
+ {
+ console.assert(timeline instanceof WI.Timeline);
+ console.assert(timeline.type === WI.TimelineRecord.Type.Media);
+
+ super(timelineOverview);
+
+ this._timeline = timeline;
+ this._recordBars = [];
+
+ this.element.classList.add("media");
+
+ this.reset();
+ }
+
+ // Public
+
+ reset()
+ {
+ this.element.removeChildren();
+
+ super.reset();
+ }
+
+ shown()
+ {
+ super.shown();
+
+ this._timeline.addEventListener(WI.Timeline.Event.RecordAdded, this._handleRecordAdded, this);
+ }
+
+ hidden()
+ {
+ this._timeline.removeEventListener(null, null, this);
+
+ super.hidden();
+ }
+
+ // Protected
+
+ layout()
+ {
+ if (!this.visible)
+ return;
+
+ let recordBarIndex = 0;
+
+ let createBar = (records, renderMode) => {
+ let timelineRecordBar = this._recordBars[recordBarIndex];
+ if (timelineRecordBar) {
+ timelineRecordBar.renderMode = renderMode;
+ timelineRecordBar.records = records;
+ } else
+ timelineRecordBar = this._recordBars[recordBarIndex] = new WI.TimelineRecordBar(this, records, renderMode);
+ timelineRecordBar.refresh(this);
+ if (!timelineRecordBar.element.parentNode)
+ this.element.appendChild(timelineRecordBar.element);
+ ++recordBarIndex;
+ };
+
+ WI.TimelineRecordBar.createCombinedBars(this._timeline.records, this.timelineOverview.secondsPerPixel, this, createBar);
+
+ // Remove the remaining unused TimelineRecordBars.
+ for (let i = recordBarIndex; i < this._recordBars.length; ++i) {
+ this._recordBars[i].records = null;
+ this._recordBars[i].element.remove();
+ }
+ }
+
+ updateSelectedRecord()
+ {
+ super.updateSelectedRecord();
+
+ for (let recordBar of this._recordBars) {
+ if (recordBar.records.includes(this.selectedRecord)) {
+ this.selectedRecordBar = recordBar;
+ return;
+ }
+ }
+
+ this.selectedRecordBar = null;
+ }
+
+ // Private
+
+ _handleRecordAdded(event)
+ {
+ this.needsLayout();
+ }
+};
+
+WI.MediaTimelineOverviewGraph.MaximumRowCount = 6;
Copied: trunk/Source/WebInspectorUI/UserInterface/Views/MediaTimelineView.css (from rev 238483, trunk/Source/WebInspectorUI/UserInterface/Views/DOMNodeEventsContentView.js) (0 => 238484)
--- trunk/Source/WebInspectorUI/UserInterface/Views/MediaTimelineView.css (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/MediaTimelineView.css 2018-11-25 22:11:24 UTC (rev 238484)
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+.timeline-view.media > .data-grid {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+}
Added: trunk/Source/WebInspectorUI/UserInterface/Views/MediaTimelineView.js (0 => 238484)
--- trunk/Source/WebInspectorUI/UserInterface/Views/MediaTimelineView.js (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/MediaTimelineView.js 2018-11-25 22:11:24 UTC (rev 238484)
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2018 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.MediaTimelineView = class MediaTimelineView extends WI.TimelineView
+{
+ constructor(timeline, extraArguments)
+ {
+ console.assert(timeline instanceof WI.Timeline);
+ console.assert(timeline.type === WI.TimelineRecord.Type.Media);
+
+ super(timeline, extraArguments);
+
+ this._timelineRuler = new WI.TimelineRuler;
+
+ const columns = {
+ name: {
+ title: WI.UIString("Name"),
+ width: "10%",
+ icon: true,
+ sortable: true,
+ locked: true,
+ },
+ element: {
+ title: WI.UIString("Element"),
+ width: "10%",
+ sortable: true,
+ },
+ time: {
+ title: WI.UIString("Time"),
+ width: "10%",
+ sortable: true,
+ locked: true,
+ },
+ originator: {
+ title: WI.UIString("Originator"),
+ width: "10%",
+ sortable: true,
+ hidden: true,
+ },
+ graph: {
+ headerView: this._timelineRuler,
+ locked: true,
+ },
+ };
+
+ this._dataGrid = new WI.TimelineDataGrid(columns);
+ this._dataGrid.sortDelegate = this;
+ this._dataGrid.sortColumnIdentifier = "time";
+ this._dataGrid.sortOrder = WI.DataGrid.SortOrder.Ascending;
+ this._dataGrid.setColumnVisible("originator", false);
+ this._dataGrid.createSettings("media-timeline-view");
+ this.setupDataGrid(this._dataGrid);
+ this.addSubview(this._dataGrid);
+
+ this.element.classList.add("media");
+
+ timeline.addEventListener(WI.Timeline.Event.RecordAdded, this._handleRecordAdded, this);
+
+ this._pendingRecords = [];
+ }
+
+ // Public
+
+ get secondsPerPixel() { return this._timelineRuler.secondsPerPixel; }
+
+ get selectionPathComponents()
+ {
+ if (!this._dataGrid.selectedNode || this._dataGrid.selectedNode.hidden)
+ return null;
+
+ let pathComponent = new WI.TimelineDataGridNodePathComponent(this._dataGrid.selectedNode);
+ pathComponent.addEventListener(WI.HierarchicalPathComponent.Event.SiblingWasSelected, this._handleSelectionPathComponentSiblingSelected, this);
+ return [pathComponent];
+ }
+
+ closed()
+ {
+ this.representedObject.removeEventListener(null, null, this);
+
+ super.closed();
+ }
+
+ reset()
+ {
+ super.reset();
+
+ this._pendingRecords = [];
+ }
+
+ // TimelineDataGrid delegate
+
+ dataGridSortComparator(sortColumnIdentifier, sortDirection, node1, node2)
+ {
+ function compareDOMNodes(a, b) {
+ if (a && !b)
+ return -1;
+ if (b && !a)
+ return 1;
+ if (!a && !b)
+ return 0;
+ return a.id - b.id;
+ }
+
+ if (sortColumnIdentifier === "name") {
+ let displayName1 = node1.displayName();
+ let displayName2 = node2.displayName();
+ return displayName1.extendedLocaleCompare(displayName2) * sortDirection;
+ }
+
+ if (sortColumnIdentifier === "element")
+ return compareDOMNodes(node1.record.domNode, node2.record.domNode) * sortDirection;
+
+ if (sortColumnIdentifier === "time")
+ return (node1.record.startTime - node2.record.startTime) * sortDirection;
+
+ if (sortColumnIdentifier === "originator") {
+ function getOriginator(record) {
+ if (record.eventType !== WI.MediaTimelineRecord.EventType.DOMEvent || !record.domEvent)
+ return null;
+ return record.domEvent.originator;
+ }
+ return compareDOMNodes(getOriginator(node1.record), getOriginator(node2.record)) * sortDirection;
+ }
+
+ return null;
+ }
+
+ // Protected
+
+ layout()
+ {
+ super.layout();
+
+ this.endTime = Math.min(this.endTime, this.currentTime);
+
+ let oldZeroTime = this._timelineRuler.zeroTime;
+ let oldStartTime = this._timelineRuler.startTime;
+ let oldEndTime = this._timelineRuler.endTime;
+
+ this._timelineRuler.zeroTime = this.zeroTime;
+ this._timelineRuler.startTime = this.startTime;
+ this._timelineRuler.endTime = this.endTime;
+
+ // We only need to refresh the graphs when the any of the times change.
+ if (this.zeroTime !== oldZeroTime || this.startTime !== oldStartTime || this.endTime !== oldEndTime) {
+ for (let dataGridNode of this._dataGrid.children)
+ dataGridNode.refreshGraph();
+ }
+
+ this._processPendingRecords();
+ }
+
+ // Private
+
+ _processPendingRecords()
+ {
+ if (!this._pendingRecords.length)
+ return;
+
+ for (let timelineRecord of this._pendingRecords) {
+ if (timelineRecord.domEvent && timelineRecord.domEvent.originator)
+ this._dataGrid.setColumnVisible("originator", true);
+
+ this._dataGrid.addRowInSortOrder(new WI.MediaTimelineDataGridNode(timelineRecord, this));
+ }
+
+ this._pendingRecords = [];
+ }
+
+ _handleRecordAdded(event)
+ {
+ let record = event.data.record;
+ console.assert(record instanceof WI.MediaTimelineRecord);
+
+ this._pendingRecords.push(record);
+
+ this.needsLayout();
+ }
+
+ _handleSelectionPathComponentSiblingSelected(event)
+ {
+ let pathComponent = event.data.pathComponent;
+ console.assert(pathComponent instanceof WI.TimelineDataGridNodePathComponent);
+
+ let dataGridNode = pathComponent.timelineDataGridNode;
+ console.assert(dataGridNode.dataGrid === this._dataGrid);
+
+ dataGridNode.revealAndSelect();
+ }
+};
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/NetworkDOMNodeDetailView.js (238483 => 238484)
--- trunk/Source/WebInspectorUI/UserInterface/Views/NetworkDOMNodeDetailView.js 2018-11-25 21:44:43 UTC (rev 238483)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/NetworkDOMNodeDetailView.js 2018-11-25 22:11:24 UTC (rev 238484)
@@ -25,14 +25,12 @@
WI.NetworkDOMNodeDetailView = class NetworkDOMNodeDetailView extends WI.NetworkDetailView
{
- constructor(domNode, delegate, {startTimestamp} = {})
+ constructor(domNode, delegate)
{
console.assert(domNode instanceof WI.DOMNode);
super(domNode, delegate);
- this._startTimestamp = startTimestamp || 0;
-
this.element.classList.add("dom-node");
this._domEventsContentView = null;
@@ -56,9 +54,7 @@
switch (identifier) {
case "dom-events":
if (!this._domEventsContentView) {
- this._domEventsContentView = new WI.DOMNodeEventsContentView(this.representedObject, {
- startTimestamp: this._startTimestamp,
- });
+ this._domEventsContentView = new WI.DOMNodeEventsContentView(this.representedObject);
}
this._contentBrowser.showContentView(this._domEventsContentView, this._contentViewCookie);
break;
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/NetworkTableContentView.js (238483 => 238484)
--- trunk/Source/WebInspectorUI/UserInterface/Views/NetworkTableContentView.js 2018-11-25 21:44:43 UTC (rev 238483)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/NetworkTableContentView.js 2018-11-25 22:11:24 UTC (rev 238484)
@@ -84,8 +84,11 @@
this._typeFilterScopeBar = new WI.ScopeBar("network-type-filter-scope-bar", typeFilterScopeBarItems, typeFilterScopeBarItems[0]);
this._typeFilterScopeBar.addEventListener(WI.ScopeBar.Event.SelectionChanged, this._typeFilterScopeBarSelectionChanged, this);
- this._groupByDOMNodeNavigationItem = new WI.CheckboxNavigationItem("group-by-node", WI.UIString("Group Media Requests"), WI.settings.groupByDOMNode.value);
- this._groupByDOMNodeNavigationItem.addEventListener(WI.CheckboxNavigationItem.Event.CheckedDidChange, this._handleGroupByDOMNodeCheckedDidChange, this);
+ if (WI.MediaInstrument.supported()) {
+ this._groupByDOMNodeNavigationItem = new WI.CheckboxNavigationItem("group-by-node", WI.UIString("Group Media Requests"), WI.settings.groupByDOMNode.value);
+ this._groupByDOMNodeNavigationItem.addEventListener(WI.CheckboxNavigationItem.Event.CheckedDidChange, this._handleGroupByDOMNodeCheckedDidChange, this);
+ } else
+ WI.settings.groupByDOMNode.value = false;
this._urlFilterSearchText = null;
this._urlFilterSearchRegex = null;
@@ -213,7 +216,10 @@
get filterNavigationItems()
{
- return [this._urlFilterNavigationItem, this._typeFilterScopeBar, this._groupByDOMNodeNavigationItem];
+ let navigationItems = [this._urlFilterNavigationItem, this._typeFilterScopeBar];
+ if (WI.MediaInstrument.supported())
+ navigationItems.push(this._groupByDOMNodeNavigationItem);
+ return navigationItems;
}
get supportsSave()
@@ -695,9 +701,9 @@
let originator = fullscreenDOMEvents[i].originator || fullscreenDOMEvents[i + 1].originator;
if (originator)
- fullscreenElement.title = WI.UIString("Fullscreen from “%s“").format(originator.displayName);
+ fullscreenElement.title = WI.UIString("Full-Screen from “%s“").format(originator.displayName);
else
- fullscreenElement.title = WI.UIString("Fullscreen");
+ fullscreenElement.title = WI.UIString("Full-Screen");
}
}
@@ -707,7 +713,7 @@
let lowPowerElement = container.appendChild(document.createElement("div"));
lowPowerElement.classList.add("area", "low-power");
- lowPowerElement.title = WI.UIString("Low Power Mode");
+ lowPowerElement.title = WI.UIString("Low-Power Mode");
positionByStartOffset(lowPowerElement, startTimestamp);
setWidthForDuration(lowPowerElement, startTimestamp, endTimestamp);
}
@@ -1313,9 +1319,7 @@
if (object instanceof WI.Resource)
this._detailView = new WI.NetworkResourceDetailView(object, this);
else if (object instanceof WI.DOMNode) {
- this._detailView = new WI.NetworkDOMNodeDetailView(object, this, {
- startTimestamp: this._waterfallStartTime,
- });
+ this._detailView = new WI.NetworkDOMNodeDetailView(object, this);
}
this._detailViewMap.set(object, this._detailView);
@@ -1918,9 +1922,7 @@
{
let contentElement = this._waterfallPopoverContent();
- let breakdownView = new WI.DOMEventsBreakdownView(domEvents, {
- startTimestamp: this._waterfallStartTime,
- });
+ let breakdownView = new WI.DOMEventsBreakdownView(domEvents);
contentElement.appendChild(breakdownView.element);
breakdownView.updateLayout();
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/TimelineIcons.css (238483 => 238484)
--- trunk/Source/WebInspectorUI/UserInterface/Views/TimelineIcons.css 2018-11-25 21:44:43 UTC (rev 238483)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/TimelineIcons.css 2018-11-25 22:11:24 UTC (rev 238484)
@@ -47,6 +47,10 @@
content: url(../Images/RenderingFramesInstrument.svg);
}
+.media-icon .icon {
+ content: url(../Images/MediaInstrument.svg);
+}
+
.stopwatch-icon .icon {
content: url(../Images/Stopwatch.svg);
}
@@ -117,6 +121,18 @@
content: url(../Images/HeapSnapshot.svg);
}
+.dom-event-record .icon {
+ content: url(../Images/DOMEvent.svg);
+}
+
+.dom-event-record.fullscreen .icon {
+ content: url(../Images/DOMEventFullscreen.svg);
+}
+
+.low-power-record .icon {
+ content: url(../Images/LowPower.svg);
+}
+
@media (prefers-dark-interface) {
.time-icon .icon {
filter: invert();
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/TimelineOverview.js (238483 => 238484)
--- trunk/Source/WebInspectorUI/UserInterface/Views/TimelineOverview.js 2018-11-25 21:44:43 UTC (rev 238483)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/TimelineOverview.js 2018-11-25 22:11:24 UTC (rev 238484)
@@ -685,6 +685,9 @@
return;
for (let overviewGraph of this._overviewGraphsByTypeMap.values()) {
+ if (!overviewGraph.visible)
+ continue;
+
let graphRect = overviewGraph.element.getBoundingClientRect();
if (!(event.pageX >= graphRect.left && event.pageX <= graphRect.right && event.pageY >= graphRect.top && event.pageY <= graphRect.bottom))
continue;
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/TimelineOverviewGraph.js (238483 => 238484)
--- trunk/Source/WebInspectorUI/UserInterface/Views/TimelineOverviewGraph.js 2018-11-25 21:44:43 UTC (rev 238483)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/TimelineOverviewGraph.js 2018-11-25 22:11:24 UTC (rev 238484)
@@ -69,6 +69,9 @@
if (timelineType === WI.TimelineRecord.Type.HeapAllocations)
return new WI.HeapAllocationsTimelineOverviewGraph(timeline, timelineOverview);
+ if (timelineType === WI.TimelineRecord.Type.Media)
+ return new WI.MediaTimelineOverviewGraph(timeline, timelineOverview);
+
throw new Error("Can't make a graph for an unknown timeline.");
}
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/TimelineRecordBar.css (238483 => 238484)
--- trunk/Source/WebInspectorUI/UserInterface/Views/TimelineRecordBar.css 2018-11-25 21:44:43 UTC (rev 238483)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/TimelineRecordBar.css 2018-11-25 22:11:24 UTC (rev 238484)
@@ -126,3 +126,8 @@
background-color: hsl(23, 69%, 73%);
border-color: hsl(11, 54%, 62%);
}
+
+.timeline-record-bar.timeline-record-type-media > .segment {
+ background-color: hsl(143, 24%, 66%);
+ border-color: hsl(153, 24%, 51%);
+}
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/TimelineRuler.js (238483 => 238484)
--- trunk/Source/WebInspectorUI/UserInterface/Views/TimelineRuler.js 2018-11-25 21:44:43 UTC (rev 238483)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/TimelineRuler.js 2018-11-25 22:11:24 UTC (rev 238484)
@@ -368,8 +368,10 @@
clearMarkers()
{
- for (let markerElement of this._markerElementMap.values())
+ for (let [marker, markerElement] of this._markerElementMap) {
+ marker.removeEventListener(null, null, this);
markerElement.remove();
+ }
this._markerElementMap.clear();
}
@@ -728,12 +730,16 @@
if (this._mouseMoved)
return;
- this.element.style.pointerEvents = "none";
- let newTarget = document.elementFromPoint(event.pageX, event.pageY);
- this.element.style.pointerEvents = null;
+ for (let newTarget of document.elementsFromPoint(event.pageX, event.pageY)) {
+ if (!newTarget || typeof newTarget.click !== "function")
+ continue;
+ if (this.element.contains(newTarget))
+ continue;
- if (newTarget && newTarget.click)
- newTarget.click();
+ // Clone the event to dispatch it on the new element.
+ newTarget.dispatchEvent(new event.constructor(event.type, event));
+ return;
+ }
}
_handleDoubleClick(event)
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/TimelineTabContentView.js (238483 => 238484)
--- trunk/Source/WebInspectorUI/UserInterface/Views/TimelineTabContentView.js 2018-11-25 21:44:43 UTC (rev 238483)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/TimelineTabContentView.js 2018-11-25 22:11:24 UTC (rev 238484)
@@ -120,6 +120,8 @@
return WI.UIString("Memory");
case WI.TimelineRecord.Type.HeapAllocations:
return WI.UIString("_javascript_ Allocations");
+ case WI.TimelineRecord.Type.Media:
+ return WI.UIString("Media");
default:
console.error("Unknown Timeline type:", timelineType);
}
@@ -142,6 +144,8 @@
return "script-icon";
case WI.TimelineRecord.Type.RenderingFrame:
return "rendering-frame-icon";
+ case WI.TimelineRecord.Type.Media:
+ return "media-icon";
default:
console.error("Unknown Timeline type:", timelineType);
}
@@ -164,6 +168,8 @@
return "script";
case WI.TimelineRecord.Type.RenderingFrame:
return "rendering-frame";
+ case WI.TimelineRecord.Type.Media:
+ return "media";
default:
console.error("Unknown Timeline type:", timelineType);
}
@@ -229,6 +235,18 @@
case WI.TimelineRecord.Type.HeapAllocations:
return "heap-snapshot-record";
+ case WI.TimelineRecord.Type.Media:
+ switch (timelineRecord.eventType) {
+ case WI.MediaTimelineRecord.EventType.DOMEvent:
+ return "dom-event-record";
+ case WI.MediaTimelineRecord.EventType.LowPower:
+ return "low-power-record";
+ default:
+ console.error("Unknown MediaTimelineRecord eventType: " + timelineRecord.eventType, timelineRecord);
+ }
+
+ break;
+
case WI.TimelineRecord.Type.Memory:
// Not used. Fall through to error just in case.
@@ -254,6 +272,8 @@
if (timelineRecord.heapSnapshot.title)
return WI.UIString("Snapshot %d \u2014 %s").format(timelineRecord.heapSnapshot.identifier, timelineRecord.heapSnapshot.title);
return WI.UIString("Snapshot %d").format(timelineRecord.heapSnapshot.identifier);
+ case WI.TimelineRecord.Type.Media:
+ return timelineRecord.displayName;
case WI.TimelineRecord.Type.Memory:
// Not used. Fall through to error just in case.
default: