OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 /** | |
6 * @constructor | |
7 * @param {!HTMLSelectElement} selectElement | |
8 */ | |
9 WebInspector.NetworkConditionsSelector = function(selectElement) | |
10 { | |
11 this._selectElement = selectElement; | |
12 this._selectElement.addEventListener("change", this._optionSelected.bind(thi
s), false); | |
13 this._customSetting = WebInspector.moduleSetting("networkConditionsCustomPro
files"); | |
14 this._customSetting.addChangeListener(this._populateOptions, this); | |
15 this._manager = WebInspector.multitargetNetworkManager; | |
16 this._manager.addEventListener(WebInspector.MultitargetNetworkManager.Events
.ConditionsChanged, this._conditionsChanged, this); | |
17 this._populateOptions(); | |
18 } | |
19 | |
20 /** @typedef {!{title: string, value: !WebInspector.NetworkManager.Conditions}}
*/ | |
21 WebInspector.NetworkConditionsProfile; | |
22 | |
23 /** | |
24 * @param {number} throughput | |
25 * @return {string} | |
26 */ | |
27 WebInspector.NetworkConditionsSelector.throughputText = function(throughput) | |
28 { | |
29 if (throughput < 0) | |
30 return ""; | |
31 var throughputInKbps = throughput / (1024 / 8); | |
32 return (throughputInKbps < 1024) ? WebInspector.UIString("%d kb/s", throughp
utInKbps) : WebInspector.UIString("%d Mb/s", (throughputInKbps / 1024) | 0); | |
33 } | |
34 | |
35 /** @type {!Array.<!WebInspector.NetworkConditionsProfile>} */ | |
36 WebInspector.NetworkConditionsSelector._networkConditionsPresets = [ | |
37 {title: "Offline", value: {download: 0 * 1024 / 8, upload: 0 * 1024 / 8, lat
ency: 0}}, | |
38 {title: "GPRS", value: {download: 50 * 1024 / 8, upload: 20 * 1024 / 8, late
ncy: 500}}, | |
39 {title: "Regular 2G", value: {download: 250 * 1024 / 8, upload: 50 * 1024 /
8, latency: 300}}, | |
40 {title: "Good 2G", value: {download: 450 * 1024 / 8, upload: 150 * 1024 / 8,
latency: 150}}, | |
41 {title: "Regular 3G", value: {download: 750 * 1024 / 8, upload: 250 * 1024 /
8, latency: 100}}, | |
42 {title: "Good 3G", value: {download: 1.5 * 1024 * 1024 / 8, upload: 750 * 10
24 / 8, latency: 40}}, | |
43 {title: "Regular 4G", value: {download: 4 * 1024 * 1024 / 8, upload: 3 * 102
4 * 1024 / 8, latency: 20}}, | |
44 {title: "DSL", value: {download: 2 * 1024 * 1024 / 8, upload: 1 * 1024 * 102
4 / 8, latency: 5}}, | |
45 {title: "WiFi", value: {download: 30 * 1024 * 1024 / 8, upload: 15 * 1024 *
1024 / 8, latency: 2}} | |
46 ]; | |
47 | |
48 /** @type {!WebInspector.NetworkConditionsProfile} */ | |
49 WebInspector.NetworkConditionsSelector._disabledPreset = {title: "No throttling"
, value: {download: -1, upload: -1, latency: 0}}; | |
50 | |
51 WebInspector.NetworkConditionsSelector.prototype = { | |
52 _populateOptions: function() | |
53 { | |
54 this._selectElement.removeChildren(); | |
55 | |
56 var customGroup = this._addGroup(this._customSetting.get(), WebInspector
.UIString("Custom")); | |
57 customGroup.insertBefore(new Option(WebInspector.UIString("Add\u2026"),
WebInspector.UIString("Add\u2026")), customGroup.firstChild); | |
58 | |
59 this._addGroup(WebInspector.NetworkConditionsSelector._networkConditions
Presets, WebInspector.UIString("Presets")); | |
60 this._addGroup([WebInspector.NetworkConditionsSelector._disabledPreset],
WebInspector.UIString("Disabled")); | |
61 | |
62 this._conditionsChanged(); | |
63 }, | |
64 | |
65 /** | |
66 * @param {!Array.<!WebInspector.NetworkConditionsProfile>} presets | |
67 * @param {string} groupName | |
68 * @return {!Element} | |
69 */ | |
70 _addGroup: function(presets, groupName) | |
71 { | |
72 var groupElement = this._selectElement.createChild("optgroup"); | |
73 groupElement.label = groupName; | |
74 for (var i = 0; i < presets.length; ++i) { | |
75 var preset = presets[i]; | |
76 var downloadInKbps = preset.value.download / (1024 / 8); | |
77 var uploadInKbps = preset.value.upload / (1024 / 8); | |
78 var isThrottling = (downloadInKbps >= 0) || (uploadInKbps >= 0) || (
preset.value.latency > 0); | |
79 var option; | |
80 var presetTitle = WebInspector.UIString(preset.title); | |
81 if (!isThrottling) { | |
82 option = new Option(presetTitle, presetTitle); | |
83 } else { | |
84 var downloadText = WebInspector.NetworkConditionsSelector.throug
hputText(preset.value.download); | |
85 var uploadText = WebInspector.NetworkConditionsSelector.throughp
utText(preset.value.upload); | |
86 var title = WebInspector.UIString("%s (%s\u2b07 %s\u2b06 %dms RT
T)", presetTitle, downloadText, uploadText, preset.value.latency); | |
87 option = new Option(title, presetTitle); | |
88 option.title = WebInspector.UIString("Maximum download throughpu
t: %s.\r\nMaximum upload throughput: %s.\r\nMinimum round-trip time: %dms.", dow
nloadText, uploadText, preset.value.latency); | |
89 } | |
90 option.conditions = preset.value; | |
91 groupElement.appendChild(option); | |
92 } | |
93 return groupElement; | |
94 }, | |
95 | |
96 _optionSelected: function() | |
97 { | |
98 if (this._selectElement.selectedIndex === 0) { | |
99 WebInspector.Revealer.reveal(this._customSetting); | |
100 this._conditionsChanged(); | |
101 return; | |
102 } | |
103 | |
104 this._manager.removeEventListener(WebInspector.MultitargetNetworkManager
.Events.ConditionsChanged, this._conditionsChanged, this); | |
105 this._manager.setNetworkConditions(this._selectElement.options[this._sel
ectElement.selectedIndex].conditions); | |
106 this._manager.addEventListener(WebInspector.MultitargetNetworkManager.Ev
ents.ConditionsChanged, this._conditionsChanged, this); | |
107 }, | |
108 | |
109 _conditionsChanged: function() | |
110 { | |
111 var value = this._manager.networkConditions(); | |
112 var options = this._selectElement.options; | |
113 for (var index = 1; index < options.length; ++index) { | |
114 var option = options[index]; | |
115 if (option.conditions.download === value.download && option.conditio
ns.upload === value.upload && option.conditions.latency === value.latency) | |
116 this._selectElement.selectedIndex = index; | |
117 } | |
118 } | |
119 } | |
120 | |
121 | |
122 /** | |
123 * @constructor | |
124 * @extends {WebInspector.VBox} | |
125 * @implements {WebInspector.ListWidget.Delegate} | |
126 */ | |
127 WebInspector.NetworkConditionsSettingsTab = function() | |
128 { | |
129 WebInspector.VBox.call(this); | |
130 this.element.classList.add("settings-tab-container"); | |
131 this.element.classList.add("network-conditions-settings-tab"); | |
132 this.registerRequiredCSS("components/networkConditionsSettingsTab.css"); | |
133 | |
134 var header = this.element.createChild("header"); | |
135 header.createChild("h3").createTextChild(WebInspector.UIString("Network Thro
ttling Profiles")); | |
136 this.containerElement = this.element.createChild("div", "help-container-wrap
per").createChild("div", "settings-tab help-content help-container"); | |
137 | |
138 var buttonsRow = this.containerElement.createChild("div", "button-row"); | |
139 var addButton = createTextButton(WebInspector.UIString("Add custom profile..
."), this._addButtonClicked.bind(this)); | |
140 buttonsRow.appendChild(addButton); | |
141 | |
142 this._list = new WebInspector.ListWidget(this); | |
143 this._list.registerRequiredCSS("components/networkConditionsSettingsTab.css"
); | |
144 this._list.show(this.containerElement); | |
145 | |
146 this._customSetting = WebInspector.moduleSetting("networkConditionsCustomPro
files"); | |
147 this._customSetting.addChangeListener(this._conditionsUpdated, this); | |
148 | |
149 this.setDefaultFocusedElement(addButton); | |
150 } | |
151 | |
152 WebInspector.NetworkConditionsSettingsTab.prototype = { | |
153 wasShown: function() | |
154 { | |
155 WebInspector.VBox.prototype.wasShown.call(this); | |
156 this._conditionsUpdated(); | |
157 }, | |
158 | |
159 _conditionsUpdated: function() | |
160 { | |
161 this._list.clear(); | |
162 | |
163 var conditions = this._customSetting.get(); | |
164 for (var i = 0; i < conditions.length; ++i) | |
165 this._list.appendItem(conditions[i], true); | |
166 | |
167 this._list.appendSeparator(); | |
168 | |
169 conditions = WebInspector.NetworkConditionsSelector._networkConditionsPr
esets; | |
170 for (var i = 0; i < conditions.length; ++i) | |
171 this._list.appendItem(conditions[i], false); | |
172 }, | |
173 | |
174 _addButtonClicked: function() | |
175 { | |
176 this._list.addNewItem(this._customSetting.get().length, {title: "", valu
e: {download: -1, upload: -1, latency: 0}}); | |
177 }, | |
178 | |
179 /** | |
180 * @override | |
181 * @param {*} item | |
182 * @param {boolean} editable | |
183 * @return {!Element} | |
184 */ | |
185 renderItem: function(item, editable) | |
186 { | |
187 var conditions = /** @type {!WebInspector.NetworkConditionsProfile} */ (
item); | |
188 var element = createElementWithClass("div", "conditions-list-item"); | |
189 var title = element.createChild("div", "conditions-list-text conditions-
list-title"); | |
190 var titleText = title.createChild("div", "conditions-list-title-text"); | |
191 titleText.textContent = conditions.title; | |
192 titleText.title = conditions.title; | |
193 element.createChild("div", "conditions-list-separator"); | |
194 element.createChild("div", "conditions-list-text").textContent = WebInsp
ector.NetworkConditionsSelector.throughputText(conditions.value.download); | |
195 element.createChild("div", "conditions-list-separator"); | |
196 element.createChild("div", "conditions-list-text").textContent = WebInsp
ector.NetworkConditionsSelector.throughputText(conditions.value.upload); | |
197 element.createChild("div", "conditions-list-separator"); | |
198 element.createChild("div", "conditions-list-text").textContent = WebInsp
ector.UIString("%dms", conditions.value.latency); | |
199 return element; | |
200 }, | |
201 | |
202 /** | |
203 * @override | |
204 * @param {*} item | |
205 * @param {number} index | |
206 */ | |
207 removeItemRequested: function(item, index) | |
208 { | |
209 var list = this._customSetting.get(); | |
210 list.splice(index, 1); | |
211 this._customSetting.set(list); | |
212 }, | |
213 | |
214 /** | |
215 * @override | |
216 * @param {*} item | |
217 * @param {!WebInspector.ListWidget.Editor} editor | |
218 * @param {boolean} isNew | |
219 */ | |
220 commitEdit: function(item, editor, isNew) | |
221 { | |
222 var conditions = /** @type {?WebInspector.NetworkConditionsProfile} */ (
item); | |
223 conditions.title = editor.control("title").value.trim(); | |
224 var download = editor.control("download").value.trim(); | |
225 conditions.value.download = download ? parseInt(download, 10) * (1024 /
8) : -1; | |
226 var upload = editor.control("upload").value.trim(); | |
227 conditions.value.upload = upload ? parseInt(upload, 10) * (1024 / 8) : -
1; | |
228 var latency = editor.control("latency").value.trim(); | |
229 conditions.value.latency = latency ? parseInt(latency, 10) : 0; | |
230 | |
231 var list = this._customSetting.get(); | |
232 if (isNew) | |
233 list.push(conditions); | |
234 this._customSetting.set(list); | |
235 }, | |
236 | |
237 /** | |
238 * @override | |
239 * @param {*} item | |
240 * @return {!WebInspector.ListWidget.Editor} | |
241 */ | |
242 beginEdit: function(item) | |
243 { | |
244 var conditions = /** @type {?WebInspector.NetworkConditionsProfile} */ (
item); | |
245 var editor = this._createEditor(); | |
246 editor.control("title").value = conditions.title; | |
247 editor.control("download").value = conditions.value.download <= 0 ? "" :
String(conditions.value.download / (1024 / 8)); | |
248 editor.control("upload").value = conditions.value.upload <= 0 ? "" : Str
ing(conditions.value.upload / (1024 / 8)); | |
249 editor.control("latency").value = conditions.value.latency ? String(cond
itions.value.latency) : ""; | |
250 return editor; | |
251 }, | |
252 | |
253 /** | |
254 * @return {!WebInspector.ListWidget.Editor} | |
255 */ | |
256 _createEditor: function() | |
257 { | |
258 if (this._editor) | |
259 return this._editor; | |
260 | |
261 var editor = new WebInspector.ListWidget.Editor(); | |
262 this._editor = editor; | |
263 var content = editor.contentElement(); | |
264 | |
265 var titles = content.createChild("div", "conditions-edit-row"); | |
266 titles.createChild("div", "conditions-list-text conditions-list-title").
textContent = WebInspector.UIString("Profile Name"); | |
267 titles.createChild("div", "conditions-list-separator conditions-list-sep
arator-invisible"); | |
268 titles.createChild("div", "conditions-list-text").textContent = WebInspe
ctor.UIString("Download"); | |
269 titles.createChild("div", "conditions-list-separator conditions-list-sep
arator-invisible"); | |
270 titles.createChild("div", "conditions-list-text").textContent = WebInspe
ctor.UIString("Upload"); | |
271 titles.createChild("div", "conditions-list-separator conditions-list-sep
arator-invisible"); | |
272 titles.createChild("div", "conditions-list-text").textContent = WebInspe
ctor.UIString("Latency"); | |
273 | |
274 var fields = content.createChild("div", "conditions-edit-row"); | |
275 fields.createChild("div", "conditions-list-text conditions-list-title").
appendChild(editor.createInput("title", "text", "", titleValidator)); | |
276 fields.createChild("div", "conditions-list-separator conditions-list-sep
arator-invisible"); | |
277 | |
278 var cell = fields.createChild("div", "conditions-list-text"); | |
279 cell.appendChild(editor.createInput("download", "text", WebInspector.UIS
tring("kb/s"), throughputValidator)); | |
280 cell.createChild("div", "conditions-edit-optional").textContent = WebIns
pector.UIString("optional"); | |
281 fields.createChild("div", "conditions-list-separator conditions-list-sep
arator-invisible"); | |
282 | |
283 cell = fields.createChild("div", "conditions-list-text"); | |
284 cell.appendChild(editor.createInput("upload", "text", WebInspector.UIStr
ing("kb/s"), throughputValidator)); | |
285 cell.createChild("div", "conditions-edit-optional").textContent = WebIns
pector.UIString("optional"); | |
286 fields.createChild("div", "conditions-list-separator conditions-list-sep
arator-invisible"); | |
287 | |
288 cell = fields.createChild("div", "conditions-list-text"); | |
289 cell.appendChild(editor.createInput("latency", "text", WebInspector.UISt
ring("ms"), latencyValidator)); | |
290 cell.createChild("div", "conditions-edit-optional").textContent = WebIns
pector.UIString("optional"); | |
291 | |
292 return editor; | |
293 | |
294 /** | |
295 * @param {*} item | |
296 * @param {number} index | |
297 * @param {!HTMLInputElement|!HTMLSelectElement} input | |
298 * @return {boolean} | |
299 */ | |
300 function titleValidator(item, index, input) | |
301 { | |
302 var value = input.value.trim(); | |
303 return value.length > 0 && value.length < 50; | |
304 } | |
305 | |
306 /** | |
307 * @param {*} item | |
308 * @param {number} index | |
309 * @param {!HTMLInputElement|!HTMLSelectElement} input | |
310 * @return {boolean} | |
311 */ | |
312 function throughputValidator(item, index, input) | |
313 { | |
314 var value = input.value.trim(); | |
315 return !value || (/^[\d]+(\.\d+)?|\.\d+$/.test(value) && value >= 0
&& value <= 10000000); | |
316 } | |
317 | |
318 /** | |
319 * @param {*} item | |
320 * @param {number} index | |
321 * @param {!HTMLInputElement|!HTMLSelectElement} input | |
322 * @return {boolean} | |
323 */ | |
324 function latencyValidator(item, index, input) | |
325 { | |
326 var value = input.value.trim(); | |
327 return !value || (/^[\d]+$/.test(value) && value >= 0 && value <= 10
00000); | |
328 } | |
329 }, | |
330 | |
331 __proto__: WebInspector.VBox.prototype | |
332 } | |
OLD | NEW |