| OLD | NEW |
| 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 * @param {!HTMLSelectElement} selectElement | 7 * @param {function(!Array<!WebInspector.NetworkConditionsProfileGroup>):!Array<
!{conditions: ?WebInspector.NetworkManager.Conditions}>} populateCallback |
| 8 * @param {function(number)} selectCallback |
| 8 */ | 9 */ |
| 9 WebInspector.NetworkConditionsSelector = function(selectElement) | 10 WebInspector.NetworkConditionsSelector = function(populateCallback, selectCallba
ck) |
| 10 { | 11 { |
| 11 this._selectElement = selectElement; | 12 this._populateCallback = populateCallback; |
| 12 this._selectElement.addEventListener("change", this._optionSelected.bind(thi
s), false); | 13 this._selectCallback = selectCallback; |
| 13 this._customSetting = WebInspector.moduleSetting("networkConditionsCustomPro
files"); | 14 this._customSetting = WebInspector.moduleSetting("networkConditionsCustomPro
files"); |
| 14 this._customSetting.addChangeListener(this._populateOptions, this); | 15 this._customSetting.addChangeListener(this._populateOptions, this); |
| 15 this._manager = WebInspector.multitargetNetworkManager; | 16 this._manager = WebInspector.multitargetNetworkManager; |
| 16 this._manager.addEventListener(WebInspector.MultitargetNetworkManager.Events
.ConditionsChanged, this._conditionsChanged, this); | 17 this._manager.addEventListener(WebInspector.MultitargetNetworkManager.Events
.ConditionsChanged, this._conditionsChanged, this); |
| 17 this._populateOptions(); | 18 this._populateOptions(); |
| 18 } | 19 } |
| 19 | 20 |
| 20 /** @typedef {!{title: string, value: !WebInspector.NetworkManager.Conditions}}
*/ | 21 /** @typedef {!{title: string, value: !WebInspector.NetworkManager.Conditions}}
*/ |
| 21 WebInspector.NetworkConditionsProfile; | 22 WebInspector.NetworkConditionsProfile; |
| 22 | 23 |
| 24 /** @typedef {!{title: string, items: !Array<!WebInspector.NetworkConditionsProf
ile>}} */ |
| 25 WebInspector.NetworkConditionsProfileGroup; |
| 26 |
| 23 /** | 27 /** |
| 24 * @param {number} throughput | 28 * @param {number} throughput |
| 25 * @return {string} | 29 * @return {string} |
| 26 */ | 30 */ |
| 27 WebInspector.NetworkConditionsSelector.throughputText = function(throughput) | 31 WebInspector.NetworkConditionsSelector._throughputText = function(throughput) |
| 28 { | 32 { |
| 29 if (throughput < 0) | 33 if (throughput < 0) |
| 30 return ""; | 34 return ""; |
| 31 var throughputInKbps = throughput / (1024 / 8); | 35 var throughputInKbps = throughput / (1024 / 8); |
| 32 if (throughputInKbps < 1024) | 36 if (throughputInKbps < 1024) |
| 33 return WebInspector.UIString("%d kb/s", throughputInKbps); | 37 return WebInspector.UIString("%d kb/s", throughputInKbps); |
| 34 if (throughputInKbps < 1024 * 10) | 38 if (throughputInKbps < 1024 * 10) |
| 35 return WebInspector.UIString("%.1f Mb/s", throughputInKbps / 1024); | 39 return WebInspector.UIString("%.1f Mb/s", throughputInKbps / 1024); |
| 36 return WebInspector.UIString("%d Mb/s", (throughputInKbps / 1024) | 0); | 40 return WebInspector.UIString("%d Mb/s", (throughputInKbps / 1024) | 0); |
| 37 } | 41 } |
| 38 | 42 |
| 39 /** @type {!Array.<!WebInspector.NetworkConditionsProfile>} */ | 43 /** @type {!Array.<!WebInspector.NetworkConditionsProfile>} */ |
| 40 WebInspector.NetworkConditionsSelector._networkConditionsPresets = [ | 44 WebInspector.NetworkConditionsSelector._networkConditionsPresets = [ |
| 41 {title: "Offline", value: {download: 0 * 1024 / 8, upload: 0 * 1024 / 8, lat
ency: 0}}, | 45 {title: "Offline", value: {download: 0 * 1024 / 8, upload: 0 * 1024 / 8, lat
ency: 0}}, |
| 42 {title: "GPRS", value: {download: 50 * 1024 / 8, upload: 20 * 1024 / 8, late
ncy: 500}}, | 46 {title: "GPRS", value: {download: 50 * 1024 / 8, upload: 20 * 1024 / 8, late
ncy: 500}}, |
| 43 {title: "Regular 2G", value: {download: 250 * 1024 / 8, upload: 50 * 1024 /
8, latency: 300}}, | 47 {title: "Regular 2G", value: {download: 250 * 1024 / 8, upload: 50 * 1024 /
8, latency: 300}}, |
| 44 {title: "Good 2G", value: {download: 450 * 1024 / 8, upload: 150 * 1024 / 8,
latency: 150}}, | 48 {title: "Good 2G", value: {download: 450 * 1024 / 8, upload: 150 * 1024 / 8,
latency: 150}}, |
| 45 {title: "Regular 3G", value: {download: 750 * 1024 / 8, upload: 250 * 1024 /
8, latency: 100}}, | 49 {title: "Regular 3G", value: {download: 750 * 1024 / 8, upload: 250 * 1024 /
8, latency: 100}}, |
| 46 {title: "Good 3G", value: {download: 1.5 * 1024 * 1024 / 8, upload: 750 * 10
24 / 8, latency: 40}}, | 50 {title: "Good 3G", value: {download: 1.5 * 1024 * 1024 / 8, upload: 750 * 10
24 / 8, latency: 40}}, |
| 47 {title: "Regular 4G", value: {download: 4 * 1024 * 1024 / 8, upload: 3 * 102
4 * 1024 / 8, latency: 20}}, | 51 {title: "Regular 4G", value: {download: 4 * 1024 * 1024 / 8, upload: 3 * 102
4 * 1024 / 8, latency: 20}}, |
| 48 {title: "DSL", value: {download: 2 * 1024 * 1024 / 8, upload: 1 * 1024 * 102
4 / 8, latency: 5}}, | 52 {title: "DSL", value: {download: 2 * 1024 * 1024 / 8, upload: 1 * 1024 * 102
4 / 8, latency: 5}}, |
| 49 {title: "WiFi", value: {download: 30 * 1024 * 1024 / 8, upload: 15 * 1024 *
1024 / 8, latency: 2}} | 53 {title: "WiFi", value: {download: 30 * 1024 * 1024 / 8, upload: 15 * 1024 *
1024 / 8, latency: 2}} |
| 50 ]; | 54 ]; |
| 51 | 55 |
| 52 /** @type {!WebInspector.NetworkConditionsProfile} */ | 56 /** @type {!WebInspector.NetworkConditionsProfile} */ |
| 53 WebInspector.NetworkConditionsSelector._disabledPreset = {title: "No throttling"
, value: {download: -1, upload: -1, latency: 0}}; | 57 WebInspector.NetworkConditionsSelector._disabledPreset = {title: "No throttling"
, value: {download: -1, upload: -1, latency: 0}}; |
| 54 | 58 |
| 59 /** |
| 60 * @param {!WebInspector.NetworkConditionsProfile} preset |
| 61 * @return {!{text: string, title: string}} |
| 62 */ |
| 63 WebInspector.NetworkConditionsSelector._profileTitle = function(preset) |
| 64 { |
| 65 var downloadInKbps = preset.value.download / (1024 / 8); |
| 66 var uploadInKbps = preset.value.upload / (1024 / 8); |
| 67 var isThrottling = (downloadInKbps >= 0) || (uploadInKbps >= 0) || (preset.v
alue.latency > 0); |
| 68 var presetTitle = WebInspector.UIString(preset.title); |
| 69 if (!isThrottling) |
| 70 return {text: presetTitle, title: presetTitle}; |
| 71 |
| 72 var downloadText = WebInspector.NetworkConditionsSelector._throughputText(pr
eset.value.download); |
| 73 var uploadText = WebInspector.NetworkConditionsSelector._throughputText(pres
et.value.upload); |
| 74 var title = WebInspector.UIString("%s (%s\u2b07 %s\u2b06 %dms RTT)", presetT
itle, downloadText, uploadText, preset.value.latency); |
| 75 return {text: title, title: WebInspector.UIString("Maximum download throughp
ut: %s.\r\nMaximum upload throughput: %s.\r\nMinimum round-trip time: %dms.", do
wnloadText, uploadText, preset.value.latency)}; |
| 76 } |
| 77 |
| 55 WebInspector.NetworkConditionsSelector.prototype = { | 78 WebInspector.NetworkConditionsSelector.prototype = { |
| 56 _populateOptions: function() | 79 _populateOptions: function() |
| 57 { | 80 { |
| 58 this._selectElement.removeChildren(); | 81 var customGroup = {title: WebInspector.UIString("Custom"), items: this._
customSetting.get()}; |
| 82 var presetsGroup = {title: WebInspector.UIString("Presets"), items: WebI
nspector.NetworkConditionsSelector._networkConditionsPresets}; |
| 83 var disabledGroup = {title: WebInspector.UIString("Disabled"), items: [W
ebInspector.NetworkConditionsSelector._disabledPreset]}; |
| 84 this._options = this._populateCallback([customGroup, presetsGroup, disab
ledGroup]); |
| 85 this._conditionsChanged(); |
| 86 }, |
| 59 | 87 |
| 60 var customGroup = this._addGroup(this._customSetting.get(), WebInspector
.UIString("Custom")); | 88 revealAndUpdate: function() |
| 61 customGroup.insertBefore(new Option(WebInspector.UIString("Add\u2026"),
WebInspector.UIString("Add\u2026")), customGroup.firstChild); | 89 { |
| 62 | 90 WebInspector.Revealer.reveal(this._customSetting); |
| 63 this._addGroup(WebInspector.NetworkConditionsSelector._networkConditions
Presets, WebInspector.UIString("Presets")); | |
| 64 this._addGroup([WebInspector.NetworkConditionsSelector._disabledPreset],
WebInspector.UIString("Disabled")); | |
| 65 | |
| 66 this._conditionsChanged(); | 91 this._conditionsChanged(); |
| 67 }, | 92 }, |
| 68 | 93 |
| 69 /** | 94 /** |
| 70 * @param {!Array.<!WebInspector.NetworkConditionsProfile>} presets | 95 * @param {!WebInspector.NetworkManager.Conditions} conditions |
| 71 * @param {string} groupName | |
| 72 * @return {!Element} | |
| 73 */ | 96 */ |
| 74 _addGroup: function(presets, groupName) | 97 optionSelected: function(conditions) |
| 75 { | 98 { |
| 76 var groupElement = this._selectElement.createChild("optgroup"); | 99 this._manager.setNetworkConditions(conditions); |
| 77 groupElement.label = groupName; | |
| 78 for (var i = 0; i < presets.length; ++i) { | |
| 79 var preset = presets[i]; | |
| 80 var downloadInKbps = preset.value.download / (1024 / 8); | |
| 81 var uploadInKbps = preset.value.upload / (1024 / 8); | |
| 82 var isThrottling = (downloadInKbps >= 0) || (uploadInKbps >= 0) || (
preset.value.latency > 0); | |
| 83 var option; | |
| 84 var presetTitle = WebInspector.UIString(preset.title); | |
| 85 if (!isThrottling) { | |
| 86 option = new Option(presetTitle, presetTitle); | |
| 87 } else { | |
| 88 var downloadText = WebInspector.NetworkConditionsSelector.throug
hputText(preset.value.download); | |
| 89 var uploadText = WebInspector.NetworkConditionsSelector.throughp
utText(preset.value.upload); | |
| 90 var title = WebInspector.UIString("%s (%s\u2b07 %s\u2b06 %dms RT
T)", presetTitle, downloadText, uploadText, preset.value.latency); | |
| 91 option = new Option(title, presetTitle); | |
| 92 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); | |
| 93 } | |
| 94 option.conditions = preset.value; | |
| 95 groupElement.appendChild(option); | |
| 96 } | |
| 97 return groupElement; | |
| 98 }, | |
| 99 | |
| 100 _optionSelected: function() | |
| 101 { | |
| 102 if (this._selectElement.selectedIndex === 0) { | |
| 103 WebInspector.Revealer.reveal(this._customSetting); | |
| 104 this._conditionsChanged(); | |
| 105 return; | |
| 106 } | |
| 107 | |
| 108 this._manager.removeEventListener(WebInspector.MultitargetNetworkManager
.Events.ConditionsChanged, this._conditionsChanged, this); | |
| 109 this._manager.setNetworkConditions(this._selectElement.options[this._sel
ectElement.selectedIndex].conditions); | |
| 110 this._manager.addEventListener(WebInspector.MultitargetNetworkManager.Ev
ents.ConditionsChanged, this._conditionsChanged, this); | |
| 111 }, | 100 }, |
| 112 | 101 |
| 113 _conditionsChanged: function() | 102 _conditionsChanged: function() |
| 114 { | 103 { |
| 115 var value = this._manager.networkConditions(); | 104 var value = this._manager.networkConditions(); |
| 116 var options = this._selectElement.options; | 105 for (var index = 0; index < this._options.length; ++index) { |
| 117 for (var index = 1; index < options.length; ++index) { | 106 var option = this._options[index]; |
| 118 var option = options[index]; | 107 if (!option.conditions) |
| 108 continue; |
| 119 if (option.conditions.download === value.download && option.conditio
ns.upload === value.upload && option.conditions.latency === value.latency) | 109 if (option.conditions.download === value.download && option.conditio
ns.upload === value.upload && option.conditions.latency === value.latency) |
| 120 this._selectElement.selectedIndex = index; | 110 this._selectCallback(index); |
| 121 } | 111 } |
| 122 } | 112 } |
| 123 } | 113 } |
| 124 | 114 |
| 115 /** |
| 116 * @param {!HTMLSelectElement} selectElement |
| 117 */ |
| 118 WebInspector.NetworkConditionsSelector.decorateSelect = function(selectElement) |
| 119 { |
| 120 var options = []; |
| 121 var selector = new WebInspector.NetworkConditionsSelector(populate, select); |
| 122 selectElement.addEventListener("change", optionSelected, false); |
| 123 |
| 124 /** |
| 125 * @param {!Array.<!WebInspector.NetworkConditionsProfileGroup>} groups |
| 126 * @return {!Array<!{conditions: ?WebInspector.NetworkManager.Conditions}>} |
| 127 */ |
| 128 function populate(groups) |
| 129 { |
| 130 selectElement.removeChildren(); |
| 131 options = []; |
| 132 for (var i = 0; i < groups.length; ++i) { |
| 133 var group = groups[i]; |
| 134 var groupElement = selectElement.createChild("optgroup"); |
| 135 groupElement.label = group.title; |
| 136 if (!i) { |
| 137 groupElement.appendChild(new Option(WebInspector.UIString("Add\u
2026"), WebInspector.UIString("Add\u2026"))); |
| 138 options.push({conditions: null}); |
| 139 } |
| 140 for (var preset of group.items) { |
| 141 var title = WebInspector.NetworkConditionsSelector._profileTitle
(preset); |
| 142 var option = new Option(title.text, title.text); |
| 143 option.title = title.title; |
| 144 groupElement.appendChild(option); |
| 145 options.push({conditions: preset.value}); |
| 146 } |
| 147 } |
| 148 return options; |
| 149 } |
| 150 |
| 151 function optionSelected() |
| 152 { |
| 153 if (selectElement.selectedIndex === 0) |
| 154 selector.revealAndUpdate(); |
| 155 else |
| 156 selector.optionSelected(options[selectElement.selectedIndex].conditi
ons); |
| 157 } |
| 158 |
| 159 /** |
| 160 * @param {number} index |
| 161 */ |
| 162 function select(index) |
| 163 { |
| 164 if (selectElement.selectedIndex !== index) |
| 165 selectElement.selectedIndex = index; |
| 166 } |
| 167 } |
| 168 |
| 169 /** |
| 170 * @return {!WebInspector.ToolbarMenuButton} |
| 171 */ |
| 172 WebInspector.NetworkConditionsSelector.createToolbarMenuButton = function() |
| 173 { |
| 174 var button = new WebInspector.ToolbarMenuButton(appendItems); |
| 175 button.setGlyph(""); |
| 176 button.turnIntoSelect(); |
| 177 |
| 178 /** @type {!Array<!{separator: boolean, text: string, title: string, conditi
ons: !WebInspector.NetworkManager.Conditions}>} */ |
| 179 var items = []; |
| 180 var selectedIndex = -1; |
| 181 var selector = new WebInspector.NetworkConditionsSelector(populate, select); |
| 182 return button; |
| 183 |
| 184 /** |
| 185 * @param {!WebInspector.ContextMenu} contextMenu |
| 186 */ |
| 187 function appendItems(contextMenu) |
| 188 { |
| 189 for (var index = 0; index < items.length; ++index) { |
| 190 var item = items[index]; |
| 191 if (item.separator) |
| 192 contextMenu.appendSeparator(); |
| 193 else |
| 194 contextMenu.appendCheckboxItem(item.title, selector.optionSelect
ed.bind(selector, item.conditions), selectedIndex === index); |
| 195 } |
| 196 contextMenu.appendItem(WebInspector.UIString("Edit\u2026"), selector.rev
ealAndUpdate.bind(selector)); |
| 197 } |
| 198 |
| 199 /** |
| 200 * @param {!Array.<!WebInspector.NetworkConditionsProfileGroup>} groups |
| 201 * @return {!Array<!{conditions: !WebInspector.NetworkManager.Conditions}>} |
| 202 */ |
| 203 function populate(groups) |
| 204 { |
| 205 items = []; |
| 206 for (var group of groups) { |
| 207 for (var preset of group.items) { |
| 208 var title = WebInspector.NetworkConditionsSelector._profileTitle
(preset); |
| 209 items.push({separator: false, text: preset.title, title: title.t
ext, conditions: preset.value}); |
| 210 } |
| 211 items.push({separator: true, text: "", title: "", conditions: null})
; |
| 212 } |
| 213 return /** @type {!Array<!{conditions: !WebInspector.NetworkManager.Cond
itions}>} */ (items); |
| 214 } |
| 215 |
| 216 /** |
| 217 * @param {number} index |
| 218 */ |
| 219 function select(index) |
| 220 { |
| 221 selectedIndex = index; |
| 222 button.setText(items[index].text); |
| 223 } |
| 224 } |
| 125 | 225 |
| 126 /** | 226 /** |
| 127 * @constructor | 227 * @constructor |
| 128 * @extends {WebInspector.VBox} | 228 * @extends {WebInspector.VBox} |
| 129 * @implements {WebInspector.ListWidget.Delegate} | 229 * @implements {WebInspector.ListWidget.Delegate} |
| 130 */ | 230 */ |
| 131 WebInspector.NetworkConditionsSettingsTab = function() | 231 WebInspector.NetworkConditionsSettingsTab = function() |
| 132 { | 232 { |
| 133 WebInspector.VBox.call(this, true); | 233 WebInspector.VBox.call(this, true); |
| 134 this.registerRequiredCSS("network/networkConditionsSettingsTab.css"); | 234 this.registerRequiredCSS("components/networkConditionsSettingsTab.css"); |
| 135 | 235 |
| 136 this.contentElement.createChild("div", "header").textContent = WebInspector.
UIString("Network Throttling Profiles"); | 236 this.contentElement.createChild("div", "header").textContent = WebInspector.
UIString("Network Throttling Profiles"); |
| 137 | 237 |
| 138 var addButton = createTextButton(WebInspector.UIString("Add custom profile..
."), this._addButtonClicked.bind(this), "add-conditions-button"); | 238 var addButton = createTextButton(WebInspector.UIString("Add custom profile..
."), this._addButtonClicked.bind(this), "add-conditions-button"); |
| 139 this.contentElement.appendChild(addButton); | 239 this.contentElement.appendChild(addButton); |
| 140 | 240 |
| 141 this._list = new WebInspector.ListWidget(this); | 241 this._list = new WebInspector.ListWidget(this); |
| 142 this._list.element.classList.add("conditions-list"); | 242 this._list.element.classList.add("conditions-list"); |
| 143 this._list.registerRequiredCSS("network/networkConditionsSettingsTab.css"); | 243 this._list.registerRequiredCSS("components/networkConditionsSettingsTab.css"
); |
| 144 this._list.show(this.contentElement); | 244 this._list.show(this.contentElement); |
| 145 | 245 |
| 146 this._customSetting = WebInspector.moduleSetting("networkConditionsCustomPro
files"); | 246 this._customSetting = WebInspector.moduleSetting("networkConditionsCustomPro
files"); |
| 147 this._customSetting.addChangeListener(this._conditionsUpdated, this); | 247 this._customSetting.addChangeListener(this._conditionsUpdated, this); |
| 148 | 248 |
| 149 this.setDefaultFocusedElement(addButton); | 249 this.setDefaultFocusedElement(addButton); |
| 150 this.contentElement.tabIndex = 0; | 250 this.contentElement.tabIndex = 0; |
| 151 } | 251 } |
| 152 | 252 |
| 153 WebInspector.NetworkConditionsSettingsTab.prototype = { | 253 WebInspector.NetworkConditionsSettingsTab.prototype = { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 185 */ | 285 */ |
| 186 renderItem: function(item, editable) | 286 renderItem: function(item, editable) |
| 187 { | 287 { |
| 188 var conditions = /** @type {!WebInspector.NetworkConditionsProfile} */ (
item); | 288 var conditions = /** @type {!WebInspector.NetworkConditionsProfile} */ (
item); |
| 189 var element = createElementWithClass("div", "conditions-list-item"); | 289 var element = createElementWithClass("div", "conditions-list-item"); |
| 190 var title = element.createChild("div", "conditions-list-text conditions-
list-title"); | 290 var title = element.createChild("div", "conditions-list-text conditions-
list-title"); |
| 191 var titleText = title.createChild("div", "conditions-list-title-text"); | 291 var titleText = title.createChild("div", "conditions-list-title-text"); |
| 192 titleText.textContent = conditions.title; | 292 titleText.textContent = conditions.title; |
| 193 titleText.title = conditions.title; | 293 titleText.title = conditions.title; |
| 194 element.createChild("div", "conditions-list-separator"); | 294 element.createChild("div", "conditions-list-separator"); |
| 195 element.createChild("div", "conditions-list-text").textContent = WebInsp
ector.NetworkConditionsSelector.throughputText(conditions.value.download); | 295 element.createChild("div", "conditions-list-text").textContent = WebInsp
ector.NetworkConditionsSelector._throughputText(conditions.value.download); |
| 196 element.createChild("div", "conditions-list-separator"); | 296 element.createChild("div", "conditions-list-separator"); |
| 197 element.createChild("div", "conditions-list-text").textContent = WebInsp
ector.NetworkConditionsSelector.throughputText(conditions.value.upload); | 297 element.createChild("div", "conditions-list-text").textContent = WebInsp
ector.NetworkConditionsSelector._throughputText(conditions.value.upload); |
| 198 element.createChild("div", "conditions-list-separator"); | 298 element.createChild("div", "conditions-list-separator"); |
| 199 element.createChild("div", "conditions-list-text").textContent = WebInsp
ector.UIString("%dms", conditions.value.latency); | 299 element.createChild("div", "conditions-list-text").textContent = WebInsp
ector.UIString("%dms", conditions.value.latency); |
| 200 return element; | 300 return element; |
| 201 }, | 301 }, |
| 202 | 302 |
| 203 /** | 303 /** |
| 204 * @override | 304 * @override |
| 205 * @param {*} item | 305 * @param {*} item |
| 206 * @param {number} index | 306 * @param {number} index |
| 207 */ | 307 */ |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 324 */ | 424 */ |
| 325 function latencyValidator(item, index, input) | 425 function latencyValidator(item, index, input) |
| 326 { | 426 { |
| 327 var value = input.value.trim(); | 427 var value = input.value.trim(); |
| 328 return !value || (/^[\d]+$/.test(value) && value >= 0 && value <= 10
00000); | 428 return !value || (/^[\d]+$/.test(value) && value >= 0 && value <= 10
00000); |
| 329 } | 429 } |
| 330 }, | 430 }, |
| 331 | 431 |
| 332 __proto__: WebInspector.VBox.prototype | 432 __proto__: WebInspector.VBox.prototype |
| 333 } | 433 } |
| OLD | NEW |