⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 243213 in webkit


Ignore:
Timestamp:
Mar 20, 2019, 10:43:05 AM (7 years ago)
Author:
Devin Rousso
Message:

Web Inspector: refactor WI.TimelineDataGridNode and its subclasses to unify the API surface
https://bugs.webkit.org/show_bug.cgi?id=195959
<rdar://problem/49028896>

Reviewed by Timothy Hatcher.

  • UserInterface/Views/TimelineDataGridNode.js:

(WI.TimelineDataGridNode.prototype.get records):
(WI.TimelineDataGridNode.prototype.get data):
(WI.TimelineDataGridNode.prototype.refresh):

  • UserInterface/Views/HeapAllocationsTimelineDataGridNode.js:

(WI.HeapAllocationsTimelineDataGridNode):
(WI.HeapAllocationsTimelineDataGridNode.prototype.get heapSnapshot): Added.
(WI.HeapAllocationsTimelineDataGridNode.prototype.get data):
(WI.HeapAllocationsTimelineDataGridNode.prototype.createCellContent):
(WI.HeapAllocationsTimelineDataGridNode.prototype.createCells):
(WI.HeapAllocationsTimelineDataGridNode.prototype._handleHeapSnapshotCollectedNodes):
(WI.HeapAllocationsTimelineDataGridNode.prototype._handleHeapSnapshotInvalidated):
(WI.HeapAllocationsTimelineDataGridNode.prototype.get record): Deleted.
(WI.HeapAllocationsTimelineDataGridNode.prototype.updateTimestamp): Deleted.
(WI.HeapAllocationsTimelineDataGridNode.prototype._heapSnapshotCollectedNodes): Deleted.
(WI.HeapAllocationsTimelineDataGridNode.prototype._heapSnapshotInvalidated): Deleted.

  • UserInterface/Views/LayoutTimelineDataGridNode.js:

(WI.LayoutTimelineDataGridNode):
(WI.LayoutTimelineDataGridNode.prototype.get data):
(WI.LayoutTimelineDataGridNode.prototype.createCellContent):
(WI.LayoutTimelineDataGridNode.prototype.get records): Deleted.

  • UserInterface/Views/MediaTimelineDataGridNode.js:

(WI.MediaTimelineDataGridNode):
(WI.MediaTimelineDataGridNode.prototype.get records): Deleted.

  • UserInterface/Views/ProfileNodeDataGridNode.js:

(WI.ProfileNodeDataGridNode):
(WI.ProfileNodeDataGridNode.prototype.get profileNode):
(WI.ProfileNodeDataGridNode.prototype.get data):
(WI.ProfileNodeDataGridNode.prototype.createCellContent):
(WI.ProfileNodeDataGridNode.prototype._populate):
(WI.ProfileNodeDataGridNode.prototype.get records): Deleted.
(WI.ProfileNodeDataGridNode.prototype.get baseStartTime): Deleted.
(WI.ProfileNodeDataGridNode.prototype.get rangeStartTime): Deleted.
(WI.ProfileNodeDataGridNode.prototype.get rangeEndTime): Deleted.
(WI.ProfileNodeDataGridNode.prototype.updateRangeTimes): Deleted.
(WI.ProfileNodeDataGridNode.prototype.refresh): Deleted.

  • UserInterface/Views/RenderingFrameTimelineDataGridNode.js:

(WI.RenderingFrameTimelineDataGridNode):
(WI.RenderingFrameTimelineDataGridNode.prototype.get data):
(WI.RenderingFrameTimelineDataGridNode.prototype.createCellContent):
(WI.RenderingFrameTimelineDataGridNode.prototype.get records): Deleted.

  • UserInterface/Views/ResourceTimelineDataGridNode.js:

(WI.ResourceTimelineDataGridNode):
(WI.ResourceTimelineDataGridNode.prototype.get resource):
(WI.ResourceTimelineDataGridNode.prototype.get data):
(WI.ResourceTimelineDataGridNode.prototype.createCellContent):
(WI.ResourceTimelineDataGridNode.prototype.appendContextMenuItems):
(WI.ResourceTimelineDataGridNode.prototype.filterableDataForColumn):
(WI.ResourceTimelineDataGridNode.prototype._createNameCellDocumentFragment):
(WI.ResourceTimelineDataGridNode.prototype._cachedCellContent):
(WI.ResourceTimelineDataGridNode.prototype._timelineRecordUpdated):
(WI.ResourceTimelineDataGridNode.prototype._dataGridNodeGoToArrowClicked):
(WI.ResourceTimelineDataGridNode.prototype._updateStatus):
(WI.ResourceTimelineDataGridNode.prototype._mouseoverRecordBar.else.let.graphDataSource.get startTime):
(WI.ResourceTimelineDataGridNode.prototype._mouseoverRecordBar.else.let.graphDataSource.get currentTime):
(WI.ResourceTimelineDataGridNode.prototype._mouseoverRecordBar.else.let.graphDataSource.get endTime):
(WI.ResourceTimelineDataGridNode.prototype._mouseoverRecordBar.else.let.graphDataSource.get _extraTimePadding):
(WI.ResourceTimelineDataGridNode.prototype._mouseoverRecordBar):
(WI.ResourceTimelineDataGridNode.prototype.get records): Deleted.

  • UserInterface/Views/ResourceTimingPopoverDataGridNode.js:

(WI.ResourceTimingPopoverDataGridNode):
(WI.ResourceTimingPopoverDataGridNode.prototype.get records): Deleted.

  • UserInterface/Views/ScriptTimelineDataGridNode.js:

(WI.ScriptTimelineDataGridNode.prototype.get data):
(WI.ScriptTimelineDataGridNode.prototype.get subtitle):
(WI.ScriptTimelineDataGridNode.prototype.createCellContent):
(WI.ScriptTimelineDataGridNode.prototype.get records): Deleted.
(WI.ScriptTimelineDataGridNode.prototype.get baseStartTime): Deleted.
(WI.ScriptTimelineDataGridNode.prototype.get rangeStartTime): Deleted.
(WI.ScriptTimelineDataGridNode.prototype.get rangeEndTime): Deleted.
(WI.ScriptTimelineDataGridNode.prototype.updateRangeTimes): Deleted.

  • UserInterface/Views/SourceCodeTimelineTimelineDataGridNode.js:

(WI.SourceCodeTimelineTimelineDataGridNode.prototype.get data):

  • UserInterface/Views/HeapAllocationsTimelineView.js:

(WI.HeapAllocationsTimelineView):
(WI.HeapAllocationsTimelineView.prototype.layout):
(WI.HeapAllocationsTimelineView.prototype.reset):

  • UserInterface/Views/LayoutTimelineView.js:

(WI.LayoutTimelineView.prototype._processPendingRecords):

  • UserInterface/Views/MediaTimelineView.js:

(WI.MediaTimelineView.prototype._processPendingRecords):

  • UserInterface/Views/NetworkTimelineView.js:

(WI.NetworkTimelineView.prototype._processPendingRecords):

  • UserInterface/Views/OverviewTimelineView.js:

(WI.OverviewTimelineView.prototype._addResourceToDataGridIfNeeded):
(WI.OverviewTimelineView.prototype._addSourceCodeTimeline):

  • UserInterface/Views/RenderingFrameTimelineView.js:

(WI.RenderingFrameTimelineView.prototype._processPendingRecords):

  • UserInterface/Views/ScriptDetailsTimelineView.js:

(WI.ScriptDetailsTimelineView.prototype.layout):
(WI.ScriptDetailsTimelineView.prototype._processPendingRecords):
Update Timeline WI.DataGrid views to use the new constructor format.

  • UserInterface/Views/ResourceTimelineDataGridNode.css:

(.resource-timing-popover-content .data-grid td.graph-column):
Drive-by: add extra padding before/after resource timing bars shown when hovering.

Location:
trunk/Source/WebInspectorUI
Files:
19 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebInspectorUI/ChangeLog

    r243208 r243213  
     12019-03-20  Devin Rousso  <drousso@apple.com>
     2
     3        Web Inspector: refactor WI.TimelineDataGridNode and its subclasses to unify the API surface
     4        https://bugs.webkit.org/show_bug.cgi?id=195959
     5        <rdar://problem/49028896>
     6
     7        Reviewed by Timothy Hatcher.
     8
     9        * UserInterface/Views/TimelineDataGridNode.js:
     10        (WI.TimelineDataGridNode.prototype.get records):
     11        (WI.TimelineDataGridNode.prototype.get data):
     12        (WI.TimelineDataGridNode.prototype.refresh):
     13
     14        * UserInterface/Views/HeapAllocationsTimelineDataGridNode.js:
     15        (WI.HeapAllocationsTimelineDataGridNode):
     16        (WI.HeapAllocationsTimelineDataGridNode.prototype.get heapSnapshot): Added.
     17        (WI.HeapAllocationsTimelineDataGridNode.prototype.get data):
     18        (WI.HeapAllocationsTimelineDataGridNode.prototype.createCellContent):
     19        (WI.HeapAllocationsTimelineDataGridNode.prototype.createCells):
     20        (WI.HeapAllocationsTimelineDataGridNode.prototype._handleHeapSnapshotCollectedNodes):
     21        (WI.HeapAllocationsTimelineDataGridNode.prototype._handleHeapSnapshotInvalidated):
     22        (WI.HeapAllocationsTimelineDataGridNode.prototype.get record): Deleted.
     23        (WI.HeapAllocationsTimelineDataGridNode.prototype.updateTimestamp): Deleted.
     24        (WI.HeapAllocationsTimelineDataGridNode.prototype._heapSnapshotCollectedNodes): Deleted.
     25        (WI.HeapAllocationsTimelineDataGridNode.prototype._heapSnapshotInvalidated): Deleted.
     26
     27        * UserInterface/Views/LayoutTimelineDataGridNode.js:
     28        (WI.LayoutTimelineDataGridNode):
     29        (WI.LayoutTimelineDataGridNode.prototype.get data):
     30        (WI.LayoutTimelineDataGridNode.prototype.createCellContent):
     31        (WI.LayoutTimelineDataGridNode.prototype.get records): Deleted.
     32
     33        * UserInterface/Views/MediaTimelineDataGridNode.js:
     34        (WI.MediaTimelineDataGridNode):
     35        (WI.MediaTimelineDataGridNode.prototype.get records): Deleted.
     36
     37        * UserInterface/Views/ProfileNodeDataGridNode.js:
     38        (WI.ProfileNodeDataGridNode):
     39        (WI.ProfileNodeDataGridNode.prototype.get profileNode):
     40        (WI.ProfileNodeDataGridNode.prototype.get data):
     41        (WI.ProfileNodeDataGridNode.prototype.createCellContent):
     42        (WI.ProfileNodeDataGridNode.prototype._populate):
     43        (WI.ProfileNodeDataGridNode.prototype.get records): Deleted.
     44        (WI.ProfileNodeDataGridNode.prototype.get baseStartTime): Deleted.
     45        (WI.ProfileNodeDataGridNode.prototype.get rangeStartTime): Deleted.
     46        (WI.ProfileNodeDataGridNode.prototype.get rangeEndTime): Deleted.
     47        (WI.ProfileNodeDataGridNode.prototype.updateRangeTimes): Deleted.
     48        (WI.ProfileNodeDataGridNode.prototype.refresh): Deleted.
     49
     50        * UserInterface/Views/RenderingFrameTimelineDataGridNode.js:
     51        (WI.RenderingFrameTimelineDataGridNode):
     52        (WI.RenderingFrameTimelineDataGridNode.prototype.get data):
     53        (WI.RenderingFrameTimelineDataGridNode.prototype.createCellContent):
     54        (WI.RenderingFrameTimelineDataGridNode.prototype.get records): Deleted.
     55
     56        * UserInterface/Views/ResourceTimelineDataGridNode.js:
     57        (WI.ResourceTimelineDataGridNode):
     58        (WI.ResourceTimelineDataGridNode.prototype.get resource):
     59        (WI.ResourceTimelineDataGridNode.prototype.get data):
     60        (WI.ResourceTimelineDataGridNode.prototype.createCellContent):
     61        (WI.ResourceTimelineDataGridNode.prototype.appendContextMenuItems):
     62        (WI.ResourceTimelineDataGridNode.prototype.filterableDataForColumn):
     63        (WI.ResourceTimelineDataGridNode.prototype._createNameCellDocumentFragment):
     64        (WI.ResourceTimelineDataGridNode.prototype._cachedCellContent):
     65        (WI.ResourceTimelineDataGridNode.prototype._timelineRecordUpdated):
     66        (WI.ResourceTimelineDataGridNode.prototype._dataGridNodeGoToArrowClicked):
     67        (WI.ResourceTimelineDataGridNode.prototype._updateStatus):
     68        (WI.ResourceTimelineDataGridNode.prototype._mouseoverRecordBar.else.let.graphDataSource.get startTime):
     69        (WI.ResourceTimelineDataGridNode.prototype._mouseoverRecordBar.else.let.graphDataSource.get currentTime):
     70        (WI.ResourceTimelineDataGridNode.prototype._mouseoverRecordBar.else.let.graphDataSource.get endTime):
     71        (WI.ResourceTimelineDataGridNode.prototype._mouseoverRecordBar.else.let.graphDataSource.get _extraTimePadding):
     72        (WI.ResourceTimelineDataGridNode.prototype._mouseoverRecordBar):
     73        (WI.ResourceTimelineDataGridNode.prototype.get records): Deleted.
     74
     75        * UserInterface/Views/ResourceTimingPopoverDataGridNode.js:
     76        (WI.ResourceTimingPopoverDataGridNode):
     77        (WI.ResourceTimingPopoverDataGridNode.prototype.get records): Deleted.
     78
     79        * UserInterface/Views/ScriptTimelineDataGridNode.js:
     80        (WI.ScriptTimelineDataGridNode.prototype.get data):
     81        (WI.ScriptTimelineDataGridNode.prototype.get subtitle):
     82        (WI.ScriptTimelineDataGridNode.prototype.createCellContent):
     83        (WI.ScriptTimelineDataGridNode.prototype.get records): Deleted.
     84        (WI.ScriptTimelineDataGridNode.prototype.get baseStartTime): Deleted.
     85        (WI.ScriptTimelineDataGridNode.prototype.get rangeStartTime): Deleted.
     86        (WI.ScriptTimelineDataGridNode.prototype.get rangeEndTime): Deleted.
     87        (WI.ScriptTimelineDataGridNode.prototype.updateRangeTimes): Deleted.
     88
     89        * UserInterface/Views/SourceCodeTimelineTimelineDataGridNode.js:
     90        (WI.SourceCodeTimelineTimelineDataGridNode.prototype.get data):
     91
     92        * UserInterface/Views/HeapAllocationsTimelineView.js:
     93        (WI.HeapAllocationsTimelineView):
     94        (WI.HeapAllocationsTimelineView.prototype.layout):
     95        (WI.HeapAllocationsTimelineView.prototype.reset):
     96        * UserInterface/Views/LayoutTimelineView.js:
     97        (WI.LayoutTimelineView.prototype._processPendingRecords):
     98        * UserInterface/Views/MediaTimelineView.js:
     99        (WI.MediaTimelineView.prototype._processPendingRecords):
     100        * UserInterface/Views/NetworkTimelineView.js:
     101        (WI.NetworkTimelineView.prototype._processPendingRecords):
     102        * UserInterface/Views/OverviewTimelineView.js:
     103        (WI.OverviewTimelineView.prototype._addResourceToDataGridIfNeeded):
     104        (WI.OverviewTimelineView.prototype._addSourceCodeTimeline):
     105        * UserInterface/Views/RenderingFrameTimelineView.js:
     106        (WI.RenderingFrameTimelineView.prototype._processPendingRecords):
     107        * UserInterface/Views/ScriptDetailsTimelineView.js:
     108        (WI.ScriptDetailsTimelineView.prototype.layout):
     109        (WI.ScriptDetailsTimelineView.prototype._processPendingRecords):
     110        Update Timeline `WI.DataGrid` views to use the new constructor format.
     111
     112        * UserInterface/Views/ResourceTimelineDataGridNode.css:
     113        (.resource-timing-popover-content .data-grid td.graph-column):
     114        Drive-by: add extra padding before/after resource timing bars shown when hovering.
     115
    11162019-03-20  Devin Rousso  <drousso@apple.com>
    2117
  • trunk/Source/WebInspectorUI/UserInterface/Views/HeapAllocationsTimelineDataGridNode.js

    r220119 r243213  
    2626WI.HeapAllocationsTimelineDataGridNode = class HeapAllocationsTimelineDataGridNode extends WI.TimelineDataGridNode
    2727{
    28     constructor(heapAllocationsTimelineRecord, zeroTime, heapAllocationsView)
     28    constructor(record, options = {})
    2929    {
    30         super(false, null);
     30        console.assert(record instanceof WI.HeapAllocationsTimelineRecord);
    3131
    32         this._record = heapAllocationsTimelineRecord;
    33         this._heapAllocationsView = heapAllocationsView;
     32        super([record], options);
    3433
    35         this._data = {
    36             name: this.displayName(),
    37             timestamp: zeroTime ? this._record.timestamp - zeroTime : NaN,
    38             size: this._record.heapSnapshot.totalSize,
    39             liveSize: this._record.heapSnapshot.liveSize,
    40         };
     34        this._heapAllocationsView = options.heapAllocationsView;
    4135
    42         this._record.heapSnapshot.addEventListener(WI.HeapSnapshotProxy.Event.CollectedNodes, this._heapSnapshotCollectedNodes, this);
    43         this._record.heapSnapshot.addEventListener(WI.HeapSnapshotProxy.Event.Invalidated, this._heapSnapshotInvalidated, this);
     36        this.heapSnapshot.addEventListener(WI.HeapSnapshotProxy.Event.CollectedNodes, this._handleHeapSnapshotCollectedNodes, this);
     37        this.heapSnapshot.addEventListener(WI.HeapSnapshotProxy.Event.Invalidated, this._handleHeapSnapshotInvalidated, this);
    4438    }
    4539
    4640    // Public
    4741
    48     get record() { return this._record; }
    49     get data() { return this._data; }
     42    get heapSnapshot()
     43    {
     44        return this.record.heapSnapshot;
     45    }
     46
     47    get data()
     48    {
     49        if (this._cachedData)
     50            return this._cachedData;
     51
     52        this._cachedData = super.data;
     53        this._cachedData.name = this.displayName();
     54        this._cachedData.timestamp = this.record.timestamp - (this.graphDataSource ? this.graphDataSource.zeroTime : 0);
     55        this._cachedData.size = this.heapSnapshot.totalSize;
     56        this._cachedData.liveSize = this.heapSnapshot.liveSize;
     57        return this._cachedData;
     58    }
    5059
    5160    createCellContent(columnIdentifier, cell)
    5261    {
     62        const higherResolution = true;
     63
     64        let value = this.data[columnIdentifier];
     65
    5366        switch (columnIdentifier) {
    5467        case "name":
     
    5770            var fragment = document.createDocumentFragment();
    5871            var titleElement = fragment.appendChild(document.createElement("span"));
    59             titleElement.textContent = this._data.name;
    60             if (!this._record.heapSnapshot.invalid) {
     72            titleElement.textContent = value;
     73
     74            if (this._heapAllocationsView && !this.heapSnapshot.invalid) {
    6175                var goToButton = fragment.appendChild(WI.createGoToArrowButton());
    6276                goToButton.addEventListener("click", (event) => {
    63                     this._heapAllocationsView.showHeapSnapshotTimelineRecord(this._record);
     77                    this._heapAllocationsView.showHeapSnapshotTimelineRecord(this.record);
    6478                });
    6579            }
     80
    6681            return fragment;
    6782
    68         case "timestamp":
    69             return isNaN(this._data.timestamp) ? emDash : Number.secondsToString(this._data.timestamp, true);
     83        case "timestamp": {
     84            return isNaN(value) ? emDash : Number.secondsToString(value, higherResolution);
     85        }
    7086
    7187        case "size":
    72             return Number.bytesToString(this._data.size);
    73 
    7488        case "liveSize":
    75             return Number.bytesToString(this._data.liveSize);
     89            return Number.bytesToString(value, higherResolution);
    7690        }
    7791
     
    89103    }
    90104
    91     updateTimestamp(zeroTime)
    92     {
    93         console.assert(isNaN(this._data.timestamp));
    94         this._data.timestamp = this._record.timestamp - zeroTime;
    95         this.needsRefresh();
    96     }
    97 
    98105    // Protected
    99106
     
    102109        super.createCells();
    103110
    104         if (this._record.heapSnapshot.invalid)
     111        if (this.heapSnapshot.invalid)
    105112            this.element.classList.add("invalid");
    106113    }
     
    108115    // Private
    109116
    110     _heapSnapshotCollectedNodes()
     117    _handleHeapSnapshotCollectedNodes()
    111118    {
    112         let oldSize = this._data.liveSize;
    113         let newSize = this._record.heapSnapshot.liveSize;
    114 
    115         console.assert(newSize <= oldSize);
    116         if (oldSize === newSize)
    117             return;
    118 
    119         this._data.liveSize = newSize;
    120119        this.needsRefresh();
    121120    }
    122121
    123     _heapSnapshotInvalidated()
     122    _handleHeapSnapshotInvalidated()
    124123    {
    125         this._data.liveSize = 0;
    126 
    127124        this.needsRefresh();
    128125    }
  • trunk/Source/WebInspectorUI/UserInterface/Views/HeapAllocationsTimelineView.js

    r243024 r243213  
    102102
    103103        this._pendingRecords = [];
    104         this._pendingZeroTimeDataGridNodes = [];
    105104
    106105        timeline.addEventListener(WI.Timeline.Event.RecordAdded, this._heapAllocationsTimelineRecordAdded, this);
     
    264263    layout()
    265264    {
    266         if (this._pendingZeroTimeDataGridNodes.length && this.zeroTime) {
    267             for (let dataGridNode of this._pendingZeroTimeDataGridNodes)
    268                 dataGridNode.updateTimestamp(this.zeroTime);
    269             this._pendingZeroTimeDataGridNodes = [];
    270             this._dataGrid._sort();
    271         }
    272 
    273         if (this._pendingRecords.length) {
     265        if (this._pendingRecords.length && this.zeroTime) {
    274266            for (let heapAllocationsTimelineRecord of this._pendingRecords) {
    275                 let dataGridNode = new WI.HeapAllocationsTimelineDataGridNode(heapAllocationsTimelineRecord, this.zeroTime, this);
    276                 this._dataGrid.addRowInSortOrder(dataGridNode);
    277                 if (!this.zeroTime)
    278                     this._pendingZeroTimeDataGridNodes.push(dataGridNode);
     267                this._dataGrid.addRowInSortOrder(new WI.HeapAllocationsTimelineDataGridNode(heapAllocationsTimelineRecord, {
     268                    graphDataSource: this,
     269                    heapAllocationsView: this,
     270                }));
    279271            }
    280272
     
    292284        this.showHeapSnapshotList();
    293285        this._pendingRecords = [];
    294         this._pendingZeroTimeDataGridNodes = [];
    295286        this._updateCompareHeapSnapshotButton();
    296287    }
  • trunk/Source/WebInspectorUI/UserInterface/Views/LayoutTimelineDataGridNode.js

    r238743 r243213  
    2626WI.LayoutTimelineDataGridNode = class LayoutTimelineDataGridNode extends WI.TimelineDataGridNode
    2727{
    28     constructor(layoutTimelineRecord, baseStartTime)
     28    constructor(record, options = {})
    2929    {
    30         super(false, null);
     30        console.assert(record instanceof WI.LayoutTimelineRecord);
    3131
    32         this._record = layoutTimelineRecord;
    33         this._baseStartTime = baseStartTime || 0;
     32        super([record], options);
    3433    }
    3534
    3635    // Public
    3736
    38     get records()
    39     {
    40         return [this._record];
    41     }
    42 
    4337    get data()
    4438    {
    45         if (!this._cachedData) {
    46             this._cachedData = {
    47                 type: this._record.eventType,
    48                 name: this.displayName(),
    49                 width: this._record.width,
    50                 height: this._record.height,
    51                 area: this._record.width * this._record.height,
    52                 startTime: this._record.startTime,
    53                 totalTime: this._record.duration,
    54                 location: this._record.initiatorCallFrame,
    55             };
    56         }
     39        if (this._cachedData)
     40            return this._cachedData;
    5741
     42        this._cachedData = super.data;
     43        this._cachedData.type = this.record.eventType;
     44        this._cachedData.name = this.displayName();
     45        this._cachedData.width = this.record.width;
     46        this._cachedData.height = this.record.height;
     47        this._cachedData.area = this.record.width * this.record.height;
     48        this._cachedData.startTime = this.record.startTime - (this.graphDataSource ? this.graphDataSource.zeroTime : 0);
     49        this._cachedData.totalTime = this.record.duration;
     50        this._cachedData.location = this.record.initiatorCallFrame;
    5851        return this._cachedData;
    5952    }
     
    6255    {
    6356        var value = this.data[columnIdentifier];
     57        const higherResolution = true;
    6458
    6559        switch (columnIdentifier) {
     
    7670
    7771        case "startTime":
    78             return isNaN(value) ? emDash : Number.secondsToString(value - this._baseStartTime, true);
     72            return isNaN(value) ? emDash : Number.secondsToString(value, higherResolution);
    7973
    8074        case "totalTime":
    81             return isNaN(value) ? emDash : Number.secondsToString(value, true);
     75            return isNaN(value) ? emDash : Number.secondsToString(value, higherResolution);
    8276        }
    8377
  • trunk/Source/WebInspectorUI/UserInterface/Views/LayoutTimelineView.js

    r243024 r243213  
    205205
    206206        for (var layoutTimelineRecord of this._pendingRecords) {
    207             let dataGridNode = new WI.LayoutTimelineDataGridNode(layoutTimelineRecord, this.zeroTime);
     207            let dataGridNode = new WI.LayoutTimelineDataGridNode(layoutTimelineRecord, {
     208                graphDataSource: this,
     209            });
    208210
    209211            this._dataGrid.addRowInSortOrder(dataGridNode);
     
    218220
    219221                let childRecord = entry.children[entry.index];
    220                 console.assert(childRecord.type === WI.TimelineRecord.Type.Layout, childRecord);
    221 
    222                 let childDataGridNode = new WI.LayoutTimelineDataGridNode(childRecord, this.zeroTime);
     222
     223                const options = {
     224                    graphDataSource: this,
     225                };
     226                let childDataGridNode = null;
     227                if (childRecord.type === WI.TimelineRecord.Type.Script)
     228                    childDataGridNode = new WI.ScriptTimelineDataGridNode(childRecord, options);
     229                else {
     230                    console.assert(childRecord.type === WI.TimelineRecord.Type.Layout, childRecord);
     231                    childDataGridNode = new WI.LayoutTimelineDataGridNode(childRecord, options);
     232                }
     233
    223234                console.assert(entry.parentDataGridNode, "Missing parent node for entry.", entry);
    224235                this._dataGrid.addRowInSortOrder(childDataGridNode, entry.parentDataGridNode);
     
    226237                if (childDataGridNode && childRecord.children.length)
    227238                    stack.push({children: childRecord.children, parentDataGridNode: childDataGridNode, index: 0});
     239
    228240                ++entry.index;
    229241            }
  • trunk/Source/WebInspectorUI/UserInterface/Views/MediaTimelineDataGridNode.js

    r238484 r243213  
    2626WI.MediaTimelineDataGridNode = class MediaTimelineDataGridNode extends WI.TimelineDataGridNode
    2727{
    28     constructor(record, graphDataSource)
     28    constructor(record, options = {})
    2929    {
    3030        console.assert(record instanceof WI.MediaTimelineRecord);
    3131
    32         const includesGraph = false;
    33         super(includesGraph, graphDataSource);
    34 
    35         this._records = [record];
     32        super([record], options);
    3633    }
    3734
    3835    // Public
    39 
    40     get records() { return this._records; }
    4136
    4237    get data()
  • trunk/Source/WebInspectorUI/UserInterface/Views/MediaTimelineView.js

    r243024 r243213  
    187187                this._dataGrid.setColumnVisible("originator", true);
    188188
    189             this._dataGrid.addRowInSortOrder(new WI.MediaTimelineDataGridNode(timelineRecord, this));
     189            this._dataGrid.addRowInSortOrder(new WI.MediaTimelineDataGridNode(timelineRecord, {
     190                graphDataSource: this,
     191            }));
    190192        }
    191193
  • trunk/Source/WebInspectorUI/UserInterface/Views/NetworkTimelineView.js

    r243024 r243213  
    258258                continue;
    259259
    260             const includesGraph = false;
    261             const shouldShowPopover = true;
    262             dataGridNode = new WI.ResourceTimelineDataGridNode(resourceTimelineRecord, includesGraph, this, shouldShowPopover);
     260            dataGridNode = new WI.ResourceTimelineDataGridNode(resourceTimelineRecord, {
     261                graphDataSource: this,
     262                shouldShowPopover: true,
     263            });
     264
    263265            this._resourceDataGridNodeMap.set(resourceTimelineRecord.resource, dataGridNode);
    264266
  • trunk/Source/WebInspectorUI/UserInterface/Views/OverviewTimelineView.js

    r243024 r243213  
    221221            resourceTimelineRecord = new WI.ResourceTimelineRecord(resource);
    222222
    223         const includesGraph = true;
    224         const shouldShowPopover = false;
    225         let resourceDataGridNode = new WI.ResourceTimelineDataGridNode(resourceTimelineRecord, includesGraph, this, shouldShowPopover);
     223        let resourceDataGridNode = new WI.ResourceTimelineDataGridNode(resourceTimelineRecord, {
     224            graphDataSource: this,
     225            includesGraph: true,
     226        });
    226227        this._resourceDataGridNodeMap.set(resource, resourceDataGridNode);
    227228
     
    254255    {
    255256        let parentDataGridNode = sourceCodeTimeline.sourceCodeLocation ? this._addResourceToDataGridIfNeeded(sourceCodeTimeline.sourceCode) : null;
    256         let sourceCodeTimelineDataGridNode = new WI.SourceCodeTimelineTimelineDataGridNode(sourceCodeTimeline, this);
     257        let sourceCodeTimelineDataGridNode = new WI.SourceCodeTimelineTimelineDataGridNode(sourceCodeTimeline, {
     258            graphDataSource: this,
     259        });
    257260        this._resourceDataGridNodeMap.set(sourceCodeTimeline, sourceCodeTimelineDataGridNode);
    258261
  • trunk/Source/WebInspectorUI/UserInterface/Views/ProfileNodeDataGridNode.js

    r220119 r243213  
    2626WI.ProfileNodeDataGridNode = class ProfileNodeDataGridNode extends WI.TimelineDataGridNode
    2727{
    28     constructor(profileNode, baseStartTime, rangeStartTime, rangeEndTime)
     28    constructor(profileNode, options = {})
    2929    {
    30         var hasChildren = !!profileNode.childNodes.length;
     30        console.assert(profileNode instanceof WI.ProfileNode);
    3131
    32         super(false, null, hasChildren);
     32        options.hasChildren = !!profileNode.childNodes.length;
     33
     34        super(null, options);
    3335
    3436        this._profileNode = profileNode;
    35         this._baseStartTime = baseStartTime || 0;
    36         this._rangeStartTime = rangeStartTime || 0;
    37         this._rangeEndTime = typeof rangeEndTime === "number" ? rangeEndTime : Infinity;
    38 
    39         this._cachedData = null;
    4037
    4138        this.addEventListener("populate", this._populate, this);
     
    4441    // Public
    4542
    46     get profileNode()
    47     {
    48         return this._profileNode;
    49     }
    50 
    51     get records()
    52     {
    53         return null;
    54     }
    55 
    56     get baseStartTime()
    57     {
    58         return this._baseStartTime;
    59     }
    60 
    61     get rangeStartTime()
    62     {
    63         return this._rangeStartTime;
    64     }
    65 
    66     get rangeEndTime()
    67     {
    68         return this._rangeEndTime;
    69     }
     43    get profileNode() { return this._profileNode; }
    7044
    7145    get data()
    7246    {
    73         if (!this._cachedData) {
    74             this._cachedData = this._profileNode.computeCallInfoForTimeRange(this._rangeStartTime, this._rangeEndTime);
    75             this._cachedData.name = this.displayName();
    76             this._cachedData.location = this._profileNode.sourceCodeLocation;
     47        if (this._cachedData)
     48            return this._cachedData;
     49
     50        let baseStartTime = 0;
     51        let rangeStartTime = 0;
     52        let rangeEndTime = Infinity;
     53        if (this.graphDataSource) {
     54            baseStartTime = this.graphDataSource.zeroTime;
     55            rangeStartTime = this.graphDataSource.startTime;
     56            rangeEndTime = this.graphDataSource.endTime;
    7757        }
     58
     59        let callInfo = this._profileNode.computeCallInfoForTimeRange(rangeStartTime, rangeEndTime);
     60
     61        this._cachedData = super.data;
     62        for (let key in callInfo)
     63            this._cachedData[key] = callInfo[key];
     64        this._cachedData.startTime -= baseStartTime;
     65        this._cachedData.name = this.displayName();
     66        this._cachedData.location = this._profileNode.sourceCodeLocation;
    7867
    7968        return this._cachedData;
    8069    }
    8170
    82     updateRangeTimes(startTime, endTime)
    83     {
    84         var oldRangeStartTime = this._rangeStartTime;
    85         var oldRangeEndTime = this._rangeEndTime;
    86 
    87         if (oldRangeStartTime === startTime && oldRangeEndTime === endTime)
    88             return;
    89 
    90         this._rangeStartTime = startTime;
    91         this._rangeEndTime = endTime;
    92 
    93         // We only need a refresh if the new range time changes the visible portion of this record.
    94         var profileStart = this._profileNode.startTime;
    95         var profileEnd = this._profileNode.endTime;
    96         var oldStartBoundary = Number.constrain(oldRangeStartTime, profileStart, profileEnd);
    97         var oldEndBoundary = Number.constrain(oldRangeEndTime, profileStart, profileEnd);
    98         var newStartBoundary = Number.constrain(startTime, profileStart, profileEnd);
    99         var newEndBoundary = Number.constrain(endTime, profileStart, profileEnd);
    100 
    101         if (oldStartBoundary !== newStartBoundary || oldEndBoundary !== newEndBoundary)
    102             this.needsRefresh();
    103     }
    104 
    105     refresh()
    106     {
    107         this._data = this._profileNode.computeCallInfoForTimeRange(this._rangeStartTime, this._rangeEndTime);
    108         this._data.location = this._profileNode.sourceCodeLocation;
    109 
    110         super.refresh();
    111     }
    112 
    11371    createCellContent(columnIdentifier, cell)
    11472    {
     73        const higherResolution = true;
     74
    11575        var value = this.data[columnIdentifier];
    11676
     
    12181
    12282        case "startTime":
    123             return isNaN(value) ? emDash : Number.secondsToString(value - this._baseStartTime, true);
    124 
    12583        case "selfTime":
    12684        case "totalTime":
    12785        case "averageTime":
    128             return isNaN(value) ? emDash : Number.secondsToString(value, true);
     86            return isNaN(value) ? emDash : Number.secondsToString(value, higherResolution);
    12987        }
    13088
     
    187145
    188146        for (let node of this._profileNode.childNodes)
    189             this.appendChild(new WI.ProfileNodeDataGridNode(node, this.baseStartTime, this.rangeStartTime, this.rangeEndTime));
     147            this.appendChild(new WI.ProfileNodeDataGridNode(node, {
     148                graphDataSource: this.graphDataSource,
     149            }));
    190150    }
    191151};
  • trunk/Source/WebInspectorUI/UserInterface/Views/RenderingFrameTimelineDataGridNode.js

    r220119 r243213  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2019 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2626WI.RenderingFrameTimelineDataGridNode = class RenderingFrameTimelineDataGridNode extends WI.TimelineDataGridNode
    2727{
    28     constructor(renderingFrameTimelineRecord, baseStartTime)
     28    constructor(record, options = {})
    2929    {
    30         super(false, null);
     30        console.assert(record instanceof WI.RenderingFrameTimelineRecord);
    3131
    32         this._record = renderingFrameTimelineRecord;
    33         this._baseStartTime = baseStartTime || 0;
     32        super([record], options);
    3433    }
    3534
    3635    // Public
    3736
    38     get records()
    39     {
    40         return [this._record];
    41     }
    42 
    4337    get data()
    4438    {
    45         if (!this._cachedData) {
    46             let name = WI.TimelineTabContentView.displayNameForRecord(this._record);
    47             let scriptTime = this._record.durationForTask(WI.RenderingFrameTimelineRecord.TaskType.Script);
    48             let layoutTime = this._record.durationForTask(WI.RenderingFrameTimelineRecord.TaskType.Layout);
    49             let paintTime = this._record.durationForTask(WI.RenderingFrameTimelineRecord.TaskType.Paint);
    50             let otherTime = this._record.durationForTask(WI.RenderingFrameTimelineRecord.TaskType.Other);
    51             this._cachedData = {
    52                 name,
    53                 startTime: this._record.startTime,
    54                 totalTime: this._record.duration,
    55                 scriptTime,
    56                 layoutTime,
    57                 paintTime,
    58                 otherTime,
    59             };
    60         }
     39        if (this._cachedData)
     40            return this._cachedData;
    6141
     42        this._cachedData = super.data;
     43        this._cachedData.name = WI.TimelineTabContentView.displayNameForRecord(this.record);
     44        this._cachedData.startTime = this.record.startTime - (this.graphDataSource ? this.graphDataSource.zeroTime : 0);
     45        this._cachedData.totalTime = this.record.duration;
     46        this._cachedData.scriptTime = this.record.durationForTask(WI.RenderingFrameTimelineRecord.TaskType.Script);
     47        this._cachedData.layoutTime = this.record.durationForTask(WI.RenderingFrameTimelineRecord.TaskType.Layout);
     48        this._cachedData.paintTime = this.record.durationForTask(WI.RenderingFrameTimelineRecord.TaskType.Paint);
     49        this._cachedData.otherTime = this.record.durationForTask(WI.RenderingFrameTimelineRecord.TaskType.Other);
    6250        return this._cachedData;
    6351    }
     
    6553    createCellContent(columnIdentifier, cell)
    6654    {
     55        const higherResolution = true;
     56
    6757        var value = this.data[columnIdentifier];
    6858
     
    7363
    7464        case "startTime":
    75             return isNaN(value) ? emDash : Number.secondsToString(value - this._baseStartTime, true);
     65            return isNaN(value) ? emDash : Number.secondsToString(value, higherResolution);
    7666
    7767        case "scriptTime":
     
    8070        case "otherTime":
    8171        case "totalTime":
    82             return (isNaN(value) || value === 0) ? emDash : Number.secondsToString(value, true);
     72            return (isNaN(value) || value === 0) ? emDash : Number.secondsToString(value, higherResolution);
    8373        }
    8474
  • trunk/Source/WebInspectorUI/UserInterface/Views/RenderingFrameTimelineView.js

    r243024 r243213  
    236236            console.assert(renderingFrameTimelineRecord instanceof WI.RenderingFrameTimelineRecord);
    237237
    238             let dataGridNode = new WI.RenderingFrameTimelineDataGridNode(renderingFrameTimelineRecord, this.zeroTime);
     238            let dataGridNode = new WI.RenderingFrameTimelineDataGridNode(renderingFrameTimelineRecord, {
     239                graphDataSource: this,
     240            });
    239241            this._dataGrid.addRowInSortOrder(dataGridNode);
    240242
     
    250252                let childDataGridNode = null;
    251253                if (childRecord.type === WI.TimelineRecord.Type.Layout) {
    252                     childDataGridNode = new WI.LayoutTimelineDataGridNode(childRecord, this.zeroTime);
     254                    childDataGridNode = new WI.LayoutTimelineDataGridNode(childRecord, {
     255                        graphDataSource: this,
     256                    });
    253257
    254258                    this._dataGrid.addRowInSortOrder(childDataGridNode, entry.parentDataGridNode);
     
    260264                    }
    261265
    262                     childDataGridNode = new WI.ScriptTimelineDataGridNode(childRecord, this.zeroTime);
     266                    childDataGridNode = new WI.ScriptTimelineDataGridNode(childRecord, {
     267                        graphDataSource: this,
     268                    });
    263269
    264270                    this._dataGrid.addRowInSortOrder(childDataGridNode, entry.parentDataGridNode);
    265271
    266272                    for (let profileNode of rootNodes) {
    267                         let profileNodeDataGridNode = new WI.ProfileNodeDataGridNode(profileNode, this.zeroTime, this.startTime, this.endTime);
     273                        let profileNodeDataGridNode = new WI.ProfileNodeDataGridNode(profileNode, {
     274                            graphDataSource: this,
     275                        });
    268276                        this._dataGrid.addRowInSortOrder(profileNodeDataGridNode, childDataGridNode);
    269277                    }
  • trunk/Source/WebInspectorUI/UserInterface/Views/ResourceTimelineDataGridNode.css

    r205578 r243213  
    3838
    3939.resource-timing-popover-content .data-grid td.graph-column {
    40     padding: 4px 0 0;
     40    padding: 4px 2px 0;
    4141}
    4242
  • trunk/Source/WebInspectorUI/UserInterface/Views/ResourceTimelineDataGridNode.js

    r238743 r243213  
    2626WI.ResourceTimelineDataGridNode = class ResourceTimelineDataGridNode extends WI.TimelineDataGridNode
    2727{
    28     constructor(resourceTimelineRecord, includesGraph, graphDataSource, shouldShowPopover)
    29     {
    30         super(includesGraph, graphDataSource);
    31 
    32         this._resource = resourceTimelineRecord.resource;
    33         this._record = resourceTimelineRecord;
    34         this._shouldShowPopover = shouldShowPopover;
    35 
    36         this._resource.addEventListener(WI.Resource.Event.LoadingDidFinish, this._needsRefresh, this);
    37         this._resource.addEventListener(WI.Resource.Event.LoadingDidFail, this._needsRefresh, this);
    38         this._resource.addEventListener(WI.Resource.Event.URLDidChange, this._needsRefresh, this);
    39 
    40         if (includesGraph)
    41             this._record.addEventListener(WI.TimelineRecord.Event.Updated, this._timelineRecordUpdated, this);
     28    constructor(record, options = {})
     29    {
     30        console.assert(record instanceof WI.ResourceTimelineRecord);
     31
     32        super([record], options);
     33
     34        this._shouldShowPopover = options.shouldShowPopover;
     35
     36        this.resource.addEventListener(WI.Resource.Event.LoadingDidFinish, this._needsRefresh, this);
     37        this.resource.addEventListener(WI.Resource.Event.LoadingDidFail, this._needsRefresh, this);
     38        this.resource.addEventListener(WI.Resource.Event.URLDidChange, this._needsRefresh, this);
     39
     40        if (options.includesGraph)
     41            this.record.addEventListener(WI.TimelineRecord.Event.Updated, this._timelineRecordUpdated, this);
    4242        else {
    43             this._resource.addEventListener(WI.Resource.Event.TypeDidChange, this._needsRefresh, this);
    44             this._resource.addEventListener(WI.Resource.Event.SizeDidChange, this._needsRefresh, this);
    45             this._resource.addEventListener(WI.Resource.Event.TransferSizeDidChange, this._needsRefresh, this);
     43            this.resource.addEventListener(WI.Resource.Event.TypeDidChange, this._needsRefresh, this);
     44            this.resource.addEventListener(WI.Resource.Event.SizeDidChange, this._needsRefresh, this);
     45            this.resource.addEventListener(WI.Resource.Event.TransferSizeDidChange, this._needsRefresh, this);
    4646        }
    4747    }
     
    4949    // Public
    5050
    51     get records()
    52     {
    53         return [this._record];
    54     }
    55 
    5651    get resource()
    5752    {
    58         return this._resource;
     53        return this.record.resource;
    5954    }
    6055
     
    6459            return this._cachedData;
    6560
    66         var resource = this._resource;
    67         var data = {};
    68 
    69         if (!this._includesGraph) {
    70             var zeroTime = this.graphDataSource ? this.graphDataSource.zeroTime : 0;
    71 
    72             data.domain = WI.displayNameForHost(resource.urlComponents.host);
    73             data.scheme = resource.urlComponents.scheme ? resource.urlComponents.scheme.toUpperCase() : "";
    74             data.method = resource.requestMethod;
    75             data.type = resource.type;
    76             data.statusCode = resource.statusCode;
    77             data.cached = resource.cached;
    78             data.size = resource.size;
    79             data.transferSize = !isNaN(resource.networkTotalTransferSize) ? resource.networkTotalTransferSize : resource.estimatedTotalTransferSize;
    80             data.requestSent = resource.requestSentTimestamp - zeroTime;
    81             data.duration = resource.receiveDuration;
    82             data.latency = resource.latency;
    83             data.protocol = resource.protocol;
    84             data.priority = resource.priority;
    85             data.remoteAddress = resource.remoteAddress;
    86             data.connectionIdentifier = resource.connectionIdentifier;
    87         }
    88 
    89         data.graph = this._record.startTime;
    90 
    91         this._cachedData = data;
    92         return data;
     61        this._cachedData = super.data;
     62        this._cachedData.domain = WI.displayNameForHost(this.resource.urlComponents.host);
     63        this._cachedData.scheme = this.resource.urlComponents.scheme ? this.resource.urlComponents.scheme.toUpperCase() : "";
     64        this._cachedData.method = this.resource.requestMethod;
     65        this._cachedData.type = this.resource.type;
     66        this._cachedData.statusCode = this.resource.statusCode;
     67        this._cachedData.cached = this.resource.cached;
     68        this._cachedData.size = this.resource.size;
     69        this._cachedData.transferSize = !isNaN(this.resource.networkTotalTransferSize) ? this.resource.networkTotalTransferSize : this.resource.estimatedTotalTransferSize;
     70        this._cachedData.requestSent = this.resource.requestSentTimestamp - (this.graphDataSource ? this.graphDataSource.zeroTime : 0);
     71        this._cachedData.duration = this.resource.receiveDuration;
     72        this._cachedData.latency = this.resource.latency;
     73        this._cachedData.protocol = this.resource.protocol;
     74        this._cachedData.priority = this.resource.priority;
     75        this._cachedData.remoteAddress = this.resource.remoteAddress;
     76        this._cachedData.connectionIdentifier = this.resource.connectionIdentifier;
     77        return this._cachedData;
    9378    }
    9479
    9580    createCellContent(columnIdentifier, cell)
    9681    {
    97         let resource = this._resource;
    98 
    99         if (resource.hadLoadingError())
     82        if (this.resource.hadLoadingError())
    10083            cell.classList.add("error");
    10184
     
    10588        case "name":
    10689            cell.classList.add(...this.iconClassNames());
    107             cell.title = resource.displayURL;
     90            cell.title = this.resource.displayURL;
    10891            this._updateStatus(cell);
    10992            return this._createNameCellDocumentFragment();
     
    11598
    11699        case "statusCode":
    117             cell.title = resource.statusText || "";
     100            cell.title = this.resource.statusText || "";
    118101            return value || emDash;
    119102
     
    181164    appendContextMenuItems(contextMenu)
    182165    {
    183         WI.appendContextMenuItemsForSourceCode(contextMenu, this._resource);
     166        WI.appendContextMenuItemsForSourceCode(contextMenu, this.resource);
    184167    }
    185168
     
    214197    {
    215198        if (columnIdentifier === "name")
    216             return this._resource.url;
     199            return this.resource.url;
    217200        return super.filterableDataForColumn(columnIdentifier);
    218201    }
     
    227210
    228211        // Show the host as the subtitle if it is different from the main resource or if this is the main frame's main resource.
    229         let frame = this._resource.parentFrame;
    230         let isMainResource = this._resource.isMainResource();
     212        let frame = this.resource.parentFrame;
     213        let isMainResource = this.resource.isMainResource();
    231214        let parentResourceHost;
    232215        if (frame && isMainResource) {
     
    238221        }
    239222
    240         if (parentResourceHost !== this._resource.urlComponents.host || frame.isMainFrame() && isMainResource) {
    241             let subtitle = WI.displayNameForHost(this._resource.urlComponents.host);
     223        if (parentResourceHost !== this.resource.urlComponents.host || frame.isMainFrame() && isMainResource) {
     224            let subtitle = WI.displayNameForHost(this.resource.urlComponents.host);
    242225            if (mainTitle !== subtitle) {
    243226                let subtitleElement = document.createElement("span");
     
    253236    _cachedCellContent()
    254237    {
    255         if (!this._resource.hasResponse())
     238        if (!this.resource.hasResponse())
    256239            return emDash;
    257240
    258         let responseSource = this._resource.responseSource;
     241        let responseSource = this.resource.responseSource;
    259242        if (responseSource === WI.Resource.ResponseSource.MemoryCache || responseSource === WI.Resource.ResponseSource.DiskCache) {
    260             console.assert(this._resource.cached, "This resource has a cache responseSource it should also be marked as cached", this._resource);
     243            console.assert(this.resource.cached, "This resource has a cache responseSource it should also be marked as cached", this.resource);
    261244            let span = document.createElement("span");
    262245            let cacheType = document.createElement("span");
     
    268251
    269252        let fragment = document.createDocumentFragment();
    270         fragment.append(this._resource.cached ? WI.UIString("Yes") : WI.UIString("No"));
     253        fragment.append(this.resource.cached ? WI.UIString("Yes") : WI.UIString("No"));
    271254        return fragment;
    272255    }
     
    287270    _timelineRecordUpdated(event)
    288271    {
    289         if (this.isRecordVisible(this._record))
     272        if (this.isRecordVisible(this.record))
    290273            this.needsGraphRefresh();
    291274    }
     
    297280            ignoreSearchTab: true,
    298281        };
    299         WI.showSourceCode(this._resource, options);
     282        WI.showSourceCode(this.resource, options);
    300283    }
    301284
    302285    _updateStatus(cell)
    303286    {
    304         if (this._resource.failed)
     287        if (this.resource.failed)
    305288            cell.classList.add("error");
    306289        else {
    307290            cell.classList.remove("error");
    308291
    309             if (this._resource.finished)
     292            if (this.resource.finished)
    310293                this.createGoToArrowButton(cell, this._dataGridNodeGoToArrowClicked.bind(this));
    311294        }
    312295
    313         if (this._resource.isLoading()) {
     296        if (this.resource.isLoading()) {
    314297            if (!this._spinner)
    315298                this._spinner = new WI.IndeterminateProgressSpinner;
     
    387370                get secondsPerPixel() { return resource.totalDuration / WI.ResourceTimelineDataGridNode.PopoverGraphColumnWidthPixels; },
    388371                get zeroTime() { return resource.firstTimestamp; },
    389                 get startTime() { return resource.firstTimestamp; },
    390                 get currentTime() { return this.endTime; },
    391 
    392                 get endTime()
    393                 {
    394                     let endTimePadding = this.secondsPerPixel * WI.TimelineRecordBar.MinimumWidthPixels;
    395                     return resource.lastTimestamp + endTimePadding;
    396                 }
     372                get startTime() { return this.zeroTime; },
     373                get currentTime() { return resource.lastTimestamp + this._extraTimePadding; },
     374                get endTime() { return this.currentTime; },
     375                get _extraTimePadding() { return this.secondsPerPixel * WI.TimelineRecordBar.MinimumWidthPixels; },
    397376            };
    398377
  • trunk/Source/WebInspectorUI/UserInterface/Views/ResourceTimingPopoverDataGridNode.js

    r220119 r243213  
    11/*
    2  * Copyright (C) 2016 Apple Inc. All rights reserved.
     2 * Copyright (C) 2019 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2828    constructor(description, startTime, endTime, graphDataSource)
    2929    {
    30         super(true, graphDataSource);
     30        let record = new WI.TimelineRecord(WI.TimelineRecord.Type.Network, startTime, endTime);
     31        super([record], {
     32            includesGraph: true,
     33            graphDataSource,
     34        });
    3135
    3236        const higherResolution = true;
     
    3438
    3539        this._data = {description, duration};
    36         this._record = new WI.TimelineRecord(WI.TimelineRecord.Type.Network, startTime, endTime);
    3740    }
    3841
    3942    // Public
    4043
    41     get records() { return [this._record]; }
    4244    get data() { return this._data; }
    43     get selectable() { return false; }
     45
     46    get selectable()
     47    {
     48        return false;
     49    }
    4450
    4551    // Protected
  • trunk/Source/WebInspectorUI/UserInterface/Views/ScriptDetailsTimelineView.js

    r243024 r243213  
    180180            let dataGridNode = this._dataGrid.children[0];
    181181            while (dataGridNode) {
    182                 dataGridNode.updateRangeTimes(this.startTime, this.endTime);
    183182                if (dataGridNode.revealed)
    184                     dataGridNode.refreshIfNeeded();
     183                    dataGridNode.refresh();
     184                else
     185                    dataGridNode.needsRefresh();
     186
    185187                dataGridNode = dataGridNode.traverseNextNode(false, null, true);
    186188            }
     
    202204        if (!this._pendingRecords.length)
    203205            return;
    204 
    205         let zeroTime = this.zeroTime;
    206         let startTime = this.startTime;
    207         let endTime = this.endTime;
    208206
    209207        for (let scriptTimelineRecord of this._pendingRecords) {
     
    214212            }
    215213
    216             let dataGridNode = new WI.ScriptTimelineDataGridNode(scriptTimelineRecord, zeroTime);
     214            let dataGridNode = new WI.ScriptTimelineDataGridNode(scriptTimelineRecord, {
     215                graphDataSource: this,
     216            });
    217217            this._dataGrid.addRowInSortOrder(dataGridNode);
    218218
    219219            for (let profileNode of rootNodes) {
    220                 let profileNodeDataGridNode = new WI.ProfileNodeDataGridNode(profileNode, zeroTime, startTime, endTime);
     220                let profileNodeDataGridNode = new WI.ProfileNodeDataGridNode(profileNode, {
     221                    graphDataSource: this,
     222                });
    221223                this._dataGrid.addRowInSortOrder(profileNodeDataGridNode, dataGridNode);
    222224            }
  • trunk/Source/WebInspectorUI/UserInterface/Views/ScriptTimelineDataGridNode.js

    r222064 r243213  
    11/*
    2  * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2019 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2626WI.ScriptTimelineDataGridNode = class ScriptTimelineDataGridNode extends WI.TimelineDataGridNode
    2727{
    28     constructor(scriptTimelineRecord, baseStartTime, rangeStartTime, rangeEndTime)
     28    constructor(record, options = {})
    2929    {
    30         super(false, null);
     30        console.assert(record instanceof WI.ScriptTimelineRecord);
    3131
    32         this._record = scriptTimelineRecord;
    33         this._baseStartTime = baseStartTime || 0;
    34         this._rangeStartTime = rangeStartTime || 0;
    35         this._rangeEndTime = typeof rangeEndTime === "number" ? rangeEndTime : Infinity;
     32        super([record], options);
    3633    }
    3734
    3835    // Public
    3936
    40     get records()
    41     {
    42         return [this._record];
    43     }
    44 
    45     get baseStartTime()
    46     {
    47         return this._baseStartTime;
    48     }
    49 
    50     get rangeStartTime()
    51     {
    52         return this._rangeStartTime;
    53     }
    54 
    55     get rangeEndTime()
    56     {
    57         return this._rangeEndTime;
    58     }
    59 
    6037    get data()
    6138    {
    62         if (!this._cachedData) {
    63             var startTime = this._record.startTime;
    64             var duration = this._record.startTime + this._record.duration - startTime;
    65             var callFrameOrSourceCodeLocation = this._record.initiatorCallFrame || this._record.sourceCodeLocation;
     39        if (this._cachedData)
     40            return this._cachedData;
    6641
    67             // COMPATIBILITY (iOS 8): Profiles included per-call information and can be finely partitioned.
    68             if (this._record.profile) {
    69                 var oneRootNode = this._record.profile.topDownRootNodes[0];
    70                 if (oneRootNode && oneRootNode.calls) {
    71                     startTime = Math.max(this._rangeStartTime, this._record.startTime);
    72                     duration = Math.min(this._record.startTime + this._record.duration, this._rangeEndTime) - startTime;
    73                 }
     42        let baseStartTime = 0;
     43        let rangeStartTime = 0;
     44        let rangeEndTime = Infinity;
     45        if (this.graphDataSource) {
     46            baseStartTime = this.graphDataSource.zeroTime;
     47            rangeStartTime = this.graphDataSource.startTime;
     48            rangeEndTime = this.graphDataSource.endTime;
     49        }
     50
     51        let startTime = this.record.startTime;
     52        let duration = this.record.startTime + this.record.duration - startTime;
     53
     54        // COMPATIBILITY (iOS 8): Profiles included per-call information and can be finely partitioned.
     55        if (this.record.profile) {
     56            let oneRootNode = this.record.profile.topDownRootNodes[0];
     57            if (oneRootNode && oneRootNode.calls) {
     58                startTime = Math.max(rangeStartTime, this.record.startTime);
     59                duration = Math.min(this.record.startTime + this.record.duration, rangeEndTime) - startTime;
    7460            }
     61        }
    7562
    76             this._cachedData = {
    77                 eventType: this._record.eventType,
    78                 startTime,
    79                 selfTime: duration,
    80                 totalTime: duration,
    81                 averageTime: duration,
    82                 callCount: this._record.callCountOrSamples,
    83                 location: callFrameOrSourceCodeLocation,
    84             };
    85         }
     63        this._cachedData = super.data;
     64        this._cachedData.type = this.record.eventType;
     65        this._cachedData.name = this.displayName();
     66        this._cachedData.startTime = startTime - baseStartTime;
     67        this._cachedData.selfTime = duration;
     68        this._cachedData.totalTime = duration;
     69        this._cachedData.averageTime = duration;
     70        this._cachedData.callCount = this.record.callCountOrSamples;
     71        this._cachedData.location = this.record.initiatorCallFrame || this.record.sourceCodeLocation;
    8672
    8773        return this._cachedData;
     
    9581        this._subtitle = "";
    9682
    97         if (this._record.eventType === WI.ScriptTimelineRecord.EventType.TimerInstalled) {
    98             let timeoutString = Number.secondsToString(this._record.details.timeout / 1000);
    99             if (this._record.details.repeating)
     83        if (this.record.eventType === WI.ScriptTimelineRecord.EventType.TimerInstalled) {
     84            let timeoutString = Number.secondsToString(this.record.details.timeout / 1000);
     85            if (this.record.details.repeating)
    10086                this._subtitle = WI.UIString("%s interval").format(timeoutString);
    10187            else
     
    10692    }
    10793
    108     updateRangeTimes(startTime, endTime)
    109     {
    110         var oldRangeStartTime = this._rangeStartTime;
    111         var oldRangeEndTime = this._rangeEndTime;
    112 
    113         if (oldRangeStartTime === startTime && oldRangeEndTime === endTime)
    114             return;
    115 
    116         this._rangeStartTime = startTime;
    117         this._rangeEndTime = endTime;
    118 
    119         // If we have no duration the range does not matter.
    120         if (!this._record.duration)
    121             return;
    122 
    123         // We only need a refresh if the new range time changes the visible portion of this record.
    124         var recordStart = this._record.startTime;
    125         var recordEnd = this._record.startTime + this._record.duration;
    126         var oldStartBoundary = Number.constrain(oldRangeStartTime, recordStart, recordEnd);
    127         var oldEndBoundary = Number.constrain(oldRangeEndTime, recordStart, recordEnd);
    128         var newStartBoundary = Number.constrain(startTime, recordStart, recordEnd);
    129         var newEndBoundary = Number.constrain(endTime, recordStart, recordEnd);
    130 
    131         if (oldStartBoundary !== newStartBoundary || oldEndBoundary !== newEndBoundary)
    132             this.needsRefresh();
    133     }
    134 
    13594    createCellContent(columnIdentifier, cell)
    13695    {
     96        const higherResolution = true;
     97
    13798        var value = this.data[columnIdentifier];
    13899
     
    143104
    144105        case "startTime":
    145             return isNaN(value) ? emDash : Number.secondsToString(value - this._baseStartTime, true);
    146 
    147106        case "selfTime":
    148107        case "totalTime":
    149108        case "averageTime":
    150             return isNaN(value) ? emDash : Number.secondsToString(value, true);
     109            return isNaN(value) ? emDash : Number.secondsToString(value, higherResolution);
    151110
    152111        case "callCount":
    153112            return isNaN(value) ? emDash : value.toLocaleString();
     113
     114        // Necessary to be displayed in WI.LayoutTimelineView.
     115        case "width":
     116        case "height":
     117        case "area":
     118            return zeroWidthSpace;
    154119        }
    155120
  • trunk/Source/WebInspectorUI/UserInterface/Views/SourceCodeTimelineTimelineDataGridNode.js

    r220119 r243213  
    2626WI.SourceCodeTimelineTimelineDataGridNode = class SourceCodeTimelineTimelineDataGridNode extends WI.TimelineDataGridNode
    2727{
    28     constructor(sourceCodeTimeline, graphDataSource)
     28    constructor(sourceCodeTimeline, options = {})
    2929    {
    30         super(true, graphDataSource);
     30        const records = [];
     31        super(records, {includesGraph: true, ...options});
    3132
    3233        this._sourceCodeTimeline = sourceCodeTimeline;
     
    4849    get data()
    4950    {
    50         return {graph: this._sourceCodeTimeline.startTime};
     51        if (this._cachedData)
     52            return this._cachedData;
     53
     54        this._cachedData = super.data;
     55        this._cachedData.graph = this._sourceCodeTimeline.startTime;
     56        return this._cachedData;
    5157    }
    5258
  • trunk/Source/WebInspectorUI/UserInterface/Views/TimelineDataGridNode.js

    r237195 r243213  
    2626WI.TimelineDataGridNode = class TimelineDataGridNode extends WI.DataGridNode
    2727{
    28     constructor(includesGraph, graphDataSource, hasChildren)
    29     {
    30         super({}, hasChildren);
     28    constructor(records, options = {})
     29    {
     30        super({}, options.hasChildren);
    3131
    3232        this.copyable = false;
    3333
    34         this._includesGraph = includesGraph || false;
    35         this._graphDataSource = graphDataSource || null;
    36 
    37         if (graphDataSource) {
     34        this._records = records;
     35        this._includesGraph = options.includesGraph || false;
     36        this._graphDataSource = options.graphDataSource || null;
     37        this._cachedData = null;
     38
     39        if (this._graphDataSource) {
    3840            this._graphContainerElement = document.createElement("div");
    3941            this._timelineRecordBars = [];
     
    4345    // Public
    4446
     47    get records() { return this._records; }
     48
    4549    get record()
    4650    {
    4751        return this.records && this.records.length ? this.records[0] : null;
    48     }
    49 
    50     get records()
    51     {
    52         // Implemented by subclasses.
    53         return [];
    5452    }
    5553
     
    6462            return {};
    6563
    66         var records = this.records || [];
    67         return {graph: records.length ? records[0].startTime : 0};
     64        return {
     65            graph: this.record ? this.record.startTime : 0,
     66        };
    6867    }
    6968
     
    208207    refresh()
    209208    {
     209        this._cachedData = null;
     210
    210211        if (this._graphDataSource && this._includesGraph)
    211212            this.needsGraphRefresh();
Note: See TracChangeset for help on using the changeset viewer.