2 * Copyright (C) 2014 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 * @extends {WebInspector.VBox}
35 WebInspector
.OverridesView = function()
37 WebInspector
.VBox
.call(this);
38 this.setMinimumSize(0, 30);
39 this.registerRequiredCSS("emulation/overrides.css");
40 this.element
.classList
.add("overrides-view");
42 this._tabbedPane
= new WebInspector
.TabbedPane();
43 this._tabbedPane
.setShrinkableTabs(false);
44 this._tabbedPane
.setVerticalTabLayout(true);
46 new WebInspector
.OverridesView
.DeviceTab().appendAsTab(this._tabbedPane
);
47 new WebInspector
.OverridesView
.MediaTab().appendAsTab(this._tabbedPane
);
48 new WebInspector
.OverridesView
.NetworkTab().appendAsTab(this._tabbedPane
);
49 new WebInspector
.OverridesView
.SensorsTab().appendAsTab(this._tabbedPane
);
51 this._lastSelectedTabSetting
= WebInspector
.settings
.createSetting("lastSelectedEmulateTab", "device");
52 this._tabbedPane
.selectTab(this._lastSelectedTabSetting
.get());
53 this._tabbedPane
.addEventListener(WebInspector
.TabbedPane
.EventTypes
.TabSelected
, this._tabSelected
, this);
54 this._tabbedPane
.show(this.element
);
56 var resetButtonElement
= createTextButton(WebInspector
.UIString("Reset"), WebInspector
.overridesSupport
.reset
.bind(WebInspector
.overridesSupport
));
57 resetButtonElement
.id
= "overrides-reset-button";
58 this._tabbedPane
.appendAfterTabStrip(resetButtonElement
);
60 var disableButtonElement
= createTextButton(WebInspector
.UIString("Disable"), this._toggleEmulationEnabled
.bind(this), "overrides-disable-button");
61 disableButtonElement
.id
= "overrides-disable-button";
62 this._tabbedPane
.appendAfterTabStrip(disableButtonElement
);
64 this._splashScreenElement
= this.element
.createChild("div", "overrides-splash-screen");
65 this._splashScreenElement
.appendChild(createTextButton(WebInspector
.UIString("Enable emulation"), this._toggleEmulationEnabled
.bind(this), "overrides-enable-button"));
67 this._unavailableSplashScreenElement
= this.element
.createChild("div", "overrides-splash-screen");
68 this._unavailableSplashScreenElement
.createTextChild(WebInspector
.UIString("Emulation is not available."));
70 this._warningFooter
= this.element
.createChild("div", "overrides-footer");
71 this._overridesWarningUpdated();
73 WebInspector
.overridesSupport
.addEventListener(WebInspector
.OverridesSupport
.Events
.OverridesWarningUpdated
, this._overridesWarningUpdated
, this);
74 WebInspector
.overridesSupport
.addEventListener(WebInspector
.OverridesSupport
.Events
.EmulationStateChanged
, this._emulationStateChanged
, this);
75 this._emulationStateChanged();
78 WebInspector
.OverridesView
.prototype = {
80 * @param {!WebInspector.Event} event
82 _tabSelected: function(event
)
84 this._lastSelectedTabSetting
.set(this._tabbedPane
.selectedTabId
);
87 _overridesWarningUpdated: function()
89 var message
= WebInspector
.overridesSupport
.warningMessage();
90 this._warningFooter
.classList
.toggle("hidden", !message
);
91 this._warningFooter
.textContent
= message
;
94 _toggleEmulationEnabled: function()
96 WebInspector
.overridesSupport
.setEmulationEnabled(!WebInspector
.overridesSupport
.emulationEnabled());
99 _emulationStateChanged: function()
101 this._unavailableSplashScreenElement
.classList
.toggle("hidden", WebInspector
.overridesSupport
.canEmulate());
102 this._tabbedPane
.element
.classList
.toggle("hidden", !WebInspector
.overridesSupport
.emulationEnabled());
103 this._splashScreenElement
.classList
.toggle("hidden", WebInspector
.overridesSupport
.emulationEnabled() || !WebInspector
.overridesSupport
.canEmulate());
106 __proto__
: WebInspector
.VBox
.prototype
111 * @extends {WebInspector.VBox}
113 * @param {string} name
114 * @param {!Array.<!WebInspector.Setting>} settings
115 * @param {!Array.<function():boolean>=} predicates
117 WebInspector
.OverridesView
.Tab = function(id
, name
, settings
, predicates
)
119 WebInspector
.VBox
.call(this);
122 this._settings
= settings
;
123 this._predicates
= predicates
|| [];
124 for (var i
= 0; i
< settings
.length
; ++i
)
125 settings
[i
].addChangeListener(this.updateActiveState
, this);
128 WebInspector
.OverridesView
.Tab
.prototype = {
130 * @param {!WebInspector.TabbedPane} tabbedPane
132 appendAsTab: function(tabbedPane
)
134 this._tabbedPane
= tabbedPane
;
135 tabbedPane
.appendTab(this._id
, this._name
, this);
136 this.updateActiveState();
139 updateActiveState: function()
141 if (!this._tabbedPane
)
144 for (var i
= 0; !active
&& i
< this._settings
.length
; ++i
)
145 active
= this._settings
[i
].get();
146 for (var i
= 0; !active
&& i
< this._predicates
.length
; ++i
)
147 active
= this._predicates
[i
]();
148 this._tabbedPane
.toggleTabClass(this._id
, "overrides-activate", active
);
152 * @param {string} name
153 * @param {!WebInspector.Setting} setting
154 * @param {function(boolean)=} callback
156 _createSettingCheckbox: function(name
, setting
, callback
)
158 var checkbox
= WebInspector
.SettingsUI
.createSettingCheckbox(name
, setting
, true);
160 function changeListener(value
)
162 callback(setting
.get());
166 setting
.addChangeListener(changeListener
);
171 __proto__
: WebInspector
.VBox
.prototype
176 * @extends {WebInspector.OverridesView.Tab}
178 WebInspector
.OverridesView
.DeviceTab = function()
180 WebInspector
.OverridesView
.Tab
.call(this, "device", WebInspector
.UIString("Device"), [
181 WebInspector
.overridesSupport
.settings
.emulateResolution
,
182 WebInspector
.overridesSupport
.settings
.deviceScaleFactor
,
183 WebInspector
.overridesSupport
.settings
.emulateMobile
185 this.element
.classList
.add("overrides-device");
187 this.element
.appendChild(this._createDeviceElement());
189 var footnote
= this.element
.createChild("p", "help-footnote");
190 footnote
.appendChild(WebInspector
.linkifyDocumentationURLAsNode("setup/remote-debugging/remote-debugging", WebInspector
.UIString("More information about screen emulation")));
193 WebInspector
.OverridesView
.DeviceTab
.prototype = {
194 _createDeviceElement: function()
196 var fieldsetElement
= createElement("fieldset");
197 fieldsetElement
.id
= "metrics-override-section";
199 var deviceModelElement
= fieldsetElement
.createChild("p", "overrides-device-model-section");
200 deviceModelElement
.createChild("span").textContent
= WebInspector
.UIString("Model:");
202 var rotateButton
= createElement("button");
203 rotateButton
.textContent
= " \u21C4 ";
204 var deviceSelect
= new WebInspector
.DeviceSelect(rotateButton
, null);
205 deviceModelElement
.appendChild(deviceSelect
.element
);
207 var emulateResolutionCheckbox
= WebInspector
.SettingsUI
.createSettingCheckbox(WebInspector
.UIString("Emulate screen resolution"), WebInspector
.overridesSupport
.settings
.emulateResolution
, true);
208 fieldsetElement
.appendChild(emulateResolutionCheckbox
);
209 var resolutionFieldset
= WebInspector
.SettingsUI
.createSettingFieldset(WebInspector
.overridesSupport
.settings
.emulateResolution
);
210 fieldsetElement
.appendChild(resolutionFieldset
);
212 var tableElement
= resolutionFieldset
.createChild("table");
213 var rowElement
= tableElement
.createChild("tr");
214 var cellElement
= rowElement
.createChild("td");
215 cellElement
.createTextChild(WebInspector
.UIString("Resolution:"));
216 cellElement
= rowElement
.createChild("td");
218 var widthOverrideInput
= WebInspector
.SettingsUI
.createSettingInputField("", WebInspector
.overridesSupport
.settings
.deviceWidth
, true, 4, "80px", WebInspector
.OverridesSupport
.deviceSizeValidator
, true, true, WebInspector
.UIString("\u2013"));
219 cellElement
.appendChild(widthOverrideInput
);
220 var heightOverrideInput
= WebInspector
.SettingsUI
.createSettingInputField("", WebInspector
.overridesSupport
.settings
.deviceHeight
, true, 4, "80px", WebInspector
.OverridesSupport
.deviceSizeValidator
, true, true, WebInspector
.UIString("\u2013"));
221 cellElement
.appendChild(heightOverrideInput
);
223 rowElement
= tableElement
.createChild("tr");
224 cellElement
= rowElement
.createChild("td");
225 cellElement
.colSpan
= 4;
227 rowElement
= tableElement
.createChild("tr");
228 rowElement
.title
= WebInspector
.UIString("Ratio between a device's physical pixels and device-independent pixels");
229 rowElement
.createChild("td").createTextChild(WebInspector
.UIString("Device pixel ratio:"));
230 rowElement
.createChild("td").appendChild(WebInspector
.SettingsUI
.createSettingInputField("", WebInspector
.overridesSupport
.settings
.deviceScaleFactor
, true, 4, "80px", WebInspector
.OverridesSupport
.deviceScaleFactorValidator
, true, true, WebInspector
.UIString("\u2013")));
232 var mobileCheckbox
= this._createSettingCheckbox(WebInspector
.UIString("Emulate mobile"), WebInspector
.overridesSupport
.settings
.emulateMobile
);
233 mobileCheckbox
.title
= WebInspector
.UIString("Enable meta viewport, overlay scrollbars, text autosizing and default 980px body width");
234 fieldsetElement
.appendChild(mobileCheckbox
);
236 fieldsetElement
.appendChild(this._createSettingCheckbox(WebInspector
.UIString("Shrink to fit"), WebInspector
.overridesSupport
.settings
.deviceFitWindow
));
238 return fieldsetElement
;
241 __proto__
: WebInspector
.OverridesView
.Tab
.prototype
247 * @extends {WebInspector.OverridesView.Tab}
249 WebInspector
.OverridesView
.MediaTab = function()
251 var settings
= [WebInspector
.overridesSupport
.settings
.overrideCSSMedia
];
252 WebInspector
.OverridesView
.Tab
.call(this, "media", WebInspector
.UIString("Media"), settings
);
253 this.element
.classList
.add("overrides-media");
255 this._createMediaEmulationFragment();
258 WebInspector
.OverridesView
.MediaTab
.prototype = {
259 _createMediaEmulationFragment: function()
261 var checkbox
= WebInspector
.SettingsUI
.createSettingCheckbox(WebInspector
.UIString("CSS media"), WebInspector
.overridesSupport
.settings
.overrideCSSMedia
, true);
262 var fieldsetElement
= WebInspector
.SettingsUI
.createSettingFieldset(WebInspector
.overridesSupport
.settings
.overrideCSSMedia
);
263 var mediaSelectElement
= fieldsetElement
.createChild("select");
264 var mediaTypes
= WebInspector
.CSSStyleModel
.MediaTypes
;
265 var defaultMedia
= WebInspector
.overridesSupport
.settings
.emulatedCSSMedia
.get();
266 for (var i
= 0; i
< mediaTypes
.length
; ++i
) {
267 var mediaType
= mediaTypes
[i
];
268 if (mediaType
=== "all") {
269 // "all" is not a device-specific media type.
272 var option
= createElement("option");
273 option
.text
= mediaType
;
274 option
.value
= mediaType
;
275 mediaSelectElement
.add(option
);
276 if (mediaType
=== defaultMedia
)
277 mediaSelectElement
.selectedIndex
= mediaSelectElement
.options
.length
- 1;
280 mediaSelectElement
.addEventListener("change", this._emulateMediaChanged
.bind(this, mediaSelectElement
), false);
281 var fragment
= createDocumentFragment();
282 fragment
.appendChild(checkbox
);
283 fragment
.appendChild(fieldsetElement
);
284 this.element
.appendChild(fragment
);
287 _emulateMediaChanged: function(select
)
289 var media
= select
.options
[select
.selectedIndex
].value
;
290 WebInspector
.overridesSupport
.settings
.emulatedCSSMedia
.set(media
);
293 __proto__
: WebInspector
.OverridesView
.Tab
.prototype
299 * @extends {WebInspector.OverridesView.Tab}
301 WebInspector
.OverridesView
.NetworkTab = function()
303 WebInspector
.OverridesView
.Tab
.call(this, "network", WebInspector
.UIString("Network"), [], [this._userAgentOverrideEnabled
.bind(this)]);
304 this.element
.classList
.add("overrides-network");
305 this._createUserAgentSection();
308 WebInspector
.OverridesView
.NetworkTab
.prototype = {
312 _userAgentOverrideEnabled: function()
314 return !!WebInspector
.overridesSupport
.settings
.userAgent
.get();
317 _createUserAgentSection: function()
319 var fieldsetElement
= this.element
.createChild("fieldset");
320 fieldsetElement
.createChild("label").textContent
= WebInspector
.UIString("Spoof user agent:");
321 var selectAndInput
= WebInspector
.OverridesUI
.createUserAgentSelectAndInput();
322 fieldsetElement
.appendChild(selectAndInput
.select
);
323 fieldsetElement
.appendChild(selectAndInput
.input
);
325 WebInspector
.overridesSupport
.settings
.userAgent
.addChangeListener(this.updateActiveState
, this);
328 __proto__
: WebInspector
.OverridesView
.Tab
.prototype
334 * @extends {WebInspector.OverridesView.Tab}
336 WebInspector
.OverridesView
.SensorsTab = function()
338 WebInspector
.OverridesView
.Tab
.call(this, "sensors", WebInspector
.UIString("Sensors"), [
339 WebInspector
.overridesSupport
.settings
.overrideGeolocation
,
340 WebInspector
.overridesSupport
.settings
.overrideDeviceOrientation
,
341 WebInspector
.overridesSupport
.settings
.emulateTouch
344 this.element
.classList
.add("overrides-sensors");
345 this.registerRequiredCSS("emulation/accelerometer.css");
346 this.element
.appendChild(this._createSettingCheckbox(WebInspector
.UIString("Emulate touch screen"), WebInspector
.overridesSupport
.settings
.emulateTouch
, undefined));
347 this._appendGeolocationOverrideControl();
348 this._apendDeviceOrientationOverrideControl();
351 WebInspector
.OverridesView
.SensorsTab
.prototype = {
352 _appendGeolocationOverrideControl: function()
354 const geolocationSetting
= WebInspector
.overridesSupport
.settings
.geolocationOverride
.get();
355 var geolocation
= WebInspector
.OverridesSupport
.GeolocationPosition
.parseSetting(geolocationSetting
);
356 this.element
.appendChild(this._createSettingCheckbox(WebInspector
.UIString("Emulate geolocation coordinates"), WebInspector
.overridesSupport
.settings
.overrideGeolocation
, this._geolocationOverrideCheckboxClicked
.bind(this)));
357 this.element
.appendChild(this._createGeolocationOverrideElement(geolocation
));
358 this._geolocationOverrideCheckboxClicked(WebInspector
.overridesSupport
.settings
.overrideGeolocation
.get());
362 * @param {boolean} enabled
364 _geolocationOverrideCheckboxClicked: function(enabled
)
366 if (enabled
&& !this._latitudeElement
.value
)
367 this._latitudeElement
.focus();
370 _applyGeolocationUserInput: function()
372 this._setGeolocationPosition(WebInspector
.OverridesSupport
.GeolocationPosition
.parseUserInput(this._latitudeElement
.value
.trim(), this._longitudeElement
.value
.trim(), this._geolocationErrorElement
.checked
), true);
376 * @param {?WebInspector.OverridesSupport.GeolocationPosition} geolocation
377 * @param {boolean} userInputModified
379 _setGeolocationPosition: function(geolocation
, userInputModified
)
384 if (!userInputModified
) {
385 this._latitudeElement
.value
= geolocation
.latitude
;
386 this._longitudeElement
.value
= geolocation
.longitude
;
389 var value
= geolocation
.toSetting();
390 WebInspector
.overridesSupport
.settings
.geolocationOverride
.set(value
);
394 * @param {!WebInspector.OverridesSupport.GeolocationPosition} geolocation
397 _createGeolocationOverrideElement: function(geolocation
)
399 var fieldsetElement
= WebInspector
.SettingsUI
.createSettingFieldset(WebInspector
.overridesSupport
.settings
.overrideGeolocation
);
400 fieldsetElement
.id
= "geolocation-override-section";
402 var tableElement
= fieldsetElement
.createChild("table");
403 var rowElement
= tableElement
.createChild("tr");
404 var cellElement
= rowElement
.createChild("td");
405 cellElement
= rowElement
.createChild("td");
406 cellElement
.createTextChild(WebInspector
.UIString("Lat = "));
407 this._latitudeElement
= WebInspector
.SettingsUI
.createInput(cellElement
, "geolocation-override-latitude", String(geolocation
.latitude
), this._applyGeolocationUserInput
.bind(this), true);
408 cellElement
.createTextChild(" , ");
409 cellElement
.createTextChild(WebInspector
.UIString("Lon = "));
410 this._longitudeElement
= WebInspector
.SettingsUI
.createInput(cellElement
, "geolocation-override-longitude", String(geolocation
.longitude
), this._applyGeolocationUserInput
.bind(this), true);
411 rowElement
= tableElement
.createChild("tr");
412 cellElement
= rowElement
.createChild("td");
413 cellElement
.colSpan
= 2;
414 var geolocationErrorLabelElement
= createCheckboxLabel(WebInspector
.UIString("Emulate position unavailable"), !geolocation
|| !!geolocation
.error
);
415 var geolocationErrorCheckboxElement
= geolocationErrorLabelElement
.checkboxElement
;
416 geolocationErrorCheckboxElement
.id
= "geolocation-error";
417 geolocationErrorCheckboxElement
.addEventListener("click", this._applyGeolocationUserInput
.bind(this), false);
418 this._geolocationErrorElement
= geolocationErrorCheckboxElement
;
419 cellElement
.appendChild(geolocationErrorLabelElement
);
421 return fieldsetElement
;
424 _apendDeviceOrientationOverrideControl: function()
426 const deviceOrientationSetting
= WebInspector
.overridesSupport
.settings
.deviceOrientationOverride
.get();
427 var deviceOrientation
= WebInspector
.OverridesSupport
.DeviceOrientation
.parseSetting(deviceOrientationSetting
);
428 this.element
.appendChild(this._createSettingCheckbox(WebInspector
.UIString("Accelerometer"), WebInspector
.overridesSupport
.settings
.overrideDeviceOrientation
, this._deviceOrientationOverrideCheckboxClicked
.bind(this)));
429 this.element
.appendChild(this._createDeviceOrientationOverrideElement(deviceOrientation
));
430 this._deviceOrientationOverrideCheckboxClicked(WebInspector
.overridesSupport
.settings
.overrideDeviceOrientation
.get());
434 * @param {boolean} enabled
436 _deviceOrientationOverrideCheckboxClicked: function(enabled
)
438 if (enabled
&& !this._alphaElement
.value
)
439 this._alphaElement
.focus();
442 _applyDeviceOrientationUserInput: function()
444 this._setDeviceOrientation(WebInspector
.OverridesSupport
.DeviceOrientation
.parseUserInput(this._alphaElement
.value
.trim(), this._betaElement
.value
.trim(), this._gammaElement
.value
.trim()), WebInspector
.OverridesView
.SensorsTab
.DeviceOrientationModificationSource
.UserInput
);
447 _resetDeviceOrientation: function()
449 this._setDeviceOrientation(new WebInspector
.OverridesSupport
.DeviceOrientation(0, 0, 0), WebInspector
.OverridesView
.SensorsTab
.DeviceOrientationModificationSource
.ResetButton
);
453 * @param {?WebInspector.OverridesSupport.DeviceOrientation} deviceOrientation
454 * @param {!WebInspector.OverridesView.SensorsTab.DeviceOrientationModificationSource} modificationSource
456 _setDeviceOrientation: function(deviceOrientation
, modificationSource
)
458 if (!deviceOrientation
)
461 if (modificationSource
!= WebInspector
.OverridesView
.SensorsTab
.DeviceOrientationModificationSource
.UserInput
) {
462 this._alphaElement
.value
= deviceOrientation
.alpha
;
463 this._betaElement
.value
= deviceOrientation
.beta
;
464 this._gammaElement
.value
= deviceOrientation
.gamma
;
467 if (modificationSource
!= WebInspector
.OverridesView
.SensorsTab
.DeviceOrientationModificationSource
.UserDrag
)
468 this._setBoxOrientation(deviceOrientation
);
470 var value
= deviceOrientation
.toSetting();
471 WebInspector
.overridesSupport
.settings
.deviceOrientationOverride
.set(value
);
475 * @param {!Element} parentElement
477 * @param {string} label
478 * @param {string} defaultText
481 _createAxisInput: function(parentElement
, id
, label
, defaultText
)
483 var div
= parentElement
.createChild("div", "accelerometer-axis-input-container");
484 div
.createTextChild(label
);
485 return WebInspector
.SettingsUI
.createInput(div
, id
, defaultText
, this._applyDeviceOrientationUserInput
.bind(this), true);
489 * @param {!WebInspector.OverridesSupport.DeviceOrientation} deviceOrientation
491 _createDeviceOrientationOverrideElement: function(deviceOrientation
)
493 var fieldsetElement
= WebInspector
.SettingsUI
.createSettingFieldset(WebInspector
.overridesSupport
.settings
.overrideDeviceOrientation
);
494 fieldsetElement
.id
= "device-orientation-override-section";
495 var tableElement
= fieldsetElement
.createChild("table");
496 var rowElement
= tableElement
.createChild("tr");
497 var cellElement
= rowElement
.createChild("td", "accelerometer-inputs-cell");
499 this._alphaElement
= this._createAxisInput(cellElement
, "device-orientation-override-alpha", "\u03B1: ", String(deviceOrientation
.alpha
));
500 this._betaElement
= this._createAxisInput(cellElement
, "device-orientation-override-beta", "\u03B2: ", String(deviceOrientation
.beta
));
501 this._gammaElement
= this._createAxisInput(cellElement
, "device-orientation-override-gamma", "\u03B3: ", String(deviceOrientation
.gamma
));
503 cellElement
.appendChild(createTextButton(WebInspector
.UIString("Reset"), this._resetDeviceOrientation
.bind(this), "accelerometer-reset-button"));
505 this._stageElement
= rowElement
.createChild("td","accelerometer-stage");
506 this._boxElement
= this._stageElement
.createChild("section", "accelerometer-box");
508 this._boxElement
.createChild("section", "front");
509 this._boxElement
.createChild("section", "top");
510 this._boxElement
.createChild("section", "back");
511 this._boxElement
.createChild("section", "left");
512 this._boxElement
.createChild("section", "right");
513 this._boxElement
.createChild("section", "bottom");
515 WebInspector
.installDragHandle(this._stageElement
, this._onBoxDragStart
.bind(this), this._onBoxDrag
.bind(this), this._onBoxDragEnd
.bind(this), "move");
516 this._setBoxOrientation(deviceOrientation
);
517 return fieldsetElement
;
521 * @param {!WebInspector.OverridesSupport.DeviceOrientation} deviceOrientation
523 _setBoxOrientation: function(deviceOrientation
)
525 var matrix
= new WebKitCSSMatrix();
526 this._boxMatrix
= matrix
.rotate(-deviceOrientation
.beta
, deviceOrientation
.gamma
, -deviceOrientation
.alpha
);
527 this._boxElement
.style
.webkitTransform
= this._boxMatrix
.toString();
531 * @param {!MouseEvent} event
534 _onBoxDrag: function(event
)
536 var mouseMoveVector
= this._calculateRadiusVector(event
.x
, event
.y
);
537 if (!mouseMoveVector
)
541 var axis
= WebInspector
.Geometry
.crossProduct(this._mouseDownVector
, mouseMoveVector
);
543 var angle
= WebInspector
.Geometry
.calculateAngle(this._mouseDownVector
, mouseMoveVector
);
544 var matrix
= new WebKitCSSMatrix();
545 var rotationMatrix
= matrix
.rotateAxisAngle(axis
.x
, axis
.y
, axis
.z
, angle
);
546 this._currentMatrix
= rotationMatrix
.multiply(this._boxMatrix
);
547 this._boxElement
.style
.webkitTransform
= this._currentMatrix
;
548 var eulerAngles
= WebInspector
.Geometry
.EulerAngles
.fromRotationMatrix(this._currentMatrix
);
549 var newOrientation
= new WebInspector
.OverridesSupport
.DeviceOrientation(-eulerAngles
.alpha
, -eulerAngles
.beta
, eulerAngles
.gamma
);
550 this._setDeviceOrientation(newOrientation
, WebInspector
.OverridesView
.SensorsTab
.DeviceOrientationModificationSource
.UserDrag
);
555 * @param {!MouseEvent} event
558 _onBoxDragStart: function(event
)
560 if (!WebInspector
.overridesSupport
.settings
.overrideDeviceOrientation
.get())
563 this._mouseDownVector
= this._calculateRadiusVector(event
.x
, event
.y
);
565 if (!this._mouseDownVector
)
572 _onBoxDragEnd: function()
574 this._boxMatrix
= this._currentMatrix
;
580 * @return {?WebInspector.Geometry.Vector}
582 _calculateRadiusVector: function(x
, y
)
584 var rect
= this._stageElement
.getBoundingClientRect();
585 var radius
= Math
.max(rect
.width
, rect
.height
) / 2;
586 var sphereX
= (x
- rect
.left
- rect
.width
/ 2) / radius
;
587 var sphereY
= (y
- rect
.top
- rect
.height
/ 2) / radius
;
588 var sqrSum
= sphereX
* sphereX
+ sphereY
* sphereY
;
590 return new WebInspector
.Geometry
.Vector(sphereX
, sphereY
, 0.5 / Math
.sqrt(sqrSum
));
592 return new WebInspector
.Geometry
.Vector(sphereX
, sphereY
, Math
.sqrt(1 - sqrSum
));
595 __proto__
: WebInspector
.OverridesView
.Tab
.prototype
598 /** @enum {string} */
599 WebInspector
.OverridesView
.SensorsTab
.DeviceOrientationModificationSource
= {
600 UserInput
: "userInput",
601 UserDrag
: "userDrag",
602 ResetButton
: "resetButton"
607 * @implements {WebInspector.Revealer}
609 WebInspector
.OverridesView
.Revealer = function()
613 WebInspector
.OverridesView
.Revealer
.prototype = {
616 * @param {!Object} overridesSupport
619 reveal: function(overridesSupport
)
621 WebInspector
.inspectorView
.showViewInDrawer("emulation");
622 return Promise
.resolve();