mirror of
https://github.com/jupyter/notebook.git
synced 2025-01-24 12:05:22 +08:00
Merge pull request #6481 from jdfreder/intvalidatefix
Fix bug in bounded int/float logic.
This commit is contained in:
commit
60531c917f
@ -64,7 +64,7 @@ define([
|
||||
if (options === undefined || options.updated_view != this) {
|
||||
// JQuery slider option keys. These keys happen to have a
|
||||
// one-to-one mapping with the corrosponding keys of the model.
|
||||
var jquery_slider_keys = ['step', 'max', 'min', 'disabled'];
|
||||
var jquery_slider_keys = ['step', 'disabled'];
|
||||
var that = this;
|
||||
that.$slider.slider({});
|
||||
_.each(jquery_slider_keys, function(key, i) {
|
||||
@ -73,6 +73,14 @@ define([
|
||||
that.$slider.slider("option", key, model_value);
|
||||
}
|
||||
});
|
||||
|
||||
var max = this.model.get('max');
|
||||
var min = this.model.get('min');
|
||||
if (min <= max) {
|
||||
if (max !== undefined) this.$slider.slider('option', 'max', max);
|
||||
if (min !== undefined) this.$slider.slider('option', 'min', min);
|
||||
}
|
||||
|
||||
var range_value = this.model.get("_range");
|
||||
if (range_value !== undefined) {
|
||||
this.$slider.slider("option", "range", range_value);
|
||||
|
@ -154,4 +154,22 @@ casper.notebook_test(function () {
|
||||
this.test.assertEquals(this.get_output_cell(index).text, '50\n',
|
||||
'Invalid int textbox characters ignored');
|
||||
});
|
||||
|
||||
index = this.append_cell(
|
||||
'a = widgets.IntSlider()\n' +
|
||||
'display(a)\n' +
|
||||
'a.max = -1\n' +
|
||||
'print("Success")\n');
|
||||
this.execute_cell_then(index, function(index){
|
||||
this.test.assertEquals(0, 0, 'Invalid int range max bound does not cause crash.');
|
||||
});
|
||||
|
||||
index = this.append_cell(
|
||||
'a = widgets.IntSlider()\n' +
|
||||
'display(a)\n' +
|
||||
'a.min = 101\n' +
|
||||
'print("Success")\n');
|
||||
this.execute_cell_then(index, function(index){
|
||||
this.test.assertEquals(0, 0, 'Invalid int range min bound does not cause crash.');
|
||||
});
|
||||
});
|
@ -125,7 +125,6 @@ class Widget(LoggingConfigurable):
|
||||
self._model_id = kwargs.pop('model_id', None)
|
||||
super(Widget, self).__init__(**kwargs)
|
||||
|
||||
self.on_trait_change(self._handle_property_changed, self.keys)
|
||||
Widget._call_widget_constructed(self)
|
||||
self.open()
|
||||
|
||||
@ -323,13 +322,21 @@ class Widget(LoggingConfigurable):
|
||||
def _handle_custom_msg(self, content):
|
||||
"""Called when a custom msg is received."""
|
||||
self._msg_callbacks(self, content)
|
||||
|
||||
def _handle_property_changed(self, name, old, new):
|
||||
|
||||
def _notify_trait(self, name, old_value, new_value):
|
||||
"""Called when a property has been changed."""
|
||||
# Make sure this isn't information that the front-end just sent us.
|
||||
if self._should_send_property(name, new):
|
||||
# Send new state to front-end
|
||||
self.send_state(key=name)
|
||||
# Trigger default traitlet callback machinery. This allows any user
|
||||
# registered validation to be processed prior to allowing the widget
|
||||
# machinery to handle the state.
|
||||
LoggingConfigurable._notify_trait(self, name, old_value, new_value)
|
||||
|
||||
# Send the state after the user registered callbacks for trait changes
|
||||
# have all fired (allows for user to validate values).
|
||||
if self.comm is not None and name in self.keys:
|
||||
# Make sure this isn't information that the front-end just sent us.
|
||||
if self._should_send_property(name, new_value):
|
||||
# Send new state to front-end
|
||||
self.send_state(key=name)
|
||||
|
||||
def _handle_displayed(self, **kwargs):
|
||||
"""Called when a view has been displayed for this widget instance"""
|
||||
|
@ -37,13 +37,24 @@ class _BoundedInt(_Int):
|
||||
def __init__(self, *pargs, **kwargs):
|
||||
"""Constructor"""
|
||||
DOMWidget.__init__(self, *pargs, **kwargs)
|
||||
self.on_trait_change(self._validate, ['value', 'min', 'max'])
|
||||
self.on_trait_change(self._validate_value, ['value'])
|
||||
self.on_trait_change(self._handle_max_changed, ['max'])
|
||||
self.on_trait_change(self._handle_min_changed, ['min'])
|
||||
|
||||
def _validate(self, name, old, new):
|
||||
"""Validate value, max, min."""
|
||||
def _validate_value(self, name, old, new):
|
||||
"""Validate value."""
|
||||
if self.min > new or new > self.max:
|
||||
self.value = min(max(new, self.min), self.max)
|
||||
|
||||
def _handle_max_changed(self, name, old, new):
|
||||
"""Make sure the min is always <= the max."""
|
||||
if new < self.min:
|
||||
raise ValueError("setting max < min")
|
||||
|
||||
def _handle_min_changed(self, name, old, new):
|
||||
"""Make sure the max is always >= the min."""
|
||||
if new > self.max:
|
||||
raise ValueError("setting min > max")
|
||||
|
||||
class IntText(_Int):
|
||||
"""Textbox widget that represents a int."""
|
||||
@ -134,11 +145,9 @@ class _BoundedIntRange(_IntRange):
|
||||
if name == "min":
|
||||
if new > self.max:
|
||||
raise ValueError("setting min > max")
|
||||
self.min = new
|
||||
elif name == "max":
|
||||
if new < self.min:
|
||||
raise ValueError("setting max < min")
|
||||
self.max = new
|
||||
|
||||
low, high = self.value
|
||||
if name == "value":
|
||||
|
Loading…
Reference in New Issue
Block a user