2 * Copyright (C) 2012 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 * @extends {WebInspector.Object}
35 WebInspector
.OverridesSupport = function()
37 this._touchEmulationSuspended
= false;
38 this._emulateMobileEnabled
= false;
40 this._pageResizer
= null;
41 this._deviceScale
= 1;
42 this._fixedDeviceScale
= false;
43 this._initialized
= false;
44 this._deviceMetricsThrottler
= new WebInspector
.Throttler(0);
47 this.settings
._emulationEnabled
= WebInspector
.settings
.createSetting("emulationEnabled", false);
49 this.settings
.userAgent
= WebInspector
.settings
.createSetting("userAgent", "");
51 this.settings
.emulateResolution
= WebInspector
.settings
.createSetting("emulateResolution", true);
52 this.settings
.deviceWidth
= WebInspector
.settings
.createSetting("deviceWidth", 360);
53 this.settings
.deviceHeight
= WebInspector
.settings
.createSetting("deviceHeight", 640);
54 this.settings
.deviceScaleFactor
= WebInspector
.settings
.createSetting("deviceScaleFactor", 0);
55 this.settings
.deviceFitWindow
= WebInspector
.settings
.createSetting("deviceFitWindow", true);
56 this.settings
.emulateMobile
= WebInspector
.settings
.createSetting("emulateMobile", false);
58 this.settings
.emulateTouch
= WebInspector
.settings
.createSetting("emulateTouch", false);
60 this.settings
.overrideGeolocation
= WebInspector
.settings
.createSetting("overrideGeolocation", false);
61 this.settings
.geolocationOverride
= WebInspector
.settings
.createSetting("geolocationOverride", "");
63 this.settings
.overrideDeviceOrientation
= WebInspector
.settings
.createSetting("overrideDeviceOrientation", false);
64 this.settings
.deviceOrientationOverride
= WebInspector
.settings
.createSetting("deviceOrientationOverride", "");
66 this.settings
.screenOrientationOverride
= WebInspector
.settings
.createSetting("screenOrientationOverride", "");
68 this.settings
.overrideCSSMedia
= WebInspector
.settings
.createSetting("overrideCSSMedia", false);
69 this.settings
.emulatedCSSMedia
= WebInspector
.settings
.createSetting("emulatedCSSMedia", "print");
71 this.settings
.javaScriptDisabled
= WebInspector
.moduleSetting("javaScriptDisabled");
74 WebInspector
.OverridesSupport
.Events
= {
75 OverridesWarningUpdated
: "OverridesWarningUpdated",
76 EmulationStateChanged
: "EmulationStateChanged"
79 WebInspector
.OverridesSupport
.MaxDeviceSize
= 9999;
83 * @extends {WebInspector.EventTarget}
85 WebInspector
.OverridesSupport
.PageResizer = function()
89 WebInspector
.OverridesSupport
.PageResizer
.Events
= {
90 AvailableSizeChanged
: "AvailableSizeChanged",
91 ResizeRequested
: "ResizeRequested",
92 FixedScaleRequested
: "FixedScaleRequested",
93 InsetsChanged
: "InsetsChanged"
96 WebInspector
.OverridesSupport
.PageResizer
.prototype = {
98 * Zero width and height mean default size.
99 * Scale should be applied to page-scale-dependent UI bits. Zero means no scale.
100 * @param {number} dipWidth
101 * @param {number} dipHeight
102 * @param {number} scale
104 update: function(dipWidth
, dipHeight
, scale
) { }
107 /** @typedef {{width: number, height: number, deviceScaleFactor: number, userAgent: string, touch: boolean, mobile: boolean}} */
108 WebInspector
.OverridesSupport
.Device
= {};
112 * @param {number} latitude
113 * @param {number} longitude
114 * @param {string} error
116 WebInspector
.OverridesSupport
.GeolocationPosition = function(latitude
, longitude
, error
)
118 this.latitude
= latitude
;
119 this.longitude
= longitude
;
123 WebInspector
.OverridesSupport
.GeolocationPosition
.prototype = {
127 toSetting: function()
129 return (typeof this.latitude
=== "number" && typeof this.longitude
=== "number" && typeof this.error
=== "string") ? this.latitude
+ "@" + this.longitude
+ ":" + this.error
: "";
134 * @return {!WebInspector.OverridesSupport.GeolocationPosition}
136 WebInspector
.OverridesSupport
.GeolocationPosition
.parseSetting = function(value
)
139 var splitError
= value
.split(":");
140 if (splitError
.length
=== 2) {
141 var splitPosition
= splitError
[0].split("@");
142 if (splitPosition
.length
=== 2)
143 return new WebInspector
.OverridesSupport
.GeolocationPosition(parseFloat(splitPosition
[0]), parseFloat(splitPosition
[1]), splitError
[1]);
146 return new WebInspector
.OverridesSupport
.GeolocationPosition(0, 0, "");
150 * @return {?WebInspector.OverridesSupport.GeolocationPosition}
152 WebInspector
.OverridesSupport
.GeolocationPosition
.parseUserInput = function(latitudeString
, longitudeString
, errorStatus
)
154 function isUserInputValid(value
)
158 return /^[-]?[0-9]*[.]?[0-9]*$/.test(value
);
161 if (!latitudeString
&& !longitudeString
)
164 var isLatitudeValid
= isUserInputValid(latitudeString
);
165 var isLongitudeValid
= isUserInputValid(longitudeString
);
167 if (!isLatitudeValid
&& !isLongitudeValid
)
170 var latitude
= isLatitudeValid
? parseFloat(latitudeString
) : -1;
171 var longitude
= isLongitudeValid
? parseFloat(longitudeString
) : -1;
173 return new WebInspector
.OverridesSupport
.GeolocationPosition(latitude
, longitude
, errorStatus
? "PositionUnavailable" : "");
178 * @param {number} alpha
179 * @param {number} beta
180 * @param {number} gamma
182 WebInspector
.OverridesSupport
.DeviceOrientation = function(alpha
, beta
, gamma
)
189 WebInspector
.OverridesSupport
.DeviceOrientation
.prototype = {
193 toSetting: function()
195 return JSON
.stringify(this);
200 * @return {!WebInspector.OverridesSupport.DeviceOrientation}
202 WebInspector
.OverridesSupport
.DeviceOrientation
.parseSetting = function(value
)
205 var jsonObject
= JSON
.parse(value
);
206 return new WebInspector
.OverridesSupport
.DeviceOrientation(jsonObject
.alpha
, jsonObject
.beta
, jsonObject
.gamma
);
208 return new WebInspector
.OverridesSupport
.DeviceOrientation(0, 0, 0);
212 * @return {?WebInspector.OverridesSupport.DeviceOrientation}
214 WebInspector
.OverridesSupport
.DeviceOrientation
.parseUserInput = function(alphaString
, betaString
, gammaString
)
216 function isUserInputValid(value
)
220 return /^[-]?[0-9]*[.]?[0-9]*$/.test(value
);
223 if (!alphaString
&& !betaString
&& !gammaString
)
226 var isAlphaValid
= isUserInputValid(alphaString
);
227 var isBetaValid
= isUserInputValid(betaString
);
228 var isGammaValid
= isUserInputValid(gammaString
);
230 if (!isAlphaValid
&& !isBetaValid
&& !isGammaValid
)
233 var alpha
= isAlphaValid
? parseFloat(alphaString
) : -1;
234 var beta
= isBetaValid
? parseFloat(betaString
) : -1;
235 var gamma
= isGammaValid
? parseFloat(gammaString
) : -1;
237 return new WebInspector
.OverridesSupport
.DeviceOrientation(alpha
, beta
, gamma
);
241 * @param {string} value
244 WebInspector
.OverridesSupport
.deviceSizeValidator = function(value
)
246 if (!value
|| (/^[\d]+$/.test(value
) && value
>= 0 && value
<= WebInspector
.OverridesSupport
.MaxDeviceSize
))
248 return WebInspector
.UIString("Value must be non-negative integer");
252 * @param {string} value
255 WebInspector
.OverridesSupport
.deviceScaleFactorValidator = function(value
)
257 if (!value
|| (/^[\d]+(\.\d+)?|\.\d+$/.test(value
) && value
>= 0 && value
<= 10))
259 return WebInspector
.UIString("Value must be non-negative float");
262 WebInspector
.OverridesSupport
._touchEventsScriptIdSymbol
= Symbol("OverridesSupport.touchEventsScriptIdSymbol");
264 WebInspector
.OverridesSupport
.prototype = {
268 canEmulate: function()
270 return !!this._target
&& this._targetCanEmulate
;
276 emulationEnabled: function()
278 return this.canEmulate() && this.settings
._emulationEnabled
.get();
282 * @param {boolean} enabled
284 setEmulationEnabled: function(enabled
)
286 if (this.canEmulate()) {
287 this.settings
._emulationEnabled
.set(enabled
);
288 this.dispatchEventToListeners(WebInspector
.OverridesSupport
.Events
.EmulationStateChanged
);
289 if (enabled
&& this.settings
.emulateResolution
.get())
290 this._target
.emulationAgent().resetScrollAndPageScaleFactor();
295 * @param {!WebInspector.Target} target
296 * @param {function()} callback
298 init: function(target
, callback
)
301 target
.emulationAgent().canEmulate(canEmulateCallback
.bind(this));
303 canEmulateCallback
.call(this, null, false);
306 * @param {?Protocol.Error} error
307 * @param {boolean} canEmulate
308 * @this {WebInspector.OverridesSupport}
310 function canEmulateCallback(error
, canEmulate
)
312 this._target
= target
;
313 this._targetCanEmulate
= !error
&& canEmulate
;
314 this._initialized
= true;
316 if (this.canEmulate()) {
317 target
.resourceTreeModel
.addEventListener(WebInspector
.ResourceTreeModel
.EventTypes
.MainFrameNavigated
, this._onMainFrameNavigated
, this);
318 var domModel
= WebInspector
.DOMModel
.fromTarget(this._target
);
320 domModel
.addEventListener(WebInspector
.DOMModel
.Events
.InspectModeWillBeToggled
, this._inspectModeWillBeToggled
, this);
321 this._applyInitialOverrides();
324 this.dispatchEventToListeners(WebInspector
.OverridesSupport
.Events
.EmulationStateChanged
);
331 * @param {?WebInspector.OverridesSupport.PageResizer} pageResizer
332 * @param {!Size} availableSize
333 * @param {!Insets} insets
335 setPageResizer: function(pageResizer
, availableSize
, insets
)
337 if (pageResizer
=== this._pageResizer
)
340 if (this._pageResizer
) {
341 this._pageResizer
.removeEventListener(WebInspector
.OverridesSupport
.PageResizer
.Events
.AvailableSizeChanged
, this._onPageResizerAvailableSizeChanged
, this);
342 this._pageResizer
.removeEventListener(WebInspector
.OverridesSupport
.PageResizer
.Events
.ResizeRequested
, this._onPageResizerResizeRequested
, this);
343 this._pageResizer
.removeEventListener(WebInspector
.OverridesSupport
.PageResizer
.Events
.FixedScaleRequested
, this._onPageResizerFixedScaleRequested
, this);
344 this._pageResizer
.removeEventListener(WebInspector
.OverridesSupport
.PageResizer
.Events
.InsetsChanged
, this._onPageResizerInsetsChanged
, this);
346 this._pageResizer
= pageResizer
;
347 this._pageResizerAvailableSize
= availableSize
;
348 this._pageResizerInsets
= insets
;
349 if (this._pageResizer
) {
350 this._pageResizer
.addEventListener(WebInspector
.OverridesSupport
.PageResizer
.Events
.AvailableSizeChanged
, this._onPageResizerAvailableSizeChanged
, this);
351 this._pageResizer
.addEventListener(WebInspector
.OverridesSupport
.PageResizer
.Events
.ResizeRequested
, this._onPageResizerResizeRequested
, this);
352 this._pageResizer
.addEventListener(WebInspector
.OverridesSupport
.PageResizer
.Events
.FixedScaleRequested
, this._onPageResizerFixedScaleRequested
, this);
353 this._pageResizer
.addEventListener(WebInspector
.OverridesSupport
.PageResizer
.Events
.InsetsChanged
, this._onPageResizerInsetsChanged
, this);
355 this._deviceMetricsChanged(false);
359 * @param {!WebInspector.OverridesSupport.Device} device
361 emulateDevice: function(device
)
363 this._deviceMetricsChangedListenerMuted
= true;
364 this._userAgentChangedListenerMuted
= true;
365 this.settings
.userAgent
.set(device
.userAgent
);
366 this.settings
.emulateResolution
.set(true);
367 this.settings
.deviceWidth
.set(device
.width
);
368 this.settings
.deviceHeight
.set(device
.height
);
369 this.settings
.deviceScaleFactor
.set(device
.deviceScaleFactor
);
370 this.settings
.emulateTouch
.set(device
.touch
);
371 this.settings
.emulateMobile
.set(device
.mobile
);
372 delete this._deviceMetricsChangedListenerMuted
;
373 delete this._userAgentChangedListenerMuted
;
375 if (this._initialized
) {
376 this._deviceMetricsChanged(true);
377 this._userAgentChanged();
383 this._deviceMetricsChangedListenerMuted
= true;
384 this._userAgentChangedListenerMuted
= true;
385 this.settings
.userAgent
.set("");
386 this.settings
.emulateResolution
.set(false);
387 this.settings
.deviceScaleFactor
.set(0);
388 this.settings
.emulateTouch
.set(false);
389 this.settings
.emulateMobile
.set(false);
390 this.settings
.overrideDeviceOrientation
.set(false);
391 this.settings
.screenOrientationOverride
.set("");
392 this.settings
.overrideGeolocation
.set(false);
393 this.settings
.overrideCSSMedia
.set(false);
394 delete this._deviceMetricsChangedListenerMuted
;
395 delete this._userAgentChangedListenerMuted
;
397 if (this._initialized
) {
398 this._deviceMetricsChanged(false);
399 this._userAgentChanged();
404 * @param {!WebInspector.OverridesSupport.Device} device
407 isEmulatingDevice: function(device
)
409 var sameResolution
= this.settings
.emulateResolution
.get() ?
410 (this.settings
.deviceWidth
.get() === device
.width
&& this.settings
.deviceHeight
.get() === device
.height
&& this.settings
.deviceScaleFactor
.get() === device
.deviceScaleFactor
) :
411 (!device
.width
&& !device
.height
&& !device
.deviceScaleFactor
);
412 return this.settings
.userAgent
.get() === device
.userAgent
413 && this.settings
.emulateTouch
.get() === device
.touch
414 && this.settings
.emulateMobile
.get() === device
.mobile
419 * @param {!WebInspector.Event} event
421 _inspectModeWillBeToggled: function(event
)
423 var inspectModeEnabled
= /** @type {boolean} */ (event
.data
);
424 this._touchEmulationSuspended
= inspectModeEnabled
;
425 this._emulateTouchEventsChanged();
428 _applyInitialOverrides: function()
430 this.settings
._emulationEnabled
.addChangeListener(this._userAgentChanged
, this);
431 this.settings
.userAgent
.addChangeListener(this._userAgentChanged
, this);
433 this.settings
._emulationEnabled
.addChangeListener(this._deviceMetricsChanged
.bind(this, false));
434 this.settings
.emulateResolution
.addChangeListener(this._deviceMetricsChanged
.bind(this, false));
435 this.settings
.deviceWidth
.addChangeListener(this._deviceMetricsChanged
.bind(this, false));
436 this.settings
.deviceHeight
.addChangeListener(this._deviceMetricsChanged
.bind(this, false));
437 this.settings
.deviceScaleFactor
.addChangeListener(this._deviceMetricsChanged
.bind(this, false));
438 this.settings
.emulateMobile
.addChangeListener(this._deviceMetricsChanged
.bind(this, false));
439 this.settings
.deviceFitWindow
.addChangeListener(this._deviceMetricsChanged
.bind(this, false));
441 this.settings
._emulationEnabled
.addChangeListener(this._geolocationPositionChanged
, this);
442 this.settings
.overrideGeolocation
.addChangeListener(this._geolocationPositionChanged
, this);
443 this.settings
.geolocationOverride
.addChangeListener(this._geolocationPositionChanged
, this);
445 this.settings
._emulationEnabled
.addChangeListener(this._deviceOrientationChanged
, this);
446 this.settings
.overrideDeviceOrientation
.addChangeListener(this._deviceOrientationChanged
, this);
447 this.settings
.deviceOrientationOverride
.addChangeListener(this._deviceOrientationChanged
, this);
449 this.settings
._emulationEnabled
.addChangeListener(this._screenOrientationChanged
, this);
450 this.settings
.screenOrientationOverride
.addChangeListener(this._screenOrientationChanged
, this);
452 this.settings
._emulationEnabled
.addChangeListener(this._emulateTouchEventsChanged
, this);
453 this.settings
.emulateTouch
.addChangeListener(this._emulateTouchEventsChanged
, this);
455 this.settings
._emulationEnabled
.addChangeListener(this._cssMediaChanged
, this);
456 this.settings
.overrideCSSMedia
.addChangeListener(this._cssMediaChanged
, this);
457 this.settings
.emulatedCSSMedia
.addChangeListener(this._cssMediaChanged
, this);
459 this.settings
.javaScriptDisabled
.addChangeListener(this._javaScriptDisabledChanged
, this);
460 this._javaScriptDisabledChanged();
462 this.settings
._emulationEnabled
.addChangeListener(this._showRulersChanged
, this);
463 WebInspector
.moduleSetting("showMetricsRulers").addChangeListener(this._showRulersChanged
, this);
464 this._showRulersChanged();
466 if (this.emulationEnabled()) {
467 if (this.settings
.overrideDeviceOrientation
.get())
468 this._deviceOrientationChanged();
470 if (this.settings
.screenOrientationOverride
.get())
471 this._screenOrientationChanged();
473 if (this.settings
.overrideGeolocation
.get())
474 this._geolocationPositionChanged();
476 if (this.settings
.emulateTouch
.get())
477 this._emulateTouchEventsChanged();
479 if (this.settings
.overrideCSSMedia
.get())
480 this._cssMediaChanged();
482 this._deviceMetricsChanged(true);
484 this._userAgentChanged();
488 _userAgentChanged: function()
490 if (this._userAgentChangedListenerMuted
)
492 var userAgent
= this.emulationEnabled() ? this.settings
.userAgent
.get() : "";
493 WebInspector
.multitargetNetworkManager
.setUserAgentOverride(userAgent
);
494 if (this._userAgent
!== userAgent
)
495 this._updateUserAgentWarningMessage(WebInspector
.UIString("You might need to reload the page for proper user agent spoofing and viewport rendering."));
496 this._userAgent
= userAgent
;
500 * @param {!WebInspector.Event} event
502 _onPageResizerAvailableSizeChanged: function(event
)
504 this._pageResizerAvailableSize
= /** @type {!Size} */ (event
.data
.size
);
505 this._pageResizerInsets
= /** @type {!Insets} */ (event
.data
.insets
);
506 this._deviceMetricsChanged(false);
510 * @param {!WebInspector.Event} event
512 _onPageResizerInsetsChanged: function(event
)
514 this._pageResizerInsets
= /** @type {!Insets} */ (event
.data
);
518 * @param {!WebInspector.Event} event
520 _onPageResizerResizeRequested: function(event
)
522 if (typeof event
.data
.width
!== "undefined") {
523 var width
= /** @type {number} */ (event
.data
.width
);
524 if (width
!== this.settings
.deviceWidth
.get())
525 this.settings
.deviceWidth
.set(width
);
527 if (typeof event
.data
.height
!== "undefined") {
528 var height
= /** @type {number} */ (event
.data
.height
);
529 if (height
!== this.settings
.deviceHeight
.get())
530 this.settings
.deviceHeight
.set(height
);
535 * @param {!WebInspector.Event} event
537 _onPageResizerFixedScaleRequested: function(event
)
539 this._fixedDeviceScale
= /** @type {boolean} */ (event
.data
);
540 this._deviceMetricsChanged(false);
544 * @param {boolean} resetScrollAndPageScale
546 _deviceMetricsChanged: function(resetScrollAndPageScale
)
548 if (!this._initialized
)
551 this._showRulersChanged();
553 if (this._deviceMetricsChangedListenerMuted
)
556 if (!this.emulationEnabled()) {
557 this._deviceMetricsThrottler
.schedule(clearDeviceMetricsOverride
.bind(this));
558 if (this._pageResizer
)
559 this._pageResizer
.update(0, 0, 1);
563 var dipWidth
= this.settings
.emulateResolution
.get() ? this.settings
.deviceWidth
.get() : 0;
564 var dipHeight
= this.settings
.emulateResolution
.get() ? this.settings
.deviceHeight
.get() : 0;
566 var overrideWidth
= dipWidth
;
567 var overrideHeight
= dipHeight
;
568 var screenWidth
= dipWidth
;
569 var screenHeight
= dipHeight
;
573 if (this._pageResizer
) {
574 var available
= this._pageResizerAvailableSize
;
575 var insets
= this._pageResizerInsets
;
576 if (this.settings
.deviceFitWindow
.get()) {
577 if (this._fixedDeviceScale
) {
578 scale
= this._deviceScale
;
581 while (available
.width
< (dipWidth
+ insets
.left
+ insets
.right
) * scale
|| available
.height
< (dipHeight
+ insets
.top
+ insets
.bottom
) * scale
)
586 this._pageResizer
.update(Math
.min(dipWidth
* scale
, available
.width
- insets
.left
* scale
), Math
.min(dipHeight
* scale
, available
.height
- insets
.top
* scale
), scale
);
587 if (scale
=== 1 && available
.width
>= dipWidth
&& available
.height
>= dipHeight
) {
588 // When we have enough space, no page size override is required. This will speed things up and remove lag.
592 if (dipWidth
=== 0 && dipHeight
!== 0)
593 overrideWidth
= Math
.round(available
.width
/ scale
);
594 if (dipHeight
=== 0 && dipWidth
!== 0)
595 overrideHeight
= Math
.round(available
.height
/ scale
);
596 screenWidth
= dipWidth
+ insets
.left
+ insets
.right
;
597 screenHeight
= dipHeight
+ insets
.top
+ insets
.bottom
;
598 positionX
= insets
.left
;
599 positionY
= insets
.top
;
601 this._deviceScale
= scale
;
603 this._deviceMetricsThrottler
.schedule(setDeviceMetricsOverride
.bind(this));
606 * @this {WebInspector.OverridesSupport}
607 * @return {!Promise.<?>}
609 function setDeviceMetricsOverride()
611 var setDevicePromise
= this._target
.emulationAgent().setDeviceMetricsOverride(
612 overrideWidth
, overrideHeight
, this.settings
.emulateResolution
.get() ? this.settings
.deviceScaleFactor
.get() : 0,
613 this.settings
.emulateMobile
.get(), this._pageResizer
? false : this.settings
.deviceFitWindow
.get(), scale
, 0, 0,
614 screenWidth
, screenHeight
, positionX
, positionY
, apiCallback
.bind(this))
615 var allPromises
= [ setDevicePromise
];
616 if (resetScrollAndPageScale
)
617 allPromises
.push(this._target
.emulationAgent().resetScrollAndPageScaleFactor());
618 return Promise
.all(allPromises
);
622 * @this {WebInspector.OverridesSupport}
623 * @return {!Promise.<?>}
625 function clearDeviceMetricsOverride()
627 return this._target
.emulationAgent().clearDeviceMetricsOverride(apiCallback
.bind(this))
631 * @param {?Protocol.Error} error
632 * @this {WebInspector.OverridesSupport}
634 function apiCallback(error
)
637 this._updateDeviceMetricsWarningMessage(WebInspector
.UIString("Screen emulation is not available on this page."));
638 this._deviceMetricsOverrideAppliedForTest();
642 var mobileEnabled
= this.emulationEnabled() && this.settings
.emulateMobile
.get();
643 if (this._emulateMobileEnabled
!== mobileEnabled
)
644 this._updateDeviceMetricsWarningMessage(WebInspector
.UIString("You might need to reload the page for proper user agent spoofing and viewport rendering."));
645 this._emulateMobileEnabled
= mobileEnabled
;
646 this._deviceMetricsOverrideAppliedForTest();
650 _deviceMetricsOverrideAppliedForTest: function()
652 // Used for sniffing in tests.
655 _geolocationPositionChanged: function()
657 if (!this.emulationEnabled() || !this.settings
.overrideGeolocation
.get()) {
658 this._target
.emulationAgent().clearGeolocationOverride();
661 var geolocation
= WebInspector
.OverridesSupport
.GeolocationPosition
.parseSetting(this.settings
.geolocationOverride
.get());
662 if (geolocation
.error
)
663 this._target
.emulationAgent().setGeolocationOverride();
665 this._target
.emulationAgent().setGeolocationOverride(geolocation
.latitude
, geolocation
.longitude
, 150);
668 _deviceOrientationChanged: function()
670 if (!this.emulationEnabled() || !this.settings
.overrideDeviceOrientation
.get()) {
671 this._target
.deviceOrientationAgent().clearDeviceOrientationOverride();
675 var deviceOrientation
= WebInspector
.OverridesSupport
.DeviceOrientation
.parseSetting(this.settings
.deviceOrientationOverride
.get());
676 this._target
.deviceOrientationAgent().setDeviceOrientationOverride(deviceOrientation
.alpha
, deviceOrientation
.beta
, deviceOrientation
.gamma
);
679 _screenOrientationChanged: function()
681 if (!this.emulationEnabled() || !this.settings
.screenOrientationOverride
.get()) {
682 this._target
.screenOrientationAgent().clearScreenOrientationOverride();
686 var screenOrientation
= this.settings
.screenOrientationOverride
.get();
687 this._target
.screenOrientationAgent().setScreenOrientationOverride(screenOrientation
=== "landscapePrimary" ? 90 : 0, screenOrientation
);
690 _emulateTouchEventsChanged: function()
692 var emulationEnabled
= this.emulationEnabled() && this.settings
.emulateTouch
.get() && !this._touchEmulationSuspended
;
693 var configuration
= this.settings
.emulateMobile
.get() ? "mobile" : "desktop";
694 var target
= this._target
;
697 * @suppressGlobalPropertiesCheck
699 const injectedFunction = function() {
700 const touchEvents
= ["ontouchstart", "ontouchend", "ontouchmove", "ontouchcancel"];
701 var recepients
= [window
.__proto__
, document
.__proto__
];
702 for (var i
= 0; i
< touchEvents
.length
; ++i
) {
703 for (var j
= 0; j
< recepients
.length
; ++j
) {
704 if (!(touchEvents
[i
] in recepients
[j
]))
705 Object
.defineProperty(recepients
[j
], touchEvents
[i
], { value
: null, writable
: true, configurable
: true, enumerable
: true });
710 var symbol
= WebInspector
.OverridesSupport
._touchEventsScriptIdSymbol
;
712 if (typeof target
[symbol
] !== "undefined") {
713 target
.pageAgent().removeScriptToEvaluateOnLoad(target
[symbol
]);
714 delete target
[symbol
];
717 if (emulationEnabled
)
718 target
.pageAgent().addScriptToEvaluateOnLoad("(" + injectedFunction
.toString() + ")()", scriptAddedCallback
);
721 * @param {?Protocol.Error} error
722 * @param {string} scriptId
724 function scriptAddedCallback(error
, scriptId
)
727 delete target
[symbol
];
729 target
[symbol
] = scriptId
;
732 target
.emulationAgent().setTouchEmulationEnabled(emulationEnabled
, configuration
);
735 _cssMediaChanged: function()
737 var enabled
= this.emulationEnabled() && this.settings
.overrideCSSMedia
.get();
738 this._target
.emulationAgent().setEmulatedMedia(enabled
? this.settings
.emulatedCSSMedia
.get() : "");
739 var cssModel
= WebInspector
.CSSStyleModel
.fromTarget(this._target
);
741 cssModel
.mediaQueryResultChanged();
744 _javaScriptDisabledChanged: function()
746 this._target
.emulationAgent().setScriptExecutionDisabled(this.settings
.javaScriptDisabled
.get());
749 _pageResizerActive: function()
751 return this._pageResizer
&& this.emulationEnabled();
754 _showRulersChanged: function()
756 var showRulersValue
= WebInspector
.moduleSetting("showMetricsRulers").get();
757 for (var target
of WebInspector
.targetManager
.targets(WebInspector
.Target
.Type
.Page
)) {
758 target
.pageAgent().setShowViewportSizeOnResize(!this._pageResizerActive(), showRulersValue
);
759 var domModel
= WebInspector
.DOMModel
.fromTarget(target
);
761 domModel
.setHighlightSettings(showRulersValue
&& !this._pageResizerActive(), showRulersValue
);
765 _onMainFrameNavigated: function()
767 this._deviceMetricsChanged(false);
768 this._updateUserAgentWarningMessage("");
769 this._updateDeviceMetricsWarningMessage("");
772 _dispatchWarningChanged: function()
774 this.dispatchEventToListeners(WebInspector
.OverridesSupport
.Events
.OverridesWarningUpdated
);
778 * @param {string} warningMessage
780 _updateDeviceMetricsWarningMessage: function(warningMessage
)
782 this._deviceMetricsWarningMessage
= warningMessage
;
783 this._dispatchWarningChanged();
787 * @param {string} warningMessage
789 _updateUserAgentWarningMessage: function(warningMessage
)
791 this._userAgentWarningMessage
= warningMessage
;
792 this._dispatchWarningChanged();
798 warningMessage: function()
800 return this._deviceMetricsWarningMessage
|| this._userAgentWarningMessage
|| "";
803 clearWarningMessage: function()
805 this._deviceMetricsWarningMessage
= "";
806 this._userAgentWarningMessage
= "";
807 this._dispatchWarningChanged();
810 swapDimensions: function()
812 var width
= WebInspector
.overridesSupport
.settings
.deviceWidth
.get();
813 var height
= WebInspector
.overridesSupport
.settings
.deviceHeight
.get();
814 WebInspector
.overridesSupport
.settings
.deviceWidth
.set(height
);
815 WebInspector
.overridesSupport
.settings
.deviceHeight
.set(width
);
818 __proto__
: WebInspector
.Object
.prototype
823 * @type {!WebInspector.OverridesSupport}
825 WebInspector
.overridesSupport
;