Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(59)

Side by Side Diff: Source/devtools/front_end/components_lazy/FilmStripView.js

Issue 1183483011: DevTools: Support popover on timeline overview. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Addressing comments. Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 /** 5 /**
6 * @constructor 6 * @constructor
7 * @extends {WebInspector.HBox} 7 * @extends {WebInspector.HBox}
8 */ 8 */
9 WebInspector.FilmStripView = function() 9 WebInspector.FilmStripView = function()
10 { 10 {
11 WebInspector.HBox.call(this, true); 11 WebInspector.HBox.call(this, true);
12 this.registerRequiredCSS("components_lazy/filmStripView.css"); 12 this.registerRequiredCSS("components_lazy/filmStripView.css");
13 this.contentElement.classList.add("film-strip-view"); 13 this.contentElement.classList.add("film-strip-view");
14 this._mode = WebInspector.FilmStripView.Modes.TimeBased;
15 this.reset(); 14 this.reset();
15 this.setMode(WebInspector.FilmStripView.Modes.TimeBased);
16 } 16 }
17 17
18 WebInspector.FilmStripView.Events = { 18 WebInspector.FilmStripView.Events = {
19 FrameSelected: "FrameSelected", 19 FrameSelected: "FrameSelected",
20 FrameEnter: "FrameEnter", 20 FrameEnter: "FrameEnter",
21 FrameExit: "FrameExit", 21 FrameExit: "FrameExit",
22 } 22 }
23 23
24 WebInspector.FilmStripView.Modes = { 24 WebInspector.FilmStripView.Modes = {
25 TimeBased: "TimeBased", 25 TimeBased: "TimeBased",
26 FrameBased: "FrameBased" 26 FrameBased: "FrameBased"
27 } 27 }
28 28
29 WebInspector.FilmStripView.prototype = { 29 WebInspector.FilmStripView.prototype = {
30 /** 30 /**
31 * @param {string} mode 31 * @param {string} mode
32 */ 32 */
33 setMode: function(mode) 33 setMode: function(mode)
34 { 34 {
35 this._mode = mode; 35 this._mode = mode;
36 this.contentElement.classList.toggle("time-based", mode === WebInspector .FilmStripView.Modes.TimeBased);
36 this.update(); 37 this.update();
37 }, 38 },
38 39
39 /** 40 /**
40 * @param {!WebInspector.FilmStripModel} filmStripModel 41 * @param {!WebInspector.FilmStripModel} filmStripModel
41 * @param {number} zeroTime 42 * @param {number} zeroTime
42 * @param {number} spanTime 43 * @param {number} spanTime
43 */ 44 */
44 setModel: function(filmStripModel, zeroTime, spanTime) 45 setModel: function(filmStripModel, zeroTime, spanTime)
45 { 46 {
46 this._model = filmStripModel; 47 this._model = filmStripModel;
47 this._zeroTime = zeroTime; 48 this._zeroTime = zeroTime;
48 this._spanTime = spanTime; 49 this._spanTime = spanTime;
49 var frames = filmStripModel.frames(); 50 var frames = filmStripModel.frames();
50 if (!frames.length) { 51 if (!frames.length) {
51 this.reset(); 52 this.reset();
52 return; 53 return;
53 } 54 }
54 this.update(); 55 this.update();
55 }, 56 },
56 57
57 update: function() 58 /**
59 * @param {number} index
60 * @return {!Element}
61 */
62 frameElementByIndex: function(index)
58 { 63 {
59 if (!this._model) 64 var element = this._elementsCache[index];
60 return; 65 if (!element) {
61 var frames = this._model.frames(); 66 var frame = this._model.frames()[index];
62 if (!frames.length) 67 var time = frame.timestamp;
63 return; 68 element = createElementWithClass("div", "frame");
64 this.contentElement.removeChildren(); 69 element.createChild("div", "thumbnail").createChild("img").src = "da ta:image/jpg;base64," + frame.imageData;
65 this._label.remove(); 70 element.createChild("div", "time").textContent = Number.millisToStri ng(time - this._zeroTime);
66 var zeroTime = this._zeroTime; 71 this._elementsCache[index] = element;
72 }
73 return element;
74 },
67 75
68 /** 76 /**
69 * @param {!WebInspector.FilmStripModel.Frame} frame 77 * @param {number} index
70 * @param {boolean=} skipTimeLabel 78 * @return {!Element}
71 * @return {!Element} 79 */
72 * @this {WebInspector.FilmStripView} 80 frameElementCloneByIndex: function(index)
73 */ 81 {
74 function createElementForFrame(frame, skipTimeLabel) 82 var element = this.frameElementByIndex(index).cloneNode(true);
75 { 83 var frame = this._model.frames()[index];
76 var time = frame.timestamp; 84 var time = frame.timestamp;
77 var element = createElementWithClass("div", "frame"); 85 element.addEventListener("mousedown", this._onMouseEvent.bind(this, WebI nspector.FilmStripView.Events.FrameSelected, time), false);
78 element.createChild("div", "thumbnail").createChild("img").src = "da ta:image/jpg;base64," + frame.imageData; 86 element.addEventListener("mouseenter", this._onMouseEvent.bind(this, Web Inspector.FilmStripView.Events.FrameEnter, time), false);
79 if (!skipTimeLabel) 87 element.addEventListener("mouseout", this._onMouseEvent.bind(this, WebIn spector.FilmStripView.Events.FrameExit, time), false);
80 element.createChild("div", "time").textContent = Number.millisTo String(time - zeroTime); 88 element.addEventListener("dblclick", this._onDoubleClick.bind(this, fram e), false);
81 element.addEventListener("mousedown", this._onMouseEvent.bind(this, WebInspector.FilmStripView.Events.FrameSelected, time), false); 89 return element;
82 element.addEventListener("mouseenter", this._onMouseEvent.bind(this, WebInspector.FilmStripView.Events.FrameEnter, time), false); 90 },
83 element.addEventListener("mouseout", this._onMouseEvent.bind(this, W ebInspector.FilmStripView.Events.FrameExit, time), false);
84 element.addEventListener("dblclick", this._onDoubleClick.bind(this, frame), false);
85 this.contentElement.appendChild(element);
86 return element;
87 }
88 91
89 if (this._mode === WebInspector.FilmStripView.Modes.FrameBased) { 92 /**
90 for (var frame of frames) 93 * @param {number} time
91 createElementForFrame.call(this, frame); 94 * @return {number}
92 return; 95 */
93 } 96 frameIndexByTime: function(time)
94 97 {
95 /**
96 * @return {!Element}
97 * @this {WebInspector.FilmStripView}
98 */
99 function createEmptyElement()
100 {
101 var element = createElementWithClass("div", "frame");
102 this.contentElement.appendChild(element);
103 return element;
104 }
105
106 /** 98 /**
107 * @param {number} time 99 * @param {number} time
108 * @param {!WebInspector.FilmStripModel.Frame} frame 100 * @param {!WebInspector.FilmStripModel.Frame} frame
109 * @return {number} 101 * @return {number}
110 */ 102 */
111 function comparator(time, frame) 103 function comparator(time, frame)
112 { 104 {
113 return time - frame.timestamp; 105 return time - frame.timestamp;
114 } 106 }
107 // Using the first frame to fill the interval between recording start
108 // and a moment the frame is taken.
109 return Math.max(this._model.frames().upperBound(time, comparator) - 1, 0 );
110 },
111
112 update: function()
113 {
114 if (!this._model)
115 return;
116 var frames = this._model.frames();
117 if (!frames.length)
118 return;
119 this.contentElement.removeChildren();
120 this._statusLabel.remove();
121
122 if (this._mode === WebInspector.FilmStripView.Modes.FrameBased) {
123 for (var i = 0; i < frames.length; ++i)
124 this.contentElement.appendChild(this.frameElementCloneByIndex(i) );
125 return;
126 }
115 127
116 var width = this.contentElement.clientWidth; 128 var width = this.contentElement.clientWidth;
117 var scale = this._spanTime / width; 129 var scale = this._spanTime / width;
118 130 var element0 = this.frameElementByIndex(0); // Calculate frame width ba sing on the first frame.
119 // Calculate frame width basing on the first frame. 131 var frameWidth = Math.ceil(WebInspector.measurePreferredSize(element0, t his.contentElement).width);
120 var tempElement = createElementWithClass("div", "frame");
121 tempElement.createChild("div", "thumbnail").createChild("img").src = "da ta:image/jpg;base64," + frames[0].imageData;
122 var frameWidth = Math.ceil(WebInspector.measurePreferredSize(tempElement , this.contentElement).width);
123 if (!frameWidth) 132 if (!frameWidth)
124 return; 133 return;
125 134
126 for (var pos = frameWidth; pos < width; pos += frameWidth) { 135 for (var pos = frameWidth; pos < width; pos += frameWidth) {
127 var time = pos * scale + zeroTime; 136 var time = pos * scale + this._zeroTime;
128 var index = frames.upperBound(time, comparator) - 1; 137 var index = this.frameIndexByTime(time);
129 var element = index >= 0 ? createElementForFrame.call(this, frames[i ndex], true) : createEmptyElement.call(this); 138 var element = this.contentElement.appendChild(this.frameElementClone ByIndex(index));
130 element.style.width = frameWidth + "px"; 139 element.style.width = frameWidth + "px";
131 } 140 }
132 }, 141 },
133 142
134 /** 143 /**
135 * @override 144 * @override
136 */ 145 */
137 onResize: function() 146 onResize: function()
138 { 147 {
139 if (this._mode === WebInspector.FilmStripView.Modes.FrameBased) 148 if (this._mode === WebInspector.FilmStripView.Modes.FrameBased)
(...skipping 14 matching lines...) Expand all
154 * @param {!WebInspector.FilmStripModel.Frame} filmStripFrame 163 * @param {!WebInspector.FilmStripModel.Frame} filmStripFrame
155 */ 164 */
156 _onDoubleClick: function(filmStripFrame) 165 _onDoubleClick: function(filmStripFrame)
157 { 166 {
158 WebInspector.Dialog.show(null, new WebInspector.FilmStripView.DialogDele gate(filmStripFrame, this._zeroTime)); 167 WebInspector.Dialog.show(null, new WebInspector.FilmStripView.DialogDele gate(filmStripFrame, this._zeroTime));
159 }, 168 },
160 169
161 reset: function() 170 reset: function()
162 { 171 {
163 this._zeroTime = 0; 172 this._zeroTime = 0;
173 this._elementsCache = [];
164 this.contentElement.removeChildren(); 174 this.contentElement.removeChildren();
165 this._label = this.contentElement.createChild("div", "label"); 175 this._statusLabel = this.contentElement.createChild("div", "label");
166 this._label.textContent = WebInspector.UIString("No frames recorded. Rel oad page to start recording."); 176 this._statusLabel.textContent = WebInspector.UIString("No frames recorde d. Reload page to start recording.");
167 }, 177 },
168 178
169 setRecording: function() 179 setRecording: function()
170 { 180 {
171 this.reset(); 181 this.reset();
172 this._label.textContent = WebInspector.UIString("Recording frames..."); 182 this._statusLabel.textContent = WebInspector.UIString("Recording frames. ..");
173 }, 183 },
174 184
175 setFetching: function() 185 setFetching: function()
176 { 186 {
177 this._label.textContent = WebInspector.UIString("Fetching frames..."); 187 this._statusLabel.textContent = WebInspector.UIString("Fetching frames.. .");
178 }, 188 },
179 189
180 __proto__: WebInspector.HBox.prototype 190 __proto__: WebInspector.HBox.prototype
181 } 191 }
182 192
183 /** 193 /**
184 * @constructor 194 * @constructor
185 * @extends {WebInspector.DialogDelegate} 195 * @extends {WebInspector.DialogDelegate}
186 * @param {!WebInspector.FilmStripModel.Frame} filmStripFrame 196 * @param {!WebInspector.FilmStripModel.Frame} filmStripFrame
187 * @param {number=} zeroTime 197 * @param {number=} zeroTime
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 289
280 _render: function() 290 _render: function()
281 { 291 {
282 var frame = this._frames[this._index]; 292 var frame = this._frames[this._index];
283 this._imageElement.src = "data:image/jpg;base64," + frame.imageData; 293 this._imageElement.src = "data:image/jpg;base64," + frame.imageData;
284 this._timeLabel.textContent = Number.millisToString(frame.timestamp - th is._zeroTime); 294 this._timeLabel.textContent = Number.millisToString(frame.timestamp - th is._zeroTime);
285 }, 295 },
286 296
287 __proto__: WebInspector.DialogDelegate.prototype 297 __proto__: WebInspector.DialogDelegate.prototype
288 } 298 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698