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

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/emulation/DeviceModeModel.js

Issue 2466123002: DevTools: reformat front-end code to match chromium style. (Closed)
Patch Set: all done Created 4 years, 1 month 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
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
5 /** 4 /**
6 * @constructor
7 * @param {function()} updateCallback
8 * @implements {WebInspector.TargetManager.Observer} 5 * @implements {WebInspector.TargetManager.Observer}
6 * @unrestricted
9 */ 7 */
10 WebInspector.DeviceModeModel = function(updateCallback) 8 WebInspector.DeviceModeModel = class {
11 { 9 /**
10 * @param {function()} updateCallback
11 */
12 constructor(updateCallback) {
12 this._updateCallback = updateCallback; 13 this._updateCallback = updateCallback;
13 this._screenRect = new WebInspector.Rect(0, 0, 1, 1); 14 this._screenRect = new WebInspector.Rect(0, 0, 1, 1);
14 this._visiblePageRect = new WebInspector.Rect(0, 0, 1, 1); 15 this._visiblePageRect = new WebInspector.Rect(0, 0, 1, 1);
15 this._availableSize = new Size(1, 1); 16 this._availableSize = new Size(1, 1);
16 this._preferredSize = new Size(1, 1); 17 this._preferredSize = new Size(1, 1);
17 this._initialized = false; 18 this._initialized = false;
18 this._deviceMetricsThrottler = new WebInspector.Throttler(0); 19 this._deviceMetricsThrottler = new WebInspector.Throttler(0);
19 this._appliedDeviceSize = new Size(1, 1); 20 this._appliedDeviceSize = new Size(1, 1);
20 this._appliedDeviceScaleFactor = window.devicePixelRatio; 21 this._appliedDeviceScaleFactor = window.devicePixelRatio;
21 this._appliedUserAgentType = WebInspector.DeviceModeModel.UA.Desktop; 22 this._appliedUserAgentType = WebInspector.DeviceModeModel.UA.Desktop;
22 23
23 this._scaleSetting = WebInspector.settings.createSetting("emulation.deviceSc ale", 1); 24 this._scaleSetting = WebInspector.settings.createSetting('emulation.deviceSc ale', 1);
24 // We've used to allow zero before. 25 // We've used to allow zero before.
25 if (!this._scaleSetting.get()) 26 if (!this._scaleSetting.get())
26 this._scaleSetting.set(1); 27 this._scaleSetting.set(1);
27 this._scaleSetting.addChangeListener(this._scaleSettingChanged, this); 28 this._scaleSetting.addChangeListener(this._scaleSettingChanged, this);
28 29
29 this._widthSetting = WebInspector.settings.createSetting("emulation.deviceWi dth", 400); 30 this._widthSetting = WebInspector.settings.createSetting('emulation.deviceWi dth', 400);
30 if (this._widthSetting.get() < WebInspector.DeviceModeModel.MinDeviceSize) 31 if (this._widthSetting.get() < WebInspector.DeviceModeModel.MinDeviceSize)
31 this._widthSetting.set(WebInspector.DeviceModeModel.MinDeviceSize); 32 this._widthSetting.set(WebInspector.DeviceModeModel.MinDeviceSize);
32 if (this._widthSetting.get() > WebInspector.DeviceModeModel.MaxDeviceSize) 33 if (this._widthSetting.get() > WebInspector.DeviceModeModel.MaxDeviceSize)
33 this._widthSetting.set(WebInspector.DeviceModeModel.MaxDeviceSize); 34 this._widthSetting.set(WebInspector.DeviceModeModel.MaxDeviceSize);
34 this._widthSetting.addChangeListener(this._widthSettingChanged, this); 35 this._widthSetting.addChangeListener(this._widthSettingChanged, this);
35 36
36 this._heightSetting = WebInspector.settings.createSetting("emulation.deviceH eight", 0); 37 this._heightSetting = WebInspector.settings.createSetting('emulation.deviceH eight', 0);
37 if (this._heightSetting.get() && this._heightSetting.get() < WebInspector.De viceModeModel.MinDeviceSize) 38 if (this._heightSetting.get() && this._heightSetting.get() < WebInspector.De viceModeModel.MinDeviceSize)
38 this._heightSetting.set(WebInspector.DeviceModeModel.MinDeviceSize); 39 this._heightSetting.set(WebInspector.DeviceModeModel.MinDeviceSize);
39 if (this._heightSetting.get() > WebInspector.DeviceModeModel.MaxDeviceSize) 40 if (this._heightSetting.get() > WebInspector.DeviceModeModel.MaxDeviceSize)
40 this._heightSetting.set(WebInspector.DeviceModeModel.MaxDeviceSize); 41 this._heightSetting.set(WebInspector.DeviceModeModel.MaxDeviceSize);
41 this._heightSetting.addChangeListener(this._heightSettingChanged, this); 42 this._heightSetting.addChangeListener(this._heightSettingChanged, this);
42 43
43 this._uaSetting = WebInspector.settings.createSetting("emulation.deviceUA", WebInspector.DeviceModeModel.UA.Mobile); 44 this._uaSetting = WebInspector.settings.createSetting('emulation.deviceUA', WebInspector.DeviceModeModel.UA.Mobile);
44 this._uaSetting.addChangeListener(this._uaSettingChanged, this); 45 this._uaSetting.addChangeListener(this._uaSettingChanged, this);
45 this._deviceScaleFactorSetting = WebInspector.settings.createSetting("emulat ion.deviceScaleFactor", 0); 46 this._deviceScaleFactorSetting = WebInspector.settings.createSetting('emulat ion.deviceScaleFactor', 0);
46 this._deviceScaleFactorSetting.addChangeListener(this._deviceScaleFactorSett ingChanged, this); 47 this._deviceScaleFactorSetting.addChangeListener(this._deviceScaleFactorSett ingChanged, this);
47 48
48 this._deviceOutlineSetting = WebInspector.settings.moduleSetting("emulation. showDeviceOutline"); 49 this._deviceOutlineSetting = WebInspector.settings.moduleSetting('emulation. showDeviceOutline');
49 this._deviceOutlineSetting.addChangeListener(this._deviceOutlineSettingChang ed, this); 50 this._deviceOutlineSetting.addChangeListener(this._deviceOutlineSettingChang ed, this);
50 51
51 /** @type {!WebInspector.DeviceModeModel.Type} */ 52 /** @type {!WebInspector.DeviceModeModel.Type} */
52 this._type = WebInspector.DeviceModeModel.Type.None; 53 this._type = WebInspector.DeviceModeModel.Type.None;
53 /** @type {?WebInspector.EmulatedDevice} */ 54 /** @type {?WebInspector.EmulatedDevice} */
54 this._device = null; 55 this._device = null;
55 /** @type {?WebInspector.EmulatedDevice.Mode} */ 56 /** @type {?WebInspector.EmulatedDevice.Mode} */
56 this._mode = null; 57 this._mode = null;
57 /** @type {number} */ 58 /** @type {number} */
58 this._fitScale = 1; 59 this._fitScale = 1;
59 60
60 /** @type {?WebInspector.Target} */ 61 /** @type {?WebInspector.Target} */
61 this._target = null; 62 this._target = null;
62 /** @type {?function()} */ 63 /** @type {?function()} */
63 this._onTargetAvailable = null; 64 this._onTargetAvailable = null;
64 WebInspector.targetManager.observeTargets(this, WebInspector.Target.Capabili ty.Browser); 65 WebInspector.targetManager.observeTargets(this, WebInspector.Target.Capabili ty.Browser);
66 }
67
68 /**
69 * @param {string} value
70 * @return {boolean}
71 */
72 static deviceSizeValidator(value) {
73 if (/^[\d]+$/.test(value) && value >= WebInspector.DeviceModeModel.MinDevice Size &&
74 value <= WebInspector.DeviceModeModel.MaxDeviceSize)
75 return true;
76 return false;
77 }
78
79 /**
80 * @param {string} value
81 * @return {boolean}
82 */
83 static deviceScaleFactorValidator(value) {
84 if (!value || (/^[\d]+(\.\d+)?|\.\d+$/.test(value) && value >= 0 && value <= 10))
85 return true;
86 return false;
87 }
88
89 /**
90 * @param {!Size} availableSize
91 * @param {!Size} preferredSize
92 */
93 setAvailableSize(availableSize, preferredSize) {
94 this._availableSize = availableSize;
95 this._preferredSize = preferredSize;
96 this._initialized = true;
97 this._calculateAndEmulate(false);
98 }
99
100 /**
101 * @param {!WebInspector.DeviceModeModel.Type} type
102 * @param {?WebInspector.EmulatedDevice} device
103 * @param {?WebInspector.EmulatedDevice.Mode} mode
104 * @param {number=} scale
105 */
106 emulate(type, device, mode, scale) {
107 var resetPageScaleFactor = this._type !== type || this._device !== device || this._mode !== mode;
108 this._type = type;
109
110 if (type === WebInspector.DeviceModeModel.Type.Device) {
111 console.assert(device && mode, 'Must pass device and mode for device emula tion');
112 this._mode = mode;
113 this._device = device;
114 if (this._initialized) {
115 var orientation = device.orientationByName(mode.orientation);
116 this._scaleSetting.set(
117 scale ||
118 this._calculateFitScale(
119 orientation.width, orientation.height, this._currentOutline(), t his._currentInsets()));
120 }
121 } else {
122 this._device = null;
123 this._mode = null;
124 }
125
126 if (type !== WebInspector.DeviceModeModel.Type.None)
127 WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.Devic eModeEnabled);
128 this._calculateAndEmulate(resetPageScaleFactor);
129 }
130
131 /**
132 * @param {number} width
133 */
134 setWidth(width) {
135 var max = Math.min(WebInspector.DeviceModeModel.MaxDeviceSize, this._preferr edScaledWidth());
136 width = Math.max(Math.min(width, max), 1);
137 this._widthSetting.set(width);
138 }
139
140 /**
141 * @param {number} width
142 */
143 setWidthAndScaleToFit(width) {
144 width = Math.max(Math.min(width, WebInspector.DeviceModeModel.MaxDeviceSize) , 1);
145 this._scaleSetting.set(this._calculateFitScale(width, this._heightSetting.ge t()));
146 this._widthSetting.set(width);
147 }
148
149 /**
150 * @param {number} height
151 */
152 setHeight(height) {
153 var max = Math.min(WebInspector.DeviceModeModel.MaxDeviceSize, this._preferr edScaledHeight());
154 height = Math.max(Math.min(height, max), 0);
155 if (height === this._preferredScaledHeight())
156 height = 0;
157 this._heightSetting.set(height);
158 }
159
160 /**
161 * @param {number} height
162 */
163 setHeightAndScaleToFit(height) {
164 height = Math.max(Math.min(height, WebInspector.DeviceModeModel.MaxDeviceSiz e), 0);
165 this._scaleSetting.set(this._calculateFitScale(this._widthSetting.get(), hei ght));
166 this._heightSetting.set(height);
167 }
168
169 /**
170 * @param {number} scale
171 */
172 setScale(scale) {
173 this._scaleSetting.set(scale);
174 }
175
176 /**
177 * @return {?WebInspector.EmulatedDevice}
178 */
179 device() {
180 return this._device;
181 }
182
183 /**
184 * @return {?WebInspector.EmulatedDevice.Mode}
185 */
186 mode() {
187 return this._mode;
188 }
189
190 /**
191 * @return {!WebInspector.DeviceModeModel.Type}
192 */
193 type() {
194 return this._type;
195 }
196
197 /**
198 * @return {string}
199 */
200 screenImage() {
201 return (this._device && this._mode) ? this._device.modeImage(this._mode) : ' ';
202 }
203
204 /**
205 * @return {string}
206 */
207 outlineImage() {
208 return (this._device && this._mode && this._deviceOutlineSetting.get()) ? th is._device.outlineImage(this._mode) :
209 '' ;
210 }
211
212 /**
213 * @return {!WebInspector.Rect}
214 */
215 outlineRect() {
216 return this._outlineRect;
217 }
218
219 /**
220 * @return {!WebInspector.Rect}
221 */
222 screenRect() {
223 return this._screenRect;
224 }
225
226 /**
227 * @return {!WebInspector.Rect}
228 */
229 visiblePageRect() {
230 return this._visiblePageRect;
231 }
232
233 /**
234 * @return {number}
235 */
236 scale() {
237 return this._scale;
238 }
239
240 /**
241 * @return {number}
242 */
243 fitScale() {
244 return this._fitScale;
245 }
246
247 /**
248 * @return {!Size}
249 */
250 appliedDeviceSize() {
251 return this._appliedDeviceSize;
252 }
253
254 /**
255 * @return {number}
256 */
257 appliedDeviceScaleFactor() {
258 return this._appliedDeviceScaleFactor;
259 }
260
261 /**
262 * @return {!WebInspector.DeviceModeModel.UA}
263 */
264 appliedUserAgentType() {
265 return this._appliedUserAgentType;
266 }
267
268 /**
269 * @return {boolean}
270 */
271 isFullHeight() {
272 return !this._heightSetting.get();
273 }
274
275 /**
276 * @return {!WebInspector.Setting}
277 */
278 scaleSetting() {
279 return this._scaleSetting;
280 }
281
282 /**
283 * @return {!WebInspector.Setting}
284 */
285 uaSetting() {
286 return this._uaSetting;
287 }
288
289 /**
290 * @return {!WebInspector.Setting}
291 */
292 deviceScaleFactorSetting() {
293 return this._deviceScaleFactorSetting;
294 }
295
296 /**
297 * @return {!WebInspector.Setting}
298 */
299 deviceOutlineSetting() {
300 return this._deviceOutlineSetting;
301 }
302
303 reset() {
304 this._deviceScaleFactorSetting.set(0);
305 this._scaleSetting.set(1);
306 this.setWidth(400);
307 this.setHeight(0);
308 this._uaSetting.set(WebInspector.DeviceModeModel.UA.Mobile);
309 }
310
311 /**
312 * @override
313 * @param {!WebInspector.Target} target
314 */
315 targetAdded(target) {
316 if (!this._target) {
317 this._target = target;
318 if (this._onTargetAvailable) {
319 var callback = this._onTargetAvailable;
320 this._onTargetAvailable = null;
321 callback();
322 }
323 }
324 }
325
326 /**
327 * @override
328 * @param {!WebInspector.Target} target
329 */
330 targetRemoved(target) {
331 if (this._target === target)
332 this._target = null;
333 }
334
335 _scaleSettingChanged() {
336 this._calculateAndEmulate(false);
337 }
338
339 _widthSettingChanged() {
340 this._calculateAndEmulate(false);
341 }
342
343 _heightSettingChanged() {
344 this._calculateAndEmulate(false);
345 }
346
347 _uaSettingChanged() {
348 this._calculateAndEmulate(true);
349 }
350
351 _deviceScaleFactorSettingChanged() {
352 this._calculateAndEmulate(false);
353 }
354
355 _deviceOutlineSettingChanged() {
356 this._calculateAndEmulate(false);
357 }
358
359 /**
360 * @return {number}
361 */
362 _preferredScaledWidth() {
363 return Math.floor(this._preferredSize.width / (this._scaleSetting.get() || 1 ));
364 }
365
366 /**
367 * @return {number}
368 */
369 _preferredScaledHeight() {
370 return Math.floor(this._preferredSize.height / (this._scaleSetting.get() || 1));
371 }
372
373 /**
374 * @return {!Insets}
375 */
376 _currentOutline() {
377 var outline = new Insets(0, 0, 0, 0);
378 if (this._type !== WebInspector.DeviceModeModel.Type.Device)
379 return outline;
380 var orientation = this._device.orientationByName(this._mode.orientation);
381 if (this._deviceOutlineSetting.get())
382 outline = orientation.outlineInsets || outline;
383 return outline;
384 }
385
386 /**
387 * @return {!Insets}
388 */
389 _currentInsets() {
390 if (this._type !== WebInspector.DeviceModeModel.Type.Device)
391 return new Insets(0, 0, 0, 0);
392 return this._mode.insets;
393 }
394
395 /**
396 * @param {boolean} resetPageScaleFactor
397 */
398 _calculateAndEmulate(resetPageScaleFactor) {
399 if (!this._target)
400 this._onTargetAvailable = this._calculateAndEmulate.bind(this, resetPageSc aleFactor);
401
402 if (this._type === WebInspector.DeviceModeModel.Type.Device) {
403 var orientation = this._device.orientationByName(this._mode.orientation);
404 var outline = this._currentOutline();
405 var insets = this._currentInsets();
406 this._fitScale = this._calculateFitScale(orientation.width, orientation.he ight, outline, insets);
407 if (this._device.mobile())
408 this._appliedUserAgentType = this._device.touch() ? WebInspector.DeviceM odeModel.UA.Mobile :
409 WebInspector.DeviceM odeModel.UA.MobileNoTouch;
410 else
411 this._appliedUserAgentType = this._device.touch() ? WebInspector.DeviceM odeModel.UA.DesktopTouch :
412 WebInspector.DeviceM odeModel.UA.Desktop;
413 this._applyDeviceMetrics(
414 new Size(orientation.width, orientation.height), insets, outline, this ._scaleSetting.get(),
415 this._device.deviceScaleFactor, this._device.mobile(),
416 this._mode.orientation === WebInspector.EmulatedDevice.Horizontal ? 'l andscapePrimary' : 'portraitPrimary',
417 resetPageScaleFactor);
418 this._applyUserAgent(this._device.userAgent);
419 this._applyTouch(this._device.touch(), this._device.mobile());
420 } else if (this._type === WebInspector.DeviceModeModel.Type.None) {
421 this._fitScale = this._calculateFitScale(this._availableSize.width, this._ availableSize.height);
422 this._appliedUserAgentType = WebInspector.DeviceModeModel.UA.Desktop;
423 this._applyDeviceMetrics(
424 this._availableSize, new Insets(0, 0, 0, 0), new Insets(0, 0, 0, 0), 1 , 0, false, '', resetPageScaleFactor);
425 this._applyUserAgent('');
426 this._applyTouch(false, false);
427 } else if (this._type === WebInspector.DeviceModeModel.Type.Responsive) {
428 var screenWidth = this._widthSetting.get();
429 if (!screenWidth || screenWidth > this._preferredScaledWidth())
430 screenWidth = this._preferredScaledWidth();
431 var screenHeight = this._heightSetting.get();
432 if (!screenHeight || screenHeight > this._preferredScaledHeight())
433 screenHeight = this._preferredScaledHeight();
434 var mobile = this._uaSetting.get() === WebInspector.DeviceModeModel.UA.Mob ile ||
435 this._uaSetting.get() === WebInspector.DeviceModeModel.UA.MobileNoTouc h;
436 var defaultDeviceScaleFactor = mobile ? WebInspector.DeviceModeModel.defau ltMobileScaleFactor : 0;
437 this._fitScale = this._calculateFitScale(this._widthSetting.get(), this._h eightSetting.get());
438 this._appliedUserAgentType = this._uaSetting.get();
439 this._applyDeviceMetrics(
440 new Size(screenWidth, screenHeight), new Insets(0, 0, 0, 0), new Inset s(0, 0, 0, 0), this._scaleSetting.get(),
441 this._deviceScaleFactorSetting.get() || defaultDeviceScaleFactor, mobi le,
442 screenHeight >= screenWidth ? 'portraitPrimary' : 'landscapePrimary', resetPageScaleFactor);
443 this._applyUserAgent(mobile ? WebInspector.DeviceModeModel._defaultMobileU serAgent : '');
444 this._applyTouch(
445 this._uaSetting.get() === WebInspector.DeviceModeModel.UA.DesktopTouch ||
446 this._uaSetting.get() === WebInspector.DeviceModeModel.UA.Mobile,
447 this._uaSetting.get() === WebInspector.DeviceModeModel.UA.Mobile);
448 }
449 if (this._target)
450 this._target.renderingAgent().setShowViewportSizeOnResize(this._type === W ebInspector.DeviceModeModel.Type.None);
451 this._updateCallback.call(null);
452 }
453
454 /**
455 * @param {number} screenWidth
456 * @param {number} screenHeight
457 * @param {!Insets=} outline
458 * @param {!Insets=} insets
459 * @return {number}
460 */
461 _calculateFitScale(screenWidth, screenHeight, outline, insets) {
462 var outlineWidth = outline ? outline.left + outline.right : 0;
463 var outlineHeight = outline ? outline.top + outline.bottom : 0;
464 var insetsWidth = insets ? insets.left + insets.right : 0;
465 var insetsHeight = insets ? insets.top + insets.bottom : 0;
466 var scale = Math.min(
467 screenWidth ? this._preferredSize.width / (screenWidth + outlineWidth) : 1,
468 screenHeight ? this._preferredSize.height / (screenHeight + outlineHeigh t) : 1);
469 scale = Math.min(Math.floor(scale * 100), 100);
470
471 var sharpScale = scale;
472 while (sharpScale > scale * 0.7) {
473 var sharp = true;
474 if (screenWidth)
475 sharp = sharp && Number.isInteger((screenWidth - insetsWidth) * sharpSca le / 100);
476 if (screenHeight)
477 sharp = sharp && Number.isInteger((screenHeight - insetsHeight) * sharpS cale / 100);
478 if (sharp)
479 return sharpScale / 100;
480 sharpScale -= 1;
481 }
482 return scale / 100;
483 }
484
485 /**
486 * @param {number} width
487 * @param {number} height
488 */
489 setSizeAndScaleToFit(width, height) {
490 this._scaleSetting.set(this._calculateFitScale(width, height));
491 this.setWidth(width);
492 }
493
494 /**
495 * @param {string} userAgent
496 */
497 _applyUserAgent(userAgent) {
498 WebInspector.multitargetNetworkManager.setUserAgentOverride(userAgent);
499 }
500
501 /**
502 * @param {!Size} screenSize
503 * @param {!Insets} insets
504 * @param {!Insets} outline
505 * @param {number} scale
506 * @param {number} deviceScaleFactor
507 * @param {boolean} mobile
508 * @param {string} screenOrientation
509 * @param {boolean} resetPageScaleFactor
510 */
511 _applyDeviceMetrics(
512 screenSize,
513 insets,
514 outline,
515 scale,
516 deviceScaleFactor,
517 mobile,
518 screenOrientation,
519 resetPageScaleFactor) {
520 screenSize.width = Math.max(1, Math.floor(screenSize.width));
521 screenSize.height = Math.max(1, Math.floor(screenSize.height));
522
523 var pageWidth = screenSize.width - insets.left - insets.right;
524 var pageHeight = screenSize.height - insets.top - insets.bottom;
525
526 var positionX = insets.left;
527 var positionY = insets.top;
528 var screenOrientationAngle = screenOrientation === 'landscapePrimary' ? 90 : 0;
529
530 this._appliedDeviceSize = screenSize;
531 this._appliedDeviceScaleFactor = deviceScaleFactor || window.devicePixelRati o;
532 this._screenRect = new WebInspector.Rect(
533 Math.max(0, (this._availableSize.width - screenSize.width * scale) / 2), outline.top * scale,
534 screenSize.width * scale, screenSize.height * scale);
535 this._outlineRect = new WebInspector.Rect(
536 this._screenRect.left - outline.left * scale, 0, (outline.left + screenS ize.width + outline.right) * scale,
537 (outline.top + screenSize.height + outline.bottom) * scale);
538 this._visiblePageRect = new WebInspector.Rect(
539 positionX * scale, positionY * scale,
540 Math.min(pageWidth * scale, this._availableSize.width - this._screenRect .left - positionX * scale),
541 Math.min(pageHeight * scale, this._availableSize.height - this._screenRe ct.top - positionY * scale));
542 this._scale = scale;
543
544 if (scale === 1 && this._availableSize.width >= screenSize.width &&
545 this._availableSize.height >= screenSize.height) {
546 // When we have enough space, no page size override is required. This will speed things up and remove lag.
547 pageWidth = 0;
548 pageHeight = 0;
549 }
550 if (this._visiblePageRect.width === pageWidth * scale && this._visiblePageRe ct.height === pageHeight * scale &&
551 Number.isInteger(pageWidth * scale) && Number.isInteger(pageHeight * sca le)) {
552 // When we only have to apply scale, do not resize the page. This will spe ed things up and remove lag.
553 pageWidth = 0;
554 pageHeight = 0;
555 }
556
557 this._deviceMetricsThrottler.schedule(setDeviceMetricsOverride.bind(this));
558
559 /**
560 * @this {WebInspector.DeviceModeModel}
561 * @return {!Promise.<?>}
562 */
563 function setDeviceMetricsOverride() {
564 if (!this._target)
565 return Promise.resolve();
566
567 var clear = !pageWidth && !pageHeight && !mobile && !deviceScaleFactor && scale === 1 && !screenOrientation;
568 var allPromises = [];
569 if (resetPageScaleFactor)
570 allPromises.push(this._target.emulationAgent().resetPageScaleFactor());
571 var setDevicePromise;
572 if (clear) {
573 setDevicePromise = this._target.emulationAgent().clearDeviceMetricsOverr ide(
574 this._deviceMetricsOverrideAppliedForTest.bind(this));
575 } else {
576 var params = {
577 width: pageWidth,
578 height: pageHeight,
579 deviceScaleFactor: deviceScaleFactor,
580 mobile: mobile,
581 fitWindow: false,
582 scale: scale,
583 screenWidth: screenSize.width,
584 screenHeight: screenSize.height,
585 positionX: positionX,
586 positionY: positionY
587 };
588 if (screenOrientation)
589 params.screenOrientation = {type: screenOrientation, angle: screenOrie ntationAngle};
590 setDevicePromise = this._target.emulationAgent().invoke_setDeviceMetrics Override(
591 params, this._deviceMetricsOverrideAppliedForTest.bind(this));
592 }
593 allPromises.push(setDevicePromise);
594 return Promise.all(allPromises);
595 }
596 }
597
598 _deviceMetricsOverrideAppliedForTest() {
599 // Used for sniffing in tests.
600 }
601
602 /**
603 * @param {boolean} touchEnabled
604 * @param {boolean} mobile
605 */
606 _applyTouch(touchEnabled, mobile) {
607 WebInspector.MultitargetTouchModel.instance().setTouchEnabled(touchEnabled, mobile);
608 }
65 }; 609 };
66 610
67 /** @enum {string} */ 611 /** @enum {string} */
68 WebInspector.DeviceModeModel.Type = { 612 WebInspector.DeviceModeModel.Type = {
69 None: "None", 613 None: 'None',
70 Responsive: "Responsive", 614 Responsive: 'Responsive',
71 Device: "Device" 615 Device: 'Device'
72 }; 616 };
73 617
74 /** @enum {string} */ 618 /** @enum {string} */
75 WebInspector.DeviceModeModel.UA = { 619 WebInspector.DeviceModeModel.UA = {
76 Mobile: WebInspector.UIString("Mobile"), 620 Mobile: WebInspector.UIString('Mobile'),
77 MobileNoTouch: WebInspector.UIString("Mobile (no touch)"), 621 MobileNoTouch: WebInspector.UIString('Mobile (no touch)'),
78 Desktop: WebInspector.UIString("Desktop"), 622 Desktop: WebInspector.UIString('Desktop'),
79 DesktopTouch: WebInspector.UIString("Desktop (touch)") 623 DesktopTouch: WebInspector.UIString('Desktop (touch)')
80 }; 624 };
81 625
82 WebInspector.DeviceModeModel.MinDeviceSize = 50; 626 WebInspector.DeviceModeModel.MinDeviceSize = 50;
83 WebInspector.DeviceModeModel.MaxDeviceSize = 9999; 627 WebInspector.DeviceModeModel.MaxDeviceSize = 9999;
84 628
85 /** 629
86 * @param {string} value 630 WebInspector.DeviceModeModel._defaultMobileUserAgent =
87 * @return {boolean} 631 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 ( KHTML, like Gecko) Chrome/%s Mobile Safari/537.36';
88 */ 632 WebInspector.DeviceModeModel._defaultMobileUserAgent =
89 WebInspector.DeviceModeModel.deviceSizeValidator = function(value) 633 WebInspector.MultitargetNetworkManager.patchUserAgentWithChromeVersion(
90 { 634 WebInspector.DeviceModeModel._defaultMobileUserAgent);
91 if (/^[\d]+$/.test(value) && value >= WebInspector.DeviceModeModel.MinDevice Size && value <= WebInspector.DeviceModeModel.MaxDeviceSize)
92 return true;
93 return false;
94 };
95
96 /**
97 * @param {string} value
98 * @return {boolean}
99 */
100 WebInspector.DeviceModeModel.deviceScaleFactorValidator = function(value)
101 {
102 if (!value || (/^[\d]+(\.\d+)?|\.\d+$/.test(value) && value >= 0 && value <= 10))
103 return true;
104 return false;
105 };
106
107 WebInspector.DeviceModeModel._defaultMobileUserAgent = "Mozilla/5.0 (Linux; Andr oid 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Mobile Safari/537.36";
108 WebInspector.DeviceModeModel._defaultMobileUserAgent = WebInspector.MultitargetN etworkManager.patchUserAgentWithChromeVersion(WebInspector.DeviceModeModel._defa ultMobileUserAgent);
109 WebInspector.DeviceModeModel.defaultMobileScaleFactor = 2; 635 WebInspector.DeviceModeModel.defaultMobileScaleFactor = 2;
110
111 WebInspector.DeviceModeModel.prototype = {
112 /**
113 * @param {!Size} availableSize
114 * @param {!Size} preferredSize
115 */
116 setAvailableSize: function(availableSize, preferredSize)
117 {
118 this._availableSize = availableSize;
119 this._preferredSize = preferredSize;
120 this._initialized = true;
121 this._calculateAndEmulate(false);
122 },
123
124 /**
125 * @param {!WebInspector.DeviceModeModel.Type} type
126 * @param {?WebInspector.EmulatedDevice} device
127 * @param {?WebInspector.EmulatedDevice.Mode} mode
128 * @param {number=} scale
129 */
130 emulate: function(type, device, mode, scale)
131 {
132 var resetPageScaleFactor = this._type !== type || this._device !== devic e || this._mode !== mode;
133 this._type = type;
134
135 if (type === WebInspector.DeviceModeModel.Type.Device) {
136 console.assert(device && mode, "Must pass device and mode for device emulation");
137 this._mode = mode;
138 this._device = device;
139 if (this._initialized) {
140 var orientation = device.orientationByName(mode.orientation);
141 this._scaleSetting.set(scale || this._calculateFitScale(orientat ion.width, orientation.height, this._currentOutline(), this._currentInsets()));
142 }
143 } else {
144 this._device = null;
145 this._mode = null;
146 }
147
148 if (type !== WebInspector.DeviceModeModel.Type.None)
149 WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action .DeviceModeEnabled);
150 this._calculateAndEmulate(resetPageScaleFactor);
151 },
152
153 /**
154 * @param {number} width
155 */
156 setWidth: function(width)
157 {
158 var max = Math.min(WebInspector.DeviceModeModel.MaxDeviceSize, this._pre ferredScaledWidth());
159 width = Math.max(Math.min(width, max), 1);
160 this._widthSetting.set(width);
161 },
162
163 /**
164 * @param {number} width
165 */
166 setWidthAndScaleToFit: function(width)
167 {
168 width = Math.max(Math.min(width, WebInspector.DeviceModeModel.MaxDeviceS ize), 1);
169 this._scaleSetting.set(this._calculateFitScale(width, this._heightSettin g.get()));
170 this._widthSetting.set(width);
171 },
172
173 /**
174 * @param {number} height
175 */
176 setHeight: function(height)
177 {
178 var max = Math.min(WebInspector.DeviceModeModel.MaxDeviceSize, this._pre ferredScaledHeight());
179 height = Math.max(Math.min(height, max), 0);
180 if (height === this._preferredScaledHeight())
181 height = 0;
182 this._heightSetting.set(height);
183 },
184
185 /**
186 * @param {number} height
187 */
188 setHeightAndScaleToFit: function(height)
189 {
190 height = Math.max(Math.min(height, WebInspector.DeviceModeModel.MaxDevic eSize), 0);
191 this._scaleSetting.set(this._calculateFitScale(this._widthSetting.get(), height));
192 this._heightSetting.set(height);
193 },
194
195 /**
196 * @param {number} scale
197 */
198 setScale: function(scale)
199 {
200 this._scaleSetting.set(scale);
201 },
202
203 /**
204 * @return {?WebInspector.EmulatedDevice}
205 */
206 device: function()
207 {
208 return this._device;
209 },
210
211 /**
212 * @return {?WebInspector.EmulatedDevice.Mode}
213 */
214 mode: function()
215 {
216 return this._mode;
217 },
218
219 /**
220 * @return {!WebInspector.DeviceModeModel.Type}
221 */
222 type: function()
223 {
224 return this._type;
225 },
226
227 /**
228 * @return {string}
229 */
230 screenImage: function()
231 {
232 return (this._device && this._mode) ? this._device.modeImage(this._mode) : "";
233 },
234
235 /**
236 * @return {string}
237 */
238 outlineImage: function()
239 {
240 return (this._device && this._mode && this._deviceOutlineSetting.get()) ? this._device.outlineImage(this._mode) : "";
241 },
242
243 /**
244 * @return {!WebInspector.Rect}
245 */
246 outlineRect: function()
247 {
248 return this._outlineRect;
249 },
250
251 /**
252 * @return {!WebInspector.Rect}
253 */
254 screenRect: function()
255 {
256 return this._screenRect;
257 },
258
259 /**
260 * @return {!WebInspector.Rect}
261 */
262 visiblePageRect: function()
263 {
264 return this._visiblePageRect;
265 },
266
267 /**
268 * @return {number}
269 */
270 scale: function()
271 {
272 return this._scale;
273 },
274
275 /**
276 * @return {number}
277 */
278 fitScale: function()
279 {
280 return this._fitScale;
281 },
282
283 /**
284 * @return {!Size}
285 */
286 appliedDeviceSize: function()
287 {
288 return this._appliedDeviceSize;
289 },
290
291 /**
292 * @return {number}
293 */
294 appliedDeviceScaleFactor: function()
295 {
296 return this._appliedDeviceScaleFactor;
297 },
298
299 /**
300 * @return {!WebInspector.DeviceModeModel.UA}
301 */
302 appliedUserAgentType: function()
303 {
304 return this._appliedUserAgentType;
305 },
306
307 /**
308 * @return {boolean}
309 */
310 isFullHeight: function()
311 {
312 return !this._heightSetting.get();
313 },
314
315 /**
316 * @return {!WebInspector.Setting}
317 */
318 scaleSetting: function()
319 {
320 return this._scaleSetting;
321 },
322
323 /**
324 * @return {!WebInspector.Setting}
325 */
326 uaSetting: function()
327 {
328 return this._uaSetting;
329 },
330
331 /**
332 * @return {!WebInspector.Setting}
333 */
334 deviceScaleFactorSetting: function()
335 {
336 return this._deviceScaleFactorSetting;
337 },
338
339 /**
340 * @return {!WebInspector.Setting}
341 */
342 deviceOutlineSetting: function()
343 {
344 return this._deviceOutlineSetting;
345 },
346
347 reset: function()
348 {
349 this._deviceScaleFactorSetting.set(0);
350 this._scaleSetting.set(1);
351 this.setWidth(400);
352 this.setHeight(0);
353 this._uaSetting.set(WebInspector.DeviceModeModel.UA.Mobile);
354 },
355
356 /**
357 * @override
358 * @param {!WebInspector.Target} target
359 */
360 targetAdded: function(target)
361 {
362 if (!this._target) {
363 this._target = target;
364 if (this._onTargetAvailable) {
365 var callback = this._onTargetAvailable;
366 this._onTargetAvailable = null;
367 callback();
368 }
369 }
370 },
371
372 /**
373 * @override
374 * @param {!WebInspector.Target} target
375 */
376 targetRemoved: function(target)
377 {
378 if (this._target === target)
379 this._target = null;
380 },
381
382 _scaleSettingChanged: function()
383 {
384 this._calculateAndEmulate(false);
385 },
386
387 _widthSettingChanged: function()
388 {
389 this._calculateAndEmulate(false);
390 },
391
392 _heightSettingChanged: function()
393 {
394 this._calculateAndEmulate(false);
395 },
396
397 _uaSettingChanged: function()
398 {
399 this._calculateAndEmulate(true);
400 },
401
402 _deviceScaleFactorSettingChanged: function()
403 {
404 this._calculateAndEmulate(false);
405 },
406
407 _deviceOutlineSettingChanged: function()
408 {
409 this._calculateAndEmulate(false);
410 },
411
412 /**
413 * @return {number}
414 */
415 _preferredScaledWidth: function()
416 {
417 return Math.floor(this._preferredSize.width / (this._scaleSetting.get() || 1));
418 },
419
420 /**
421 * @return {number}
422 */
423 _preferredScaledHeight: function()
424 {
425 return Math.floor(this._preferredSize.height / (this._scaleSetting.get() || 1));
426 },
427
428 /**
429 * @return {!Insets}
430 */
431 _currentOutline: function()
432 {
433 var outline = new Insets(0, 0, 0, 0);
434 if (this._type !== WebInspector.DeviceModeModel.Type.Device)
435 return outline;
436 var orientation = this._device.orientationByName(this._mode.orientation) ;
437 if (this._deviceOutlineSetting.get())
438 outline = orientation.outlineInsets || outline;
439 return outline;
440 },
441
442 /**
443 * @return {!Insets}
444 */
445 _currentInsets: function()
446 {
447 if (this._type !== WebInspector.DeviceModeModel.Type.Device)
448 return new Insets(0, 0, 0, 0);
449 return this._mode.insets;
450 },
451
452 /**
453 * @param {boolean} resetPageScaleFactor
454 */
455 _calculateAndEmulate: function(resetPageScaleFactor)
456 {
457 if (!this._target)
458 this._onTargetAvailable = this._calculateAndEmulate.bind(this, reset PageScaleFactor);
459
460 if (this._type === WebInspector.DeviceModeModel.Type.Device) {
461 var orientation = this._device.orientationByName(this._mode.orientat ion);
462 var outline = this._currentOutline();
463 var insets = this._currentInsets();
464 this._fitScale = this._calculateFitScale(orientation.width, orientat ion.height, outline, insets);
465 if (this._device.mobile())
466 this._appliedUserAgentType = this._device.touch() ? WebInspector .DeviceModeModel.UA.Mobile : WebInspector.DeviceModeModel.UA.MobileNoTouch;
467 else
468 this._appliedUserAgentType = this._device.touch() ? WebInspector .DeviceModeModel.UA.DesktopTouch : WebInspector.DeviceModeModel.UA.Desktop;
469 this._applyDeviceMetrics(new Size(orientation.width, orientation.hei ght), insets, outline, this._scaleSetting.get(), this._device.deviceScaleFactor, this._device.mobile(), this._mode.orientation === WebInspector.EmulatedDevice.H orizontal ? "landscapePrimary" : "portraitPrimary", resetPageScaleFactor);
470 this._applyUserAgent(this._device.userAgent);
471 this._applyTouch(this._device.touch(), this._device.mobile());
472 } else if (this._type === WebInspector.DeviceModeModel.Type.None) {
473 this._fitScale = this._calculateFitScale(this._availableSize.width, this._availableSize.height);
474 this._appliedUserAgentType = WebInspector.DeviceModeModel.UA.Desktop ;
475 this._applyDeviceMetrics(this._availableSize, new Insets(0, 0, 0, 0) , new Insets(0, 0, 0, 0), 1, 0, false, "", resetPageScaleFactor);
476 this._applyUserAgent("");
477 this._applyTouch(false, false);
478 } else if (this._type === WebInspector.DeviceModeModel.Type.Responsive) {
479 var screenWidth = this._widthSetting.get();
480 if (!screenWidth || screenWidth > this._preferredScaledWidth())
481 screenWidth = this._preferredScaledWidth();
482 var screenHeight = this._heightSetting.get();
483 if (!screenHeight || screenHeight > this._preferredScaledHeight())
484 screenHeight = this._preferredScaledHeight();
485 var mobile = this._uaSetting.get() === WebInspector.DeviceModeModel. UA.Mobile || this._uaSetting.get() === WebInspector.DeviceModeModel.UA.MobileNoT ouch;
486 var defaultDeviceScaleFactor = mobile ? WebInspector.DeviceModeModel .defaultMobileScaleFactor : 0;
487 this._fitScale = this._calculateFitScale(this._widthSetting.get(), t his._heightSetting.get());
488 this._appliedUserAgentType = this._uaSetting.get();
489 this._applyDeviceMetrics(new Size(screenWidth, screenHeight), new In sets(0, 0, 0, 0), new Insets(0, 0, 0, 0), this._scaleSetting.get(), this._device ScaleFactorSetting.get() || defaultDeviceScaleFactor, mobile, screenHeight >= sc reenWidth ? "portraitPrimary" : "landscapePrimary", resetPageScaleFactor);
490 this._applyUserAgent(mobile ? WebInspector.DeviceModeModel._defaultM obileUserAgent : "");
491 this._applyTouch(this._uaSetting.get() === WebInspector.DeviceModeMo del.UA.DesktopTouch || this._uaSetting.get() === WebInspector.DeviceModeModel.UA .Mobile, this._uaSetting.get() === WebInspector.DeviceModeModel.UA.Mobile);
492 }
493 if (this._target)
494 this._target.renderingAgent().setShowViewportSizeOnResize(this._type === WebInspector.DeviceModeModel.Type.None);
495 this._updateCallback.call(null);
496 },
497
498 /**
499 * @param {number} screenWidth
500 * @param {number} screenHeight
501 * @param {!Insets=} outline
502 * @param {!Insets=} insets
503 * @return {number}
504 */
505 _calculateFitScale: function(screenWidth, screenHeight, outline, insets)
506 {
507 var outlineWidth = outline ? outline.left + outline.right : 0;
508 var outlineHeight = outline ? outline.top + outline.bottom : 0;
509 var insetsWidth = insets ? insets.left + insets.right : 0;
510 var insetsHeight = insets ? insets.top + insets.bottom : 0;
511 var scale = Math.min(screenWidth ? this._preferredSize.width / (screenWi dth + outlineWidth) : 1, screenHeight ? this._preferredSize.height / (screenHeig ht + outlineHeight) : 1);
512 scale = Math.min(Math.floor(scale * 100), 100);
513
514 var sharpScale = scale;
515 while (sharpScale > scale * 0.7) {
516 var sharp = true;
517 if (screenWidth)
518 sharp = sharp && Number.isInteger((screenWidth - insetsWidth) * sharpScale / 100);
519 if (screenHeight)
520 sharp = sharp && Number.isInteger((screenHeight - insetsHeight) * sharpScale / 100);
521 if (sharp)
522 return sharpScale / 100;
523 sharpScale -= 1;
524 }
525 return scale / 100;
526 },
527
528 /**
529 * @param {number} width
530 * @param {number} height
531 */
532 setSizeAndScaleToFit: function(width, height)
533 {
534 this._scaleSetting.set(this._calculateFitScale(width, height));
535 this.setWidth(width);
536 },
537
538 /**
539 * @param {string} userAgent
540 */
541 _applyUserAgent: function(userAgent)
542 {
543 WebInspector.multitargetNetworkManager.setUserAgentOverride(userAgent);
544 },
545
546 /**
547 * @param {!Size} screenSize
548 * @param {!Insets} insets
549 * @param {!Insets} outline
550 * @param {number} scale
551 * @param {number} deviceScaleFactor
552 * @param {boolean} mobile
553 * @param {string} screenOrientation
554 * @param {boolean} resetPageScaleFactor
555 */
556 _applyDeviceMetrics: function(screenSize, insets, outline, scale, deviceScal eFactor, mobile, screenOrientation, resetPageScaleFactor)
557 {
558 screenSize.width = Math.max(1, Math.floor(screenSize.width));
559 screenSize.height = Math.max(1, Math.floor(screenSize.height));
560
561 var pageWidth = screenSize.width - insets.left - insets.right;
562 var pageHeight = screenSize.height - insets.top - insets.bottom;
563
564 var positionX = insets.left;
565 var positionY = insets.top;
566 var screenOrientationAngle = screenOrientation === "landscapePrimary" ? 90 : 0;
567
568 this._appliedDeviceSize = screenSize;
569 this._appliedDeviceScaleFactor = deviceScaleFactor || window.devicePixel Ratio;
570 this._screenRect = new WebInspector.Rect(
571 Math.max(0, (this._availableSize.width - screenSize.width * scale) / 2),
572 outline.top * scale,
573 screenSize.width * scale,
574 screenSize.height * scale);
575 this._outlineRect = new WebInspector.Rect(
576 this._screenRect.left - outline.left * scale,
577 0,
578 (outline.left + screenSize.width + outline.right) * scale,
579 (outline.top + screenSize.height + outline.bottom) * scale);
580 this._visiblePageRect = new WebInspector.Rect(
581 positionX * scale,
582 positionY * scale,
583 Math.min(pageWidth * scale, this._availableSize.width - this._screen Rect.left - positionX * scale),
584 Math.min(pageHeight * scale, this._availableSize.height - this._scre enRect.top - positionY * scale));
585 this._scale = scale;
586
587 if (scale === 1 && this._availableSize.width >= screenSize.width && this ._availableSize.height >= screenSize.height) {
588 // When we have enough space, no page size override is required. Thi s will speed things up and remove lag.
589 pageWidth = 0;
590 pageHeight = 0;
591 }
592 if (this._visiblePageRect.width === pageWidth * scale && this._visiblePa geRect.height === pageHeight * scale && Number.isInteger(pageWidth * scale) && N umber.isInteger(pageHeight * scale)) {
593 // When we only have to apply scale, do not resize the page. This wi ll speed things up and remove lag.
594 pageWidth = 0;
595 pageHeight = 0;
596 }
597
598 this._deviceMetricsThrottler.schedule(setDeviceMetricsOverride.bind(this ));
599
600 /**
601 * @this {WebInspector.DeviceModeModel}
602 * @return {!Promise.<?>}
603 */
604 function setDeviceMetricsOverride()
605 {
606 if (!this._target)
607 return Promise.resolve();
608
609 var clear = !pageWidth && !pageHeight && !mobile && !deviceScaleFact or && scale === 1 && !screenOrientation;
610 var allPromises = [];
611 if (resetPageScaleFactor)
612 allPromises.push(this._target.emulationAgent().resetPageScaleFac tor());
613 var setDevicePromise;
614 if (clear) {
615 setDevicePromise = this._target.emulationAgent().clearDeviceMetr icsOverride(this._deviceMetricsOverrideAppliedForTest.bind(this));
616 } else {
617 var params = {width: pageWidth, height: pageHeight, deviceScaleF actor: deviceScaleFactor, mobile: mobile, fitWindow: false, scale: scale, screen Width: screenSize.width, screenHeight: screenSize.height, positionX: positionX, positionY: positionY};
618 if (screenOrientation)
619 params.screenOrientation = {type: screenOrientation, angle: screenOrientationAngle};
620 setDevicePromise = this._target.emulationAgent().invoke_setDevic eMetricsOverride(params, this._deviceMetricsOverrideAppliedForTest.bind(this));
621 }
622 allPromises.push(setDevicePromise);
623 return Promise.all(allPromises);
624 }
625 },
626
627 _deviceMetricsOverrideAppliedForTest: function()
628 {
629 // Used for sniffing in tests.
630 },
631
632 /**
633 * @param {boolean} touchEnabled
634 * @param {boolean} mobile
635 */
636 _applyTouch: function(touchEnabled, mobile)
637 {
638 WebInspector.MultitargetTouchModel.instance().setTouchEnabled(touchEnabl ed, mobile);
639 }
640 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698