Skip to content

Commit 8976bc7

Browse files
committed
Progressbar: Refactor to better handle option changes and sanitize values. Fixes #8785 - Progressbar: Remove _value() and always sanitize value option
1 parent 1e19e5e commit 8976bc7

File tree

2 files changed

+76
-25
lines changed

2 files changed

+76
-25
lines changed

tests/unit/progressbar/progressbar_options.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,21 @@ test( "{ max : 5, value : 10 }", function() {
6060
});
6161
deepEqual( 5, $( "#progressbar" ).progressbar( "value" ) );
6262
});
63+
64+
test( "{ value : 10, max : 5 }", function() {
65+
expect( 1 );
66+
$("#progressbar").progressbar({
67+
max: 5,
68+
value: 10
69+
});
70+
deepEqual( 5, $( "#progressbar" ).progressbar( "value" ) );
71+
});
72+
73+
test( "{ max : 5 }", function() {
74+
expect( 1 );
75+
$("#progressbar").progressbar({
76+
max: 10,
77+
value: 10
78+
}).progressbar( "option", "max", 5 );
79+
deepEqual( 5, $( "#progressbar" ).progressbar( "value" ) );
80+
});

ui/jquery.ui.progressbar.js

Lines changed: 58 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,22 @@ $.widget( "ui.progressbar", {
2424
min: 0,
2525

2626
_create: function() {
27+
// Constrain initial value
28+
this.options.value = this._constrainedValue();
29+
2730
this.element
2831
.addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
2932
.attr({
3033
role: "progressbar",
3134
"aria-valuemin": this.min,
3235
"aria-valuemax": this.options.max,
33-
"aria-valuenow": this._value()
36+
"aria-valuenow": this.options.value
3437
});
3538

3639
this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
3740
.appendTo( this.element );
3841

39-
this.oldValue = this._value();
42+
this.oldValue = this.options.value;
4043
this._refreshValue();
4144
},
4245

@@ -53,52 +56,82 @@ $.widget( "ui.progressbar", {
5356

5457
value: function( newValue ) {
5558
if ( newValue === undefined ) {
56-
return this._value();
59+
return this.options.value;
5760
}
5861

59-
this._setOption( "value", newValue );
62+
this._setOption( "value", this._constrainedValue( newValue ) );
6063
return this;
6164
},
6265

63-
_setOption: function( key, value ) {
64-
if ( key === "value" ) {
65-
this.options.value = value;
66-
this._refreshValue();
67-
if ( this._value() === this.options.max ) {
68-
this._trigger( "complete" );
69-
}
66+
_constrainedValue: function( newValue ) {
67+
var val;
68+
if ( newValue === undefined ) {
69+
val = this.options.value;
70+
} else {
71+
val = newValue;
7072
}
7173

72-
this._super( key, value );
73-
},
74-
75-
_value: function() {
76-
var val = this.options.value;
77-
// normalize invalid value
74+
// sanitize value
7875
if ( typeof val !== "number" ) {
7976
val = 0;
8077
}
8178
return Math.min( this.options.max, Math.max( this.min, val ) );
8279
},
8380

81+
_setOptions: function( options ) {
82+
var key, val;
83+
84+
for ( key in options ) {
85+
if ( key === "value" ) {
86+
// Store value to update last in case max is being updated at the same time
87+
val = options[ key ];
88+
} else {
89+
this._setOption( key, options[ key ] );
90+
}
91+
}
92+
93+
if ( val !== undefined ) {
94+
this._setOption( "value", val );
95+
}
96+
},
97+
98+
_setOption: function( key, value ) {
99+
if ( key === "max" ) {
100+
// Don't allow a max less than min
101+
this.options.max = Math.max( this.min, value );
102+
this.options.value = this._constrainedValue();
103+
}
104+
if ( key === "value" ) {
105+
this.options.value = this._constrainedValue( value );
106+
}
107+
else {
108+
this._super( key, value );
109+
}
110+
111+
this._refreshValue();
112+
},
113+
84114
_percentage: function() {
85-
return 100 * this._value() / this.options.max;
115+
return 100 * this.options.value / this.options.max;
86116
},
87117

88118
_refreshValue: function() {
89-
var value = this.value(),
90-
percentage = this._percentage();
119+
var percentage = this._percentage();
91120

92-
if ( this.oldValue !== value ) {
93-
this.oldValue = value;
121+
if ( this.oldValue !== this.options.value ) {
122+
this.oldValue = this.options.value;
94123
this._trigger( "change" );
95124
}
125+
if ( this.options.value === this.options.max ) {
126+
this._trigger( "complete" );
127+
}
96128

97129
this.valueDiv
98-
.toggle( value > this.min )
99-
.toggleClass( "ui-corner-right", value === this.options.max )
130+
.toggle( this.options.value > this.min )
131+
.toggleClass( "ui-corner-right", this.options.value === this.options.max )
100132
.width( percentage.toFixed(0) + "%" );
101-
this.element.attr( "aria-valuenow", value );
133+
this.element.attr( "aria-valuemax", this.options.max );
134+
this.element.attr( "aria-valuenow", this.options.value );
102135
}
103136
});
104137

0 commit comments

Comments
 (0)