[Flatpak SDK] Update ccls
[WebKit-https.git] / Source / WebInspectorUI / UserInterface / Views / HeapAllocationsTimelineOverviewGraph.js
1 /*
2  * Copyright (C) 2016 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 WI.HeapAllocationsTimelineOverviewGraph = class HeapAllocationsTimelineOverviewGraph extends WI.TimelineOverviewGraph
27 {
28     constructor(timeline, timelineOverview)
29     {
30         super(timelineOverview);
31
32         this.element.classList.add("heap-allocations");
33
34         this._heapAllocationsTimeline = timeline;
35         this._heapAllocationsTimeline.addEventListener(WI.Timeline.Event.RecordAdded, this._heapAllocationTimelineRecordAdded, this);
36
37         this._selectedImageElement = null;
38
39         this.reset();
40     }
41
42     // Protected
43
44     reset()
45     {
46         super.reset();
47
48         this.element.removeChildren();
49     }
50
51     layout()
52     {
53         super.layout();
54
55         if (this.hidden)
56             return;
57
58         this.element.removeChildren();
59
60         if (this._selectedImageElement) {
61             this._selectedImageElement.classList.remove("selected");
62             this._selectedImageElement = null;
63         }
64
65         // This may display records past the current time marker.
66         let visibleRecords = this._heapAllocationsTimeline.recordsInTimeRange(this.startTime, this.endTime);
67         if (!visibleRecords.length)
68             return;
69
70         let graphStartTime = this.startTime;
71         let secondsPerPixel = this.timelineOverview.secondsPerPixel;
72
73         function xScale(time) {
74             return (time - graphStartTime) / secondsPerPixel;
75         }
76
77         for (let record of visibleRecords) {
78             if (isNaN(record.timestamp))
79                 continue;
80
81             const halfImageWidth = 8;
82             let x = xScale(record.timestamp) - halfImageWidth;
83             if (x <= 1)
84                 x = 1;
85
86             let imageElement = record[WI.HeapAllocationsTimelineOverviewGraph.RecordElementAssociationSymbol];
87             if (!imageElement) {
88                 imageElement = record[WI.HeapAllocationsTimelineOverviewGraph.RecordElementAssociationSymbol] = document.createElement("img");
89                 imageElement.classList.add("snapshot");
90                 imageElement.addEventListener("click", (event) => {
91                     if (record.heapSnapshot.invalid)
92                         return;
93
94                     // Ensure that the container "click" listener added by `WI.TimelineOverview` isn't called.
95                     event.__timelineRecordClickEventHandled = true;
96
97                     this.selectedRecord = record;
98                 });
99             }
100
101             imageElement.style.setProperty(WI.resolvedLayoutDirection() === WI.LayoutDirection.RTL ? "right" : "left", `${x}px`);
102
103             if (record.heapSnapshot.invalid)
104                 imageElement.classList.add("invalid");
105
106             this.element.appendChild(imageElement);
107         }
108
109         this._updateSnapshotMarkers();
110     }
111
112     updateSelectedRecord()
113     {
114         this._updateSnapshotMarkers();
115     }
116
117     // Private
118
119     _updateSnapshotMarkers()
120     {
121         if (this._selectedImageElement)
122             this._selectedImageElement.classList.remove("selected");
123
124         if (!this.selectedRecord) {
125             this._selectedImageElement = null;
126             return;
127         }
128
129         let imageElement = this.selectedRecord[WI.HeapAllocationsTimelineOverviewGraph.RecordElementAssociationSymbol];
130         if (!imageElement)
131             return;
132
133         imageElement.classList.add("selected");
134
135         this._selectedImageElement = imageElement;
136     }
137
138     _heapAllocationTimelineRecordAdded(event)
139     {
140         this.needsLayout();
141     }
142 };
143
144 WI.HeapAllocationsTimelineOverviewGraph.RecordElementAssociationSymbol = Symbol("record-element-association");