Changeset 238484 in webkit


Ignore:
Timestamp:
Nov 25, 2018 2:11:24 PM (5 years ago)
Author:
Devin Rousso
Message:

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.
Location:
trunk/Source/WebInspectorUI
Files:
8 added
20 edited
3 copied

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebInspectorUI/ChangeLog

    r238483 r238484  
     12018-11-25  Devin Rousso  <drousso@apple.com>
     2
     3        Web Inspector: Timelines: add Media timeline
     4        https://bugs.webkit.org/show_bug.cgi?id=191625
     5
     6        Reviewed by Matt Baker.
     7
     8        Add a new timeline to Timelines for media related events (e.g. event/fullscreen/low-power).
     9        Mimics what is visible by using the same instrumentation points as the Network tab when
     10        "Group Media Requests" is enabled.
     11
     12        * UserInterface/Models/MediaInstrument.js: Added.
     13        (WI.MediaInstrument):
     14        (WI.MediaInstrument.supported):
     15        (WI.MediaInstrument.prototype.get timelineRecordType):
     16        (WI.MediaInstrument.prototype.startInstrumentation):
     17        (WI.MediaInstrument.prototype.stopInstrumentation):
     18
     19        * UserInterface/Models/MediaTimelineRecord.js: Added.
     20        (WI.MediaTimelineRecord):
     21        (WI.MediaTimelineRecord.prototype.get eventType):
     22        (WI.MediaTimelineRecord.prototype.get domNode):
     23        (WI.MediaTimelineRecord.prototype.get domEvent):
     24        (WI.MediaTimelineRecord.prototype.get isLowPower):
     25        (WI.MediaTimelineRecord.prototype.get displayName):
     26        (WI.MediaTimelineRecord.prototype.saveIdentityToCookie):
     27
     28        * UserInterface/Views/MediaTimelineDataGridNode.js: Added.
     29        (WI.MediaTimelineDataGridNode):
     30        (WI.MediaTimelineDataGridNode.prototype.get records):
     31        (WI.MediaTimelineDataGridNode.prototype.get data):
     32        (WI.MediaTimelineDataGridNode.prototype.createCellContent):
     33        (WI.MediaTimelineDataGridNode.prototype.iconClassNames):
     34        (WI.MediaTimelineDataGridNode.prototype.filterableDataForColumn):
     35
     36        * UserInterface/Views/MediaTimelineOverviewGraph.js: Added.
     37        (WI.MediaTimelineOverviewGraph):
     38        (WI.MediaTimelineOverviewGraph.prototype.reset):
     39        (WI.MediaTimelineOverviewGraph.prototype.shown):
     40        (WI.MediaTimelineOverviewGraph.prototype.hidden):
     41        (WI.MediaTimelineOverviewGraph.prototype.layout):
     42        (WI.MediaTimelineOverviewGraph.prototype.updateSelectedRecord):
     43        (WI.MediaTimelineOverviewGraph.prototype._handleRecordAdded):
     44        * UserInterface/Views/MediaTimelineOverviewGraph.css: Added.
     45        (.timeline-overview-graph.media > .timeline-record-bar):
     46        (.timeline-overview-graph.media > .timeline-record-bar > .segment):
     47
     48        * UserInterface/Views/MediaTimelineView.js: Added.
     49        (WI.MediaTimelineView):
     50        (WI.MediaTimelineView.prototype.get secondsPerPixel):
     51        (WI.MediaTimelineView.prototype.get selectionPathComponents):
     52        (WI.MediaTimelineView.prototype.closed):
     53        (WI.MediaTimelineView.prototype.reset):
     54        (WI.MediaTimelineView.prototype.dataGridSortComparator.compareDOMNodes):
     55        (WI.MediaTimelineView.prototype.dataGridSortComparator.):
     56        (WI.MediaTimelineView.prototype.dataGridSortComparator):
     57        (WI.MediaTimelineView.prototype.layout):
     58        (WI.MediaTimelineView.prototype._processPendingRecords):
     59        (WI.MediaTimelineView.prototype._handleRecordAdded):
     60        (WI.MediaTimelineView.prototype._handleSelectionPathComponentSiblingSelected):
     61        * UserInterface/Views/MediaTimelineView.css: Added.
     62        (.timeline-view.media > .data-grid):
     63
     64        * UserInterface/Views/DOMEventsBreakdownView.js:
     65        (WI.DOMEventsBreakdownView.prototype.layout):
     66        * UserInterface/Views/DOMNodeEventsContentView.js:
     67        (WI.DOMNodeEventsContentView.prototype.initialLayout):
     68        * UserInterface/Views/NetworkDOMNodeDetailView.js:
     69        (WI.NetworkDOMNodeDetailView):
     70        (WI.NetworkDOMNodeDetailView.prototype.showContentViewForIdentifier):
     71        * UserInterface/Views/NetworkTableContentView.js:
     72        (WI.NetworkTableContentView):
     73        (WI.NetworkTableContentView.prototype.get filterNavigationItems):
     74        (WI.NetworkTableContentView.prototype._populateWaterfallGraph):
     75        (WI.NetworkTableContentView.prototype._showDetailView):
     76        (WI.NetworkTableContentView.prototype._waterfallPopoverContentForNodeEntry):
     77        Remove passing of `startTimestamp` to `WI.DOMEventsBreakdownView`, as we should be showing
     78        absolute timestamps for each event, not relative to the start of the recording.
     79
     80        * UserInterface/Views/TimelineIcons.css:
     81        (.media-icon .icon): Added.
     82        (.dom-event-record .icon): Added.
     83        (.dom-event-record.fullscreen .icon): Added.
     84        (.low-power-record .icon): Added.
     85
     86        * UserInterface/Controllers/TimelineManager.js:
     87        (WI.TimelineManager.availableTimelineTypes):
     88        (WI.TimelineManager.prototype.capturingStarted):
     89        (WI.TimelineManager.prototype.capturingStopped):
     90        (WI.TimelineManager.prototype._updateAutoCaptureInstruments):
     91        (WI.TimelineManager.prototype._handleDOMNodeDidFireEvent): Added.
     92        (WI.TimelineManager.prototype._handleDOMNodeLowPowerChanged): Added.
     93
     94        * UserInterface/Views/TimelineRuler.js:
     95        (WI.TimelineRuler.prototype.clearMarkers):
     96        (WI.TimelineRuler.prototype._handleClick):
     97        * UserInterface/Views/TimelineOverview.js:
     98        (WI.TimelineOverview.prototype._timelineRulerMouseClicked):
     99        * UserInterface/Models/TimelineRecording.js:
     100        (WI.TimelineRecording.prototype.reset):
     101        (WI.TimelineRecording.prototype.addEventMarker):
     102        (WI.TimelineRecording.prototype.addRecord):
     103        (WI.TimelineRecording.prototype._keyForRecord):
     104        Drive-by: rework the logic for "click" event pass-through to the graph underneath.
     105
     106        * UserInterface/Models/Instrument.js:
     107        (WI.Instrument.createForTimelineType):
     108
     109        * UserInterface/Models/TimelineRecord.js:
     110
     111        * UserInterface/Views/TimelineTabContentView.js:
     112        (WI.TimelineTabContentView.displayNameForTimelineType):
     113        (WI.TimelineTabContentView.iconClassNameForTimelineType):
     114        (WI.TimelineTabContentView.genericClassNameForTimelineType):
     115        (WI.TimelineTabContentView.iconClassNameForRecord):
     116        (WI.TimelineTabContentView.displayNameForRecord):
     117        * UserInterface/Views/TimelineRecordBar.css:
     118        (.timeline-record-bar.timeline-record-type-media > .segment): Added.
     119
     120        * UserInterface/Views/ContentView.js:
     121        (WI.ContentView.createFromRepresentedObject):
     122        * UserInterface/Views/TimelineOverviewGraph.js:
     123        (WI.TimelineOverviewGraph.createForTimeline):
     124
     125        * UserInterface/Models/ScriptTimelineRecord.js:
     126        (WI.ScriptTimelineRecord.EventType.displayName):
     127
     128        * UserInterface/Main.html:
     129        * UserInterface/Test.html:
     130        * Localizations/en.lproj/localizedStrings.js:
     131        * UserInterface/Images/DOMEvent.svg: Added.
     132        * UserInterface/Images/DOMEventFullscreen.svg: Added.
     133        * UserInterface/Images/LowPower.svg: Added.
     134        * UserInterface/Images/MediaInstrument.svg: Added.
     135
    11362018-11-25  Matt Baker  <mattbaker@apple.com>
    2137
  • trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js

    r238350 r238484  
    372372localizedStrings["Ensure legend is first child in form."] = "Ensure legend is first child in form.";
    373373localizedStrings["Ensure tabindex is a number."] = "Ensure tabindex is a number.";
     374localizedStrings["Entered Full-Screen Mode"] = "Entered Full-Screen Mode";
     375localizedStrings["Entered Low-Power Mode"] = "Entered Low-Power Mode";
    374376localizedStrings["Entire Recording"] = "Entire Recording";
    375377localizedStrings["Error"] = "Error";
     
    386388localizedStrings["Example: “%s”"] = "Example: “%s”";
    387389localizedStrings["Exception with thrown value: %s"] = "Exception with thrown value: %s";
     390localizedStrings["Exited Full-Screen Mode"] = "Exited Full-Screen Mode";
     391localizedStrings["Exited Low-Power Mode"] = "Exited Low-Power Mode";
    388392localizedStrings["Expand All"] = "Expand All";
    389393localizedStrings["Expand columns"] = "Expand columns";
     
    437441localizedStrings["Full Garbage Collection"] = "Full Garbage Collection";
    438442localizedStrings["Full URL"] = "Full URL";
    439 localizedStrings["Fullscreen"] = "Fullscreen";
    440 localizedStrings["Fullscreen from “%s“"] = "Fullscreen from “%s“";
     443localizedStrings["Full-Screen"] = "Full-Screen";
     444localizedStrings["Full-Screen from “%s“"] = "Full-Screen from “%s“";
    441445localizedStrings["Function"] = "Function";
    442446localizedStrings["Function Name Variable"] = "Function Name Variable";
     
    551555localizedStrings["Logs"] = "Logs";
    552556localizedStrings["Low"] = "Low";
    553 localizedStrings["Low Power Mode"] = "Low Power Mode";
     557localizedStrings["Low-Power Mode"] = "Low-Power Mode";
    554558localizedStrings["Lowest: %s"] = "Lowest: %s";
    555559localizedStrings["MIME Type"] = "MIME Type";
     
    563567localizedStrings["Maximum maximum memory size in this recording"] = "Maximum maximum memory size in this recording";
    564568localizedStrings["Media"] = "Media";
     569localizedStrings["Media Event"] = "Media Event";
    565570localizedStrings["Media Logging:"] = "Media Logging:";
    566571localizedStrings["Medium"] = "Medium";
  • trunk/Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js

    r238168 r238484  
    112112            types.push(WI.TimelineRecord.Type.HeapAllocations);
    113113
     114        if (WI.MediaInstrument.supported()) {
     115            let insertionIndex = types.indexOf(WI.TimelineRecord.Type.Layout) + 1;
     116            types.insertAtIndex(WI.TimelineRecord.Type.Media, insertionIndex || types.length);
     117        }
     118
    114119        return types;
    115120    }
     
    252257        this._webTimelineScriptRecordsExpectingScriptProfilerEvents = [];
    253258
     259        WI.DOMNode.addEventListener(WI.DOMNode.Event.DidFireEvent, this._handleDOMNodeDidFireEvent, this);
     260        WI.DOMNode.addEventListener(WI.DOMNode.Event.LowPowerChanged, this._handleDOMNodeLowPowerChanged, this);
     261
    254262        this.dispatchEventToListeners(WI.TimelineManager.Event.CapturingStarted, {startTime});
    255263    }
     
    261269        if (!this._isCapturing)
    262270            return;
     271
     272        WI.DOMNode.removeEventListener(null, null, this);
    263273
    264274        if (this._stopCapturingTimeout) {
     
    10681078                case WI.TimelineRecord.Type.RenderingFrame:
    10691079                case WI.TimelineRecord.Type.Layout:
     1080                case WI.TimelineRecord.Type.Media:
    10701081                    instrumentSet.add(target.TimelineAgent.Instrument.Timeline);
    10711082                    break;
     
    10781089            target.TimelineAgent.setInstruments(Array.from(instrumentSet));
    10791090        }
     1091    }
     1092
     1093    _handleDOMNodeDidFireEvent(event)
     1094    {
     1095        console.assert(this._isCapturing);
     1096
     1097        let {domEvent} = event.data;
     1098
     1099        this._addRecord(new WI.MediaTimelineRecord(WI.MediaTimelineRecord.EventType.DOMEvent, domEvent.timestamp, {
     1100            domNode: event.target,
     1101            domEvent,
     1102        }));
     1103    }
     1104
     1105    _handleDOMNodeLowPowerChanged(event)
     1106    {
     1107        console.assert(this._isCapturing);
     1108
     1109        let {timestamp, isLowPower} = event.data;
     1110
     1111        this._addRecord(new WI.MediaTimelineRecord(WI.MediaTimelineRecord.EventType.LowPower, timestamp, {
     1112            domNode: event.target,
     1113            isLowPower,
     1114        }));
    10801115    }
    10811116};
  • trunk/Source/WebInspectorUI/UserInterface/Main.html

    r238192 r238484  
    125125    <link rel="stylesheet" href="Views/LogContentView.css">
    126126    <link rel="stylesheet" href="Views/LogIcon.css">
     127    <link rel="stylesheet" href="Views/MediaTimelineOverviewGraph.css">
     128    <link rel="stylesheet" href="Views/MediaTimelineView.css">
    127129    <link rel="stylesheet" href="Views/MemoryCategoryView.css">
    128130    <link rel="stylesheet" href="Views/MemoryTimelineOverviewGraph.css">
     
    397399    <script src="Models/LogObject.js"></script>
    398400    <script src="Models/LoggingChannel.js"></script>
     401    <script src="Models/MediaInstrument.js"></script>
     402    <script src="Models/MediaTimelineRecord.js"></script>
    399403    <script src="Models/MemoryCategory.js"></script>
    400404    <script src="Models/MemoryInstrument.js"></script>
     
    685689    <script src="Views/LineChart.js"></script>
    686690    <script src="Views/LogContentView.js"></script>
     691    <script src="Views/MediaTimelineDataGridNode.js"></script>
     692    <script src="Views/MediaTimelineOverviewGraph.js"></script>
     693    <script src="Views/MediaTimelineView.js"></script>
    687694    <script src="Views/MemoryCategoryView.js"></script>
    688695    <script src="Views/MemoryTimelineOverviewGraph.js"></script>
  • trunk/Source/WebInspectorUI/UserInterface/Models/Instrument.js

    r226914 r238484  
    4343        case WI.TimelineRecord.Type.HeapAllocations:
    4444            return new WI.HeapAllocationsInstrument;
     45        case WI.TimelineRecord.Type.Media:
     46            return new WI.MediaInstrument;
    4547        default:
    4648            console.error("Unknown TimelineRecord.Type: " + type);
  • trunk/Source/WebInspectorUI/UserInterface/Models/MediaInstrument.js

    r238483 r238484  
    2424 */
    2525
    26 WI.DOMNodeEventsContentView = class DOMNodeEventsContentView extends WI.ContentView
     26WI.MediaInstrument = class MediaInstrument extends WI.Instrument
    2727{
    28     constructor(domNode, {startTimestamp} = {})
     28    constructor()
    2929    {
    30         console.assert(domNode instanceof WI.DOMNode);
     30        super();
    3131
    32         const representedObject = null;
    33         super(representedObject);
     32        console.assert(WI.MediaInstrument.supported());
     33    }
    3434
    35         this._domNode = domNode;
    36         this._startTimestamp = startTimestamp || 0;
     35    // Static
    3736
    38         this.element.classList.add("dom-node-details", "dom-events");
    39 
    40         this._breakdownView = null;
     37    static supported()
     38    {
     39        // COMPATIBILITY (iOS 12): DOM.didFireEvent and DOM.videoLowPowerChanged did not exist.
     40        return window.DOMAgent && DOMAgent.hasEvent("didFireEvent") && DOMAgent.hasEvent("videoLowPowerChanged");
    4141    }
    4242
    4343    // Protected
    4444
    45     initialLayout()
     45    get timelineRecordType()
    4646    {
    47         super.initialLayout();
     47        return WI.TimelineRecord.Type.Media;
     48    }
    4849
    49         this._breakdownView = new WI.DOMEventsBreakdownView(this._domNode, {
    50             includeGraph: true,
    51             startTimestamp: this._startTimestamp,
    52         });
    53         this.addSubview(this._breakdownView);
     50    startInstrumentation(initiatedByBackend)
     51    {
     52        // Nothing to do, media instrumentation is always happening.
     53    }
     54
     55    stopInstrumentation(initiatedByBackend)
     56    {
     57        // Nothing to do, media instrumentation is always happening.
    5458    }
    5559};
  • trunk/Source/WebInspectorUI/UserInterface/Models/ScriptTimelineRecord.js

    r236766 r238484  
    330330        nameMap.set("webkitTransitionEnd", "Transition End");
    331331        nameMap.set("webkitaddsourcebuffer", "Add Source Buffer");
    332         nameMap.set("webkitbeginfullscreen", "Begin Full Screen");
     332        nameMap.set("webkitbeginfullscreen", "Begin Full-Screen");
    333333        nameMap.set("webkitcurrentplaybacktargetiswirelesschanged", "Current Playback Target Is Wireless Changed");
    334         nameMap.set("webkitendfullscreen", "End Full Screen");
    335         nameMap.set("webkitfullscreenchange", "Full Screen Change");
    336         nameMap.set("webkitfullscreenerror", "Full Screen Error");
     334        nameMap.set("webkitendfullscreen", "End Full-Screen");
     335        nameMap.set("webkitfullscreenchange", "Full-Screen Change");
     336        nameMap.set("webkitfullscreenerror", "Full-Screen Error");
    337337        nameMap.set("webkitkeyadded", "Key Added");
    338338        nameMap.set("webkitkeyerror", "Key Error");
  • trunk/Source/WebInspectorUI/UserInterface/Models/TimelineRecord.js

    r220119 r238484  
    161161    Memory: "timeline-record-type-memory",
    162162    HeapAllocations: "timeline-record-type-heap-allocations",
     163    Media: "timeline-record-type-media",
    163164};
    164165
  • trunk/Source/WebInspectorUI/UserInterface/Models/TimelineRecording.js

    r236766 r238484  
    128128
    129129        this._sourceCodeTimelinesMap = new Map;
    130         this._eventMarkers = [];
    131130        this._startTime = NaN;
    132131        this._endTime = NaN;
     
    197196            return;
    198197
    199         this._eventMarkers.push(marker);
    200 
    201198        this.dispatchEventToListeners(WI.TimelineRecording.Event.MarkerAdded, {marker});
    202199    }
     
    216213            || record.type === WI.TimelineRecord.Type.RenderingFrame
    217214            || record.type === WI.TimelineRecord.Type.Memory
    218             || record.type === WI.TimelineRecord.Type.HeapAllocations)
     215            || record.type === WI.TimelineRecord.Type.HeapAllocations
     216            || record.type === WI.TimelineRecord.Type.Media)
    219217            return;
    220218
     
    333331    {
    334332        var key = record.type;
    335         if (record instanceof WI.ScriptTimelineRecord || record instanceof WI.LayoutTimelineRecord)
     333        if (record instanceof WI.ScriptTimelineRecord || record instanceof WI.LayoutTimelineRecord || record instanceof WI.MediaTimelineRecord)
    336334            key += ":" + record.eventType;
    337335        if (record instanceof WI.ScriptTimelineRecord && record.eventType === WI.ScriptTimelineRecord.EventType.EventDispatched)
  • trunk/Source/WebInspectorUI/UserInterface/Test.html

    r238330 r238484  
    159159    <script src="Models/LazySourceCodeLocation.js"></script>
    160160    <script src="Models/LoggingChannel.js"></script>
     161    <script src="Models/MediaInstrument.js"></script>
     162    <script src="Models/MediaTimelineRecord.js"></script>
    161163    <script src="Models/MemoryCategory.js"></script>
    162164    <script src="Models/MemoryInstrument.js"></script>
  • trunk/Source/WebInspectorUI/UserInterface/Views/ContentView.js

    r237613 r238484  
    8989            if (timelineType === WI.TimelineRecord.Type.HeapAllocations)
    9090                return new WI.HeapAllocationsTimelineView(representedObject, extraArguments);
     91
     92            if (timelineType === WI.TimelineRecord.Type.Media)
     93                return new WI.MediaTimelineView(representedObject, extraArguments);
    9194        }
    9295
  • trunk/Source/WebInspectorUI/UserInterface/Views/DOMEventsBreakdownView.js

    r237669 r238484  
    2626WI.DOMEventsBreakdownView = class DOMEventsBreakdownView extends WI.View
    2727{
    28     constructor(domNodeOrEvents, {includeGraph, startTimestamp} = {})
     28    constructor(domNodeOrEvents, {includeGraph} = {})
    2929    {
    3030        console.assert(domNodeOrEvents instanceof WI.DOMNode || Array.isArray(domNodeOrEvents));
     
    4646
    4747        this._includeGraph = includeGraph || false;
    48         this._startTimestamp = startTimestamp || 0;
    4948
    5049        this._tableBodyElement = null;
     
    135134
    136135                    if (fullscreenRange.originator)
    137                         fullscreenArea.title = WI.UIString("Fullscreen from “%s“").format(fullscreenRange.originator.displayName);
     136                        fullscreenArea.title = WI.UIString("Full-Screen from “%s“").format(fullscreenRange.originator.displayName);
    138137                    else
    139                         fullscreenArea.title = WI.UIString("Fullscreen");
     138                        fullscreenArea.title = WI.UIString("Full-Screen");
    140139                }
    141140
     
    144143                    let lowPowerArea = graphCell.appendChild(document.createElement("div"));
    145144                    lowPowerArea.classList.add("area", "low-power");
    146                     lowPowerArea.title = WI.UIString("Low Power Mode");
     145                    lowPowerArea.title = WI.UIString("Low-Power Mode");
    147146                    lowPowerArea.style.setProperty(styleAttribute, percentOfTotalTime(lowPowerRange.startTimestamp - startTimestamp) + "%");
    148147                    lowPowerArea.style.setProperty("width", percentOfTotalTime(lowPowerRange.endTimestamp - lowPowerRange.startTimestamp) + "%");
     
    158157
    159158            const higherResolution = true;
    160             timeCell.textContent = Number.secondsToString(domEvent.timestamp - this._startTimestamp, higherResolution);
     159            timeCell.textContent = Number.secondsToString(domEvent.timestamp, higherResolution);
    161160
    162161            let originatorCell = rowElement.appendChild(document.createElement("td"));
  • trunk/Source/WebInspectorUI/UserInterface/Views/DOMNodeEventsContentView.js

    r237669 r238484  
    2626WI.DOMNodeEventsContentView = class DOMNodeEventsContentView extends WI.ContentView
    2727{
    28     constructor(domNode, {startTimestamp} = {})
     28    constructor(domNode)
    2929    {
    3030        console.assert(domNode instanceof WI.DOMNode);
     
    3434
    3535        this._domNode = domNode;
    36         this._startTimestamp = startTimestamp || 0;
    3736
    3837        this.element.classList.add("dom-node-details", "dom-events");
     
    4948        this._breakdownView = new WI.DOMEventsBreakdownView(this._domNode, {
    5049            includeGraph: true,
    51             startTimestamp: this._startTimestamp,
    5250        });
    5351        this.addSubview(this._breakdownView);
  • trunk/Source/WebInspectorUI/UserInterface/Views/MediaTimelineOverviewGraph.css

    r238483 r238484  
    2424 */
    2525
    26 WI.DOMNodeEventsContentView = class DOMNodeEventsContentView extends WI.ContentView
    27 {
    28     constructor(domNode, {startTimestamp} = {})
    29     {
    30         console.assert(domNode instanceof WI.DOMNode);
     26.timeline-overview-graph.media > .timeline-record-bar {
     27    margin-top: 8px;
     28    height: 20px;
     29}
    3130
    32         const representedObject = null;
    33         super(representedObject);
    34 
    35         this._domNode = domNode;
    36         this._startTimestamp = startTimestamp || 0;
    37 
    38         this.element.classList.add("dom-node-details", "dom-events");
    39 
    40         this._breakdownView = null;
    41     }
    42 
    43     // Protected
    44 
    45     initialLayout()
    46     {
    47         super.initialLayout();
    48 
    49         this._breakdownView = new WI.DOMEventsBreakdownView(this._domNode, {
    50             includeGraph: true,
    51             startTimestamp: this._startTimestamp,
    52         });
    53         this.addSubview(this._breakdownView);
    54     }
    55 };
     31.timeline-overview-graph.media > .timeline-record-bar > .segment {
     32    border-radius: 2px;
     33}
  • trunk/Source/WebInspectorUI/UserInterface/Views/MediaTimelineView.css

    r238483 r238484  
    2424 */
    2525
    26 WI.DOMNodeEventsContentView = class DOMNodeEventsContentView extends WI.ContentView
    27 {
    28     constructor(domNode, {startTimestamp} = {})
    29     {
    30         console.assert(domNode instanceof WI.DOMNode);
    31 
    32         const representedObject = null;
    33         super(representedObject);
    34 
    35         this._domNode = domNode;
    36         this._startTimestamp = startTimestamp || 0;
    37 
    38         this.element.classList.add("dom-node-details", "dom-events");
    39 
    40         this._breakdownView = null;
    41     }
    42 
    43     // Protected
    44 
    45     initialLayout()
    46     {
    47         super.initialLayout();
    48 
    49         this._breakdownView = new WI.DOMEventsBreakdownView(this._domNode, {
    50             includeGraph: true,
    51             startTimestamp: this._startTimestamp,
    52         });
    53         this.addSubview(this._breakdownView);
    54     }
    55 };
     26.timeline-view.media > .data-grid {
     27    position: absolute;
     28    top: 0;
     29    left: 0;
     30    right: 0;
     31    bottom: 0;
     32}
  • trunk/Source/WebInspectorUI/UserInterface/Views/NetworkDOMNodeDetailView.js

    r237028 r238484  
    2626WI.NetworkDOMNodeDetailView = class NetworkDOMNodeDetailView extends WI.NetworkDetailView
    2727{
    28     constructor(domNode, delegate, {startTimestamp} = {})
     28    constructor(domNode, delegate)
    2929    {
    3030        console.assert(domNode instanceof WI.DOMNode);
    3131
    3232        super(domNode, delegate);
    33 
    34         this._startTimestamp = startTimestamp || 0;
    3533
    3634        this.element.classList.add("dom-node");
     
    5755        case "dom-events":
    5856            if (!this._domEventsContentView) {
    59                 this._domEventsContentView = new WI.DOMNodeEventsContentView(this.representedObject, {
    60                     startTimestamp: this._startTimestamp,
    61                 });
     57                this._domEventsContentView = new WI.DOMNodeEventsContentView(this.representedObject);
    6258            }
    6359            this._contentBrowser.showContentView(this._domEventsContentView, this._contentViewCookie);
  • trunk/Source/WebInspectorUI/UserInterface/Views/NetworkTableContentView.js

    r238203 r238484  
    8585        this._typeFilterScopeBar.addEventListener(WI.ScopeBar.Event.SelectionChanged, this._typeFilterScopeBarSelectionChanged, this);
    8686
    87         this._groupByDOMNodeNavigationItem = new WI.CheckboxNavigationItem("group-by-node", WI.UIString("Group Media Requests"), WI.settings.groupByDOMNode.value);
    88         this._groupByDOMNodeNavigationItem.addEventListener(WI.CheckboxNavigationItem.Event.CheckedDidChange, this._handleGroupByDOMNodeCheckedDidChange, this);
     87        if (WI.MediaInstrument.supported()) {
     88            this._groupByDOMNodeNavigationItem = new WI.CheckboxNavigationItem("group-by-node", WI.UIString("Group Media Requests"), WI.settings.groupByDOMNode.value);
     89            this._groupByDOMNodeNavigationItem.addEventListener(WI.CheckboxNavigationItem.Event.CheckedDidChange, this._handleGroupByDOMNodeCheckedDidChange, this);
     90        } else
     91            WI.settings.groupByDOMNode.value = false;
    8992
    9093        this._urlFilterSearchText = null;
     
    214217    get filterNavigationItems()
    215218    {
    216         return [this._urlFilterNavigationItem, this._typeFilterScopeBar, this._groupByDOMNodeNavigationItem];
     219        let navigationItems = [this._urlFilterNavigationItem, this._typeFilterScopeBar];
     220        if (WI.MediaInstrument.supported())
     221            navigationItems.push(this._groupByDOMNodeNavigationItem);
     222        return navigationItems;
    217223    }
    218224
     
    696702                    let originator = fullscreenDOMEvents[i].originator || fullscreenDOMEvents[i + 1].originator;
    697703                    if (originator)
    698                         fullscreenElement.title = WI.UIString("Fullscreen from “%s“").format(originator.displayName);
     704                        fullscreenElement.title = WI.UIString("Full-Screen from “%s“").format(originator.displayName);
    699705                    else
    700                         fullscreenElement.title = WI.UIString("Fullscreen");
     706                        fullscreenElement.title = WI.UIString("Full-Screen");
    701707                }
    702708            }
     
    708714                let lowPowerElement = container.appendChild(document.createElement("div"));
    709715                lowPowerElement.classList.add("area", "low-power");
    710                 lowPowerElement.title = WI.UIString("Low Power Mode");
     716                lowPowerElement.title = WI.UIString("Low-Power Mode");
    711717                positionByStartOffset(lowPowerElement, startTimestamp);
    712718                setWidthForDuration(lowPowerElement, startTimestamp, endTimestamp);
     
    13141320                this._detailView = new WI.NetworkResourceDetailView(object, this);
    13151321            else if (object instanceof WI.DOMNode) {
    1316                 this._detailView = new WI.NetworkDOMNodeDetailView(object, this, {
    1317                     startTimestamp: this._waterfallStartTime,
    1318                 });
     1322                this._detailView = new WI.NetworkDOMNodeDetailView(object, this);
    13191323            }
    13201324
     
    19191923        let contentElement = this._waterfallPopoverContent();
    19201924
    1921         let breakdownView = new WI.DOMEventsBreakdownView(domEvents, {
    1922             startTimestamp: this._waterfallStartTime,
    1923         });
     1925        let breakdownView = new WI.DOMEventsBreakdownView(domEvents);
    19241926        contentElement.appendChild(breakdownView.element);
    19251927        breakdownView.updateLayout();
  • trunk/Source/WebInspectorUI/UserInterface/Views/TimelineIcons.css

    r236237 r238484  
    4646.rendering-frame-icon .icon {
    4747    content: url(../Images/RenderingFramesInstrument.svg);
     48}
     49
     50.media-icon .icon {
     51    content: url(../Images/MediaInstrument.svg);
    4852}
    4953
     
    118122}
    119123
     124.dom-event-record .icon {
     125    content: url(../Images/DOMEvent.svg);
     126}
     127
     128.dom-event-record.fullscreen .icon {
     129    content: url(../Images/DOMEventFullscreen.svg);
     130}
     131
     132.low-power-record .icon {
     133    content: url(../Images/LowPower.svg);
     134}
     135
    120136@media (prefers-dark-interface) {
    121137    .time-icon .icon {
  • trunk/Source/WebInspectorUI/UserInterface/Views/TimelineOverview.js

    r238483 r238484  
    686686
    687687        for (let overviewGraph of this._overviewGraphsByTypeMap.values()) {
     688            if (!overviewGraph.visible)
     689                continue;
     690
    688691            let graphRect = overviewGraph.element.getBoundingClientRect();
    689692            if (!(event.pageX >= graphRect.left && event.pageX <= graphRect.right && event.pageY >= graphRect.top && event.pageY <= graphRect.bottom))
  • trunk/Source/WebInspectorUI/UserInterface/Views/TimelineOverviewGraph.js

    r237195 r238484  
    7070            return new WI.HeapAllocationsTimelineOverviewGraph(timeline, timelineOverview);
    7171
     72        if (timelineType === WI.TimelineRecord.Type.Media)
     73            return new WI.MediaTimelineOverviewGraph(timeline, timelineOverview);
     74
    7275        throw new Error("Can't make a graph for an unknown timeline.");
    7376    }
  • trunk/Source/WebInspectorUI/UserInterface/Views/TimelineRecordBar.css

    r237195 r238484  
    127127    border-color: hsl(11, 54%, 62%);   
    128128}
     129
     130.timeline-record-bar.timeline-record-type-media > .segment {
     131    background-color: hsl(143, 24%, 66%);
     132    border-color: hsl(153, 24%, 51%);
     133}
  • trunk/Source/WebInspectorUI/UserInterface/Views/TimelineRuler.js

    r237706 r238484  
    369369    clearMarkers()
    370370    {
    371         for (let markerElement of this._markerElementMap.values())
     371        for (let [marker, markerElement] of this._markerElementMap) {
     372            marker.removeEventListener(null, null, this);
    372373            markerElement.remove();
     374        }
    373375
    374376        this._markerElementMap.clear();
     
    729731            return;
    730732
    731         this.element.style.pointerEvents = "none";
    732         let newTarget = document.elementFromPoint(event.pageX, event.pageY);
    733         this.element.style.pointerEvents = null;
    734 
    735         if (newTarget && newTarget.click)
    736             newTarget.click();
     733        for (let newTarget of document.elementsFromPoint(event.pageX, event.pageY)) {
     734            if (!newTarget || typeof newTarget.click !== "function")
     735                continue;
     736            if (this.element.contains(newTarget))
     737                continue;
     738
     739            // Clone the event to dispatch it on the new element.
     740            newTarget.dispatchEvent(new event.constructor(event.type, event));
     741            return;
     742        }
    737743    }
    738744
  • trunk/Source/WebInspectorUI/UserInterface/Views/TimelineTabContentView.js

    r238483 r238484  
    121121        case WI.TimelineRecord.Type.HeapAllocations:
    122122            return WI.UIString("JavaScript Allocations");
     123        case WI.TimelineRecord.Type.Media:
     124            return WI.UIString("Media");
    123125        default:
    124126            console.error("Unknown Timeline type:", timelineType);
     
    143145        case WI.TimelineRecord.Type.RenderingFrame:
    144146            return "rendering-frame-icon";
     147        case WI.TimelineRecord.Type.Media:
     148            return "media-icon";
    145149        default:
    146150            console.error("Unknown Timeline type:", timelineType);
     
    165169        case WI.TimelineRecord.Type.RenderingFrame:
    166170            return "rendering-frame";
     171        case WI.TimelineRecord.Type.Media:
     172            return "media";
    167173        default:
    168174            console.error("Unknown Timeline type:", timelineType);
     
    230236            return "heap-snapshot-record";
    231237
     238        case WI.TimelineRecord.Type.Media:
     239            switch (timelineRecord.eventType) {
     240            case WI.MediaTimelineRecord.EventType.DOMEvent:
     241                return "dom-event-record";
     242            case WI.MediaTimelineRecord.EventType.LowPower:
     243                return "low-power-record";
     244            default:
     245                console.error("Unknown MediaTimelineRecord eventType: " + timelineRecord.eventType, timelineRecord);
     246            }
     247
     248            break;
     249
    232250        case WI.TimelineRecord.Type.Memory:
    233251            // Not used. Fall through to error just in case.
     
    255273                return WI.UIString("Snapshot %d \u2014 %s").format(timelineRecord.heapSnapshot.identifier, timelineRecord.heapSnapshot.title);
    256274            return WI.UIString("Snapshot %d").format(timelineRecord.heapSnapshot.identifier);
     275        case WI.TimelineRecord.Type.Media:
     276            return timelineRecord.displayName;
    257277        case WI.TimelineRecord.Type.Memory:
    258278            // Not used. Fall through to error just in case.
Note: See TracChangeset for help on using the changeset viewer.