16af821da68d37e302c76f311bf76072f67dabec
[WebKit-https.git] / Source / WebInspectorUI / UserInterface / Views / ScriptTimelineDataGridNode.js
1 /*
2  * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 WebInspector.ScriptTimelineDataGridNode = class ScriptTimelineDataGridNode extends WebInspector.TimelineDataGridNode
27 {
28     constructor(scriptTimelineRecord, baseStartTime, rangeStartTime, rangeEndTime)
29     {
30         super(false, null);
31
32         this._record = scriptTimelineRecord;
33         this._baseStartTime = baseStartTime || 0;
34         this._rangeStartTime = rangeStartTime || 0;
35         this._rangeEndTime = typeof rangeEndTime === "number" ? rangeEndTime : Infinity;
36     }
37
38     // Public
39
40     get record()
41     {
42         return this._record;
43     }
44
45     get records()
46     {
47         return [this._record];
48     }
49
50     get baseStartTime()
51     {
52         return this._baseStartTime;
53     }
54
55     get rangeStartTime()
56     {
57         return this._rangeStartTime;
58     }
59
60     get rangeEndTime()
61     {
62         return this._rangeEndTime;
63     }
64
65     get data()
66     {
67         var startTime = this._record.startTime;
68         var duration = this._record.startTime + this._record.duration - startTime;
69         var callFrameOrSourceCodeLocation = this._record.initiatorCallFrame || this._record.sourceCodeLocation;
70
71         // COMPATIBILITY (iOS 8): Profiles included per-call information and can be finely partitioned.
72         if (this._record.profile) {
73             var oneRootNode = this._record.profile.topDownRootNodes[0];
74             if (oneRootNode && oneRootNode.calls) {
75                 startTime = Math.max(this._rangeStartTime, this._record.startTime);
76                 duration = Math.min(this._record.startTime + this._record.duration, this._rangeEndTime) - startTime;
77             }
78         }
79
80         return {
81             eventType: this._record.eventType,
82             startTime,
83             selfTime: duration,
84             totalTime: duration,
85             averageTime: duration,
86             callCount: NaN,
87             location: callFrameOrSourceCodeLocation
88         };
89     }
90
91     updateRangeTimes(startTime, endTime)
92     {
93         var oldRangeStartTime = this._rangeStartTime;
94         var oldRangeEndTime = this._rangeEndTime;
95
96         if (oldRangeStartTime === startTime && oldRangeEndTime === endTime)
97             return;
98
99         this._rangeStartTime = startTime;
100         this._rangeEndTime = endTime;
101
102         // If we have no duration the range does not matter.
103         if (!this._record.duration)
104             return;
105
106         // We only need a refresh if the new range time changes the visible portion of this record.
107         var recordStart = this._record.startTime;
108         var recordEnd = this._record.startTime + this._record.duration;
109         var oldStartBoundary = Number.constrain(oldRangeStartTime, recordStart, recordEnd);
110         var oldEndBoundary = Number.constrain(oldRangeEndTime, recordStart, recordEnd);
111         var newStartBoundary = Number.constrain(startTime, recordStart, recordEnd);
112         var newEndBoundary = Number.constrain(endTime, recordStart, recordEnd);
113
114         if (oldStartBoundary !== newStartBoundary || oldEndBoundary !== newEndBoundary)
115             this.needsRefresh();
116     }
117
118     createCellContent(columnIdentifier, cell)
119     {
120         const emptyValuePlaceholderString = "\u2014";
121         var value = this.data[columnIdentifier];
122
123         switch (columnIdentifier) {
124         case "eventType":
125             return WebInspector.ScriptTimelineRecord.EventType.displayName(value, this._record.details);
126
127         case "startTime":
128             return isNaN(value) ? emptyValuePlaceholderString : Number.secondsToString(value - this._baseStartTime, true);
129
130         case "selfTime":
131         case "totalTime":
132         case "averageTime":
133             return isNaN(value) ? emptyValuePlaceholderString : Number.secondsToString(value, true);
134
135         case "callCount":
136             return isNaN(value) ? emptyValuePlaceholderString : value;
137         }
138
139         return super.createCellContent(columnIdentifier, cell);
140     }
141 };