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

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

Issue 2608043002: DevTools: extract modules (with extensions) (Closed)
Patch Set: fixes Created 3 years, 11 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
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4 /**
5 * @unrestricted
6 */
7 Components.FilmStripView = class extends UI.HBox {
8 constructor() {
9 super(true);
10 this.registerRequiredCSS('components_lazy/filmStripView.css');
11 this.contentElement.classList.add('film-strip-view');
12 this._statusLabel = this.contentElement.createChild('div', 'label');
13 this.reset();
14 this.setMode(Components.FilmStripView.Modes.TimeBased);
15 }
16
17 /**
18 * @param {!Element} imageElement
19 * @param {?string} data
20 */
21 static _setImageData(imageElement, data) {
22 if (data)
23 imageElement.src = 'data:image/jpg;base64,' + data;
24 }
25
26 /**
27 * @param {string} mode
28 */
29 setMode(mode) {
30 this._mode = mode;
31 this.contentElement.classList.toggle('time-based', mode === Components.FilmS tripView.Modes.TimeBased);
32 this.update();
33 }
34
35 /**
36 * @param {!Components.FilmStripModel} filmStripModel
37 * @param {number} zeroTime
38 * @param {number} spanTime
39 */
40 setModel(filmStripModel, zeroTime, spanTime) {
41 this._model = filmStripModel;
42 this._zeroTime = zeroTime;
43 this._spanTime = spanTime;
44 var frames = filmStripModel.frames();
45 if (!frames.length) {
46 this.reset();
47 return;
48 }
49 this.update();
50 }
51
52 /**
53 * @param {!Components.FilmStripModel.Frame} frame
54 * @return {!Promise<!Element>}
55 */
56 createFrameElement(frame) {
57 var time = frame.timestamp;
58 var element = createElementWithClass('div', 'frame');
59 element.title = Common.UIString('Doubleclick to zoom image. Click to view pr eceding requests.');
60 element.createChild('div', 'time').textContent = Number.millisToString(time - this._zeroTime);
61 var imageElement = element.createChild('div', 'thumbnail').createChild('img' );
62 element.addEventListener(
63 'mousedown', this._onMouseEvent.bind(this, Components.FilmStripView.Even ts.FrameSelected, time), false);
64 element.addEventListener(
65 'mouseenter', this._onMouseEvent.bind(this, Components.FilmStripView.Eve nts.FrameEnter, time), false);
66 element.addEventListener(
67 'mouseout', this._onMouseEvent.bind(this, Components.FilmStripView.Event s.FrameExit, time), false);
68 element.addEventListener('dblclick', this._onDoubleClick.bind(this, frame), false);
69
70 return frame.imageDataPromise()
71 .then(Components.FilmStripView._setImageData.bind(null, imageElement))
72 .then(returnElement);
73 /**
74 * @return {!Element}
75 */
76 function returnElement() {
77 return element;
78 }
79 }
80
81 /**
82 * @param {number} time
83 * @return {!Components.FilmStripModel.Frame}
84 */
85 frameByTime(time) {
86 /**
87 * @param {number} time
88 * @param {!Components.FilmStripModel.Frame} frame
89 * @return {number}
90 */
91 function comparator(time, frame) {
92 return time - frame.timestamp;
93 }
94 // Using the first frame to fill the interval between recording start
95 // and a moment the frame is taken.
96 var frames = this._model.frames();
97 var index = Math.max(frames.upperBound(time, comparator) - 1, 0);
98 return frames[index];
99 }
100
101 update() {
102 if (!this._model)
103 return;
104 var frames = this._model.frames();
105 if (!frames.length)
106 return;
107
108 if (this._mode === Components.FilmStripView.Modes.FrameBased) {
109 Promise.all(frames.map(this.createFrameElement.bind(this))).then(appendEle ments.bind(this));
110 return;
111 }
112
113 var width = this.contentElement.clientWidth;
114 var scale = this._spanTime / width;
115 this.createFrameElement(frames[0]).then(
116 continueWhenFrameImageLoaded.bind(this)); // Calculate frame width basi ng on the first frame.
117
118 /**
119 * @this {Components.FilmStripView}
120 * @param {!Element} element0
121 */
122 function continueWhenFrameImageLoaded(element0) {
123 var frameWidth = Math.ceil(UI.measurePreferredSize(element0, this.contentE lement).width);
124 if (!frameWidth)
125 return;
126
127 var promises = [];
128 for (var pos = frameWidth; pos < width; pos += frameWidth) {
129 var time = pos * scale + this._zeroTime;
130 promises.push(this.createFrameElement(this.frameByTime(time)).then(fixWi dth));
131 }
132 Promise.all(promises).then(appendElements.bind(this));
133 /**
134 * @param {!Element} element
135 * @return {!Element}
136 */
137 function fixWidth(element) {
138 element.style.width = frameWidth + 'px';
139 return element;
140 }
141 }
142
143 /**
144 * @param {!Array.<!Element>} elements
145 * @this {Components.FilmStripView}
146 */
147 function appendElements(elements) {
148 this.contentElement.removeChildren();
149 for (var i = 0; i < elements.length; ++i)
150 this.contentElement.appendChild(elements[i]);
151 }
152 }
153
154 /**
155 * @override
156 */
157 onResize() {
158 if (this._mode === Components.FilmStripView.Modes.FrameBased)
159 return;
160 this.update();
161 }
162
163 /**
164 * @param {string} eventName
165 * @param {number} timestamp
166 */
167 _onMouseEvent(eventName, timestamp) {
168 this.dispatchEventToListeners(eventName, timestamp);
169 }
170
171 /**
172 * @param {!Components.FilmStripModel.Frame} filmStripFrame
173 */
174 _onDoubleClick(filmStripFrame) {
175 new Components.FilmStripView.Dialog(filmStripFrame, this._zeroTime);
176 }
177
178 reset() {
179 this._zeroTime = 0;
180 this.contentElement.removeChildren();
181 this.contentElement.appendChild(this._statusLabel);
182 }
183
184 /**
185 * @param {string} text
186 */
187 setStatusText(text) {
188 this._statusLabel.textContent = text;
189 }
190 };
191
192 /** @enum {symbol} */
193 Components.FilmStripView.Events = {
194 FrameSelected: Symbol('FrameSelected'),
195 FrameEnter: Symbol('FrameEnter'),
196 FrameExit: Symbol('FrameExit'),
197 };
198
199 Components.FilmStripView.Modes = {
200 TimeBased: 'TimeBased',
201 FrameBased: 'FrameBased'
202 };
203
204
205 /**
206 * @unrestricted
207 */
208 Components.FilmStripView.Dialog = class extends UI.VBox {
209 /**
210 * @param {!Components.FilmStripModel.Frame} filmStripFrame
211 * @param {number=} zeroTime
212 */
213 constructor(filmStripFrame, zeroTime) {
214 super(true);
215 this.registerRequiredCSS('components_lazy/filmStripDialog.css');
216 this.contentElement.classList.add('filmstrip-dialog');
217 this.contentElement.tabIndex = 0;
218
219 this._frames = filmStripFrame.model().frames();
220 this._index = filmStripFrame.index;
221 this._zeroTime = zeroTime || filmStripFrame.model().zeroTime();
222
223 this._imageElement = this.contentElement.createChild('img');
224 var footerElement = this.contentElement.createChild('div', 'filmstrip-dialog -footer');
225 footerElement.createChild('div', 'flex-auto');
226 var prevButton =
227 UI.createTextButton('\u25C0', this._onPrevFrame.bind(this), undefined, C ommon.UIString('Previous frame'));
228 footerElement.appendChild(prevButton);
229 this._timeLabel = footerElement.createChild('div', 'filmstrip-dialog-label') ;
230 var nextButton =
231 UI.createTextButton('\u25B6', this._onNextFrame.bind(this), undefined, C ommon.UIString('Next frame'));
232 footerElement.appendChild(nextButton);
233 footerElement.createChild('div', 'flex-auto');
234
235 this.contentElement.addEventListener('keydown', this._keyDown.bind(this), fa lse);
236 this.setDefaultFocusedElement(this.contentElement);
237 this._render();
238 }
239
240 _resize() {
241 if (!this._dialog) {
242 this._dialog = new UI.Dialog();
243 this.show(this._dialog.element);
244 this._dialog.setWrapsContent(true);
245 this._dialog.show();
246 }
247 this._dialog.contentResized();
248 }
249
250 /**
251 * @param {!Event} event
252 */
253 _keyDown(event) {
254 switch (event.key) {
255 case 'ArrowLeft':
256 if (Host.isMac() && event.metaKey)
257 this._onFirstFrame();
258 else
259 this._onPrevFrame();
260 break;
261
262 case 'ArrowRight':
263 if (Host.isMac() && event.metaKey)
264 this._onLastFrame();
265 else
266 this._onNextFrame();
267 break;
268
269 case 'Home':
270 this._onFirstFrame();
271 break;
272
273 case 'End':
274 this._onLastFrame();
275 break;
276 }
277 }
278
279 _onPrevFrame() {
280 if (this._index > 0)
281 --this._index;
282 this._render();
283 }
284
285 _onNextFrame() {
286 if (this._index < this._frames.length - 1)
287 ++this._index;
288 this._render();
289 }
290
291 _onFirstFrame() {
292 this._index = 0;
293 this._render();
294 }
295
296 _onLastFrame() {
297 this._index = this._frames.length - 1;
298 this._render();
299 }
300
301 /**
302 * @return {!Promise<undefined>}
303 */
304 _render() {
305 var frame = this._frames[this._index];
306 this._timeLabel.textContent = Number.millisToString(frame.timestamp - this._ zeroTime);
307 return frame.imageDataPromise()
308 .then(Components.FilmStripView._setImageData.bind(null, this._imageEleme nt))
309 .then(this._resize.bind(this));
310 }
311 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698