| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright (C) 2012 Google Inc. All rights reserved. | |
| 3 * | |
| 4 * Redistribution and use in source and binary forms, with or without | |
| 5 * modification, are permitted provided that the following conditions are | |
| 6 * met: | |
| 7 * | |
| 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 | |
| 13 * distribution. | |
| 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. | |
| 17 * | |
| 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. | |
| 29 */ | |
| 30 | |
| 31 /** | |
| 32 * @constructor | |
| 33 * @extends {WebInspector.Object} | |
| 34 */ | |
| 35 WebInspector.OverridesSupport = function() | |
| 36 { | |
| 37 this._touchEmulationSuspended = false; | |
| 38 this._emulateMobileEnabled = false; | |
| 39 this._userAgent = ""; | |
| 40 this._pageResizer = null; | |
| 41 this._deviceScale = 1; | |
| 42 this._fixedDeviceScale = false; | |
| 43 this._initialized = false; | |
| 44 this._deviceMetricsThrottler = new WebInspector.Throttler(0); | |
| 45 | |
| 46 this.settings = {}; | |
| 47 this.settings._emulationEnabled = WebInspector.settings.createSetting("emula
tionEnabled", false); | |
| 48 if (Runtime.experiments.isEnabled("deviceMode")) | |
| 49 this.settings._emulationEnabled.set(false); | |
| 50 | |
| 51 this.settings.userAgent = WebInspector.settings.createSetting("userAgent", "
"); | |
| 52 | |
| 53 this.settings.emulateResolution = WebInspector.settings.createSetting("emula
teResolution", true); | |
| 54 this.settings.deviceWidth = WebInspector.settings.createSetting("deviceWidth
", 360); | |
| 55 this.settings.deviceHeight = WebInspector.settings.createSetting("deviceHeig
ht", 640); | |
| 56 this.settings.deviceScaleFactor = WebInspector.settings.createSetting("devic
eScaleFactor", 0); | |
| 57 this.settings.deviceFitWindow = WebInspector.settings.createSetting("deviceF
itWindow", true); | |
| 58 this.settings.emulateMobile = WebInspector.settings.createSetting("emulateMo
bile", false); | |
| 59 | |
| 60 this.settings.emulateTouch = WebInspector.settings.createSetting("emulateTou
ch", false); | |
| 61 | |
| 62 this.settings.geolocationOverride = WebInspector.settings.createSetting("geo
locationOverride", ""); | |
| 63 this.settings.deviceOrientationOverride = WebInspector.settings.createSettin
g("deviceOrientationOverride", ""); | |
| 64 | |
| 65 this.settings.screenOrientationOverride = WebInspector.settings.createSettin
g("screenOrientationOverride", ""); | |
| 66 | |
| 67 this.settings.javaScriptDisabled = WebInspector.moduleSetting("javaScriptDis
abled"); | |
| 68 } | |
| 69 | |
| 70 WebInspector.OverridesSupport.Events = { | |
| 71 OverridesWarningUpdated: "OverridesWarningUpdated", | |
| 72 EmulationStateChanged: "EmulationStateChanged" | |
| 73 } | |
| 74 | |
| 75 WebInspector.OverridesSupport.MaxDeviceSize = 9999; | |
| 76 | |
| 77 /** | |
| 78 * @interface | |
| 79 * @extends {WebInspector.EventTarget} | |
| 80 */ | |
| 81 WebInspector.OverridesSupport.PageResizer = function() | |
| 82 { | |
| 83 }; | |
| 84 | |
| 85 WebInspector.OverridesSupport.PageResizer.Events = { | |
| 86 AvailableSizeChanged: "AvailableSizeChanged", | |
| 87 ResizeRequested: "ResizeRequested", | |
| 88 FixedScaleRequested: "FixedScaleRequested", | |
| 89 InsetsChanged: "InsetsChanged" | |
| 90 }; | |
| 91 | |
| 92 WebInspector.OverridesSupport.PageResizer.prototype = { | |
| 93 /** | |
| 94 * Zero width and height mean default size. | |
| 95 * Scale should be applied to page-scale-dependent UI bits. Zero means no sc
ale. | |
| 96 * @param {number} dipWidth | |
| 97 * @param {number} dipHeight | |
| 98 * @param {number} scale | |
| 99 * @param {number} pageWidth | |
| 100 * @param {number} pageHeight | |
| 101 */ | |
| 102 update: function(dipWidth, dipHeight, scale, pageWidth, pageHeight) { } | |
| 103 }; | |
| 104 | |
| 105 /** @typedef {{width: number, height: number, deviceScaleFactor: number, userAge
nt: string, touch: boolean, mobile: boolean}} */ | |
| 106 WebInspector.OverridesSupport.Device = {}; | |
| 107 | |
| 108 /** | |
| 109 * @constructor | |
| 110 * @param {number} latitude | |
| 111 * @param {number} longitude | |
| 112 * @param {string} error | |
| 113 */ | |
| 114 WebInspector.OverridesSupport.GeolocationPosition = function(latitude, longitude
, error) | |
| 115 { | |
| 116 this.latitude = latitude; | |
| 117 this.longitude = longitude; | |
| 118 this.error = error; | |
| 119 } | |
| 120 | |
| 121 WebInspector.OverridesSupport.GeolocationPosition.prototype = { | |
| 122 /** | |
| 123 * @return {string} | |
| 124 */ | |
| 125 toSetting: function() | |
| 126 { | |
| 127 return (typeof this.latitude === "number" && typeof this.longitude === "
number" && typeof this.error === "string") ? this.latitude + "@" + this.longitud
e + ":" + this.error : ""; | |
| 128 } | |
| 129 } | |
| 130 | |
| 131 /** | |
| 132 * @return {!WebInspector.OverridesSupport.GeolocationPosition} | |
| 133 */ | |
| 134 WebInspector.OverridesSupport.GeolocationPosition.parseSetting = function(value) | |
| 135 { | |
| 136 if (value) { | |
| 137 var splitError = value.split(":"); | |
| 138 if (splitError.length === 2) { | |
| 139 var splitPosition = splitError[0].split("@"); | |
| 140 if (splitPosition.length === 2) | |
| 141 return new WebInspector.OverridesSupport.GeolocationPosition(par
seFloat(splitPosition[0]), parseFloat(splitPosition[1]), splitError[1]); | |
| 142 } | |
| 143 } | |
| 144 return new WebInspector.OverridesSupport.GeolocationPosition(0, 0, ""); | |
| 145 } | |
| 146 | |
| 147 /** | |
| 148 * @return {?WebInspector.OverridesSupport.GeolocationPosition} | |
| 149 */ | |
| 150 WebInspector.OverridesSupport.GeolocationPosition.parseUserInput = function(lati
tudeString, longitudeString, errorStatus) | |
| 151 { | |
| 152 function isUserInputValid(value) | |
| 153 { | |
| 154 if (!value) | |
| 155 return true; | |
| 156 return /^[-]?[0-9]*[.]?[0-9]*$/.test(value); | |
| 157 } | |
| 158 | |
| 159 if (!latitudeString && !longitudeString) | |
| 160 return null; | |
| 161 | |
| 162 var isLatitudeValid = isUserInputValid(latitudeString); | |
| 163 var isLongitudeValid = isUserInputValid(longitudeString); | |
| 164 | |
| 165 if (!isLatitudeValid && !isLongitudeValid) | |
| 166 return null; | |
| 167 | |
| 168 var latitude = isLatitudeValid ? parseFloat(latitudeString) : -1; | |
| 169 var longitude = isLongitudeValid ? parseFloat(longitudeString) : -1; | |
| 170 | |
| 171 return new WebInspector.OverridesSupport.GeolocationPosition(latitude, longi
tude, errorStatus ? "PositionUnavailable" : ""); | |
| 172 } | |
| 173 | |
| 174 /** | |
| 175 * @constructor | |
| 176 * @param {number} alpha | |
| 177 * @param {number} beta | |
| 178 * @param {number} gamma | |
| 179 */ | |
| 180 WebInspector.OverridesSupport.DeviceOrientation = function(alpha, beta, gamma) | |
| 181 { | |
| 182 this.alpha = alpha; | |
| 183 this.beta = beta; | |
| 184 this.gamma = gamma; | |
| 185 } | |
| 186 | |
| 187 WebInspector.OverridesSupport.DeviceOrientation.prototype = { | |
| 188 /** | |
| 189 * @return {string} | |
| 190 */ | |
| 191 toSetting: function() | |
| 192 { | |
| 193 return JSON.stringify(this); | |
| 194 } | |
| 195 } | |
| 196 | |
| 197 /** | |
| 198 * @return {!WebInspector.OverridesSupport.DeviceOrientation} | |
| 199 */ | |
| 200 WebInspector.OverridesSupport.DeviceOrientation.parseSetting = function(value) | |
| 201 { | |
| 202 if (value) { | |
| 203 var jsonObject = JSON.parse(value); | |
| 204 return new WebInspector.OverridesSupport.DeviceOrientation(jsonObject.al
pha, jsonObject.beta, jsonObject.gamma); | |
| 205 } | |
| 206 return new WebInspector.OverridesSupport.DeviceOrientation(0, 0, 0); | |
| 207 } | |
| 208 | |
| 209 /** | |
| 210 * @return {?WebInspector.OverridesSupport.DeviceOrientation} | |
| 211 */ | |
| 212 WebInspector.OverridesSupport.DeviceOrientation.parseUserInput = function(alphaS
tring, betaString, gammaString) | |
| 213 { | |
| 214 function isUserInputValid(value) | |
| 215 { | |
| 216 if (!value) | |
| 217 return true; | |
| 218 return /^[-]?[0-9]*[.]?[0-9]*$/.test(value); | |
| 219 } | |
| 220 | |
| 221 if (!alphaString && !betaString && !gammaString) | |
| 222 return null; | |
| 223 | |
| 224 var isAlphaValid = isUserInputValid(alphaString); | |
| 225 var isBetaValid = isUserInputValid(betaString); | |
| 226 var isGammaValid = isUserInputValid(gammaString); | |
| 227 | |
| 228 if (!isAlphaValid && !isBetaValid && !isGammaValid) | |
| 229 return null; | |
| 230 | |
| 231 var alpha = isAlphaValid ? parseFloat(alphaString) : -1; | |
| 232 var beta = isBetaValid ? parseFloat(betaString) : -1; | |
| 233 var gamma = isGammaValid ? parseFloat(gammaString) : -1; | |
| 234 | |
| 235 return new WebInspector.OverridesSupport.DeviceOrientation(alpha, beta, gamm
a); | |
| 236 } | |
| 237 | |
| 238 /** | |
| 239 * @param {string} value | |
| 240 * @return {string} | |
| 241 */ | |
| 242 WebInspector.OverridesSupport.deviceSizeValidator = function(value) | |
| 243 { | |
| 244 if (!value || (/^[\d]+$/.test(value) && value >= 0 && value <= WebInspector.
OverridesSupport.MaxDeviceSize)) | |
| 245 return ""; | |
| 246 return WebInspector.UIString("Value must be non-negative integer"); | |
| 247 } | |
| 248 | |
| 249 /** | |
| 250 * @param {string} value | |
| 251 * @return {string} | |
| 252 */ | |
| 253 WebInspector.OverridesSupport.deviceScaleFactorValidator = function(value) | |
| 254 { | |
| 255 if (!value || (/^[\d]+(\.\d+)?|\.\d+$/.test(value) && value >= 0 && value <=
10)) | |
| 256 return ""; | |
| 257 return WebInspector.UIString("Value must be non-negative float"); | |
| 258 } | |
| 259 | |
| 260 WebInspector.OverridesSupport._touchEventsScriptIdSymbol = Symbol("OverridesSupp
ort.touchEventsScriptIdSymbol"); | |
| 261 | |
| 262 WebInspector.OverridesSupport.prototype = { | |
| 263 /** | |
| 264 * @return {boolean} | |
| 265 */ | |
| 266 canEmulate: function() | |
| 267 { | |
| 268 return !!this._target && this._targetCanEmulate; | |
| 269 }, | |
| 270 | |
| 271 /** | |
| 272 * @return {boolean} | |
| 273 */ | |
| 274 emulationEnabled: function() | |
| 275 { | |
| 276 return this.canEmulate() && this.settings._emulationEnabled.get(); | |
| 277 }, | |
| 278 | |
| 279 /** | |
| 280 * @param {boolean} enabled | |
| 281 */ | |
| 282 setEmulationEnabled: function(enabled) | |
| 283 { | |
| 284 if (this.canEmulate()) { | |
| 285 this.settings._emulationEnabled.set(enabled); | |
| 286 this.dispatchEventToListeners(WebInspector.OverridesSupport.Events.E
mulationStateChanged); | |
| 287 if (enabled && this.settings.emulateResolution.get()) | |
| 288 this._target.emulationAgent().resetPageScaleFactor(); | |
| 289 } | |
| 290 }, | |
| 291 | |
| 292 /** | |
| 293 * @param {!WebInspector.Target} target | |
| 294 * @param {function()} callback | |
| 295 */ | |
| 296 init: function(target, callback) | |
| 297 { | |
| 298 if (target.isPage()) | |
| 299 target.emulationAgent().canEmulate(canEmulateCallback.bind(this)); | |
| 300 else | |
| 301 canEmulateCallback.call(this, null, false); | |
| 302 | |
| 303 /** | |
| 304 * @param {?Protocol.Error} error | |
| 305 * @param {boolean} canEmulate | |
| 306 * @this {WebInspector.OverridesSupport} | |
| 307 */ | |
| 308 function canEmulateCallback(error, canEmulate) | |
| 309 { | |
| 310 this._target = target; | |
| 311 this._targetCanEmulate = !error && canEmulate; | |
| 312 this._initialized = true; | |
| 313 | |
| 314 if (this.canEmulate()) { | |
| 315 target.resourceTreeModel.addEventListener(WebInspector.ResourceT
reeModel.EventTypes.MainFrameNavigated, this._onMainFrameNavigated, this); | |
| 316 if (!Runtime.experiments.isEnabled("deviceMode")) { | |
| 317 var domModel = WebInspector.DOMModel.fromTarget(this._target
); | |
| 318 if (domModel) | |
| 319 domModel.addEventListener(WebInspector.DOMModel.Events.I
nspectModeWillBeToggled, this._inspectModeWillBeToggled, this); | |
| 320 } | |
| 321 this._applyInitialOverrides(); | |
| 322 } | |
| 323 | |
| 324 this.dispatchEventToListeners(WebInspector.OverridesSupport.Events.E
mulationStateChanged); | |
| 325 | |
| 326 callback(); | |
| 327 } | |
| 328 }, | |
| 329 | |
| 330 /** | |
| 331 * @param {?WebInspector.OverridesSupport.PageResizer} pageResizer | |
| 332 * @param {!Size} availableSize | |
| 333 * @param {!Insets} insets | |
| 334 */ | |
| 335 setPageResizer: function(pageResizer, availableSize, insets) | |
| 336 { | |
| 337 if (pageResizer === this._pageResizer) | |
| 338 return; | |
| 339 | |
| 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); | |
| 345 } | |
| 346 this._pageResizer = pageResizer; | |
| 347 this._pageResizerAvailableSize = availableSize; | |
| 348 this._pageResizerInsets = insets; | |
| 349 if (this._pageResizer) { | |
| 350 this._pageResizer.addEventListener(WebInspector.OverridesSupport.Pag
eResizer.Events.AvailableSizeChanged, this._onPageResizerAvailableSizeChanged, t
his); | |
| 351 this._pageResizer.addEventListener(WebInspector.OverridesSupport.Pag
eResizer.Events.ResizeRequested, this._onPageResizerResizeRequested, this); | |
| 352 this._pageResizer.addEventListener(WebInspector.OverridesSupport.Pag
eResizer.Events.FixedScaleRequested, this._onPageResizerFixedScaleRequested, thi
s); | |
| 353 this._pageResizer.addEventListener(WebInspector.OverridesSupport.Pag
eResizer.Events.InsetsChanged, this._onPageResizerInsetsChanged, this); | |
| 354 } | |
| 355 this._deviceMetricsChanged(false); | |
| 356 }, | |
| 357 | |
| 358 /** | |
| 359 * @param {!WebInspector.OverridesSupport.Device} device | |
| 360 */ | |
| 361 emulateDevice: function(device) | |
| 362 { | |
| 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; | |
| 374 | |
| 375 if (this._initialized) { | |
| 376 this._deviceMetricsChanged(true); | |
| 377 this._userAgentChanged(); | |
| 378 } | |
| 379 }, | |
| 380 | |
| 381 reset: function() | |
| 382 { | |
| 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.screenOrientationOverride.set(""); | |
| 391 delete this._deviceMetricsChangedListenerMuted; | |
| 392 delete this._userAgentChangedListenerMuted; | |
| 393 | |
| 394 if (this._initialized) { | |
| 395 this._deviceMetricsChanged(false); | |
| 396 this._userAgentChanged(); | |
| 397 } | |
| 398 }, | |
| 399 | |
| 400 /** | |
| 401 * @param {!WebInspector.OverridesSupport.Device} device | |
| 402 * @return {boolean} | |
| 403 */ | |
| 404 isEmulatingDevice: function(device) | |
| 405 { | |
| 406 var sameResolution = this.settings.emulateResolution.get() ? | |
| 407 (this.settings.deviceWidth.get() === device.width && this.settings.d
eviceHeight.get() === device.height && this.settings.deviceScaleFactor.get() ===
device.deviceScaleFactor) : | |
| 408 (!device.width && !device.height && !device.deviceScaleFactor); | |
| 409 return this.settings.userAgent.get() === device.userAgent | |
| 410 && this.settings.emulateTouch.get() === device.touch | |
| 411 && this.settings.emulateMobile.get() === device.mobile | |
| 412 && sameResolution; | |
| 413 }, | |
| 414 | |
| 415 /** | |
| 416 * @param {!WebInspector.Event} event | |
| 417 */ | |
| 418 _inspectModeWillBeToggled: function(event) | |
| 419 { | |
| 420 var inspectModeEnabled = /** @type {boolean} */ (event.data); | |
| 421 this._touchEmulationSuspended = inspectModeEnabled; | |
| 422 this._emulateTouchEventsChanged(); | |
| 423 }, | |
| 424 | |
| 425 _applyInitialOverrides: function() | |
| 426 { | |
| 427 this.settings._emulationEnabled.addChangeListener(this._userAgentChanged
, this); | |
| 428 this.settings.userAgent.addChangeListener(this._userAgentChanged, this); | |
| 429 | |
| 430 this.settings._emulationEnabled.addChangeListener(this._deviceMetricsCha
nged.bind(this, false)); | |
| 431 this.settings.emulateResolution.addChangeListener(this._deviceMetricsCha
nged.bind(this, false)); | |
| 432 this.settings.deviceWidth.addChangeListener(this._deviceMetricsChanged.b
ind(this, false)); | |
| 433 this.settings.deviceHeight.addChangeListener(this._deviceMetricsChanged.
bind(this, false)); | |
| 434 this.settings.deviceScaleFactor.addChangeListener(this._deviceMetricsCha
nged.bind(this, false)); | |
| 435 this.settings.emulateMobile.addChangeListener(this._deviceMetricsChanged
.bind(this, false)); | |
| 436 this.settings.deviceFitWindow.addChangeListener(this._deviceMetricsChang
ed.bind(this, false)); | |
| 437 | |
| 438 this.settings.geolocationOverride.addChangeListener(this._geolocationPos
itionChanged, this); | |
| 439 this.settings.deviceOrientationOverride.addChangeListener(this._deviceOr
ientationChanged, this); | |
| 440 | |
| 441 this.settings._emulationEnabled.addChangeListener(this._screenOrientatio
nChanged, this); | |
| 442 this.settings.screenOrientationOverride.addChangeListener(this._screenOr
ientationChanged, this); | |
| 443 | |
| 444 this.settings._emulationEnabled.addChangeListener(this._emulateTouchEven
tsChanged, this); | |
| 445 this.settings.emulateTouch.addChangeListener(this._emulateTouchEventsCha
nged, this); | |
| 446 | |
| 447 this.settings.javaScriptDisabled.addChangeListener(this._javaScriptDisab
ledChanged, this); | |
| 448 this._javaScriptDisabledChanged(); | |
| 449 | |
| 450 this.settings._emulationEnabled.addChangeListener(this._showRulersChange
d, this); | |
| 451 WebInspector.moduleSetting("showMetricsRulers").addChangeListener(this._
showRulersChanged, this); | |
| 452 this._showRulersChanged(); | |
| 453 | |
| 454 if (this.emulationEnabled()) { | |
| 455 if (this.settings.screenOrientationOverride.get()) | |
| 456 this._screenOrientationChanged(); | |
| 457 | |
| 458 if (this.settings.emulateTouch.get()) | |
| 459 this._emulateTouchEventsChanged(); | |
| 460 | |
| 461 this._deviceMetricsChanged(true); | |
| 462 | |
| 463 this._userAgentChanged(); | |
| 464 } | |
| 465 }, | |
| 466 | |
| 467 _userAgentChanged: function() | |
| 468 { | |
| 469 if (this._userAgentChangedListenerMuted) | |
| 470 return; | |
| 471 var userAgent = this.emulationEnabled() ? this.settings.userAgent.get()
: ""; | |
| 472 WebInspector.multitargetNetworkManager.setUserAgentOverride(userAgent); | |
| 473 if (this._userAgent !== userAgent) | |
| 474 this._updateUserAgentWarningMessage(WebInspector.UIString("You might
need to reload the page for proper user agent spoofing and viewport rendering."
)); | |
| 475 this._userAgent = userAgent; | |
| 476 }, | |
| 477 | |
| 478 /** | |
| 479 * @param {!WebInspector.Event} event | |
| 480 */ | |
| 481 _onPageResizerAvailableSizeChanged: function(event) | |
| 482 { | |
| 483 this._pageResizerAvailableSize = /** @type {!Size} */ (event.data.size); | |
| 484 this._pageResizerInsets = /** @type {!Insets} */ (event.data.insets); | |
| 485 this._deviceMetricsChanged(false); | |
| 486 }, | |
| 487 | |
| 488 /** | |
| 489 * @param {!WebInspector.Event} event | |
| 490 */ | |
| 491 _onPageResizerInsetsChanged: function(event) | |
| 492 { | |
| 493 var insets = /** @type {!Insets} */ (event.data); | |
| 494 if (!insets.isEqual(this._pageResizerInsets)) { | |
| 495 this._pageResizerInsets = insets; | |
| 496 this._deviceMetricsChanged(false); | |
| 497 } | |
| 498 }, | |
| 499 | |
| 500 /** | |
| 501 * @param {!WebInspector.Event} event | |
| 502 */ | |
| 503 _onPageResizerResizeRequested: function(event) | |
| 504 { | |
| 505 if (typeof event.data.width !== "undefined") { | |
| 506 var width = /** @type {number} */ (event.data.width); | |
| 507 if (width !== this.settings.deviceWidth.get()) | |
| 508 this.settings.deviceWidth.set(width); | |
| 509 } | |
| 510 if (typeof event.data.height !== "undefined") { | |
| 511 var height = /** @type {number} */ (event.data.height); | |
| 512 if (height !== this.settings.deviceHeight.get()) | |
| 513 this.settings.deviceHeight.set(height); | |
| 514 } | |
| 515 }, | |
| 516 | |
| 517 /** | |
| 518 * @param {!WebInspector.Event} event | |
| 519 */ | |
| 520 _onPageResizerFixedScaleRequested: function(event) | |
| 521 { | |
| 522 this._fixedDeviceScale = /** @type {boolean} */ (event.data); | |
| 523 this._deviceMetricsChanged(false); | |
| 524 }, | |
| 525 | |
| 526 /** | |
| 527 * @param {boolean} resetPageScaleFactor | |
| 528 */ | |
| 529 _deviceMetricsChanged: function(resetPageScaleFactor) | |
| 530 { | |
| 531 if (!this._initialized) | |
| 532 return; | |
| 533 | |
| 534 this._showRulersChanged(); | |
| 535 | |
| 536 if (this._deviceMetricsChangedListenerMuted) | |
| 537 return; | |
| 538 | |
| 539 if (!this.emulationEnabled()) { | |
| 540 this._deviceMetricsThrottler.schedule(clearDeviceMetricsOverride.bin
d(this)); | |
| 541 if (this._pageResizer) | |
| 542 this._pageResizer.update(0, 0, 1, 0, 0); | |
| 543 return; | |
| 544 } | |
| 545 | |
| 546 var dipWidth = this.settings.emulateResolution.get() ? this.settings.dev
iceWidth.get() : 0; | |
| 547 var dipHeight = this.settings.emulateResolution.get() ? this.settings.de
viceHeight.get() : 0; | |
| 548 | |
| 549 var overrideWidth = dipWidth; | |
| 550 var overrideHeight = dipHeight; | |
| 551 var screenWidth = dipWidth; | |
| 552 var screenHeight = dipHeight; | |
| 553 var positionX = 0; | |
| 554 var positionY = 0; | |
| 555 var scale = 1; | |
| 556 if (this._pageResizer) { | |
| 557 var available = this._pageResizerAvailableSize; | |
| 558 var insets = this._pageResizerInsets; | |
| 559 if (this.settings.deviceFitWindow.get()) { | |
| 560 if (this._fixedDeviceScale) { | |
| 561 scale = this._deviceScale; | |
| 562 } else { | |
| 563 scale = 1; | |
| 564 while (available.width < (dipWidth + insets.left + insets.ri
ght) * scale || available.height < (dipHeight + insets.top + insets.bottom) * sc
ale) | |
| 565 scale *= 0.8; | |
| 566 } | |
| 567 } | |
| 568 | |
| 569 this._pageResizer.update( | |
| 570 Math.min(dipWidth * scale, available.width - insets.left * scale
), Math.min(dipHeight * scale, available.height - insets.top * scale), | |
| 571 scale, | |
| 572 (dipWidth + insets.left + insets.right) * scale, (dipHeight + in
sets.top + insets.bottom) * scale); | |
| 573 if (scale === 1 && available.width >= dipWidth && available.height >
= dipHeight) { | |
| 574 // When we have enough space, no page size override is required.
This will speed things up and remove lag. | |
| 575 overrideWidth = 0; | |
| 576 overrideHeight = 0; | |
| 577 } | |
| 578 if (dipWidth === 0 && dipHeight !== 0) | |
| 579 overrideWidth = Math.round(available.width / scale); | |
| 580 if (dipHeight === 0 && dipWidth !== 0) | |
| 581 overrideHeight = Math.round(available.height / scale); | |
| 582 screenWidth = dipWidth + insets.left + insets.right; | |
| 583 screenHeight = dipHeight + insets.top + insets.bottom; | |
| 584 positionX = insets.left; | |
| 585 positionY = insets.top; | |
| 586 } | |
| 587 this._deviceScale = scale; | |
| 588 | |
| 589 this._deviceMetricsThrottler.schedule(setDeviceMetricsOverride.bind(this
)); | |
| 590 | |
| 591 /** | |
| 592 * @this {WebInspector.OverridesSupport} | |
| 593 * @return {!Promise.<?>} | |
| 594 */ | |
| 595 function setDeviceMetricsOverride() | |
| 596 { | |
| 597 var setDevicePromise = this._target.emulationAgent().setDeviceMetric
sOverride( | |
| 598 overrideWidth, overrideHeight, this.settings.emulateResolution.g
et() ? this.settings.deviceScaleFactor.get() : 0, | |
| 599 this.settings.emulateMobile.get(), this._pageResizer ? false : t
his.settings.deviceFitWindow.get(), scale, 0, 0, | |
| 600 screenWidth, screenHeight, positionX, positionY, apiCallback.bin
d(this)) | |
| 601 var allPromises = [ setDevicePromise ]; | |
| 602 if (resetPageScaleFactor) | |
| 603 allPromises.push(this._target.emulationAgent().resetPageScaleFac
tor()); | |
| 604 return Promise.all(allPromises); | |
| 605 } | |
| 606 | |
| 607 /** | |
| 608 * @this {WebInspector.OverridesSupport} | |
| 609 * @return {!Promise.<?>} | |
| 610 */ | |
| 611 function clearDeviceMetricsOverride() | |
| 612 { | |
| 613 return this._target.emulationAgent().clearDeviceMetricsOverride(apiC
allback.bind(this)) | |
| 614 } | |
| 615 | |
| 616 /** | |
| 617 * @param {?Protocol.Error} error | |
| 618 * @this {WebInspector.OverridesSupport} | |
| 619 */ | |
| 620 function apiCallback(error) | |
| 621 { | |
| 622 if (error) { | |
| 623 this._updateDeviceMetricsWarningMessage(WebInspector.UIString("S
creen emulation is not available on this page.")); | |
| 624 this._deviceMetricsOverrideAppliedForTest(); | |
| 625 return; | |
| 626 } | |
| 627 | |
| 628 var mobileEnabled = this.emulationEnabled() && this.settings.emulate
Mobile.get(); | |
| 629 if (this._emulateMobileEnabled !== mobileEnabled) | |
| 630 this._updateDeviceMetricsWarningMessage(WebInspector.UIString("Y
ou might need to reload the page for proper user agent spoofing and viewport ren
dering.")); | |
| 631 this._emulateMobileEnabled = mobileEnabled; | |
| 632 this._deviceMetricsOverrideAppliedForTest(); | |
| 633 } | |
| 634 }, | |
| 635 | |
| 636 _deviceMetricsOverrideAppliedForTest: function() | |
| 637 { | |
| 638 // Used for sniffing in tests. | |
| 639 }, | |
| 640 | |
| 641 /** | |
| 642 * @param {boolean} enabled | |
| 643 */ | |
| 644 setGeolocationOverrideEnabled: function(enabled) | |
| 645 { | |
| 646 this._overrideGeolocation = enabled; | |
| 647 this._geolocationPositionChanged(); | |
| 648 }, | |
| 649 | |
| 650 _geolocationPositionChanged: function() | |
| 651 { | |
| 652 if (!this._overrideGeolocation) { | |
| 653 this._target.emulationAgent().clearGeolocationOverride(); | |
| 654 return; | |
| 655 } | |
| 656 var geolocation = WebInspector.OverridesSupport.GeolocationPosition.pars
eSetting(this.settings.geolocationOverride.get()); | |
| 657 if (geolocation.error) | |
| 658 this._target.emulationAgent().setGeolocationOverride(); | |
| 659 else | |
| 660 this._target.emulationAgent().setGeolocationOverride(geolocation.lat
itude, geolocation.longitude, 150); | |
| 661 }, | |
| 662 | |
| 663 /** | |
| 664 * @param {boolean} enabled | |
| 665 */ | |
| 666 setDeviceOrientationOverrideEnabled: function(enabled) | |
| 667 { | |
| 668 this._overrideDeviceOrientation = enabled; | |
| 669 this._deviceOrientationChanged(); | |
| 670 }, | |
| 671 | |
| 672 _deviceOrientationChanged: function() | |
| 673 { | |
| 674 if (!this._overrideDeviceOrientation) { | |
| 675 this._target.deviceOrientationAgent().clearDeviceOrientationOverride
(); | |
| 676 return; | |
| 677 } | |
| 678 | |
| 679 var deviceOrientation = WebInspector.OverridesSupport.DeviceOrientation.
parseSetting(this.settings.deviceOrientationOverride.get()); | |
| 680 this._target.deviceOrientationAgent().setDeviceOrientationOverride(devic
eOrientation.alpha, deviceOrientation.beta, deviceOrientation.gamma); | |
| 681 }, | |
| 682 | |
| 683 _screenOrientationChanged: function() | |
| 684 { | |
| 685 if (!this.emulationEnabled() || !this.settings.screenOrientationOverride
.get()) { | |
| 686 this._target.screenOrientationAgent().clearScreenOrientationOverride
(); | |
| 687 return; | |
| 688 } | |
| 689 | |
| 690 var screenOrientation = this.settings.screenOrientationOverride.get(); | |
| 691 this._target.screenOrientationAgent().setScreenOrientationOverride(scree
nOrientation === "landscapePrimary" ? 90 : 0, screenOrientation); | |
| 692 }, | |
| 693 | |
| 694 _emulateTouchEventsChanged: function() | |
| 695 { | |
| 696 var emulationEnabled = this.emulationEnabled() && this.settings.emulateT
ouch.get() && !this._touchEmulationSuspended; | |
| 697 var configuration = this.settings.emulateMobile.get() ? "mobile" : "desk
top"; | |
| 698 var target = this._target; | |
| 699 | |
| 700 /** | |
| 701 * @suppressGlobalPropertiesCheck | |
| 702 */ | |
| 703 const injectedFunction = function() { | |
| 704 const touchEvents = ["ontouchstart", "ontouchend", "ontouchmove", "o
ntouchcancel"]; | |
| 705 var recepients = [window.__proto__, document.__proto__]; | |
| 706 for (var i = 0; i < touchEvents.length; ++i) { | |
| 707 for (var j = 0; j < recepients.length; ++j) { | |
| 708 if (!(touchEvents[i] in recepients[j])) | |
| 709 Object.defineProperty(recepients[j], touchEvents[i], { v
alue: null, writable: true, configurable: true, enumerable: true }); | |
| 710 } | |
| 711 } | |
| 712 }; | |
| 713 | |
| 714 var symbol = WebInspector.OverridesSupport._touchEventsScriptIdSymbol; | |
| 715 | |
| 716 if (typeof target[symbol] !== "undefined") { | |
| 717 target.pageAgent().removeScriptToEvaluateOnLoad(target[symbol]); | |
| 718 delete target[symbol]; | |
| 719 } | |
| 720 | |
| 721 if (emulationEnabled) | |
| 722 target.pageAgent().addScriptToEvaluateOnLoad("(" + injectedFunction.
toString() + ")()", scriptAddedCallback); | |
| 723 | |
| 724 /** | |
| 725 * @param {?Protocol.Error} error | |
| 726 * @param {string} scriptId | |
| 727 */ | |
| 728 function scriptAddedCallback(error, scriptId) | |
| 729 { | |
| 730 if (error) | |
| 731 delete target[symbol]; | |
| 732 else | |
| 733 target[symbol] = scriptId; | |
| 734 } | |
| 735 | |
| 736 target.emulationAgent().setTouchEmulationEnabled(emulationEnabled, confi
guration); | |
| 737 }, | |
| 738 | |
| 739 _javaScriptDisabledChanged: function() | |
| 740 { | |
| 741 this._target.emulationAgent().setScriptExecutionDisabled(this.settings.j
avaScriptDisabled.get()); | |
| 742 }, | |
| 743 | |
| 744 _pageResizerActive: function() | |
| 745 { | |
| 746 return this._pageResizer && this.emulationEnabled(); | |
| 747 }, | |
| 748 | |
| 749 _showRulersChanged: function() | |
| 750 { | |
| 751 var showRulersValue = WebInspector.moduleSetting("showMetricsRulers").ge
t(); | |
| 752 for (var target of WebInspector.targetManager.targets(WebInspector.Targe
t.Type.Page)) { | |
| 753 var domModel = WebInspector.DOMModel.fromTarget(target); | |
| 754 if (domModel) | |
| 755 domModel.setHighlightSettings(showRulersValue && !this._pageResi
zerActive(), showRulersValue); | |
| 756 } | |
| 757 }, | |
| 758 | |
| 759 _onMainFrameNavigated: function() | |
| 760 { | |
| 761 if (!Runtime.experiments.isEnabled("deviceMode")) | |
| 762 this._deviceMetricsChanged(false); | |
| 763 this._updateUserAgentWarningMessage(""); | |
| 764 this._updateDeviceMetricsWarningMessage(""); | |
| 765 }, | |
| 766 | |
| 767 _dispatchWarningChanged: function() | |
| 768 { | |
| 769 this.dispatchEventToListeners(WebInspector.OverridesSupport.Events.Overr
idesWarningUpdated); | |
| 770 }, | |
| 771 | |
| 772 /** | |
| 773 * @param {string} warningMessage | |
| 774 */ | |
| 775 _updateDeviceMetricsWarningMessage: function(warningMessage) | |
| 776 { | |
| 777 this._deviceMetricsWarningMessage = warningMessage; | |
| 778 this._dispatchWarningChanged(); | |
| 779 }, | |
| 780 | |
| 781 /** | |
| 782 * @param {string} warningMessage | |
| 783 */ | |
| 784 _updateUserAgentWarningMessage: function(warningMessage) | |
| 785 { | |
| 786 this._userAgentWarningMessage = warningMessage; | |
| 787 this._dispatchWarningChanged(); | |
| 788 }, | |
| 789 | |
| 790 /** | |
| 791 * @return {string} | |
| 792 */ | |
| 793 warningMessage: function() | |
| 794 { | |
| 795 return this._deviceMetricsWarningMessage || this._userAgentWarningMessag
e || ""; | |
| 796 }, | |
| 797 | |
| 798 clearWarningMessage: function() | |
| 799 { | |
| 800 this._deviceMetricsWarningMessage = ""; | |
| 801 this._userAgentWarningMessage = ""; | |
| 802 this._dispatchWarningChanged(); | |
| 803 }, | |
| 804 | |
| 805 swapDimensions: function() | |
| 806 { | |
| 807 var width = WebInspector.overridesSupport.settings.deviceWidth.get(); | |
| 808 var height = WebInspector.overridesSupport.settings.deviceHeight.get(); | |
| 809 WebInspector.overridesSupport.settings.deviceWidth.set(height); | |
| 810 WebInspector.overridesSupport.settings.deviceHeight.set(width); | |
| 811 }, | |
| 812 | |
| 813 __proto__: WebInspector.Object.prototype | |
| 814 } | |
| 815 | |
| 816 | |
| 817 /** | |
| 818 * @type {!WebInspector.OverridesSupport} | |
| 819 */ | |
| 820 WebInspector.overridesSupport; | |
| OLD | NEW |