Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(714)

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/emulation/DevicesSettingsTab.js

Issue 1412463006: [DevTools] Use ListWidget to render DevicesSettingsTab. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | third_party/WebKit/Source/devtools/front_end/emulation/devicesSettingsTab.css » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 /** 5 /**
6 * @constructor 6 * @constructor
7 * @extends {WebInspector.VBox} 7 * @extends {WebInspector.VBox}
8 * @implements {WebInspector.ListWidget.Delegate}
8 */ 9 */
9 WebInspector.DevicesSettingsTab = function() 10 WebInspector.DevicesSettingsTab = function()
10 { 11 {
11 WebInspector.VBox.call(this); 12 WebInspector.VBox.call(this);
12 this.element.classList.add("settings-tab-container"); 13 this.element.classList.add("settings-tab-container");
13 this.element.classList.add("devices-settings-tab"); 14 this.element.classList.add("devices-settings-tab");
14 this.registerRequiredCSS("emulation/devicesSettingsTab.css"); 15 this.registerRequiredCSS("emulation/devicesSettingsTab.css");
15 16
16 var header = this.element.createChild("header"); 17 var header = this.element.createChild("header");
17 header.createChild("h3").createTextChild(WebInspector.UIString("Emulated Dev ices")); 18 header.createChild("h3").createTextChild(WebInspector.UIString("Emulated Dev ices"));
18 this.containerElement = this.element.createChild("div", "help-container-wrap per").createChild("div", "settings-tab help-content help-container"); 19 this.containerElement = this.element.createChild("div", "help-container-wrap per").createChild("div", "settings-tab help-content help-container");
19 20
20 var buttonsRow = this.containerElement.createChild("div", "devices-button-ro w"); 21 var buttonsRow = this.containerElement.createChild("div", "devices-button-ro w");
21 this._addCustomButton = createTextButton(WebInspector.UIString("Add custom d evice..."), this._addCustomDevice.bind(this)); 22 var addCustomButton = createTextButton(WebInspector.UIString("Add custom dev ice..."), this._addCustomDevice.bind(this));
22 buttonsRow.appendChild(this._addCustomButton); 23 buttonsRow.appendChild(addCustomButton);
23 24
24 this._devicesList = this.containerElement.createChild("div", "devices-list") ; 25 this._list = new WebInspector.ListWidget(this);
25 this._customListSearator = createElementWithClass("div", "devices-custom-sep arator"); 26 this._list.registerRequiredCSS("emulation/devicesSettingsTab.css");
26 27 this._list.element.classList.add("devices-list");
27 this._editDevice = null; 28 this._list.show(this.containerElement);
28 this._editDeviceListItem = null;
29 this._createEditDeviceElement();
30 29
31 this._muteUpdate = false; 30 this._muteUpdate = false;
32 WebInspector.emulatedDevicesList.addEventListener(WebInspector.EmulatedDevic esList.Events.CustomDevicesUpdated, this._devicesUpdated, this); 31 WebInspector.emulatedDevicesList.addEventListener(WebInspector.EmulatedDevic esList.Events.CustomDevicesUpdated, this._devicesUpdated, this);
33 WebInspector.emulatedDevicesList.addEventListener(WebInspector.EmulatedDevic esList.Events.StandardDevicesUpdated, this._devicesUpdated, this); 32 WebInspector.emulatedDevicesList.addEventListener(WebInspector.EmulatedDevic esList.Events.StandardDevicesUpdated, this._devicesUpdated, this);
33
34 this.setDefaultFocusedElement(addCustomButton);
34 } 35 }
35 36
36 WebInspector.DevicesSettingsTab.prototype = { 37 WebInspector.DevicesSettingsTab.prototype = {
37 wasShown: function() 38 wasShown: function()
38 { 39 {
39 WebInspector.VBox.prototype.wasShown.call(this); 40 WebInspector.VBox.prototype.wasShown.call(this);
40 this._devicesUpdated(); 41 this._devicesUpdated();
41 this._stopEditing();
42 }, 42 },
43 43
44 _devicesUpdated: function() 44 _devicesUpdated: function()
45 { 45 {
46 if (this._muteUpdate) 46 if (this._muteUpdate)
47 return; 47 return;
48 48
49 this._devicesList.removeChildren(); 49 this._list.clear();
50 50
51 var devices = WebInspector.emulatedDevicesList.custom().slice(); 51 var devices = WebInspector.emulatedDevicesList.custom().slice();
52 devices.sort(WebInspector.EmulatedDevice.compareByTitle);
53 for (var i = 0; i < devices.length; ++i) 52 for (var i = 0; i < devices.length; ++i)
54 this._devicesList.appendChild(this._createDeviceListItem(devices[i], true)); 53 this._list.appendItem(devices[i], true);
55 54
56 this._devicesList.appendChild(this._customListSearator); 55 this._list.appendSeparator();
57 this._updateSeparatorVisibility();
58 56
59 devices = WebInspector.emulatedDevicesList.standard().slice(); 57 devices = WebInspector.emulatedDevicesList.standard().slice();
60 devices.sort(WebInspector.EmulatedDevice.compareByTitle); 58 devices.sort(WebInspector.EmulatedDevice.compareByTitle);
61 for (var i = 0; i < devices.length; ++i) 59 for (var i = 0; i < devices.length; ++i)
62 this._devicesList.appendChild(this._createDeviceListItem(devices[i], false)); 60 this._list.appendItem(devices[i], false);
63 },
64
65 _updateSeparatorVisibility: function()
66 {
67 this._customListSearator.classList.toggle("hidden", this._devicesList.fi rstChild === this._customListSearator);
68 }, 61 },
69 62
70 /** 63 /**
71 * @param {boolean} custom 64 * @param {boolean} custom
72 */ 65 */
73 _muteAndSaveDeviceList: function(custom) 66 _muteAndSaveDeviceList: function(custom)
74 { 67 {
75 this._muteUpdate = true; 68 this._muteUpdate = true;
76 if (custom) 69 if (custom)
77 WebInspector.emulatedDevicesList.saveCustomDevices(); 70 WebInspector.emulatedDevicesList.saveCustomDevices();
78 else 71 else
79 WebInspector.emulatedDevicesList.saveStandardDevices(); 72 WebInspector.emulatedDevicesList.saveStandardDevices();
80 this._muteUpdate = false; 73 this._muteUpdate = false;
81 }, 74 },
82 75
76 _addCustomDevice: function()
77 {
78 var device = new WebInspector.EmulatedDevice();
79 device.deviceScaleFactor = 0;
80 this._list.addNewItem(WebInspector.emulatedDevicesList.custom().length, device);
81 },
82
83 /** 83 /**
84 * @param {!WebInspector.EmulatedDevice} device 84 * @param {number} value
85 * @param {boolean} custom 85 * @return {string}
86 */
87 _toNumericInputValue: function(value)
88 {
89 return value ? String(value) : "";
90 },
91
92 /**
93 * @override
94 * @param {*} item
95 * @param {boolean} editable
86 * @return {!Element} 96 * @return {!Element}
87 */ 97 */
88 _createDeviceListItem: function(device, custom) 98 renderItem: function(item, editable)
89 { 99 {
90 var item = createElementWithClass("div", "devices-list-item"); 100 var device = /** @type {!WebInspector.EmulatedDevice} */ (item);
91 var checkbox = item.createChild("input", "devices-list-checkbox"); 101 var element = createElementWithClass("div", "devices-list-item");
102 var checkbox = element.createChild("input", "devices-list-checkbox");
92 checkbox.type = "checkbox"; 103 checkbox.type = "checkbox";
93 checkbox.checked = device.show(); 104 checkbox.checked = device.show();
94 item.createChild("div", "devices-list-title").textContent = device.title ; 105 element.createChild("div", "devices-list-title").textContent = device.ti tle;
95 item.addEventListener("click", onItemClicked.bind(this), false); 106 element.addEventListener("click", onItemClicked.bind(this), false);
96 item.classList.toggle("device-list-item-show", device.show()); 107 element.classList.toggle("device-list-item-show", device.show());
97 if (custom) { 108 return element;
98 var editButton = item.createChild("div", "devices-list-edit");
99 editButton.title = WebInspector.UIString("Edit");
100 editButton.addEventListener("click", onEditClicked.bind(this), false );
101
102 var removeButton = item.createChild("div", "devices-list-remove");
103 removeButton.title = WebInspector.UIString("Remove");
104 removeButton.addEventListener("click", onRemoveClicked, false);
105 }
106 109
107 /** 110 /**
108 * @param {!Event} event 111 * @param {!Event} event
109 * @this {WebInspector.DevicesSettingsTab} 112 * @this {WebInspector.DevicesSettingsTab}
110 */ 113 */
111 function onItemClicked(event) 114 function onItemClicked(event)
112 { 115 {
113 var show = !checkbox.checked; 116 var show = !checkbox.checked;
114 device.setShow(show); 117 device.setShow(show);
115 this._muteAndSaveDeviceList(custom); 118 this._muteAndSaveDeviceList(editable);
116 checkbox.checked = show; 119 checkbox.checked = show;
117 item.classList.toggle("device-list-item-show", show); 120 element.classList.toggle("device-list-item-show", show);
118 event.consume(); 121 event.consume();
119 } 122 }
120
121 /**
122 * @param {!Event} event
123 * @this {WebInspector.DevicesSettingsTab}
124 */
125 function onEditClicked(event)
126 {
127 event.consume();
128 this._startEditing(device, item);
129 }
130
131 /**
132 * @param {!Event} event
133 */
134 function onRemoveClicked(event)
135 {
136 WebInspector.emulatedDevicesList.removeCustomDevice(device);
137 event.consume();
138 }
139
140 return item;
141 },
142
143 _addCustomDevice: function()
144 {
145 this._startEditing(new WebInspector.EmulatedDevice(), null);
146 },
147
148 _createEditDeviceElement: function()
149 {
150 this._editDeviceElement = createElementWithClass("div", "devices-edit-co ntainer");
151 this._editDeviceElement.addEventListener("keydown", onKeyDown.bind(null, isEscKey, this._stopEditing.bind(this)), false);
152 this._editDeviceElement.addEventListener("keydown", onKeyDown.bind(null, isEnterKey, this._editDeviceCommitClicked.bind(this)), false);
153 this._editDeviceCheckbox = this._editDeviceElement.createChild("input", "devices-edit-checkbox");
154 this._editDeviceCheckbox.type = "checkbox";
155 var fields = this._editDeviceElement.createChild("div", "devices-edit-fi elds");
156
157 this._editDeviceTitle = this._createInput(WebInspector.UIString("Device name"));
158 fields.appendChild(this._editDeviceTitle);
159
160 var screen = fields.createChild("div", "hbox");
161 this._editDeviceWidth = this._createInput(WebInspector.UIString("Width") , "80px");
162 screen.appendChild(this._editDeviceWidth);
163 this._editDeviceHeight = this._createInput(WebInspector.UIString("Height "), "80px");
164 screen.appendChild(this._editDeviceHeight);
165 this._editDeviceScale = this._createInput(WebInspector.UIString("Device pixel ratio"));
166 screen.appendChild(this._editDeviceScale);
167
168 this._editDeviceUserAgent = this._createInput(WebInspector.UIString("Use r agent string"));
169 fields.appendChild(this._editDeviceUserAgent);
170
171 var buttonsRow = fields.createChild("div", "devices-edit-buttons");
172 this._editDeviceCommitButton = createTextButton("", this._editDeviceComm itClicked.bind(this));
173 buttonsRow.appendChild(this._editDeviceCommitButton);
174 this._editDeviceCancelButton = createTextButton(WebInspector.UIString("C ancel"), this._stopEditing.bind(this));
175 this._editDeviceCancelButton.addEventListener("keydown", onKeyDown.bind( null, isEnterKey, this._stopEditing.bind(this)), false);
176 buttonsRow.appendChild(this._editDeviceCancelButton);
177
178 /**
179 * @param {function(!Event):boolean} predicate
180 * @param {function()} callback
181 * @param {!Event} event
182 */
183 function onKeyDown(predicate, callback, event)
184 {
185 if (predicate(event)) {
186 event.consume(true);
187 callback();
188 }
189 }
190 }, 123 },
191 124
192 /** 125 /**
193 * @param {string} title 126 * @override
194 * @param {string=} width 127 * @param {*} item
195 * @return {!Element} 128 * @param {number} index
196 */ 129 */
197 _createInput: function(title, width) 130 removeItemRequested: function(item, index)
198 { 131 {
199 var input = createElement("input"); 132 WebInspector.emulatedDevicesList.removeCustomDevice(/** @type {!WebInspe ctor.EmulatedDevice} */ (item));
200 input.type = "text";
201 if (width)
202 input.style.width = width;
203 input.placeholder = title;
204 input.addEventListener("input", this._validateInputs.bind(this, false), false);
205 input.addEventListener("blur", this._validateInputs.bind(this, false), f alse);
206 return input;
207 }, 133 },
208 134
209 /** 135 /**
210 * @param {boolean} forceValid 136 * @override
137 * @param {*} item
138 * @param {!WebInspector.ListWidget.Editor} editor
139 * @param {boolean} isNew
211 */ 140 */
212 _validateInputs: function(forceValid) 141 commitEdit: function(item, editor, isNew)
213 { 142 {
214 var trimmedTitle = this._editDeviceTitle.value.trim(); 143 var device = /** @type {!WebInspector.EmulatedDevice} */ (item);
215 var titleValid = trimmedTitle.length > 0 && trimmedTitle.length < 50; 144 device.title = editor.control("title").value.trim();
216 this._editDeviceTitle.classList.toggle("error-input", !titleValid && !fo rceValid); 145 device.vertical.width = editor.control("width").value ? parseInt(editor. control("width").value, 10) : 0;
146 device.vertical.height = editor.control("height").value ? parseInt(edito r.control("height").value, 10) : 0;
147 device.horizontal.width = device.vertical.height;
148 device.horizontal.height = device.vertical.width;
149 device.deviceScaleFactor = editor.control("scale").value ? parseFloat(ed itor.control("scale").value) : 0;
150 device.userAgent = editor.control("user-agent").value;
151 device.modes = [];
152 device.modes.push({title: "", orientation: WebInspector.EmulatedDevice.H orizontal, insets: new Insets(0, 0, 0, 0), images: null});
153 device.modes.push({title: "", orientation: WebInspector.EmulatedDevice.V ertical, insets: new Insets(0, 0, 0, 0), images: null});
217 154
218 var widthValid = !WebInspector.OverridesSupport.deviceSizeValidator(this ._editDeviceWidth.value); 155 if (isNew)
219 this._editDeviceWidth.classList.toggle("error-input", !widthValid && !fo rceValid); 156 WebInspector.emulatedDevicesList.addCustomDevice(device);
220 157 else
221 var heightValid = !WebInspector.OverridesSupport.deviceSizeValidator(thi s._editDeviceHeight.value); 158 WebInspector.emulatedDevicesList.saveCustomDevices();
222 this._editDeviceHeight.classList.toggle("error-input", !heightValid && ! forceValid);
223
224 var scaleValid = !WebInspector.OverridesSupport.deviceScaleFactorValidat or(this._editDeviceScale.value);
225 this._editDeviceScale.classList.toggle("error-input", !scaleValid && !fo rceValid);
226
227 var allValid = titleValid && widthValid && heightValid && scaleValid;
228 this._editDeviceCommitButton.disabled = !allValid;
229 }, 159 },
230 160
231 /** 161 /**
232 * @param {number} value 162 * @override
233 * @return {string} 163 * @param {*} item
164 * @return {!WebInspector.ListWidget.Editor}
234 */ 165 */
235 _toNumericInputValue: function(value) 166 beginEdit: function(item)
236 { 167 {
237 return value ? String(value) : ""; 168 var device = /** @type {!WebInspector.EmulatedDevice} */ (item);
169 var editor = this._createEditor();
170 editor.control("title").value = device.title;
171 editor.control("width").value = this._toNumericInputValue(device.vertica l.width);
172 editor.control("height").value = this._toNumericInputValue(device.vertic al.height);
173 editor.control("scale").value = this._toNumericInputValue(device.deviceS caleFactor);
174 editor.control("user-agent").value = device.userAgent;
175 return editor;
238 }, 176 },
239 177
240 /** 178 /**
241 * @param {!WebInspector.EmulatedDevice} device 179 * @return {!WebInspector.ListWidget.Editor}
242 * @param {?Element} listItem
243 */ 180 */
244 _startEditing: function(device, listItem) 181 _createEditor: function()
245 { 182 {
246 this._stopEditing(); 183 if (this._editor)
184 return this._editor;
247 185
248 this._addCustomButton.disabled = true; 186 var editor = new WebInspector.ListWidget.Editor();
249 this._devicesList.classList.add("devices-list-editing"); 187 this._editor = editor;
250 this._editDevice = device; 188 var content = editor.contentElement();
251 this._editDeviceListItem = listItem;
252 if (listItem)
253 listItem.classList.add("hidden");
254 189
255 this._editDeviceCommitButton.textContent = listItem ? WebInspector.UIStr ing("Save") : WebInspector.UIString("Add device"); 190 var fields = content.createChild("div", "devices-edit-fields");
256 this._editDeviceCheckbox.checked = device.show(); 191 fields.appendChild(editor.createInput("title", "text", WebInspector.UISt ring("Device name"), titleValidator));
257 this._editDeviceTitle.value = device.title; 192 var screen = fields.createChild("div", "hbox");
258 this._editDeviceWidth.value = listItem ? this._toNumericInputValue(devic e.vertical.width) : ""; 193 var width = editor.createInput("width", "text", WebInspector.UIString("W idth"), sizeValidator);
259 this._editDeviceHeight.value = listItem ? this._toNumericInputValue(devi ce.vertical.height) : ""; 194 width.classList.add("device-edit-small");
260 this._editDeviceScale.value = listItem ? this._toNumericInputValue(devic e.deviceScaleFactor) : ""; 195 screen.appendChild(width);
261 this._editDeviceUserAgent.value = device.userAgent; 196 var height = editor.createInput("height", "text", WebInspector.UIString( "height"), sizeValidator);
262 this._validateInputs(true); 197 height.classList.add("device-edit-small");
198 screen.appendChild(height);
199 screen.appendChild(editor.createInput("scale", "text", WebInspector.UISt ring("Device pixel ratio"), scaleValidator));
200 fields.appendChild(editor.createInput("user-agent", "text", WebInspector .UIString("User agent string"), userAgentValidator));
263 201
264 if (listItem && listItem.nextElementSibling) 202 return editor;
265 this._devicesList.insertBefore(this._editDeviceElement, listItem.nex tElementSibling);
266 else
267 this._devicesList.insertBefore(this._editDeviceElement, this._custom ListSearator);
268 this._editDeviceCommitButton.scrollIntoView();
269 this._editDeviceTitle.focus();
270 },
271 203
272 _editDeviceCommitClicked: function() 204 /**
273 { 205 * @param {!HTMLInputElement|!HTMLSelectElement} input
274 if (this._editDeviceCommitButton.disabled) 206 * @return {boolean}
275 return; 207 */
208 function titleValidator(input)
209 {
210 var value = input.value.trim();
211 return value.length > 0 && value.length < 50;
212 }
276 213
277 this._editDevice.setShow(this._editDeviceCheckbox.checked); 214 /**
278 this._editDevice.title = this._editDeviceTitle.value; 215 * @param {!HTMLInputElement|!HTMLSelectElement} input
279 this._editDevice.vertical.width = this._editDeviceWidth.value ? parseInt (this._editDeviceWidth.value, 10) : 0; 216 * @return {boolean}
280 this._editDevice.vertical.height = this._editDeviceHeight.value ? parseI nt(this._editDeviceHeight.value, 10) : 0; 217 */
281 this._editDevice.horizontal.width = this._editDevice.vertical.height; 218 function sizeValidator(input)
282 this._editDevice.horizontal.height = this._editDevice.vertical.width; 219 {
283 this._editDevice.deviceScaleFactor = this._editDeviceScale.value ? parse Float(this._editDeviceScale.value) : 0; 220 return !WebInspector.OverridesSupport.deviceSizeValidator(input.valu e);
284 this._editDevice.userAgent = this._editDeviceUserAgent.value; 221 }
285 this._editDevice.modes.push({title: "", orientation: WebInspector.Emulat edDevice.Horizontal, insets: new Insets(0, 0, 0, 0), images: null});
286 this._editDevice.modes.push({title: "", orientation: WebInspector.Emulat edDevice.Vertical, insets: new Insets(0, 0, 0, 0), images: null});
287 222
288 this._stopEditing(); 223 /**
289 if (this._editDeviceListItem) 224 * @param {!HTMLInputElement|!HTMLSelectElement} input
290 WebInspector.emulatedDevicesList.saveCustomDevices(); 225 * @return {boolean}
291 else 226 */
292 WebInspector.emulatedDevicesList.addCustomDevice(this._editDevice); 227 function scaleValidator(input)
293 this._editDevice = null; 228 {
294 this._editDeviceListItem = null; 229 return !WebInspector.OverridesSupport.deviceScaleFactorValidator(inp ut.value);
295 }, 230 }
296 231
297 _stopEditing: function() 232 /**
298 { 233 * @param {!HTMLInputElement|!HTMLSelectElement} input
299 this._devicesList.classList.remove("devices-list-editing"); 234 * @return {boolean}
300 if (this._editDeviceListItem) 235 */
301 this._editDeviceListItem.classList.remove("hidden"); 236 function userAgentValidator(input)
302 if (this._editDeviceElement.parentElement) 237 {
303 this._devicesList.removeChild(this._editDeviceElement); 238 return true;
304 this._addCustomButton.disabled = false; 239 }
305 this._addCustomButton.focus();
306 }, 240 },
307 241
308 __proto__: WebInspector.VBox.prototype 242 __proto__: WebInspector.VBox.prototype
309 } 243 }
OLDNEW
« no previous file with comments | « no previous file | third_party/WebKit/Source/devtools/front_end/emulation/devicesSettingsTab.css » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698