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 |