| OLD | NEW |
| 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 |
| 58 /** |
| 59 * @param {!WebInspector.FilmStripModel.Frame} frame |
| 60 * @return {!Element} |
| 61 */ |
| 62 createFrameElement: function(frame) |
| 63 { |
| 64 var time = frame.timestamp; |
| 65 var element = createElementWithClass("div", "frame"); |
| 66 element.createChild("div", "thumbnail").createChild("img").src = "data:i
mage/jpg;base64," + frame.imageData; |
| 67 element.createChild("div", "time").textContent = Number.millisToString(t
ime - this._zeroTime); |
| 68 element.addEventListener("mousedown", this._onMouseEvent.bind(this, WebI
nspector.FilmStripView.Events.FrameSelected, time), false); |
| 69 element.addEventListener("mouseenter", this._onMouseEvent.bind(this, Web
Inspector.FilmStripView.Events.FrameEnter, time), false); |
| 70 element.addEventListener("mouseout", this._onMouseEvent.bind(this, WebIn
spector.FilmStripView.Events.FrameExit, time), false); |
| 71 element.addEventListener("dblclick", this._onDoubleClick.bind(this, fram
e), false); |
| 72 return element; |
| 73 }, |
| 74 |
| 75 /** |
| 76 * @param {number} time |
| 77 * @return {!WebInspector.FilmStripModel.Frame} |
| 78 */ |
| 79 frameByTime: function(time) |
| 80 { |
| 81 /** |
| 82 * @param {number} time |
| 83 * @param {!WebInspector.FilmStripModel.Frame} frame |
| 84 * @return {number} |
| 85 */ |
| 86 function comparator(time, frame) |
| 87 { |
| 88 return time - frame.timestamp; |
| 89 } |
| 90 // Using the first frame to fill the interval between recording start |
| 91 // and a moment the frame is taken. |
| 92 var frames = this._model.frames(); |
| 93 var index = Math.max(frames.upperBound(time, comparator) - 1, 0); |
| 94 return frames[index]; |
| 95 }, |
| 96 |
| 57 update: function() | 97 update: function() |
| 58 { | 98 { |
| 59 if (!this._model) | 99 if (!this._model) |
| 60 return; | 100 return; |
| 61 var frames = this._model.frames(); | 101 var frames = this._model.frames(); |
| 62 if (!frames.length) | 102 if (!frames.length) |
| 63 return; | 103 return; |
| 64 this.contentElement.removeChildren(); | 104 this.contentElement.removeChildren(); |
| 65 this._label.remove(); | 105 this._statusLabel.remove(); |
| 66 var zeroTime = this._zeroTime; | |
| 67 | |
| 68 /** | |
| 69 * @param {!WebInspector.FilmStripModel.Frame} frame | |
| 70 * @param {boolean=} skipTimeLabel | |
| 71 * @return {!Element} | |
| 72 * @this {WebInspector.FilmStripView} | |
| 73 */ | |
| 74 function createElementForFrame(frame, skipTimeLabel) | |
| 75 { | |
| 76 var time = frame.timestamp; | |
| 77 var element = createElementWithClass("div", "frame"); | |
| 78 element.createChild("div", "thumbnail").createChild("img").src = "da
ta:image/jpg;base64," + frame.imageData; | |
| 79 if (!skipTimeLabel) | |
| 80 element.createChild("div", "time").textContent = Number.millisTo
String(time - zeroTime); | |
| 81 element.addEventListener("mousedown", this._onMouseEvent.bind(this,
WebInspector.FilmStripView.Events.FrameSelected, time), false); | |
| 82 element.addEventListener("mouseenter", this._onMouseEvent.bind(this,
WebInspector.FilmStripView.Events.FrameEnter, time), false); | |
| 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 | 106 |
| 89 if (this._mode === WebInspector.FilmStripView.Modes.FrameBased) { | 107 if (this._mode === WebInspector.FilmStripView.Modes.FrameBased) { |
| 90 for (var frame of frames) | 108 frames.map(this.createFrameElement.bind(this)).forEach(this.contentE
lement.appendChild.bind(this.contentElement)); |
| 91 createElementForFrame.call(this, frame); | |
| 92 return; | 109 return; |
| 93 } | 110 } |
| 94 | 111 |
| 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 /** | |
| 107 * @param {number} time | |
| 108 * @param {!WebInspector.FilmStripModel.Frame} frame | |
| 109 * @return {number} | |
| 110 */ | |
| 111 function comparator(time, frame) | |
| 112 { | |
| 113 return time - frame.timestamp; | |
| 114 } | |
| 115 | |
| 116 var width = this.contentElement.clientWidth; | 112 var width = this.contentElement.clientWidth; |
| 117 var scale = this._spanTime / width; | 113 var scale = this._spanTime / width; |
| 118 | 114 var element0 = this.createFrameElement(frames[0]); // Calculate frame w
idth basing on the first frame. |
| 119 // Calculate frame width basing on the first frame. | 115 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) | 116 if (!frameWidth) |
| 124 return; | 117 return; |
| 125 | 118 |
| 126 for (var pos = frameWidth; pos < width; pos += frameWidth) { | 119 for (var pos = frameWidth; pos < width; pos += frameWidth) { |
| 127 var time = pos * scale + zeroTime; | 120 var time = pos * scale + this._zeroTime; |
| 128 var index = frames.upperBound(time, comparator) - 1; | 121 var frame = this.frameByTime(time); |
| 129 var element = index >= 0 ? createElementForFrame.call(this, frames[i
ndex], true) : createEmptyElement.call(this); | 122 var element = this.contentElement.appendChild(this.createFrameElemen
t(frame)); |
| 130 element.style.width = frameWidth + "px"; | 123 element.style.width = frameWidth + "px"; |
| 131 } | 124 } |
| 132 }, | 125 }, |
| 133 | 126 |
| 134 /** | 127 /** |
| 135 * @override | 128 * @override |
| 136 */ | 129 */ |
| 137 onResize: function() | 130 onResize: function() |
| 138 { | 131 { |
| 139 if (this._mode === WebInspector.FilmStripView.Modes.FrameBased) | 132 if (this._mode === WebInspector.FilmStripView.Modes.FrameBased) |
| (...skipping 15 matching lines...) Expand all Loading... |
| 155 */ | 148 */ |
| 156 _onDoubleClick: function(filmStripFrame) | 149 _onDoubleClick: function(filmStripFrame) |
| 157 { | 150 { |
| 158 WebInspector.Dialog.show(null, new WebInspector.FilmStripView.DialogDele
gate(filmStripFrame, this._zeroTime)); | 151 WebInspector.Dialog.show(null, new WebInspector.FilmStripView.DialogDele
gate(filmStripFrame, this._zeroTime)); |
| 159 }, | 152 }, |
| 160 | 153 |
| 161 reset: function() | 154 reset: function() |
| 162 { | 155 { |
| 163 this._zeroTime = 0; | 156 this._zeroTime = 0; |
| 164 this.contentElement.removeChildren(); | 157 this.contentElement.removeChildren(); |
| 165 this._label = this.contentElement.createChild("div", "label"); | 158 this._statusLabel = this.contentElement.createChild("div", "label"); |
| 166 this._label.textContent = WebInspector.UIString("No frames recorded. Rel
oad page to start recording."); | 159 this._statusLabel.textContent = WebInspector.UIString("No frames recorde
d. Reload page to start recording."); |
| 167 }, | 160 }, |
| 168 | 161 |
| 169 setRecording: function() | 162 setRecording: function() |
| 170 { | 163 { |
| 171 this.reset(); | 164 this.reset(); |
| 172 this._label.textContent = WebInspector.UIString("Recording frames..."); | 165 this._statusLabel.textContent = WebInspector.UIString("Recording frames.
.."); |
| 173 }, | 166 }, |
| 174 | 167 |
| 175 setFetching: function() | 168 setFetching: function() |
| 176 { | 169 { |
| 177 this._label.textContent = WebInspector.UIString("Fetching frames..."); | 170 this._statusLabel.textContent = WebInspector.UIString("Fetching frames..
."); |
| 178 }, | 171 }, |
| 179 | 172 |
| 180 __proto__: WebInspector.HBox.prototype | 173 __proto__: WebInspector.HBox.prototype |
| 181 } | 174 } |
| 182 | 175 |
| 183 /** | 176 /** |
| 184 * @constructor | 177 * @constructor |
| 185 * @extends {WebInspector.DialogDelegate} | 178 * @extends {WebInspector.DialogDelegate} |
| 186 * @param {!WebInspector.FilmStripModel.Frame} filmStripFrame | 179 * @param {!WebInspector.FilmStripModel.Frame} filmStripFrame |
| 187 * @param {number=} zeroTime | 180 * @param {number=} zeroTime |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 279 | 272 |
| 280 _render: function() | 273 _render: function() |
| 281 { | 274 { |
| 282 var frame = this._frames[this._index]; | 275 var frame = this._frames[this._index]; |
| 283 this._imageElement.src = "data:image/jpg;base64," + frame.imageData; | 276 this._imageElement.src = "data:image/jpg;base64," + frame.imageData; |
| 284 this._timeLabel.textContent = Number.millisToString(frame.timestamp - th
is._zeroTime); | 277 this._timeLabel.textContent = Number.millisToString(frame.timestamp - th
is._zeroTime); |
| 285 }, | 278 }, |
| 286 | 279 |
| 287 __proto__: WebInspector.DialogDelegate.prototype | 280 __proto__: WebInspector.DialogDelegate.prototype |
| 288 } | 281 } |
| OLD | NEW |