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.registerRequiredCSS("overrides.css");
39 this.registerRequiredCSS("helpScreen.css");
40 this.element.classList.add("overrides-view");
42 this._tabbedPane = new WebInspector.TabbedPane();
43 this._tabbedPane.shrinkableTabs = false;
44 this._tabbedPane.verticalTabLayout = true;
46 new WebInspector.OverridesView.DeviceTab().appendAsTab(this._tabbedPane);
47 new WebInspector.OverridesView.ViewportTab().appendAsTab(this._tabbedPane);
48 new WebInspector.OverridesView.UserAgentTab().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 this._warningFooter = this.element.createChild("div", "overrides-footer");
57 this._overridesWarningUpdated();
58 WebInspector.overridesSupport.addEventListener(WebInspector.OverridesSupport.Events.OverridesWarningUpdated, this._overridesWarningUpdated, this);
61 WebInspector.OverridesView.prototype = {
63 * @param {!WebInspector.Event} event
65 _tabSelected: function(event)
67 this._lastSelectedTabSetting.set(this._tabbedPane.selectedTabId);
70 _overridesWarningUpdated: function()
72 var message = WebInspector.overridesSupport.warningMessage();
73 this._warningFooter.classList.toggle("hidden", !message);
74 this._warningFooter.textContent = message;
77 __proto__: WebInspector.VBox.prototype
82 * @extends {WebInspector.VBox}
84 * @param {string} name
85 * @param {!Array.<!WebInspector.Setting>} settings
87 WebInspector.OverridesView.Tab = function(id, name, settings)
89 WebInspector.VBox.call(this);
92 this._settings = settings;
93 for (var i = 0; i < settings.length; ++i)
94 settings[i].addChangeListener(this._updateActiveState, this);
97 WebInspector.OverridesView.Tab.prototype = {
99 * @param {!WebInspector.TabbedPane} tabbedPane
101 appendAsTab: function(tabbedPane)
103 this._tabbedPane = tabbedPane;
104 tabbedPane.appendTab(this._id, this._name, this);
105 this._updateActiveState();
108 _updateActiveState: function()
111 for (var i = 0; !active && i < this._settings.length; ++i)
112 active = this._settings[i].get();
113 this._tabbedPane.element.classList.toggle("overrides-activate-" + this._id, active);
114 this._tabbedPane.changeTabTitle(this._id, active ? this._name + " \u2713" : this._name);
118 * Creates an input element under the parentElement with the given id and defaultText.
119 * It also sets an onblur event listener.
120 * @param {!Element} parentElement
122 * @param {string} defaultText
123 * @param {function(*)} eventListener
124 * @param {boolean=} numeric
125 * @return {!Element} element
127 _createInput: function(parentElement, id, defaultText, eventListener, numeric)
129 var element = parentElement.createChild("input");
131 element.type = "text";
132 element.maxLength = 12;
133 element.style.width = "80px";
134 element.value = defaultText;
135 element.align = "right";
137 element.className = "numeric";
138 element.addEventListener("input", eventListener, false);
139 element.addEventListener("keydown", keyDownListener, false);
140 function keyDownListener(event)
142 if (isEnterKey(event))
143 eventListener(event);
149 * @param {string} title
150 * @param {function(boolean)} callback
152 _createNonPersistedCheckbox: function(title, callback)
154 var labelElement = document.createElement("label");
155 var checkboxElement = labelElement.createChild("input");
156 checkboxElement.type = "checkbox";
157 checkboxElement.checked = false;
158 checkboxElement.addEventListener("click", onclick, false);
159 labelElement.appendChild(document.createTextNode(title));
164 callback(checkboxElement.checked);
169 * @param {string} name
170 * @param {!WebInspector.Setting} setting
171 * @param {function(boolean)=} callback
173 _createSettingCheckbox: function(name, setting, callback)
175 var checkbox = WebInspector.SettingsUI.createCheckbox(name, setting.get.bind(setting), listener, true);
177 function listener(value)
179 if (setting.get() === value)
187 setting.addChangeListener(changeListener);
189 function changeListener()
191 if (checkbox.firstChild.checked !== setting.get())
192 checkbox.firstChild.checked = setting.get();
197 __proto__: WebInspector.VBox.prototype
202 * @extends {WebInspector.OverridesView.Tab}
204 WebInspector.OverridesView.DeviceTab = function()
206 WebInspector.OverridesView.Tab.call(this, "device", WebInspector.UIString("Device"), []);
207 this.element.classList.add("overrides-device");
209 this._emulatedDeviceSetting = WebInspector.settings.createSetting("emulatedDevice", "Google Nexus 4");
210 this._emulateDeviceViewportSetting = WebInspector.settings.overrideDeviceMetrics;
211 this._emulateDeviceUserAgentSetting = WebInspector.settings.overrideUserAgent;
213 this._deviceSelectElement = this.element.createChild("select");
215 var devices = WebInspector.OverridesView.DeviceTab._phones.concat(WebInspector.OverridesView.DeviceTab._tablets);
217 var selectionRestored = false;
218 for (var i = 0; i < devices.length; ++i) {
219 var device = devices[i];
220 var option = new Option(device[0], device[0]);
221 option._userAgent = device[1];
222 option._metrics = device[2];
223 this._deviceSelectElement.add(option);
224 if (this._emulatedDeviceSetting.get() === device[0]) {
225 this._deviceSelectElement.selectedIndex = i;
226 selectionRestored = true;
230 if (!selectionRestored)
231 this._deviceSelectElement.selectedIndex = devices.length - 1;
233 this._deviceSelectElement.addEventListener("change", this._deviceSelected.bind(this), false);
234 this._deviceSelectElement.addEventListener("keypress", this._keyPressed.bind(this), false);
235 this._deviceSelectElement.disabled = WebInspector.OverridesSupport.isInspectingDevice();
237 var buttonsBar = this.element.createChild("div");
238 var emulateButton = buttonsBar.createChild("button", "settings-tab-text-button");
239 emulateButton.textContent = WebInspector.UIString("Emulate");
240 emulateButton.addEventListener("click", this._emulateButtonClicked.bind(this), false);
241 emulateButton.disabled = WebInspector.OverridesSupport.isInspectingDevice();
243 var resetButton = buttonsBar.createChild("button", "settings-tab-text-button");
244 resetButton.textContent = WebInspector.UIString("Reset");
245 resetButton.addEventListener("click", this._resetButtonClicked.bind(this), false);
246 this._resetButton = resetButton;
248 this._viewportValueLabel = this.element.createChild("div", "overrides-device-value-label");
249 this._viewportValueLabel.textContent = WebInspector.UIString("Viewport:");
250 this._viewportValueElement = this._viewportValueLabel.createChild("span", "overrides-device-value");
252 this._userAgentLabel = this.element.createChild("div", "overrides-device-value-label");
253 this._userAgentLabel.textContent = WebInspector.UIString("User agent:");
254 this._userAgentValueElement = this._userAgentLabel.createChild("span", "overrides-device-value");
256 this._updateValueLabels();
257 WebInspector.overridesSupport.addEventListener(WebInspector.OverridesSupport.Events.HasActiveOverridesChanged, this._hasActiveOverridesChanged, this);
258 this._hasActiveOverridesChanged();
261 // Third element lists device metrics separated by 'x':
264 // - device scale factor,
265 // - use text autosizing.
266 WebInspector.OverridesView.DeviceTab._phones = [
268 "Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_2_1 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148 Safari/6533.18.5",
271 "Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_2_1 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148 Safari/6533.18.5",
274 "Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X; en-us) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53",
277 "Mozilla/5.0 (BB10; Touch) AppleWebKit/537.10+ (KHTML, like Gecko) Version/10.0.9.2372 Mobile Safari/537.10+",
280 "Mozilla/5.0 (BB10; Touch) AppleWebKit/537.10+ (KHTML, like Gecko) Version/10.0.9.2372 Mobile Safari/537.10+",
283 "Mozilla/5.0 (Linux; Android 4.2.1; en-us; Nexus 4 Build/JOP40D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19",
286 "Mozilla/5.0 (Linux; Android 4.2.1; en-us; Nexus 5 Build/JOP40D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19",
289 "Mozilla/5.0 (Linux; U; Android 2.3.4; en-us; Nexus S Build/GRJ22) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
291 ["HTC Evo, Touch HD, Desire HD, Desire",
292 "Mozilla/5.0 (Linux; U; Android 2.2; en-us; Sprint APA9292KT Build/FRF91) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
294 ["HTC One X, EVO LTE",
295 "Mozilla/5.0 (Linux; Android 4.0.3; HTC One X Build/IML74K) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19",
297 ["HTC Sensation, Evo 3D",
298 "Mozilla/5.0 (Linux; U; Android 4.0.3; en-us; HTC Sensation Build/IML74K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30",
300 ["LG Optimus 2X, Optimus 3D, Optimus Black",
301 "Mozilla/5.0 (Linux; U; Android 2.2; en-us; LG-P990/V08c Build/FRG83) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1 MMS/LG-Android-MMS-V1.0/1.2",
304 "Mozilla/5.0 (Linux; Android 4.0; LG-E975 Build/IMM76L) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19",
306 ["LG Optimus LTE, Optimus 4X HD",
307 "Mozilla/5.0 (Linux; U; Android 2.3; en-us; LG-P930 Build/GRJ90) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
310 "Mozilla/5.0 (Linux; U; Android 2.2.1; en-us; LG-MS690 Build/FRG83) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
312 ["Motorola Defy, Droid, Droid X, Milestone",
313 "Mozilla/5.0 (Linux; U; Android 2.0; en-us; Milestone Build/ SHOLS_U2_01.03.1) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17",
315 ["Motorola Droid 3, Droid 4, Droid Razr, Atrix 4G, Atrix 2",
316 "Mozilla/5.0 (Linux; U; Android 2.2; en-us; Droid Build/FRG22D) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
318 ["Motorola Droid Razr HD",
319 "Mozilla/5.0 (Linux; U; Android 2.3; en-us; DROID RAZR 4G Build/6.5.1-73_DHD-11_M1-29) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
321 ["Nokia C5, C6, C7, N97, N8, X7",
322 "NokiaN97/21.1.107 (SymbianOS/9.4; Series60/5.0 Mozilla/5.0; Profile/MIDP-2.1 Configuration/CLDC-1.1) AppleWebkit/525 (KHTML, like Gecko) BrowserNG/7.1.4",
324 ["Nokia Lumia 7X0, Lumia 8XX, Lumia 900, N800, N810, N900",
325 "Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; IEMobile/10.0; ARM; Touch; NOKIA; Lumia 820)",
327 ["Samsung Galaxy Note 3",
328 "Mozilla/5.0 (Linux; U; Android 4.3; en-us; SM-N900T Build/JSS15J) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30",
330 ["Samsung Galaxy Note II",
331 "Mozilla/5.0 (Linux; U; Android 4.1; en-us; GT-N7100 Build/JRO03C) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30",
333 ["Samsung Galaxy Note",
334 "Mozilla/5.0 (Linux; U; Android 2.3; en-us; SAMSUNG-SGH-I717 Build/GINGERBREAD) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
336 ["Samsung Galaxy S III, Galaxy Nexus",
337 "Mozilla/5.0 (Linux; U; Android 4.0; en-us; GT-I9300 Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30",
339 ["Samsung Galaxy S, S II, W",
340 "Mozilla/5.0 (Linux; U; Android 2.1; en-us; GT-I9000 Build/ECLAIR) AppleWebKit/525.10+ (KHTML, like Gecko) Version/3.0.4 Mobile Safari/523.12.2",
342 ["Samsung Galaxy S4",
343 "Mozilla/5.0 (Linux; Android 4.2.2; GT-I9505 Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.59 Mobile Safari/537.36",
345 ["Sony Xperia S, Ion",
346 "Mozilla/5.0 (Linux; U; Android 4.0; en-us; LT28at Build/6.1.C.1.111) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30",
348 ["Sony Xperia Sola, U",
349 "Mozilla/5.0 (Linux; U; Android 2.3; en-us; SonyEricssonST25i Build/6.0.B.1.564) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
351 ["Sony Xperia Z, Z1",
352 "Mozilla/5.0 (Linux; U; Android 4.2; en-us; SonyC6903 Build/14.1.G.1.518) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30",
356 WebInspector.OverridesView.DeviceTab._tablets = [
357 ["Amazon Amazon Kindle Fire HD 7\u2033",
358 "Mozilla/5.0 (Linux; U; Android 2.3.4; en-us; Kindle Fire HD Build/GINGERBREAD) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
360 ["Amazon Amazon Kindle Fire HD 8.9\u2033",
361 "Mozilla/5.0 (Linux; U; Android 2.3.4; en-us; Kindle Fire HD Build/GINGERBREAD) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
363 ["Amazon Amazon Kindle Fire",
364 "Mozilla/5.0 (Linux; U; Android 2.3.4; en-us; Kindle Fire Build/GINGERBREAD) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
366 ["Apple iPad 1 / 2 / iPad Mini",
367 "Mozilla/5.0 (iPad; CPU OS 4_3_5 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8L1 Safari/6533.18.5",
370 "Mozilla/5.0 (iPad; CPU OS 7_0 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53",
372 ["BlackBerry PlayBook",
373 "Mozilla/5.0 (PlayBook; U; RIM Tablet OS 2.1.0; en-US) AppleWebKit/536.2+ (KHTML like Gecko) Version/7.2.1.0 Safari/536.2+",
376 "Mozilla/5.0 (Linux; Android 4.3; Nexus 10 Build/JSS15Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.72 Safari/537.36",
379 "Mozilla/5.0 (Linux; Android 4.3; Nexus 7 Build/JSS15Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.72 Safari/537.36",
382 "Mozilla/5.0 (Linux; Android 4.3; Nexus 7 Build/JSS15Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.72 Safari/537.36",
384 ["Motorola Xoom, Xyboard",
385 "Mozilla/5.0 (Linux; U; Android 3.0; en-us; Xoom Build/HRI39) AppleWebKit/525.10 (KHTML, like Gecko) Version/3.0.4 Mobile Safari/523.12.2",
387 ["Samsung Galaxy Tab 7.7, 8.9, 10.1",
388 "Mozilla/5.0 (Linux; U; Android 2.2; en-us; SCH-I800 Build/FROYO) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
390 ["Samsung Galaxy Tab",
391 "Mozilla/5.0 (Linux; U; Android 2.2; en-us; SCH-I800 Build/FROYO) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
395 WebInspector.OverridesView.DeviceTab.prototype = {
399 _keyPressed: function(e)
401 if (e.keyCode === WebInspector.KeyboardShortcut.Keys.Enter.code)
402 this._emulateButtonClicked();
405 _emulateButtonClicked: function()
407 var option = this._deviceSelectElement.options[this._deviceSelectElement.selectedIndex];
408 WebInspector.overridesSupport.emulateDevice(option._metrics, option._userAgent);
411 _resetButtonClicked: function()
413 WebInspector.overridesSupport.reset();
416 _hasActiveOverridesChanged: function()
418 this._resetButton.disabled = !WebInspector.overridesSupport.hasActiveOverrides();
421 _deviceSelected: function()
423 var option = this._deviceSelectElement.options[this._deviceSelectElement.selectedIndex];
424 this._emulatedDeviceSetting.set(option.value);
425 this._updateValueLabels();
428 _updateValueLabels: function()
430 var option = this._deviceSelectElement.options[this._deviceSelectElement.selectedIndex];
432 if (option._metrics && (metrics = WebInspector.OverridesSupport.DeviceMetrics.parseSetting(option._metrics)))
433 this._viewportValueElement.textContent = WebInspector.UIString("%s \xD7 %s, devicePixelRatio = %s", metrics.width, metrics.height, metrics.deviceScaleFactor);
435 this._viewportValueElement.textContent = "";
436 this._userAgentValueElement.textContent = option._userAgent || "";
439 __proto__: WebInspector.OverridesView.Tab.prototype
445 * @extends {WebInspector.OverridesView.Tab}
447 WebInspector.OverridesView.ViewportTab = function()
449 WebInspector.OverridesView.Tab.call(this, "viewport", WebInspector.UIString("Screen"), [WebInspector.settings.overrideDeviceMetrics, WebInspector.settings.overrideCSSMedia]);
450 this.element.classList.add("overrides-viewport");
452 const metricsSetting = WebInspector.settings.deviceMetrics.get();
453 var metrics = WebInspector.OverridesSupport.DeviceMetrics.parseSetting(metricsSetting);
454 var checkbox = this._createSettingCheckbox(WebInspector.UIString("Emulate screen"), WebInspector.settings.overrideDeviceMetrics, this._onMetricsCheckboxClicked.bind(this));
455 checkbox.firstChild.disabled = WebInspector.OverridesSupport.isInspectingDevice();
456 WebInspector.settings.deviceMetrics.addChangeListener(this._updateDeviceMetricsElement, this);
458 this.element.appendChild(checkbox);
459 this.element.appendChild(this._createDeviceMetricsElement(metrics));
460 this.element.appendChild(this._createMediaEmulationFragment());
462 var footnote = this.element.createChild("p", "help-footnote");
463 var footnoteLink = footnote.createChild("a");
464 footnoteLink.href = "https://developers.google.com/chrome-developer-tools/docs/mobile-emulation";
465 footnoteLink.target = "_blank";
466 footnoteLink.createTextChild(WebInspector.UIString("More information about screen emulation"));
468 this._onMetricsCheckboxClicked(WebInspector.settings.overrideDeviceMetrics.get());
471 WebInspector.OverridesView.ViewportTab.prototype = {
473 * @param {boolean} enabled
475 _onMetricsCheckboxClicked: function(enabled)
477 if (enabled && !this._widthOverrideElement.value)
478 this._widthOverrideElement.focus();
479 this._applyDeviceMetricsUserInput();
482 _applyDeviceMetricsUserInput: function()
484 this._muteRangeListener = true;
485 this._widthRangeInput.value = this._widthOverrideElement.value;
486 delete this._muteRangeListener;
487 if (this._applyDeviceMetricsTimer)
488 clearTimeout(this._applyDeviceMetricsTimer);
489 this._applyDeviceMetricsTimer = setTimeout(this._doApplyDeviceMetricsUserInput.bind(this), 50);
492 _doApplyDeviceMetricsUserInput: function()
494 delete this._applyDeviceMetricsTimer;
495 this._setDeviceMetricsOverride(WebInspector.OverridesSupport.DeviceMetrics.parseUserInput(this._widthOverrideElement.value.trim(), this._heightOverrideElement.value.trim(), this._deviceScaleFactorOverrideElement.value.trim(), this._textAutosizingOverrideCheckbox.checked), true);
499 * @param {?WebInspector.OverridesSupport.DeviceMetrics} metrics
500 * @param {boolean} userInputModified
502 _setDeviceMetricsOverride: function(metrics, userInputModified)
504 function setValid(condition, element)
507 element.classList.remove("error-input");
509 element.classList.add("error-input");
512 setValid(metrics && metrics.isWidthValid(), this._widthOverrideElement);
513 setValid(metrics && metrics.isHeightValid(), this._heightOverrideElement);
514 setValid(metrics && metrics.isDeviceScaleFactorValid(), this._deviceScaleFactorOverrideElement);
519 if (!userInputModified) {
520 this._widthOverrideElement.value = metrics.widthToInput();
521 this._heightOverrideElement.value = metrics.heightToInput();
522 this._deviceScaleFactorOverrideElement.value = metrics.deviceScaleFactorToInput();
523 this._textAutosizingOverrideCheckbox.checked = metrics.textAutosizing;
526 if (metrics.isValid()) {
527 var value = metrics.toSetting();
528 if (value !== WebInspector.settings.deviceMetrics.get())
529 WebInspector.settings.deviceMetrics.set(value);
534 * @param {!WebInspector.OverridesSupport.DeviceMetrics} metrics
536 _createDeviceMetricsElement: function(metrics)
538 var fieldsetElement = WebInspector.SettingsUI.createSettingFieldset(WebInspector.settings.overrideDeviceMetrics);
539 if (WebInspector.OverridesSupport.isInspectingDevice())
540 fieldsetElement.disabled = true;
541 fieldsetElement.id = "metrics-override-section";
544 * @this {WebInspector.OverridesView.ViewportTab}
546 function swapDimensionsClicked()
548 var widthValue = this._widthOverrideElement.value;
549 this._widthOverrideElement.value = this._heightOverrideElement.value;
550 this._heightOverrideElement.value = widthValue;
551 this._applyDeviceMetricsUserInput();
554 var tableElement = fieldsetElement.createChild("table", "nowrap");
556 var rowElement = tableElement.createChild("tr");
557 var cellElement = rowElement.createChild("td");
558 cellElement.appendChild(document.createTextNode(WebInspector.UIString("Resolution:")));
559 cellElement = rowElement.createChild("td");
560 this._widthOverrideElement = this._createInput(cellElement, "metrics-override-width", String(metrics.width || screen.width), this._applyDeviceMetricsUserInput.bind(this), true);
561 this._swapDimensionsElement = cellElement.createChild("button", "overrides-swap");
562 this._swapDimensionsElement.appendChild(document.createTextNode(" \u21C4 ")); // RIGHTWARDS ARROW OVER LEFTWARDS ARROW.
563 this._swapDimensionsElement.title = WebInspector.UIString("Swap dimensions");
564 this._swapDimensionsElement.addEventListener("click", swapDimensionsClicked.bind(this), false);
565 this._swapDimensionsElement.tabIndex = -1;
566 this._heightOverrideElement = this._createInput(cellElement, "metrics-override-height", String(metrics.height || screen.height), this._applyDeviceMetricsUserInput.bind(this), true);
568 rowElement = tableElement.createChild("tr");
569 cellElement = rowElement.createChild("td");
570 cellElement.colSpan = 4;
571 this._widthRangeInput = cellElement.createChild("input");
572 this._widthRangeInput.type = "range";
573 this._widthRangeInput.min = 100;
574 this._widthRangeInput.max = 2000;
575 this._widthRangeInput.addEventListener("change", this._rangeValueChanged.bind(this), false);
576 this._widthRangeInput.addEventListener("input", this._rangeValueChanged.bind(this), false);
577 this._widthRangeInput.value = this._widthOverrideElement.value;
579 rowElement = tableElement.createChild("tr");
580 rowElement.title = WebInspector.UIString("Ratio between a device's physical pixels and device-independent pixels.");
581 cellElement = rowElement.createChild("td");
582 cellElement.appendChild(document.createTextNode(WebInspector.UIString("Device pixel ratio:")));
583 cellElement = rowElement.createChild("td");
584 this._deviceScaleFactorOverrideElement = this._createInput(cellElement, "metrics-override-device-scale", String(metrics.deviceScaleFactor || 1), this._applyDeviceMetricsUserInput.bind(this), true);
586 var textAutosizingOverrideElement = this._createNonPersistedCheckbox(WebInspector.UIString("Enable text autosizing "), this._applyDeviceMetricsUserInput.bind(this));
587 textAutosizingOverrideElement.title = WebInspector.UIString("Text autosizing is the feature that boosts font sizes on mobile devices.");
588 this._textAutosizingOverrideCheckbox = textAutosizingOverrideElement.firstChild;
589 this._textAutosizingOverrideCheckbox.checked = metrics.textAutosizing;
590 fieldsetElement.appendChild(textAutosizingOverrideElement);
592 var checkbox = this._createSettingCheckbox(WebInspector.UIString("Emulate viewport"), WebInspector.settings.emulateViewport);
593 fieldsetElement.appendChild(checkbox);
595 checkbox = this._createSettingCheckbox(WebInspector.UIString("Shrink to fit"), WebInspector.settings.deviceFitWindow);
596 fieldsetElement.appendChild(checkbox);
598 return fieldsetElement;
601 _updateDeviceMetricsElement: function()
603 const metricsSetting = WebInspector.settings.deviceMetrics.get();
604 var metrics = WebInspector.OverridesSupport.DeviceMetrics.parseSetting(metricsSetting);
606 if (this._widthOverrideElement.value !== metrics.width)
607 this._widthOverrideElement.value = metrics.width || screen.width;
608 this._muteRangeListener = true;
609 if (this._widthRangeInput.value != metrics.width)
610 this._widthRangeInput.value = metrics.width || screen.width;
611 delete this._muteRangeListener;
612 if (this._heightOverrideElement.value !== metrics.height)
613 this._heightOverrideElement.value = metrics.height || screen.height;
614 if (this._deviceScaleFactorOverrideElement.value !== metrics.deviceScaleFactor)
615 this._deviceScaleFactorOverrideElement.value = metrics.deviceScaleFactor || 1;
616 if (this._textAutosizingOverrideCheckbox.checked !== metrics.textAutosizing)
617 this._textAutosizingOverrideCheckbox.checked = metrics.textAutosizing || false;
620 _createMediaEmulationFragment: function()
622 var checkbox = WebInspector.SettingsUI.createSettingCheckbox(WebInspector.UIString("CSS media"), WebInspector.settings.overrideCSSMedia, true);
623 var fieldsetElement = WebInspector.SettingsUI.createSettingFieldset(WebInspector.settings.overrideCSSMedia);
624 if (WebInspector.OverridesSupport.isInspectingDevice())
625 fieldsetElement.disabled = true;
627 var mediaSelectElement = fieldsetElement.createChild("select");
628 var mediaTypes = WebInspector.CSSStyleModel.MediaTypes;
629 var defaultMedia = WebInspector.settings.emulatedCSSMedia.get();
630 for (var i = 0; i < mediaTypes.length; ++i) {
631 var mediaType = mediaTypes[i];
632 if (mediaType === "all") {
633 // "all" is not a device-specific media type.
636 var option = document.createElement("option");
637 option.text = mediaType;
638 option.value = mediaType;
639 mediaSelectElement.add(option);
640 if (mediaType === defaultMedia)
641 mediaSelectElement.selectedIndex = mediaSelectElement.options.length - 1;
644 mediaSelectElement.addEventListener("change", this._emulateMediaChanged.bind(this, mediaSelectElement), false);
645 var fragment = document.createDocumentFragment();
646 fragment.appendChild(checkbox);
647 fragment.appendChild(fieldsetElement);
651 _emulateMediaChanged: function(select)
653 var media = select.options[select.selectedIndex].value;
654 WebInspector.settings.emulatedCSSMedia.set(media);
657 _rangeValueChanged: function()
659 if (this._muteRangeListener)
661 this._widthOverrideElement.value = this._widthRangeInput.value;
662 this._applyDeviceMetricsUserInput();
665 __proto__: WebInspector.OverridesView.Tab.prototype
671 * @extends {WebInspector.OverridesView.Tab}
673 WebInspector.OverridesView.UserAgentTab = function()
675 WebInspector.OverridesView.Tab.call(this, "user-agent", WebInspector.UIString("User Agent"), [WebInspector.settings.overrideUserAgent]);
676 this.element.classList.add("overrides-user-agent");
677 var checkbox = this._createSettingCheckbox(WebInspector.UIString("Spoof user agent"), WebInspector.settings.overrideUserAgent);
678 checkbox.firstChild.disabled = WebInspector.OverridesSupport.isInspectingDevice();
679 this.element.appendChild(checkbox);
680 this.element.appendChild(this._createUserAgentSelectRowElement());
683 WebInspector.OverridesView.UserAgentTab._userAgents = [
684 ["Android 4.0.2 \u2014 Galaxy Nexus", "Mozilla/5.0 (Linux; U; Android 4.0.2; en-us; Galaxy Nexus Build/ICL53F) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30"],
685 ["Android 2.3 \u2014 Nexus S", "Mozilla/5.0 (Linux; U; Android 2.3.6; en-us; Nexus S Build/GRK39F) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1"],
686 ["BlackBerry \u2014 BB10", "Mozilla/5.0 (BB10; Touch) AppleWebKit/537.1+ (KHTML, like Gecko) Version/10.0.0.1337 Mobile Safari/537.1+"],
687 ["BlackBerry \u2014 PlayBook 2.1", "Mozilla/5.0 (PlayBook; U; RIM Tablet OS 2.1.0; en-US) AppleWebKit/536.2+ (KHTML, like Gecko) Version/7.2.1.0 Safari/536.2+"],
688 ["BlackBerry \u2014 9900", "Mozilla/5.0 (BlackBerry; U; BlackBerry 9900; en-US) AppleWebKit/534.11+ (KHTML, like Gecko) Version/7.0.0.187 Mobile Safari/534.11+"],
689 ["Chrome 31 \u2014 Mac", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36"],
690 ["Chrome 31 \u2014 Windows", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.16 Safari/537.36"],
691 ["Chrome \u2014 Android Tablet", "Mozilla/5.0 (Linux; Android 4.1.2; Nexus 7 Build/JZ054K) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Safari/535.19"],
692 ["Chrome \u2014 Android Mobile", "Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19"],
693 ["Firefox 14 \u2014 Android Mobile", "Mozilla/5.0 (Android; Mobile; rv:14.0) Gecko/14.0 Firefox/14.0"],
694 ["Firefox 14 \u2014 Android Tablet", "Mozilla/5.0 (Android; Tablet; rv:14.0) Gecko/14.0 Firefox/14.0"],
695 ["Firefox 4 \u2014 Mac", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0.1) Gecko/20100101 Firefox/4.0.1"],
696 ["Firefox 4 \u2014 Windows", "Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1"],
697 ["Firefox 7 \u2014 Mac", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:7.0.1) Gecko/20100101 Firefox/7.0.1"],
698 ["Firefox 7 \u2014 Windows", "Mozilla/5.0 (Windows NT 6.1; Intel Mac OS X 10.6; rv:7.0.1) Gecko/20100101 Firefox/7.0.1"],
699 ["Internet Explorer 10", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)"],
700 ["Internet Explorer 7", "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)"],
701 ["Internet Explorer 8", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)"],
702 ["Internet Explorer 9", "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)"],
703 ["iPad \u2014 iOS 7", "Mozilla/5.0 (iPad; CPU OS 7_0_2 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A501 Safari/9537.53"],
704 ["iPad \u2014 iOS 6", "Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5376e Safari/8536.25"],
705 ["iPhone \u2014 iOS 7", "Mozilla/5.0 (iPhone; CPU iPhone OS 7_0_2 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A4449d Safari/9537.53"],
706 ["iPhone \u2014 iOS 6", "Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5376e Safari/8536.25"],
707 ["MeeGo \u2014 Nokia N9", "Mozilla/5.0 (MeeGo; NokiaN9) AppleWebKit/534.13 (KHTML, like Gecko) NokiaBrowser/8.5.0 Mobile Safari/534.13"],
708 ["Opera 18 \u2014 Mac", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36 OPR/18.0.1284.68"],
709 ["Opera 18 \u2014 Windows", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36 OPR/18.0.1284.68"],
710 ["Opera 12 \u2014 Mac", "Opera/9.80 (Macintosh; Intel Mac OS X 10.9.1) Presto/2.12.388 Version/12.16"],
711 ["Opera 12 \u2014 Windows", "Opera/9.80 (Windows NT 6.1) Presto/2.12.388 Version/12.16"],
714 WebInspector.OverridesView.UserAgentTab.prototype = {
718 _createUserAgentSelectRowElement: function()
720 var userAgent = WebInspector.settings.userAgent.get();
721 var userAgents = WebInspector.OverridesView.UserAgentTab._userAgents.concat([[WebInspector.UIString("Other"), "Other"]]);
723 var fieldsetElement = WebInspector.SettingsUI.createSettingFieldset(WebInspector.settings.overrideUserAgent);
724 if (WebInspector.OverridesSupport.isInspectingDevice())
725 fieldsetElement.disabled = true;
727 this._selectElement = fieldsetElement.createChild("select");
728 fieldsetElement.createChild("br");
729 this._otherUserAgentElement = fieldsetElement.createChild("input");
730 this._otherUserAgentElement.type = "text";
731 this._otherUserAgentElement.value = userAgent;
732 this._otherUserAgentElement.title = userAgent;
734 var selectionRestored = false;
735 for (var i = 0; i < userAgents.length; ++i) {
736 var agent = userAgents[i];
737 var option = new Option(agent[0], agent[1]);
738 option._metrics = agent[2] ? agent[2] : "";
739 this._selectElement.add(option);
740 if (userAgent === agent[1]) {
741 this._selectElement.selectedIndex = i;
742 selectionRestored = true;
746 if (!selectionRestored) {
748 this._selectElement.selectedIndex = 0;
750 this._selectElement.selectedIndex = userAgents.length - 1;
753 this._selectElement.addEventListener("change", this._userAgentChanged.bind(this, true), false);
754 WebInspector.settings.userAgent.addChangeListener(this._userAgentSettingChanged, this);
756 fieldsetElement.addEventListener("dblclick", textDoubleClicked.bind(this), false);
757 this._otherUserAgentElement.addEventListener("blur", textChanged.bind(this), false);
760 * @this {WebInspector.OverridesView.UserAgentTab}
762 function textDoubleClicked()
764 this._selectElement.selectedIndex = userAgents.length - 1;
765 this._userAgentChanged();
769 * @this {WebInspector.OverridesView.UserAgentTab}
771 function textChanged()
773 if (WebInspector.settings.userAgent.get() !== this._otherUserAgentElement.value)
774 WebInspector.settings.userAgent.set(this._otherUserAgentElement.value);
777 return fieldsetElement;
781 * @param {boolean=} isUserGesture
783 _userAgentChanged: function(isUserGesture)
785 var value = this._selectElement.options[this._selectElement.selectedIndex].value;
786 if (value !== "Other") {
787 WebInspector.settings.userAgent.set(value);
788 this._otherUserAgentElement.value = value;
789 this._otherUserAgentElement.title = value;
790 this._otherUserAgentElement.disabled = true;
792 this._otherUserAgentElement.disabled = false;
793 this._otherUserAgentElement.focus();
797 _userAgentSettingChanged: function()
799 var value = WebInspector.settings.userAgent.get();
800 var options = this._selectElement.options;
801 var foundMatch = false;
802 for (var i = 0; i < options.length; ++i) {
803 if (options[i].value === value) {
804 if (this._selectElement.selectedIndex !== i)
805 this._selectElement.selectedIndex = i;
811 this._otherUserAgentElement.disabled = foundMatch;
813 this._selectElement.selectedIndex = options.length - 1;
815 if (this._otherUserAgentElement.value !== value) {
816 this._otherUserAgentElement.value = value;
817 this._otherUserAgentElement.title = value;
821 __proto__: WebInspector.OverridesView.Tab.prototype
827 * @extends {WebInspector.OverridesView.Tab}
829 WebInspector.OverridesView.SensorsTab = function()
831 WebInspector.OverridesView.Tab.call(this, "sensors", WebInspector.UIString("Sensors"), [WebInspector.settings.emulateTouchEvents, WebInspector.settings.overrideGeolocation, WebInspector.settings.overrideDeviceOrientation]);
832 this.element.classList.add("overrides-sensors");
833 this.registerRequiredCSS("accelerometer.css");
834 if (!WebInspector.OverridesSupport.isInspectingDevice())
835 this.element.appendChild(this._createSettingCheckbox(WebInspector.UIString("Emulate touch screen"), WebInspector.settings.emulateTouchEvents));
836 this._appendGeolocationOverrideControl();
837 this._apendDeviceOrientationOverrideControl();
840 WebInspector.OverridesView.SensorsTab.prototype = {
841 _appendGeolocationOverrideControl: function()
843 const geolocationSetting = WebInspector.settings.geolocationOverride.get();
844 var geolocation = WebInspector.OverridesSupport.GeolocationPosition.parseSetting(geolocationSetting);
845 this.element.appendChild(this._createSettingCheckbox(WebInspector.UIString("Emulate geolocation coordinates"), WebInspector.settings.overrideGeolocation, this._geolocationOverrideCheckboxClicked.bind(this)));
846 this.element.appendChild(this._createGeolocationOverrideElement(geolocation));
847 this._geolocationOverrideCheckboxClicked(WebInspector.settings.overrideGeolocation.get());
851 * @param {boolean} enabled
853 _geolocationOverrideCheckboxClicked: function(enabled)
855 if (enabled && !this._latitudeElement.value)
856 this._latitudeElement.focus();
859 _applyGeolocationUserInput: function()
861 this._setGeolocationPosition(WebInspector.OverridesSupport.GeolocationPosition.parseUserInput(this._latitudeElement.value.trim(), this._longitudeElement.value.trim(), this._geolocationErrorElement.checked), true);
865 * @param {?WebInspector.OverridesSupport.GeolocationPosition} geolocation
866 * @param {boolean} userInputModified
868 _setGeolocationPosition: function(geolocation, userInputModified)
873 if (!userInputModified) {
874 this._latitudeElement.value = geolocation.latitude;
875 this._longitudeElement.value = geolocation.longitude;
878 var value = geolocation.toSetting();
879 WebInspector.settings.geolocationOverride.set(value);
883 * @param {!WebInspector.OverridesSupport.GeolocationPosition} geolocation
886 _createGeolocationOverrideElement: function(geolocation)
888 var fieldsetElement = WebInspector.SettingsUI.createSettingFieldset(WebInspector.settings.overrideGeolocation);
889 fieldsetElement.id = "geolocation-override-section";
891 var tableElement = fieldsetElement.createChild("table");
892 var rowElement = tableElement.createChild("tr");
893 var cellElement = rowElement.createChild("td");
894 cellElement = rowElement.createChild("td");
895 cellElement.appendChild(document.createTextNode(WebInspector.UIString("Lat = ")));
896 this._latitudeElement = this._createInput(cellElement, "geolocation-override-latitude", String(geolocation.latitude), this._applyGeolocationUserInput.bind(this), true);
897 cellElement.appendChild(document.createTextNode(" , "));
898 cellElement.appendChild(document.createTextNode(WebInspector.UIString("Lon = ")));
899 this._longitudeElement = this._createInput(cellElement, "geolocation-override-longitude", String(geolocation.longitude), this._applyGeolocationUserInput.bind(this), true);
900 rowElement = tableElement.createChild("tr");
901 cellElement = rowElement.createChild("td");
902 cellElement.colSpan = 2;
903 var geolocationErrorLabelElement = document.createElement("label");
904 var geolocationErrorCheckboxElement = geolocationErrorLabelElement.createChild("input");
905 geolocationErrorCheckboxElement.id = "geolocation-error";
906 geolocationErrorCheckboxElement.type = "checkbox";
907 geolocationErrorCheckboxElement.checked = !geolocation || geolocation.error;
908 geolocationErrorCheckboxElement.addEventListener("click", this._applyGeolocationUserInput.bind(this), false);
909 geolocationErrorLabelElement.appendChild(document.createTextNode(WebInspector.UIString("Emulate position unavailable")));
910 this._geolocationErrorElement = geolocationErrorCheckboxElement;
911 cellElement.appendChild(geolocationErrorLabelElement);
913 return fieldsetElement;
916 _apendDeviceOrientationOverrideControl: function()
918 const deviceOrientationSetting = WebInspector.settings.deviceOrientationOverride.get();
919 var deviceOrientation = WebInspector.OverridesSupport.DeviceOrientation.parseSetting(deviceOrientationSetting);
920 this.element.appendChild(this._createSettingCheckbox(WebInspector.UIString("Accelerometer"), WebInspector.settings.overrideDeviceOrientation, this._deviceOrientationOverrideCheckboxClicked.bind(this)));
921 this.element.appendChild(this._createDeviceOrientationOverrideElement(deviceOrientation));
922 this._deviceOrientationOverrideCheckboxClicked(WebInspector.settings.overrideDeviceOrientation.get());
926 * @param {boolean} enabled
928 _deviceOrientationOverrideCheckboxClicked: function(enabled)
930 if (enabled && !this._alphaElement.value)
931 this._alphaElement.focus();
934 _applyDeviceOrientationUserInput: function()
936 this._setDeviceOrientation(WebInspector.OverridesSupport.DeviceOrientation.parseUserInput(this._alphaElement.value.trim(), this._betaElement.value.trim(), this._gammaElement.value.trim()), WebInspector.OverridesView.SensorsTab.DeviceOrientationModificationSource.UserInput);
939 _resetDeviceOrientation: function()
941 this._setDeviceOrientation(new WebInspector.OverridesSupport.DeviceOrientation(0, 0, 0), WebInspector.OverridesView.SensorsTab.DeviceOrientationModificationSource.ResetButton);
945 * @param {?WebInspector.OverridesSupport.DeviceOrientation} deviceOrientation
946 * @param {!WebInspector.OverridesView.SensorsTab.DeviceOrientationModificationSource} modificationSource
948 _setDeviceOrientation: function(deviceOrientation, modificationSource)
950 if (!deviceOrientation)
953 if (modificationSource != WebInspector.OverridesView.SensorsTab.DeviceOrientationModificationSource.UserInput) {
954 this._alphaElement.value = deviceOrientation.alpha;
955 this._betaElement.value = deviceOrientation.beta;
956 this._gammaElement.value = deviceOrientation.gamma;
959 if (modificationSource != WebInspector.OverridesView.SensorsTab.DeviceOrientationModificationSource.UserDrag)
960 this._setBoxOrientation(deviceOrientation);
962 var value = deviceOrientation.toSetting();
963 WebInspector.settings.deviceOrientationOverride.set(value);
967 * @param {!Element} parentElement
969 * @param {string} label
970 * @param {string} defaultText
973 _createAxisInput: function(parentElement, id, label, defaultText)
975 var div = parentElement.createChild("div", "accelerometer-axis-input-container");
976 div.appendChild(document.createTextNode(label));
977 return this._createInput(div, id, defaultText, this._applyDeviceOrientationUserInput.bind(this), true);
981 * @param {!WebInspector.OverridesSupport.DeviceOrientation} deviceOrientation
983 _createDeviceOrientationOverrideElement: function(deviceOrientation)
985 var fieldsetElement = WebInspector.SettingsUI.createSettingFieldset(WebInspector.settings.overrideDeviceOrientation);
986 fieldsetElement.id = "device-orientation-override-section";
987 var tableElement = fieldsetElement.createChild("table");
988 var rowElement = tableElement.createChild("tr");
989 var cellElement = rowElement.createChild("td", "accelerometer-inputs-cell");
991 this._alphaElement = this._createAxisInput(cellElement, "device-orientation-override-alpha", "\u03B1: ", String(deviceOrientation.alpha));
992 this._betaElement = this._createAxisInput(cellElement, "device-orientation-override-beta", "\u03B2: ", String(deviceOrientation.beta));
993 this._gammaElement = this._createAxisInput(cellElement, "device-orientation-override-gamma", "\u03B3: ", String(deviceOrientation.gamma));
995 var resetButton = cellElement.createChild("button", "settings-tab-text-button accelerometer-reset-button");
996 resetButton.textContent = WebInspector.UIString("Reset");
997 resetButton.addEventListener("click", this._resetDeviceOrientation.bind(this), false);
999 this._stageElement = rowElement.createChild("td","accelerometer-stage");
1000 this._boxElement = this._stageElement.createChild("section", "accelerometer-box");
1002 this._boxElement.createChild("section", "front");
1003 this._boxElement.createChild("section", "top");
1004 this._boxElement.createChild("section", "back");
1005 this._boxElement.createChild("section", "left");
1006 this._boxElement.createChild("section", "right");
1007 this._boxElement.createChild("section", "bottom");
1009 WebInspector.installDragHandle(this._stageElement, this._onBoxDragStart.bind(this), this._onBoxDrag.bind(this), this._onBoxDragEnd.bind(this), "move");
1010 this._setBoxOrientation(deviceOrientation);
1011 return fieldsetElement;
1015 * @param {!WebInspector.OverridesSupport.DeviceOrientation} deviceOrientation
1017 _setBoxOrientation: function(deviceOrientation)
1019 var matrix = new WebKitCSSMatrix();
1020 this._boxMatrix = matrix.rotate(-deviceOrientation.beta, deviceOrientation.gamma, -deviceOrientation.alpha);
1021 this._boxElement.style.webkitTransform = this._boxMatrix.toString();
1025 * @param {!MouseEvent} event
1028 _onBoxDrag: function(event)
1030 var mouseMoveVector = this._calculateRadiusVector(event.x, event.y);
1031 if (!mouseMoveVector)
1034 event.consume(true);
1035 var axis = WebInspector.Geometry.crossProduct(this._mouseDownVector, mouseMoveVector);
1037 var angle = WebInspector.Geometry.calculateAngle(this._mouseDownVector, mouseMoveVector);
1038 var matrix = new WebKitCSSMatrix();
1039 var rotationMatrix = matrix.rotateAxisAngle(axis.x, axis.y, axis.z, angle);
1040 this._currentMatrix = rotationMatrix.multiply(this._boxMatrix)
1041 this._boxElement.style.webkitTransform = this._currentMatrix;
1042 var eulerAngles = WebInspector.Geometry.EulerAngles.fromRotationMatrix(this._currentMatrix);
1043 var newOrientation = new WebInspector.OverridesSupport.DeviceOrientation(-eulerAngles.alpha, -eulerAngles.beta, eulerAngles.gamma);
1044 this._setDeviceOrientation(newOrientation, WebInspector.OverridesView.SensorsTab.DeviceOrientationModificationSource.UserDrag);
1049 * @param {!MouseEvent} event
1052 _onBoxDragStart: function(event)
1054 if (!WebInspector.settings.overrideDeviceOrientation.get())
1057 this._mouseDownVector = this._calculateRadiusVector(event.x, event.y);
1059 if (!this._mouseDownVector)
1062 event.consume(true);
1066 _onBoxDragEnd: function()
1068 this._boxMatrix = this._currentMatrix;
1074 * @return {?WebInspector.Geometry.Vector}
1076 _calculateRadiusVector: function(x, y)
1078 var rect = this._stageElement.getBoundingClientRect();
1079 var radius = Math.max(rect.width, rect.height) / 2;
1080 var sphereX = (x - rect.left - rect.width / 2) / radius;
1081 var sphereY = (y - rect.top - rect.height / 2) / radius;
1082 var sqrSum = sphereX * sphereX + sphereY * sphereY;
1084 return new WebInspector.Geometry.Vector(sphereX, sphereY, 0.5 / Math.sqrt(sqrSum));
1086 return new WebInspector.Geometry.Vector(sphereX, sphereY, Math.sqrt(1 - sqrSum));
1089 __proto__ : WebInspector.OverridesView.Tab.prototype
1092 /** @enum {string} */
1093 WebInspector.OverridesView.SensorsTab.DeviceOrientationModificationSource = {
1094 UserInput: "userInput",
1095 UserDrag: "userDrag",
1096 ResetButton: "resetButton"