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 * @implements {WebInspector.TargetManager.Observer}
34 * @extends {WebInspector.Object}
35 * @param {boolean} responsiveDesignAvailable
37 WebInspector.OverridesSupport = function(responsiveDesignAvailable)
39 this._touchEmulationSuspended = false;
40 this._emulateMobileEnabled = false;
42 this._pageResizer = null;
43 this._deviceScale = 1;
44 this._fixedDeviceScale = false;
45 this._initialized = false;
46 this._deviceMetricsThrottler = new WebInspector.Throttler(0);
47 this._responsiveDesignAvailable = responsiveDesignAvailable;
50 this.settings._emulationEnabled = WebInspector.settings.createSetting("emulationEnabled", false);
52 this.settings.userAgent = WebInspector.settings.createSetting("userAgent", "");
54 this.settings.emulateResolution = WebInspector.settings.createSetting("emulateResolution", true);
55 this.settings.deviceWidth = WebInspector.settings.createSetting("deviceWidth", 360);
56 this.settings.deviceHeight = WebInspector.settings.createSetting("deviceHeight", 640);
57 this.settings.deviceScaleFactor = WebInspector.settings.createSetting("deviceScaleFactor", 0);
58 this.settings.deviceFitWindow = WebInspector.settings.createSetting("deviceFitWindow", true);
59 this.settings.emulateMobile = WebInspector.settings.createSetting("emulateMobile", false);
60 this.settings.customDevicePresets = WebInspector.settings.createSetting("customDevicePresets", []);
62 this.settings.emulateTouch = WebInspector.settings.createSetting("emulateTouch", false);
64 this.settings.overrideGeolocation = WebInspector.settings.createSetting("overrideGeolocation", false);
65 this.settings.geolocationOverride = WebInspector.settings.createSetting("geolocationOverride", "");
67 this.settings.overrideDeviceOrientation = WebInspector.settings.createSetting("overrideDeviceOrientation", false);
68 this.settings.deviceOrientationOverride = WebInspector.settings.createSetting("deviceOrientationOverride", "");
70 this.settings.overrideCSSMedia = WebInspector.settings.createSetting("overrideCSSMedia", false);
71 this.settings.emulatedCSSMedia = WebInspector.settings.createSetting("emulatedCSSMedia", "print");
73 this.settings.networkConditions = WebInspector.settings.createSetting("networkConditions", {throughput: WebInspector.OverridesSupport.NetworkThroughputUnlimitedValue, latency: 0});
75 WebInspector.targetManager.observeTargets(this);
78 WebInspector.OverridesSupport.Events = {
79 OverridesWarningUpdated: "OverridesWarningUpdated",
80 EmulationStateChanged: "EmulationStateChanged"
83 WebInspector.OverridesSupport.MaxDeviceSize = 3000;
87 * @extends {WebInspector.EventTarget}
89 WebInspector.OverridesSupport.PageResizer = function()
93 WebInspector.OverridesSupport.PageResizer.Events = {
94 AvailableSizeChanged: "AvailableSizeChanged",
95 ResizeRequested: "ResizeRequested",
96 FixedScaleRequested: "FixedScaleRequested"
99 WebInspector.OverridesSupport.PageResizer.prototype = {
101 * Zero width and height mean default size.
102 * Scale should be applied to page-scale-dependent UI bits. Zero means no scale.
103 * @param {number} dipWidth
104 * @param {number} dipHeight
105 * @param {number} scale
107 update: function(dipWidth, dipHeight, scale) { }
110 /** @typedef {{title: string, width: number, height: number, deviceScaleFactor: number, userAgent: string, touch: boolean, mobile: boolean}} */
111 WebInspector.OverridesSupport.Device = {};
115 * @param {number} latitude
116 * @param {number} longitude
117 * @param {string} error
119 WebInspector.OverridesSupport.GeolocationPosition = function(latitude, longitude, error)
121 this.latitude = latitude;
122 this.longitude = longitude;
126 WebInspector.OverridesSupport.GeolocationPosition.prototype = {
130 toSetting: function()
132 return (typeof this.latitude === "number" && typeof this.longitude === "number" && typeof this.error === "string") ? this.latitude + "@" + this.longitude + ":" + this.error : "";
137 * @return {!WebInspector.OverridesSupport.GeolocationPosition}
139 WebInspector.OverridesSupport.GeolocationPosition.parseSetting = function(value)
142 var splitError = value.split(":");
143 if (splitError.length === 2) {
144 var splitPosition = splitError[0].split("@")
145 if (splitPosition.length === 2)
146 return new WebInspector.OverridesSupport.GeolocationPosition(parseFloat(splitPosition[0]), parseFloat(splitPosition[1]), splitError[1]);
149 return new WebInspector.OverridesSupport.GeolocationPosition(0, 0, "");
153 * @return {?WebInspector.OverridesSupport.GeolocationPosition}
155 WebInspector.OverridesSupport.GeolocationPosition.parseUserInput = function(latitudeString, longitudeString, errorStatus)
157 function isUserInputValid(value)
161 return /^[-]?[0-9]*[.]?[0-9]*$/.test(value);
164 if (!latitudeString ^ !latitudeString)
167 var isLatitudeValid = isUserInputValid(latitudeString);
168 var isLongitudeValid = isUserInputValid(longitudeString);
170 if (!isLatitudeValid && !isLongitudeValid)
173 var latitude = isLatitudeValid ? parseFloat(latitudeString) : -1;
174 var longitude = isLongitudeValid ? parseFloat(longitudeString) : -1;
176 return new WebInspector.OverridesSupport.GeolocationPosition(latitude, longitude, errorStatus ? "PositionUnavailable" : "");
179 WebInspector.OverridesSupport.GeolocationPosition.clearGeolocationOverride = function()
181 PageAgent.clearGeolocationOverride();
186 * @param {number} alpha
187 * @param {number} beta
188 * @param {number} gamma
190 WebInspector.OverridesSupport.DeviceOrientation = function(alpha, beta, gamma)
197 WebInspector.OverridesSupport.DeviceOrientation.prototype = {
201 toSetting: function()
203 return JSON.stringify(this);
208 * @return {!WebInspector.OverridesSupport.DeviceOrientation}
210 WebInspector.OverridesSupport.DeviceOrientation.parseSetting = function(value)
213 var jsonObject = JSON.parse(value);
214 return new WebInspector.OverridesSupport.DeviceOrientation(jsonObject.alpha, jsonObject.beta, jsonObject.gamma);
216 return new WebInspector.OverridesSupport.DeviceOrientation(0, 0, 0);
220 * @return {?WebInspector.OverridesSupport.DeviceOrientation}
222 WebInspector.OverridesSupport.DeviceOrientation.parseUserInput = function(alphaString, betaString, gammaString)
224 function isUserInputValid(value)
228 return /^[-]?[0-9]*[.]?[0-9]*$/.test(value);
231 if (!alphaString ^ !betaString ^ !gammaString)
234 var isAlphaValid = isUserInputValid(alphaString);
235 var isBetaValid = isUserInputValid(betaString);
236 var isGammaValid = isUserInputValid(gammaString);
238 if (!isAlphaValid && !isBetaValid && !isGammaValid)
241 var alpha = isAlphaValid ? parseFloat(alphaString) : -1;
242 var beta = isBetaValid ? parseFloat(betaString) : -1;
243 var gamma = isGammaValid ? parseFloat(gammaString) : -1;
245 return new WebInspector.OverridesSupport.DeviceOrientation(alpha, beta, gamma);
248 WebInspector.OverridesSupport.DeviceOrientation.clearDeviceOrientationOverride = function()
250 PageAgent.clearDeviceOrientationOverride();
254 * @param {string} value
257 WebInspector.OverridesSupport.deviceSizeValidator = function(value)
259 if (!value || (/^[\d]+$/.test(value) && value >= 0 && value <= WebInspector.OverridesSupport.MaxDeviceSize))
261 return WebInspector.UIString("Value must be non-negative integer");
265 * @param {string} value
268 WebInspector.OverridesSupport.deviceScaleFactorValidator = function(value)
270 if (!value || (/^[\d]+(\.\d+)?|\.\d+$/.test(value) && value >= 0 && value <= 10))
272 return WebInspector.UIString("Value must be non-negative float");
275 WebInspector.OverridesSupport.NetworkThroughputUnlimitedValue = -1;
277 /** @typedef {{id: string, title: string, throughput: number, latency: number}} */
278 WebInspector.OverridesSupport.NetworkConditionsPreset;
280 WebInspector.OverridesSupport.prototype = {
284 canEmulate: function()
286 return !!this._target && this._target.canEmulate();
292 emulationEnabled: function()
294 return this.canEmulate() && this.settings._emulationEnabled.get();
298 * @param {boolean} enabled
300 setEmulationEnabled: function(enabled)
302 if (this.canEmulate()) {
303 this.settings._emulationEnabled.set(enabled);
304 this.dispatchEventToListeners(WebInspector.OverridesSupport.Events.EmulationStateChanged);
305 if (enabled && this.settings.emulateResolution.get())
306 this._target.pageAgent().resetScrollAndPageScaleFactor();
313 responsiveDesignAvailable: function()
315 return this._responsiveDesignAvailable;
319 * @param {?WebInspector.OverridesSupport.PageResizer} pageResizer
320 * @param {!Size} availableSize
322 setPageResizer: function(pageResizer, availableSize)
324 if (pageResizer === this._pageResizer)
327 if (this._pageResizer) {
328 this._pageResizer.removeEventListener(WebInspector.OverridesSupport.PageResizer.Events.AvailableSizeChanged, this._onPageResizerAvailableSizeChanged, this);
329 this._pageResizer.removeEventListener(WebInspector.OverridesSupport.PageResizer.Events.ResizeRequested, this._onPageResizerResizeRequested, this);
330 this._pageResizer.removeEventListener(WebInspector.OverridesSupport.PageResizer.Events.FixedScaleRequested, this._onPageResizerFixedScaleRequested, this);
332 this._pageResizer = pageResizer;
333 this._pageResizerAvailableSize = availableSize;
334 if (this._pageResizer) {
335 this._pageResizer.addEventListener(WebInspector.OverridesSupport.PageResizer.Events.AvailableSizeChanged, this._onPageResizerAvailableSizeChanged, this);
336 this._pageResizer.addEventListener(WebInspector.OverridesSupport.PageResizer.Events.ResizeRequested, this._onPageResizerResizeRequested, this);
337 this._pageResizer.addEventListener(WebInspector.OverridesSupport.PageResizer.Events.FixedScaleRequested, this._onPageResizerFixedScaleRequested, this);
339 if (this._initialized)
340 this._deviceMetricsChanged();
344 * @param {!WebInspector.OverridesSupport.Device} device
346 emulateDevice: function(device)
348 this._deviceMetricsChangedListenerMuted = true;
349 this._userAgentChangedListenerMuted = true;
350 this.settings.userAgent.set(device.userAgent);
351 this.settings.emulateResolution.set(true);
352 this.settings.deviceWidth.set(device.width);
353 this.settings.deviceHeight.set(device.height);
354 this.settings.deviceScaleFactor.set(device.deviceScaleFactor);
355 this.settings.emulateTouch.set(device.touch);
356 this.settings.emulateMobile.set(device.mobile);
357 delete this._deviceMetricsChangedListenerMuted;
358 delete this._userAgentChangedListenerMuted;
360 if (this._initialized) {
361 this._deviceMetricsChanged();
362 this._userAgentChanged();
363 this._target.pageAgent().resetScrollAndPageScaleFactor();
369 this._deviceMetricsChangedListenerMuted = true;
370 this._userAgentChangedListenerMuted = true;
371 this.settings.userAgent.set("");
372 this.settings.emulateResolution.set(false);
373 this.settings.deviceScaleFactor.set(0);
374 this.settings.emulateTouch.set(false);
375 this.settings.emulateMobile.set(false);
376 this.settings.overrideDeviceOrientation.set(false);
377 this.settings.overrideGeolocation.set(false);
378 this.settings.overrideCSSMedia.set(false);
379 this.settings.networkConditions.set({throughput: WebInspector.OverridesSupport.NetworkThroughputUnlimitedValue, latency: 0});
380 delete this._deviceMetricsChangedListenerMuted;
381 delete this._userAgentChangedListenerMuted;
383 if (this._initialized) {
384 this._deviceMetricsChanged();
385 this._userAgentChanged();
390 * @param {!WebInspector.OverridesSupport.Device} device
393 isEmulatingDevice: function(device)
395 var sameResolution = this.settings.emulateResolution.get() ?
396 (this.settings.deviceWidth.get() === device.width && this.settings.deviceHeight.get() === device.height && this.settings.deviceScaleFactor.get() === device.deviceScaleFactor) :
397 (!device.width && !device.height && !device.deviceScaleFactor);
398 return this.settings.userAgent.get() === device.userAgent
399 && this.settings.emulateTouch.get() === device.touch
400 && this.settings.emulateMobile.get() === device.mobile
405 * @return {!WebInspector.OverridesSupport.Device}
407 deviceFromCurrentSettings: function()
410 if (this.settings.emulateResolution.get()) {
411 device.width = this.settings.deviceWidth.get();
412 device.height = this.settings.deviceHeight.get();
417 device.deviceScaleFactor = this.settings.deviceScaleFactor.get();
418 device.touch = this.settings.emulateTouch.get();
419 device.mobile = this.settings.emulateMobile.get();
420 device.userAgent = this.settings.userAgent.get();
426 * @param {boolean} suspended
428 setTouchEmulationSuspended: function(suspended)
430 this._touchEmulationSuspended = suspended;
431 if (this._initialized)
432 this._emulateTouchEventsChanged();
435 applyInitialOverrides: function()
438 this._applyInitialOverridesOnTargetAdded = true;
442 this._initialized = true;
444 this.settings._emulationEnabled.addChangeListener(this._userAgentChanged, this);
445 this.settings.userAgent.addChangeListener(this._userAgentChanged, this);
447 this.settings._emulationEnabled.addChangeListener(this._deviceMetricsChanged, this);
448 this.settings.emulateResolution.addChangeListener(this._deviceMetricsChanged, this);
449 this.settings.deviceWidth.addChangeListener(this._deviceMetricsChanged, this);
450 this.settings.deviceHeight.addChangeListener(this._deviceMetricsChanged, this);
451 this.settings.deviceScaleFactor.addChangeListener(this._deviceMetricsChanged, this);
452 this.settings.emulateMobile.addChangeListener(this._deviceMetricsChanged, this);
453 this.settings.deviceFitWindow.addChangeListener(this._deviceMetricsChanged, this);
455 this.settings._emulationEnabled.addChangeListener(this._geolocationPositionChanged, this);
456 this.settings.overrideGeolocation.addChangeListener(this._geolocationPositionChanged, this);
457 this.settings.geolocationOverride.addChangeListener(this._geolocationPositionChanged, this);
459 this.settings._emulationEnabled.addChangeListener(this._deviceOrientationChanged, this);
460 this.settings.overrideDeviceOrientation.addChangeListener(this._deviceOrientationChanged, this);
461 this.settings.deviceOrientationOverride.addChangeListener(this._deviceOrientationChanged, this);
463 this.settings._emulationEnabled.addChangeListener(this._emulateTouchEventsChanged, this);
464 this.settings.emulateTouch.addChangeListener(this._emulateTouchEventsChanged, this);
466 this.settings._emulationEnabled.addChangeListener(this._cssMediaChanged, this);
467 this.settings.overrideCSSMedia.addChangeListener(this._cssMediaChanged, this);
468 this.settings.emulatedCSSMedia.addChangeListener(this._cssMediaChanged, this);
470 this.settings._emulationEnabled.addChangeListener(this._networkConditionsChanged, this);
471 this.settings.networkConditions.addChangeListener(this._networkConditionsChanged, this);
473 this.settings._emulationEnabled.addChangeListener(this._showRulersChanged, this);
474 WebInspector.settings.showMetricsRulers.addChangeListener(this._showRulersChanged, this);
475 this._showRulersChanged();
477 if (!this.emulationEnabled())
480 if (this.settings.overrideDeviceOrientation.get())
481 this._deviceOrientationChanged();
483 if (this.settings.overrideGeolocation.get())
484 this._geolocationPositionChanged();
486 if (this.settings.emulateTouch.get())
487 this._emulateTouchEventsChanged();
489 if (this.settings.overrideCSSMedia.get())
490 this._cssMediaChanged();
492 this._deviceMetricsChanged();
493 if (this.settings.emulateResolution.get())
494 this._target.pageAgent().resetScrollAndPageScaleFactor();
496 this._userAgentChanged();
498 if (this.networkThroughputIsLimited())
499 this._networkConditionsChanged();
502 _userAgentChanged: function()
504 if (this._userAgentChangedListenerMuted)
506 var userAgent = this.emulationEnabled() ? this.settings.userAgent.get() : "";
507 NetworkAgent.setUserAgentOverride(userAgent);
508 if (this._userAgent !== userAgent)
509 this._updateUserAgentWarningMessage(WebInspector.UIString("You might need to reload the page for proper user agent spoofing and viewport rendering."));
510 this._userAgent = userAgent;
514 * @param {!WebInspector.Event} event
516 _onPageResizerAvailableSizeChanged: function(event)
518 this._pageResizerAvailableSize = /** @type {!Size} */ (event.data);
519 if (this._initialized)
520 this._deviceMetricsChanged();
524 * @param {!WebInspector.Event} event
526 _onPageResizerResizeRequested: function(event)
528 if (typeof event.data.width !== "undefined") {
529 var width = /** @type {number} */ (event.data.width);
530 if (width !== this.settings.deviceWidth.get())
531 this.settings.deviceWidth.set(width);
533 if (typeof event.data.height !== "undefined") {
534 var height = /** @type {number} */ (event.data.height);
535 if (height !== this.settings.deviceHeight.get())
536 this.settings.deviceHeight.set(height);
541 * @param {!WebInspector.Event} event
543 _onPageResizerFixedScaleRequested: function(event)
545 this._fixedDeviceScale = /** @type {boolean} */ (event.data);
546 if (this._initialized)
547 this._deviceMetricsChanged();
550 _deviceMetricsChanged: function()
552 this._showRulersChanged();
554 if (this._deviceMetricsChangedListenerMuted)
557 if (!this.emulationEnabled()) {
558 this._deviceMetricsThrottler.schedule(clearDeviceMetricsOverride.bind(this));
559 if (this._pageResizer)
560 this._pageResizer.update(0, 0, 1);
564 var dipWidth = this.settings.emulateResolution.get() ? this.settings.deviceWidth.get() : 0;
565 var dipHeight = this.settings.emulateResolution.get() ? this.settings.deviceHeight.get() : 0;
567 var overrideWidth = dipWidth;
568 var overrideHeight = dipHeight;
570 if (this._pageResizer) {
571 var available = this._pageResizerAvailableSize;
572 if (this.settings.deviceFitWindow.get()) {
573 if (this._fixedDeviceScale) {
574 scale = this._deviceScale;
577 while (available.width < dipWidth * scale || available.height < dipHeight * scale)
582 this._pageResizer.update(Math.min(dipWidth * scale, available.width), Math.min(dipHeight * scale, available.height), scale);
583 if (scale === 1 && available.width >= dipWidth && available.height >= dipHeight) {
584 // When we have enough space, no page size override is required. This will speed things up and remove lag.
588 if (dipWidth === 0 && dipHeight !== 0)
589 overrideWidth = Math.round(available.width / scale);
590 if (dipHeight === 0 && dipWidth !== 0)
591 overrideHeight = Math.round(available.height / scale);
593 this._deviceScale = scale;
595 this._deviceMetricsThrottler.schedule(setDeviceMetricsOverride.bind(this));
598 * @param {!WebInspector.Throttler.FinishCallback} finishCallback
599 * @this {WebInspector.OverridesSupport}
601 function setDeviceMetricsOverride(finishCallback)
603 this._target.pageAgent().setDeviceMetricsOverride(
604 overrideWidth, overrideHeight, this.settings.emulateResolution.get() ? this.settings.deviceScaleFactor.get() : 0,
605 this.settings.emulateMobile.get(), this._pageResizer ? false : this.settings.deviceFitWindow.get(), scale, 0, 0,
606 apiCallback.bind(this, finishCallback));
610 * @param {!WebInspector.Throttler.FinishCallback} finishCallback
611 * @this {WebInspector.OverridesSupport}
613 function clearDeviceMetricsOverride(finishCallback)
615 this._target.pageAgent().clearDeviceMetricsOverride(apiCallback.bind(this, finishCallback));
619 * @param {!WebInspector.Throttler.FinishCallback} finishCallback
620 * @param {?Protocol.Error} error
621 * @this {WebInspector.OverridesSupport}
623 function apiCallback(finishCallback, error)
626 this._updateDeviceMetricsWarningMessage(WebInspector.UIString("Screen emulation is not available on this page."));
627 this._deviceMetricsOverrideAppliedForTest();
632 var mobileEnabled = this.emulationEnabled() && this.settings.emulateMobile.get();
633 if (this._emulateMobileEnabled !== mobileEnabled)
634 this._updateDeviceMetricsWarningMessage(WebInspector.UIString("You might need to reload the page for proper user agent spoofing and viewport rendering."));
635 this._emulateMobileEnabled = mobileEnabled;
636 this._deviceMetricsOverrideAppliedForTest();
641 _deviceMetricsOverrideAppliedForTest: function()
643 // Used for sniffing in tests.
646 _geolocationPositionChanged: function()
648 if (!this.emulationEnabled() || !this.settings.overrideGeolocation.get()) {
649 PageAgent.clearGeolocationOverride();
652 var geolocation = WebInspector.OverridesSupport.GeolocationPosition.parseSetting(this.settings.geolocationOverride.get());
653 if (geolocation.error)
654 PageAgent.setGeolocationOverride();
656 PageAgent.setGeolocationOverride(geolocation.latitude, geolocation.longitude, 150);
659 _deviceOrientationChanged: function()
661 if (!this.emulationEnabled() || !this.settings.overrideDeviceOrientation.get()) {
662 PageAgent.clearDeviceOrientationOverride();
666 var deviceOrientation = WebInspector.OverridesSupport.DeviceOrientation.parseSetting(this.settings.deviceOrientationOverride.get());
667 PageAgent.setDeviceOrientationOverride(deviceOrientation.alpha, deviceOrientation.beta, deviceOrientation.gamma);
670 _emulateTouchEventsChanged: function()
672 var emulateTouch = this.emulationEnabled() && this.settings.emulateTouch.get() && !this._touchEmulationSuspended;
673 var targets = WebInspector.targetManager.targets();
674 for (var i = 0; i < targets.length; ++i)
675 targets[i].domModel.emulateTouchEventObjects(emulateTouch);
678 _cssMediaChanged: function()
680 var enabled = this.emulationEnabled() && this.settings.overrideCSSMedia.get();
681 PageAgent.setEmulatedMedia(enabled ? this.settings.emulatedCSSMedia.get() : "");
682 var targets = WebInspector.targetManager.targets();
683 for (var i = 0; i < targets.length; ++i)
684 targets[i].cssModel.mediaQueryResultChanged();
687 _networkConditionsChanged: function()
689 if (!this.emulationEnabled() || !this.networkThroughputIsLimited()) {
690 NetworkAgent.emulateNetworkConditions(false, 0, 0, 0);
692 var conditions = this.settings.networkConditions.get();
693 var throughput = conditions.throughput;
694 var latency = conditions.latency;
695 var offline = !throughput && !latency;
696 NetworkAgent.emulateNetworkConditions(offline, latency, throughput, throughput);
700 _pageResizerActive: function()
702 return this._pageResizer && this.emulationEnabled();
708 showMetricsRulers: function()
710 return WebInspector.settings.showMetricsRulers.get() && !this._pageResizerActive();
716 showExtensionLines: function()
718 return WebInspector.settings.showMetricsRulers.get();
721 _showRulersChanged: function()
723 PageAgent.setShowViewportSizeOnResize(!this._pageResizerActive(), WebInspector.settings.showMetricsRulers.get());
726 _onMainFrameNavigated: function()
728 if (this._initialized)
729 this._deviceMetricsChanged();
730 this._updateUserAgentWarningMessage("");
731 this._updateDeviceMetricsWarningMessage("");
734 _dispatchWarningChanged: function()
736 this.dispatchEventToListeners(WebInspector.OverridesSupport.Events.OverridesWarningUpdated);
740 * @param {string} warningMessage
742 _updateDeviceMetricsWarningMessage: function(warningMessage)
744 this._deviceMetricsWarningMessage = warningMessage;
745 this._dispatchWarningChanged();
749 * @param {string} warningMessage
751 _updateUserAgentWarningMessage: function(warningMessage)
753 this._userAgentWarningMessage = warningMessage;
754 this._dispatchWarningChanged();
760 warningMessage: function()
762 return this._deviceMetricsWarningMessage || this._userAgentWarningMessage || "";
765 clearWarningMessage: function()
767 this._deviceMetricsWarningMessage = "";
768 this._userAgentWarningMessage = "";
769 this._dispatchWarningChanged();
773 * @param {!WebInspector.Target} target
775 targetAdded: function(target)
779 this._target = target;
780 target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._onMainFrameNavigated, this);
782 if (this._applyInitialOverridesOnTargetAdded) {
783 delete this._applyInitialOverridesOnTargetAdded;
784 this.applyInitialOverrides();
786 this.dispatchEventToListeners(WebInspector.OverridesSupport.Events.EmulationStateChanged);
789 swapDimensions: function()
791 var width = WebInspector.overridesSupport.settings.deviceWidth.get();
792 var height = WebInspector.overridesSupport.settings.deviceHeight.get();
793 WebInspector.overridesSupport.settings.deviceWidth.set(height);
794 WebInspector.overridesSupport.settings.deviceHeight.set(width);
798 * @param {!WebInspector.Target} target
800 targetRemoved: function(target)
802 if (target === this._target) {
803 target.resourceTreeModel.removeEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._onMainFrameNavigated, this);
805 this.dispatchEventToListeners(WebInspector.OverridesSupport.Events.EmulationStateChanged);
812 networkThroughputIsLimited: function()
814 var conditions = this.settings.networkConditions.get();
815 return conditions.throughput !== WebInspector.OverridesSupport.NetworkThroughputUnlimitedValue;
818 __proto__: WebInspector.Object.prototype
823 * @type {!WebInspector.OverridesSupport}
825 WebInspector.overridesSupport;