slider.js 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755
  1. /*!
  2. * jQuery UI Slider 1.14.1
  3. * https://jqueryui.com
  4. *
  5. * Copyright OpenJS Foundation and other contributors
  6. * Released under the MIT license.
  7. * https://jquery.org/license
  8. */
  9. //>>label: Slider
  10. //>>group: Widgets
  11. //>>description: Displays a flexible slider with ranges and accessibility via keyboard.
  12. //>>docs: https://api.jqueryui.com/slider/
  13. //>>demos: https://jqueryui.com/slider/
  14. //>>css.structure: ../../themes/base/core.css
  15. //>>css.structure: ../../themes/base/slider.css
  16. //>>css.theme: ../../themes/base/theme.css
  17. ( function( factory ) {
  18. "use strict";
  19. if ( typeof define === "function" && define.amd ) {
  20. // AMD. Register as an anonymous module.
  21. define( [
  22. "jquery",
  23. "./mouse",
  24. "../keycode",
  25. "../version",
  26. "../widget"
  27. ], factory );
  28. } else {
  29. // Browser globals
  30. factory( jQuery );
  31. }
  32. } )( function( $ ) {
  33. "use strict";
  34. return $.widget( "ui.slider", $.ui.mouse, {
  35. version: "1.14.1",
  36. widgetEventPrefix: "slide",
  37. options: {
  38. animate: false,
  39. classes: {
  40. "ui-slider": "ui-corner-all",
  41. "ui-slider-handle": "ui-corner-all",
  42. // Note: ui-widget-header isn't the most fittingly semantic framework class for this
  43. // element, but worked best visually with a variety of themes
  44. "ui-slider-range": "ui-corner-all ui-widget-header"
  45. },
  46. distance: 0,
  47. max: 100,
  48. min: 0,
  49. orientation: "horizontal",
  50. range: false,
  51. step: 1,
  52. value: 0,
  53. values: null,
  54. // Callbacks
  55. change: null,
  56. slide: null,
  57. start: null,
  58. stop: null
  59. },
  60. // Number of pages in a slider
  61. // (how many times can you page up/down to go through the whole range)
  62. numPages: 5,
  63. _create: function() {
  64. this._keySliding = false;
  65. this._mouseSliding = false;
  66. this._animateOff = true;
  67. this._handleIndex = null;
  68. this._detectOrientation();
  69. this._mouseInit();
  70. this._calculateNewMax();
  71. this._addClass( "ui-slider ui-slider-" + this.orientation,
  72. "ui-widget ui-widget-content" );
  73. this._refresh();
  74. this._animateOff = false;
  75. },
  76. _refresh: function() {
  77. this._createRange();
  78. this._createHandles();
  79. this._setupEvents();
  80. this._refreshValue();
  81. },
  82. _createHandles: function() {
  83. var i, handleCount,
  84. options = this.options,
  85. existingHandles = this.element.find( ".ui-slider-handle" ),
  86. handle = "<span tabindex='0'></span>",
  87. handles = [];
  88. handleCount = ( options.values && options.values.length ) || 1;
  89. if ( existingHandles.length > handleCount ) {
  90. existingHandles.slice( handleCount ).remove();
  91. existingHandles = existingHandles.slice( 0, handleCount );
  92. }
  93. for ( i = existingHandles.length; i < handleCount; i++ ) {
  94. handles.push( handle );
  95. }
  96. this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
  97. this._addClass( this.handles, "ui-slider-handle", "ui-state-default" );
  98. this.handle = this.handles.eq( 0 );
  99. this.handles.each( function( i ) {
  100. $( this )
  101. .data( "ui-slider-handle-index", i )
  102. .attr( "tabIndex", 0 );
  103. } );
  104. },
  105. _createRange: function() {
  106. var options = this.options;
  107. if ( options.range ) {
  108. if ( options.range === true ) {
  109. if ( !options.values ) {
  110. options.values = [ this._valueMin(), this._valueMin() ];
  111. } else if ( options.values.length && options.values.length !== 2 ) {
  112. options.values = [ options.values[ 0 ], options.values[ 0 ] ];
  113. } else if ( Array.isArray( options.values ) ) {
  114. options.values = options.values.slice( 0 );
  115. }
  116. }
  117. if ( !this.range || !this.range.length ) {
  118. this.range = $( "<div>" )
  119. .appendTo( this.element );
  120. this._addClass( this.range, "ui-slider-range" );
  121. } else {
  122. this._removeClass( this.range, "ui-slider-range-min ui-slider-range-max" );
  123. // Handle range switching from true to min/max
  124. this.range.css( {
  125. "left": "",
  126. "bottom": ""
  127. } );
  128. }
  129. if ( options.range === "min" || options.range === "max" ) {
  130. this._addClass( this.range, "ui-slider-range-" + options.range );
  131. }
  132. } else {
  133. if ( this.range ) {
  134. this.range.remove();
  135. }
  136. this.range = null;
  137. }
  138. },
  139. _setupEvents: function() {
  140. this._off( this.handles );
  141. this._on( this.handles, this._handleEvents );
  142. this._hoverable( this.handles );
  143. this._focusable( this.handles );
  144. },
  145. _destroy: function() {
  146. this.handles.remove();
  147. if ( this.range ) {
  148. this.range.remove();
  149. }
  150. this._mouseDestroy();
  151. },
  152. _mouseCapture: function( event ) {
  153. var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
  154. that = this,
  155. o = this.options;
  156. if ( o.disabled ) {
  157. return false;
  158. }
  159. this.elementSize = {
  160. width: this.element.outerWidth(),
  161. height: this.element.outerHeight()
  162. };
  163. this.elementOffset = this.element.offset();
  164. position = { x: event.pageX, y: event.pageY };
  165. normValue = this._normValueFromMouse( position );
  166. distance = this._valueMax() - this._valueMin() + 1;
  167. this.handles.each( function( i ) {
  168. var thisDistance = Math.abs( normValue - that.values( i ) );
  169. if ( ( distance > thisDistance ) ||
  170. ( distance === thisDistance &&
  171. ( i === that._lastChangedValue || that.values( i ) === o.min ) ) ) {
  172. distance = thisDistance;
  173. closestHandle = $( this );
  174. index = i;
  175. }
  176. } );
  177. allowed = this._start( event, index );
  178. if ( allowed === false ) {
  179. return false;
  180. }
  181. this._mouseSliding = true;
  182. this._handleIndex = index;
  183. this._addClass( closestHandle, null, "ui-state-active" );
  184. closestHandle.trigger( "focus" );
  185. offset = closestHandle.offset();
  186. mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
  187. this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
  188. left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
  189. top: event.pageY - offset.top -
  190. ( closestHandle.height() / 2 ) -
  191. ( parseInt( closestHandle.css( "borderTopWidth" ), 10 ) || 0 ) -
  192. ( parseInt( closestHandle.css( "borderBottomWidth" ), 10 ) || 0 ) +
  193. ( parseInt( closestHandle.css( "marginTop" ), 10 ) || 0 )
  194. };
  195. if ( !this.handles.hasClass( "ui-state-hover" ) ) {
  196. this._slide( event, index, normValue );
  197. }
  198. this._animateOff = true;
  199. return true;
  200. },
  201. _mouseStart: function() {
  202. return true;
  203. },
  204. _mouseDrag: function( event ) {
  205. var position = { x: event.pageX, y: event.pageY },
  206. normValue = this._normValueFromMouse( position );
  207. this._slide( event, this._handleIndex, normValue );
  208. return false;
  209. },
  210. _mouseStop: function( event ) {
  211. this._removeClass( this.handles, null, "ui-state-active" );
  212. this._mouseSliding = false;
  213. this._stop( event, this._handleIndex );
  214. this._change( event, this._handleIndex );
  215. this._handleIndex = null;
  216. this._clickOffset = null;
  217. this._animateOff = false;
  218. return false;
  219. },
  220. _detectOrientation: function() {
  221. this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
  222. },
  223. _normValueFromMouse: function( position ) {
  224. var pixelTotal,
  225. pixelMouse,
  226. percentMouse,
  227. valueTotal,
  228. valueMouse;
  229. if ( this.orientation === "horizontal" ) {
  230. pixelTotal = this.elementSize.width;
  231. pixelMouse = position.x - this.elementOffset.left -
  232. ( this._clickOffset ? this._clickOffset.left : 0 );
  233. } else {
  234. pixelTotal = this.elementSize.height;
  235. pixelMouse = position.y - this.elementOffset.top -
  236. ( this._clickOffset ? this._clickOffset.top : 0 );
  237. }
  238. percentMouse = ( pixelMouse / pixelTotal );
  239. if ( percentMouse > 1 ) {
  240. percentMouse = 1;
  241. }
  242. if ( percentMouse < 0 ) {
  243. percentMouse = 0;
  244. }
  245. if ( this.orientation === "vertical" ) {
  246. percentMouse = 1 - percentMouse;
  247. }
  248. valueTotal = this._valueMax() - this._valueMin();
  249. valueMouse = this._valueMin() + percentMouse * valueTotal;
  250. return this._trimAlignValue( valueMouse );
  251. },
  252. _uiHash: function( index, value, values ) {
  253. var uiHash = {
  254. handle: this.handles[ index ],
  255. handleIndex: index,
  256. value: value !== undefined ? value : this.value()
  257. };
  258. if ( this._hasMultipleValues() ) {
  259. uiHash.value = value !== undefined ? value : this.values( index );
  260. uiHash.values = values || this.values();
  261. }
  262. return uiHash;
  263. },
  264. _hasMultipleValues: function() {
  265. return this.options.values && this.options.values.length;
  266. },
  267. _start: function( event, index ) {
  268. return this._trigger( "start", event, this._uiHash( index ) );
  269. },
  270. _slide: function( event, index, newVal ) {
  271. var allowed, otherVal,
  272. currentValue = this.value(),
  273. newValues = this.values();
  274. if ( this._hasMultipleValues() ) {
  275. otherVal = this.values( index ? 0 : 1 );
  276. currentValue = this.values( index );
  277. if ( this.options.values.length === 2 && this.options.range === true ) {
  278. newVal = index === 0 ? Math.min( otherVal, newVal ) : Math.max( otherVal, newVal );
  279. }
  280. newValues[ index ] = newVal;
  281. }
  282. if ( newVal === currentValue ) {
  283. return;
  284. }
  285. allowed = this._trigger( "slide", event, this._uiHash( index, newVal, newValues ) );
  286. // A slide can be canceled by returning false from the slide callback
  287. if ( allowed === false ) {
  288. return;
  289. }
  290. if ( this._hasMultipleValues() ) {
  291. this.values( index, newVal );
  292. } else {
  293. this.value( newVal );
  294. }
  295. },
  296. _stop: function( event, index ) {
  297. this._trigger( "stop", event, this._uiHash( index ) );
  298. },
  299. _change: function( event, index ) {
  300. if ( !this._keySliding && !this._mouseSliding ) {
  301. //store the last changed value index for reference when handles overlap
  302. this._lastChangedValue = index;
  303. this._trigger( "change", event, this._uiHash( index ) );
  304. }
  305. },
  306. value: function( newValue ) {
  307. if ( arguments.length ) {
  308. this.options.value = this._trimAlignValue( newValue );
  309. this._refreshValue();
  310. this._change( null, 0 );
  311. return;
  312. }
  313. return this._value();
  314. },
  315. values: function( index, newValue ) {
  316. var vals,
  317. newValues,
  318. i;
  319. if ( arguments.length > 1 ) {
  320. this.options.values[ index ] = this._trimAlignValue( newValue );
  321. this._refreshValue();
  322. this._change( null, index );
  323. return;
  324. }
  325. if ( arguments.length ) {
  326. if ( Array.isArray( arguments[ 0 ] ) ) {
  327. vals = this.options.values;
  328. newValues = arguments[ 0 ];
  329. for ( i = 0; i < vals.length; i += 1 ) {
  330. vals[ i ] = this._trimAlignValue( newValues[ i ] );
  331. this._change( null, i );
  332. }
  333. this._refreshValue();
  334. } else {
  335. if ( this._hasMultipleValues() ) {
  336. return this._values( index );
  337. } else {
  338. return this.value();
  339. }
  340. }
  341. } else {
  342. return this._values();
  343. }
  344. },
  345. _setOption: function( key, value ) {
  346. var i,
  347. valsLength = 0;
  348. if ( key === "range" && this.options.range === true ) {
  349. if ( value === "min" ) {
  350. this.options.value = this._values( 0 );
  351. this.options.values = null;
  352. } else if ( value === "max" ) {
  353. this.options.value = this._values( this.options.values.length - 1 );
  354. this.options.values = null;
  355. }
  356. }
  357. if ( Array.isArray( this.options.values ) ) {
  358. valsLength = this.options.values.length;
  359. }
  360. this._super( key, value );
  361. switch ( key ) {
  362. case "orientation":
  363. this._detectOrientation();
  364. this._removeClass( "ui-slider-horizontal ui-slider-vertical" )
  365. ._addClass( "ui-slider-" + this.orientation );
  366. this._refreshValue();
  367. if ( this.options.range ) {
  368. this._refreshRange( value );
  369. }
  370. // Reset positioning from previous orientation
  371. this.handles.css( value === "horizontal" ? "bottom" : "left", "" );
  372. break;
  373. case "value":
  374. this._animateOff = true;
  375. this._refreshValue();
  376. this._change( null, 0 );
  377. this._animateOff = false;
  378. break;
  379. case "values":
  380. this._animateOff = true;
  381. this._refreshValue();
  382. // Start from the last handle to prevent unreachable handles (#9046)
  383. for ( i = valsLength - 1; i >= 0; i-- ) {
  384. this._change( null, i );
  385. }
  386. this._animateOff = false;
  387. break;
  388. case "step":
  389. case "min":
  390. case "max":
  391. this._animateOff = true;
  392. this._calculateNewMax();
  393. this._refreshValue();
  394. this._animateOff = false;
  395. break;
  396. case "range":
  397. this._animateOff = true;
  398. this._refresh();
  399. this._animateOff = false;
  400. break;
  401. }
  402. },
  403. _setOptionDisabled: function( value ) {
  404. this._super( value );
  405. this._toggleClass( null, "ui-state-disabled", !!value );
  406. },
  407. //internal value getter
  408. // _value() returns value trimmed by min and max, aligned by step
  409. _value: function() {
  410. var val = this.options.value;
  411. val = this._trimAlignValue( val );
  412. return val;
  413. },
  414. //internal values getter
  415. // _values() returns array of values trimmed by min and max, aligned by step
  416. // _values( index ) returns single value trimmed by min and max, aligned by step
  417. _values: function( index ) {
  418. var val,
  419. vals,
  420. i;
  421. if ( arguments.length ) {
  422. val = this.options.values[ index ];
  423. val = this._trimAlignValue( val );
  424. return val;
  425. } else if ( this._hasMultipleValues() ) {
  426. // .slice() creates a copy of the array
  427. // this copy gets trimmed by min and max and then returned
  428. vals = this.options.values.slice();
  429. for ( i = 0; i < vals.length; i += 1 ) {
  430. vals[ i ] = this._trimAlignValue( vals[ i ] );
  431. }
  432. return vals;
  433. } else {
  434. return [];
  435. }
  436. },
  437. // Returns the step-aligned value that val is closest to, between (inclusive) min and max
  438. _trimAlignValue: function( val ) {
  439. if ( val <= this._valueMin() ) {
  440. return this._valueMin();
  441. }
  442. if ( val >= this._valueMax() ) {
  443. return this._valueMax();
  444. }
  445. var step = ( this.options.step > 0 ) ? this.options.step : 1,
  446. valModStep = ( val - this._valueMin() ) % step,
  447. alignValue = val - valModStep;
  448. if ( Math.abs( valModStep ) * 2 >= step ) {
  449. alignValue += ( valModStep > 0 ) ? step : ( -step );
  450. }
  451. // Since JavaScript has problems with large floats, round
  452. // the final value to 5 digits after the decimal point (see #4124)
  453. return parseFloat( alignValue.toFixed( 5 ) );
  454. },
  455. _calculateNewMax: function() {
  456. var max = this.options.max,
  457. min = this._valueMin(),
  458. step = this.options.step,
  459. aboveMin = Math.round( ( max - min ) / step ) * step;
  460. max = aboveMin + min;
  461. if ( max > this.options.max ) {
  462. //If max is not divisible by step, rounding off may increase its value
  463. max -= step;
  464. }
  465. this.max = parseFloat( max.toFixed( this._precision() ) );
  466. },
  467. _precision: function() {
  468. var precision = this._precisionOf( this.options.step );
  469. if ( this.options.min !== null ) {
  470. precision = Math.max( precision, this._precisionOf( this.options.min ) );
  471. }
  472. return precision;
  473. },
  474. _precisionOf: function( num ) {
  475. var str = num.toString(),
  476. decimal = str.indexOf( "." );
  477. return decimal === -1 ? 0 : str.length - decimal - 1;
  478. },
  479. _valueMin: function() {
  480. return this.options.min;
  481. },
  482. _valueMax: function() {
  483. return this.max;
  484. },
  485. _refreshRange: function( orientation ) {
  486. if ( orientation === "vertical" ) {
  487. this.range.css( { "width": "", "left": "" } );
  488. }
  489. if ( orientation === "horizontal" ) {
  490. this.range.css( { "height": "", "bottom": "" } );
  491. }
  492. },
  493. _refreshValue: function() {
  494. var lastValPercent, valPercent, value, valueMin, valueMax,
  495. oRange = this.options.range,
  496. o = this.options,
  497. that = this,
  498. animate = ( !this._animateOff ) ? o.animate : false,
  499. _set = {};
  500. if ( this._hasMultipleValues() ) {
  501. this.handles.each( function( i ) {
  502. valPercent = ( that.values( i ) - that._valueMin() ) / ( that._valueMax() -
  503. that._valueMin() ) * 100;
  504. _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
  505. $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
  506. if ( that.options.range === true ) {
  507. if ( that.orientation === "horizontal" ) {
  508. if ( i === 0 ) {
  509. that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
  510. left: valPercent + "%"
  511. }, o.animate );
  512. }
  513. if ( i === 1 ) {
  514. that.range[ animate ? "animate" : "css" ]( {
  515. width: ( valPercent - lastValPercent ) + "%"
  516. }, {
  517. queue: false,
  518. duration: o.animate
  519. } );
  520. }
  521. } else {
  522. if ( i === 0 ) {
  523. that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
  524. bottom: ( valPercent ) + "%"
  525. }, o.animate );
  526. }
  527. if ( i === 1 ) {
  528. that.range[ animate ? "animate" : "css" ]( {
  529. height: ( valPercent - lastValPercent ) + "%"
  530. }, {
  531. queue: false,
  532. duration: o.animate
  533. } );
  534. }
  535. }
  536. }
  537. lastValPercent = valPercent;
  538. } );
  539. } else {
  540. value = this.value();
  541. valueMin = this._valueMin();
  542. valueMax = this._valueMax();
  543. valPercent = ( valueMax !== valueMin ) ?
  544. ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
  545. 0;
  546. _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
  547. this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
  548. if ( oRange === "min" && this.orientation === "horizontal" ) {
  549. this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
  550. width: valPercent + "%"
  551. }, o.animate );
  552. }
  553. if ( oRange === "max" && this.orientation === "horizontal" ) {
  554. this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
  555. width: ( 100 - valPercent ) + "%"
  556. }, o.animate );
  557. }
  558. if ( oRange === "min" && this.orientation === "vertical" ) {
  559. this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
  560. height: valPercent + "%"
  561. }, o.animate );
  562. }
  563. if ( oRange === "max" && this.orientation === "vertical" ) {
  564. this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
  565. height: ( 100 - valPercent ) + "%"
  566. }, o.animate );
  567. }
  568. }
  569. },
  570. _handleEvents: {
  571. keydown: function( event ) {
  572. var allowed, curVal, newVal, step,
  573. index = $( event.target ).data( "ui-slider-handle-index" );
  574. switch ( event.keyCode ) {
  575. case $.ui.keyCode.HOME:
  576. case $.ui.keyCode.END:
  577. case $.ui.keyCode.PAGE_UP:
  578. case $.ui.keyCode.PAGE_DOWN:
  579. case $.ui.keyCode.UP:
  580. case $.ui.keyCode.RIGHT:
  581. case $.ui.keyCode.DOWN:
  582. case $.ui.keyCode.LEFT:
  583. event.preventDefault();
  584. if ( !this._keySliding ) {
  585. this._keySliding = true;
  586. this._addClass( $( event.target ), null, "ui-state-active" );
  587. allowed = this._start( event, index );
  588. if ( allowed === false ) {
  589. return;
  590. }
  591. }
  592. break;
  593. }
  594. step = this.options.step;
  595. if ( this._hasMultipleValues() ) {
  596. curVal = newVal = this.values( index );
  597. } else {
  598. curVal = newVal = this.value();
  599. }
  600. switch ( event.keyCode ) {
  601. case $.ui.keyCode.HOME:
  602. newVal = this._valueMin();
  603. break;
  604. case $.ui.keyCode.END:
  605. newVal = this._valueMax();
  606. break;
  607. case $.ui.keyCode.PAGE_UP:
  608. newVal = this._trimAlignValue(
  609. curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages )
  610. );
  611. break;
  612. case $.ui.keyCode.PAGE_DOWN:
  613. newVal = this._trimAlignValue(
  614. curVal - ( ( this._valueMax() - this._valueMin() ) / this.numPages ) );
  615. break;
  616. case $.ui.keyCode.UP:
  617. case $.ui.keyCode.RIGHT:
  618. if ( curVal === this._valueMax() ) {
  619. return;
  620. }
  621. newVal = this._trimAlignValue( curVal + step );
  622. break;
  623. case $.ui.keyCode.DOWN:
  624. case $.ui.keyCode.LEFT:
  625. if ( curVal === this._valueMin() ) {
  626. return;
  627. }
  628. newVal = this._trimAlignValue( curVal - step );
  629. break;
  630. }
  631. this._slide( event, index, newVal );
  632. },
  633. keyup: function( event ) {
  634. var index = $( event.target ).data( "ui-slider-handle-index" );
  635. if ( this._keySliding ) {
  636. this._keySliding = false;
  637. this._stop( event, index );
  638. this._change( event, index );
  639. this._removeClass( $( event.target ), null, "ui-state-active" );
  640. }
  641. }
  642. }
  643. } );
  644. } );