jquery-ui.js 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735
  1. /*! jQuery UI - v1.12.1 - 2018-01-21
  2. * http://jqueryui.com
  3. * Includes: widget.js, keycode.js, widgets/mouse.js, widgets/slider.js
  4. * Copyright jQuery Foundation and other contributors; Licensed MIT */
  5. (function( factory ) {
  6. if ( typeof define === "function" && define.amd ) {
  7. // AMD. Register as an anonymous module.
  8. define([ "jquery" ], factory );
  9. } else {
  10. // Browser globals
  11. factory( jQuery );
  12. }
  13. }(function( $ ) {
  14. $.ui = $.ui || {};
  15. var version = $.ui.version = "1.12.1";
  16. /*!
  17. * jQuery UI Widget 1.12.1
  18. * http://jqueryui.com
  19. *
  20. * Copyright jQuery Foundation and other contributors
  21. * Released under the MIT license.
  22. * http://jquery.org/license
  23. */
  24. //>>label: Widget
  25. //>>group: Core
  26. //>>description: Provides a factory for creating stateful widgets with a common API.
  27. //>>docs: http://api.jqueryui.com/jQuery.widget/
  28. //>>demos: http://jqueryui.com/widget/
  29. var widgetUuid = 0;
  30. var widgetSlice = Array.prototype.slice;
  31. $.cleanData = ( function( orig ) {
  32. return function( elems ) {
  33. var events, elem, i;
  34. for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) {
  35. try {
  36. // Only trigger remove when necessary to save time
  37. events = $._data( elem, "events" );
  38. if ( events && events.remove ) {
  39. $( elem ).triggerHandler( "remove" );
  40. }
  41. // Http://bugs.jquery.com/ticket/8235
  42. } catch ( e ) {}
  43. }
  44. orig( elems );
  45. };
  46. } )( $.cleanData );
  47. $.widget = function( name, base, prototype ) {
  48. var existingConstructor, constructor, basePrototype;
  49. // ProxiedPrototype allows the provided prototype to remain unmodified
  50. // so that it can be used as a mixin for multiple widgets (#8876)
  51. var proxiedPrototype = {};
  52. var namespace = name.split( "." )[ 0 ];
  53. name = name.split( "." )[ 1 ];
  54. var fullName = namespace + "-" + name;
  55. if ( !prototype ) {
  56. prototype = base;
  57. base = $.Widget;
  58. }
  59. if ( $.isArray( prototype ) ) {
  60. prototype = $.extend.apply( null, [ {} ].concat( prototype ) );
  61. }
  62. // Create selector for plugin
  63. $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
  64. return !!$.data( elem, fullName );
  65. };
  66. $[ namespace ] = $[ namespace ] || {};
  67. existingConstructor = $[ namespace ][ name ];
  68. constructor = $[ namespace ][ name ] = function( options, element ) {
  69. // Allow instantiation without "new" keyword
  70. if ( !this._createWidget ) {
  71. return new constructor( options, element );
  72. }
  73. // Allow instantiation without initializing for simple inheritance
  74. // must use "new" keyword (the code above always passes args)
  75. if ( arguments.length ) {
  76. this._createWidget( options, element );
  77. }
  78. };
  79. // Extend with the existing constructor to carry over any static properties
  80. $.extend( constructor, existingConstructor, {
  81. version: prototype.version,
  82. // Copy the object used to create the prototype in case we need to
  83. // redefine the widget later
  84. _proto: $.extend( {}, prototype ),
  85. // Track widgets that inherit from this widget in case this widget is
  86. // redefined after a widget inherits from it
  87. _childConstructors: []
  88. } );
  89. basePrototype = new base();
  90. // We need to make the options hash a property directly on the new instance
  91. // otherwise we'll modify the options hash on the prototype that we're
  92. // inheriting from
  93. basePrototype.options = $.widget.extend( {}, basePrototype.options );
  94. $.each( prototype, function( prop, value ) {
  95. if ( !$.isFunction( value ) ) {
  96. proxiedPrototype[ prop ] = value;
  97. return;
  98. }
  99. proxiedPrototype[ prop ] = ( function() {
  100. function _super() {
  101. return base.prototype[ prop ].apply( this, arguments );
  102. }
  103. function _superApply( args ) {
  104. return base.prototype[ prop ].apply( this, args );
  105. }
  106. return function() {
  107. var __super = this._super;
  108. var __superApply = this._superApply;
  109. var returnValue;
  110. this._super = _super;
  111. this._superApply = _superApply;
  112. returnValue = value.apply( this, arguments );
  113. this._super = __super;
  114. this._superApply = __superApply;
  115. return returnValue;
  116. };
  117. } )();
  118. } );
  119. constructor.prototype = $.widget.extend( basePrototype, {
  120. // TODO: remove support for widgetEventPrefix
  121. // always use the name + a colon as the prefix, e.g., draggable:start
  122. // don't prefix for widgets that aren't DOM-based
  123. widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name
  124. }, proxiedPrototype, {
  125. constructor: constructor,
  126. namespace: namespace,
  127. widgetName: name,
  128. widgetFullName: fullName
  129. } );
  130. // If this widget is being redefined then we need to find all widgets that
  131. // are inheriting from it and redefine all of them so that they inherit from
  132. // the new version of this widget. We're essentially trying to replace one
  133. // level in the prototype chain.
  134. if ( existingConstructor ) {
  135. $.each( existingConstructor._childConstructors, function( i, child ) {
  136. var childPrototype = child.prototype;
  137. // Redefine the child widget using the same prototype that was
  138. // originally used, but inherit from the new version of the base
  139. $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor,
  140. child._proto );
  141. } );
  142. // Remove the list of existing child constructors from the old constructor
  143. // so the old child constructors can be garbage collected
  144. delete existingConstructor._childConstructors;
  145. } else {
  146. base._childConstructors.push( constructor );
  147. }
  148. $.widget.bridge( name, constructor );
  149. return constructor;
  150. };
  151. $.widget.extend = function( target ) {
  152. var input = widgetSlice.call( arguments, 1 );
  153. var inputIndex = 0;
  154. var inputLength = input.length;
  155. var key;
  156. var value;
  157. for ( ; inputIndex < inputLength; inputIndex++ ) {
  158. for ( key in input[ inputIndex ] ) {
  159. value = input[ inputIndex ][ key ];
  160. if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
  161. // Clone objects
  162. if ( $.isPlainObject( value ) ) {
  163. target[ key ] = $.isPlainObject( target[ key ] ) ?
  164. $.widget.extend( {}, target[ key ], value ) :
  165. // Don't extend strings, arrays, etc. with objects
  166. $.widget.extend( {}, value );
  167. // Copy everything else by reference
  168. } else {
  169. target[ key ] = value;
  170. }
  171. }
  172. }
  173. }
  174. return target;
  175. };
  176. $.widget.bridge = function( name, object ) {
  177. var fullName = object.prototype.widgetFullName || name;
  178. $.fn[ name ] = function( options ) {
  179. var isMethodCall = typeof options === "string";
  180. var args = widgetSlice.call( arguments, 1 );
  181. var returnValue = this;
  182. if ( isMethodCall ) {
  183. // If this is an empty collection, we need to have the instance method
  184. // return undefined instead of the jQuery instance
  185. if ( !this.length && options === "instance" ) {
  186. returnValue = undefined;
  187. } else {
  188. this.each( function() {
  189. var methodValue;
  190. var instance = $.data( this, fullName );
  191. if ( options === "instance" ) {
  192. returnValue = instance;
  193. return false;
  194. }
  195. if ( !instance ) {
  196. return $.error( "cannot call methods on " + name +
  197. " prior to initialization; " +
  198. "attempted to call method '" + options + "'" );
  199. }
  200. if ( !$.isFunction( instance[ options ] ) || options.charAt( 0 ) === "_" ) {
  201. return $.error( "no such method '" + options + "' for " + name +
  202. " widget instance" );
  203. }
  204. methodValue = instance[ options ].apply( instance, args );
  205. if ( methodValue !== instance && methodValue !== undefined ) {
  206. returnValue = methodValue && methodValue.jquery ?
  207. returnValue.pushStack( methodValue.get() ) :
  208. methodValue;
  209. return false;
  210. }
  211. } );
  212. }
  213. } else {
  214. // Allow multiple hashes to be passed on init
  215. if ( args.length ) {
  216. options = $.widget.extend.apply( null, [ options ].concat( args ) );
  217. }
  218. this.each( function() {
  219. var instance = $.data( this, fullName );
  220. if ( instance ) {
  221. instance.option( options || {} );
  222. if ( instance._init ) {
  223. instance._init();
  224. }
  225. } else {
  226. $.data( this, fullName, new object( options, this ) );
  227. }
  228. } );
  229. }
  230. return returnValue;
  231. };
  232. };
  233. $.Widget = function( /* options, element */ ) {};
  234. $.Widget._childConstructors = [];
  235. $.Widget.prototype = {
  236. widgetName: "widget",
  237. widgetEventPrefix: "",
  238. defaultElement: "<div>",
  239. options: {
  240. classes: {},
  241. disabled: false,
  242. // Callbacks
  243. create: null
  244. },
  245. _createWidget: function( options, element ) {
  246. element = $( element || this.defaultElement || this )[ 0 ];
  247. this.element = $( element );
  248. this.uuid = widgetUuid++;
  249. this.eventNamespace = "." + this.widgetName + this.uuid;
  250. this.bindings = $();
  251. this.hoverable = $();
  252. this.focusable = $();
  253. this.classesElementLookup = {};
  254. if ( element !== this ) {
  255. $.data( element, this.widgetFullName, this );
  256. this._on( true, this.element, {
  257. remove: function( event ) {
  258. if ( event.target === element ) {
  259. this.destroy();
  260. }
  261. }
  262. } );
  263. this.document = $( element.style ?
  264. // Element within the document
  265. element.ownerDocument :
  266. // Element is window or document
  267. element.document || element );
  268. this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow );
  269. }
  270. this.options = $.widget.extend( {},
  271. this.options,
  272. this._getCreateOptions(),
  273. options );
  274. this._create();
  275. if ( this.options.disabled ) {
  276. this._setOptionDisabled( this.options.disabled );
  277. }
  278. this._trigger( "create", null, this._getCreateEventData() );
  279. this._init();
  280. },
  281. _getCreateOptions: function() {
  282. return {};
  283. },
  284. _getCreateEventData: $.noop,
  285. _create: $.noop,
  286. _init: $.noop,
  287. destroy: function() {
  288. var that = this;
  289. this._destroy();
  290. $.each( this.classesElementLookup, function( key, value ) {
  291. that._removeClass( value, key );
  292. } );
  293. // We can probably remove the unbind calls in 2.0
  294. // all event bindings should go through this._on()
  295. this.element
  296. .off( this.eventNamespace )
  297. .removeData( this.widgetFullName );
  298. this.widget()
  299. .off( this.eventNamespace )
  300. .removeAttr( "aria-disabled" );
  301. // Clean up events and states
  302. this.bindings.off( this.eventNamespace );
  303. },
  304. _destroy: $.noop,
  305. widget: function() {
  306. return this.element;
  307. },
  308. option: function( key, value ) {
  309. var options = key;
  310. var parts;
  311. var curOption;
  312. var i;
  313. if ( arguments.length === 0 ) {
  314. // Don't return a reference to the internal hash
  315. return $.widget.extend( {}, this.options );
  316. }
  317. if ( typeof key === "string" ) {
  318. // Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
  319. options = {};
  320. parts = key.split( "." );
  321. key = parts.shift();
  322. if ( parts.length ) {
  323. curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
  324. for ( i = 0; i < parts.length - 1; i++ ) {
  325. curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
  326. curOption = curOption[ parts[ i ] ];
  327. }
  328. key = parts.pop();
  329. if ( arguments.length === 1 ) {
  330. return curOption[ key ] === undefined ? null : curOption[ key ];
  331. }
  332. curOption[ key ] = value;
  333. } else {
  334. if ( arguments.length === 1 ) {
  335. return this.options[ key ] === undefined ? null : this.options[ key ];
  336. }
  337. options[ key ] = value;
  338. }
  339. }
  340. this._setOptions( options );
  341. return this;
  342. },
  343. _setOptions: function( options ) {
  344. var key;
  345. for ( key in options ) {
  346. this._setOption( key, options[ key ] );
  347. }
  348. return this;
  349. },
  350. _setOption: function( key, value ) {
  351. if ( key === "classes" ) {
  352. this._setOptionClasses( value );
  353. }
  354. this.options[ key ] = value;
  355. if ( key === "disabled" ) {
  356. this._setOptionDisabled( value );
  357. }
  358. return this;
  359. },
  360. _setOptionClasses: function( value ) {
  361. var classKey, elements, currentElements;
  362. for ( classKey in value ) {
  363. currentElements = this.classesElementLookup[ classKey ];
  364. if ( value[ classKey ] === this.options.classes[ classKey ] ||
  365. !currentElements ||
  366. !currentElements.length ) {
  367. continue;
  368. }
  369. // We are doing this to create a new jQuery object because the _removeClass() call
  370. // on the next line is going to destroy the reference to the current elements being
  371. // tracked. We need to save a copy of this collection so that we can add the new classes
  372. // below.
  373. elements = $( currentElements.get() );
  374. this._removeClass( currentElements, classKey );
  375. // We don't use _addClass() here, because that uses this.options.classes
  376. // for generating the string of classes. We want to use the value passed in from
  377. // _setOption(), this is the new value of the classes option which was passed to
  378. // _setOption(). We pass this value directly to _classes().
  379. elements.addClass( this._classes( {
  380. element: elements,
  381. keys: classKey,
  382. classes: value,
  383. add: true
  384. } ) );
  385. }
  386. },
  387. _setOptionDisabled: function( value ) {
  388. this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value );
  389. // If the widget is becoming disabled, then nothing is interactive
  390. if ( value ) {
  391. this._removeClass( this.hoverable, null, "ui-state-hover" );
  392. this._removeClass( this.focusable, null, "ui-state-focus" );
  393. }
  394. },
  395. enable: function() {
  396. return this._setOptions( { disabled: false } );
  397. },
  398. disable: function() {
  399. return this._setOptions( { disabled: true } );
  400. },
  401. _classes: function( options ) {
  402. var full = [];
  403. var that = this;
  404. options = $.extend( {
  405. element: this.element,
  406. classes: this.options.classes || {}
  407. }, options );
  408. function processClassString( classes, checkOption ) {
  409. var current, i;
  410. for ( i = 0; i < classes.length; i++ ) {
  411. current = that.classesElementLookup[ classes[ i ] ] || $();
  412. if ( options.add ) {
  413. current = $( $.unique( current.get().concat( options.element.get() ) ) );
  414. } else {
  415. current = $( current.not( options.element ).get() );
  416. }
  417. that.classesElementLookup[ classes[ i ] ] = current;
  418. full.push( classes[ i ] );
  419. if ( checkOption && options.classes[ classes[ i ] ] ) {
  420. full.push( options.classes[ classes[ i ] ] );
  421. }
  422. }
  423. }
  424. this._on( options.element, {
  425. "remove": "_untrackClassesElement"
  426. } );
  427. if ( options.keys ) {
  428. processClassString( options.keys.match( /\S+/g ) || [], true );
  429. }
  430. if ( options.extra ) {
  431. processClassString( options.extra.match( /\S+/g ) || [] );
  432. }
  433. return full.join( " " );
  434. },
  435. _untrackClassesElement: function( event ) {
  436. var that = this;
  437. $.each( that.classesElementLookup, function( key, value ) {
  438. if ( $.inArray( event.target, value ) !== -1 ) {
  439. that.classesElementLookup[ key ] = $( value.not( event.target ).get() );
  440. }
  441. } );
  442. },
  443. _removeClass: function( element, keys, extra ) {
  444. return this._toggleClass( element, keys, extra, false );
  445. },
  446. _addClass: function( element, keys, extra ) {
  447. return this._toggleClass( element, keys, extra, true );
  448. },
  449. _toggleClass: function( element, keys, extra, add ) {
  450. add = ( typeof add === "boolean" ) ? add : extra;
  451. var shift = ( typeof element === "string" || element === null ),
  452. options = {
  453. extra: shift ? keys : extra,
  454. keys: shift ? element : keys,
  455. element: shift ? this.element : element,
  456. add: add
  457. };
  458. options.element.toggleClass( this._classes( options ), add );
  459. return this;
  460. },
  461. _on: function( suppressDisabledCheck, element, handlers ) {
  462. var delegateElement;
  463. var instance = this;
  464. // No suppressDisabledCheck flag, shuffle arguments
  465. if ( typeof suppressDisabledCheck !== "boolean" ) {
  466. handlers = element;
  467. element = suppressDisabledCheck;
  468. suppressDisabledCheck = false;
  469. }
  470. // No element argument, shuffle and use this.element
  471. if ( !handlers ) {
  472. handlers = element;
  473. element = this.element;
  474. delegateElement = this.widget();
  475. } else {
  476. element = delegateElement = $( element );
  477. this.bindings = this.bindings.add( element );
  478. }
  479. $.each( handlers, function( event, handler ) {
  480. function handlerProxy() {
  481. // Allow widgets to customize the disabled handling
  482. // - disabled as an array instead of boolean
  483. // - disabled class as method for disabling individual parts
  484. if ( !suppressDisabledCheck &&
  485. ( instance.options.disabled === true ||
  486. $( this ).hasClass( "ui-state-disabled" ) ) ) {
  487. return;
  488. }
  489. return ( typeof handler === "string" ? instance[ handler ] : handler )
  490. .apply( instance, arguments );
  491. }
  492. // Copy the guid so direct unbinding works
  493. if ( typeof handler !== "string" ) {
  494. handlerProxy.guid = handler.guid =
  495. handler.guid || handlerProxy.guid || $.guid++;
  496. }
  497. var match = event.match( /^([\w:-]*)\s*(.*)$/ );
  498. var eventName = match[ 1 ] + instance.eventNamespace;
  499. var selector = match[ 2 ];
  500. if ( selector ) {
  501. delegateElement.on( eventName, selector, handlerProxy );
  502. } else {
  503. element.on( eventName, handlerProxy );
  504. }
  505. } );
  506. },
  507. _off: function( element, eventName ) {
  508. eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) +
  509. this.eventNamespace;
  510. element.off( eventName ).off( eventName );
  511. // Clear the stack to avoid memory leaks (#10056)
  512. this.bindings = $( this.bindings.not( element ).get() );
  513. this.focusable = $( this.focusable.not( element ).get() );
  514. this.hoverable = $( this.hoverable.not( element ).get() );
  515. },
  516. _delay: function( handler, delay ) {
  517. function handlerProxy() {
  518. return ( typeof handler === "string" ? instance[ handler ] : handler )
  519. .apply( instance, arguments );
  520. }
  521. var instance = this;
  522. return setTimeout( handlerProxy, delay || 0 );
  523. },
  524. _hoverable: function( element ) {
  525. this.hoverable = this.hoverable.add( element );
  526. this._on( element, {
  527. mouseenter: function( event ) {
  528. this._addClass( $( event.currentTarget ), null, "ui-state-hover" );
  529. },
  530. mouseleave: function( event ) {
  531. this._removeClass( $( event.currentTarget ), null, "ui-state-hover" );
  532. }
  533. } );
  534. },
  535. _focusable: function( element ) {
  536. this.focusable = this.focusable.add( element );
  537. this._on( element, {
  538. focusin: function( event ) {
  539. this._addClass( $( event.currentTarget ), null, "ui-state-focus" );
  540. },
  541. focusout: function( event ) {
  542. this._removeClass( $( event.currentTarget ), null, "ui-state-focus" );
  543. }
  544. } );
  545. },
  546. _trigger: function( type, event, data ) {
  547. var prop, orig;
  548. var callback = this.options[ type ];
  549. data = data || {};
  550. event = $.Event( event );
  551. event.type = ( type === this.widgetEventPrefix ?
  552. type :
  553. this.widgetEventPrefix + type ).toLowerCase();
  554. // The original event may come from any element
  555. // so we need to reset the target on the new event
  556. event.target = this.element[ 0 ];
  557. // Copy original event properties over to the new event
  558. orig = event.originalEvent;
  559. if ( orig ) {
  560. for ( prop in orig ) {
  561. if ( !( prop in event ) ) {
  562. event[ prop ] = orig[ prop ];
  563. }
  564. }
  565. }
  566. this.element.trigger( event, data );
  567. return !( $.isFunction( callback ) &&
  568. callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false ||
  569. event.isDefaultPrevented() );
  570. }
  571. };
  572. $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
  573. $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
  574. if ( typeof options === "string" ) {
  575. options = { effect: options };
  576. }
  577. var hasOptions;
  578. var effectName = !options ?
  579. method :
  580. options === true || typeof options === "number" ?
  581. defaultEffect :
  582. options.effect || defaultEffect;
  583. options = options || {};
  584. if ( typeof options === "number" ) {
  585. options = { duration: options };
  586. }
  587. hasOptions = !$.isEmptyObject( options );
  588. options.complete = callback;
  589. if ( options.delay ) {
  590. element.delay( options.delay );
  591. }
  592. if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
  593. element[ method ]( options );
  594. } else if ( effectName !== method && element[ effectName ] ) {
  595. element[ effectName ]( options.duration, options.easing, callback );
  596. } else {
  597. element.queue( function( next ) {
  598. $( this )[ method ]();
  599. if ( callback ) {
  600. callback.call( element[ 0 ] );
  601. }
  602. next();
  603. } );
  604. }
  605. };
  606. } );
  607. var widget = $.widget;
  608. /*!
  609. * jQuery UI Keycode 1.12.1
  610. * http://jqueryui.com
  611. *
  612. * Copyright jQuery Foundation and other contributors
  613. * Released under the MIT license.
  614. * http://jquery.org/license
  615. */
  616. //>>label: Keycode
  617. //>>group: Core
  618. //>>description: Provide keycodes as keynames
  619. //>>docs: http://api.jqueryui.com/jQuery.ui.keyCode/
  620. var keycode = $.ui.keyCode = {
  621. BACKSPACE: 8,
  622. COMMA: 188,
  623. DELETE: 46,
  624. DOWN: 40,
  625. END: 35,
  626. ENTER: 13,
  627. ESCAPE: 27,
  628. HOME: 36,
  629. LEFT: 37,
  630. PAGE_DOWN: 34,
  631. PAGE_UP: 33,
  632. PERIOD: 190,
  633. RIGHT: 39,
  634. SPACE: 32,
  635. TAB: 9,
  636. UP: 38
  637. };
  638. // This file is deprecated
  639. var ie = $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
  640. /*!
  641. * jQuery UI Mouse 1.12.1
  642. * http://jqueryui.com
  643. *
  644. * Copyright jQuery Foundation and other contributors
  645. * Released under the MIT license.
  646. * http://jquery.org/license
  647. */
  648. //>>label: Mouse
  649. //>>group: Widgets
  650. //>>description: Abstracts mouse-based interactions to assist in creating certain widgets.
  651. //>>docs: http://api.jqueryui.com/mouse/
  652. var mouseHandled = false;
  653. $( document ).on( "mouseup", function() {
  654. mouseHandled = false;
  655. } );
  656. var widgetsMouse = $.widget( "ui.mouse", {
  657. version: "1.12.1",
  658. options: {
  659. cancel: "input, textarea, button, select, option",
  660. distance: 1,
  661. delay: 0
  662. },
  663. _mouseInit: function() {
  664. var that = this;
  665. this.element
  666. .on( "mousedown." + this.widgetName, function( event ) {
  667. return that._mouseDown( event );
  668. } )
  669. .on( "click." + this.widgetName, function( event ) {
  670. if ( true === $.data( event.target, that.widgetName + ".preventClickEvent" ) ) {
  671. $.removeData( event.target, that.widgetName + ".preventClickEvent" );
  672. event.stopImmediatePropagation();
  673. return false;
  674. }
  675. } );
  676. this.started = false;
  677. },
  678. // TODO: make sure destroying one instance of mouse doesn't mess with
  679. // other instances of mouse
  680. _mouseDestroy: function() {
  681. this.element.off( "." + this.widgetName );
  682. if ( this._mouseMoveDelegate ) {
  683. this.document
  684. .off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
  685. .off( "mouseup." + this.widgetName, this._mouseUpDelegate );
  686. }
  687. },
  688. _mouseDown: function( event ) {
  689. // don't let more than one widget handle mouseStart
  690. if ( mouseHandled ) {
  691. return;
  692. }
  693. this._mouseMoved = false;
  694. // We may have missed mouseup (out of window)
  695. ( this._mouseStarted && this._mouseUp( event ) );
  696. this._mouseDownEvent = event;
  697. var that = this,
  698. btnIsLeft = ( event.which === 1 ),
  699. // event.target.nodeName works around a bug in IE 8 with
  700. // disabled inputs (#7620)
  701. elIsCancel = ( typeof this.options.cancel === "string" && event.target.nodeName ?
  702. $( event.target ).closest( this.options.cancel ).length : false );
  703. if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) {
  704. return true;
  705. }
  706. this.mouseDelayMet = !this.options.delay;
  707. if ( !this.mouseDelayMet ) {
  708. this._mouseDelayTimer = setTimeout( function() {
  709. that.mouseDelayMet = true;
  710. }, this.options.delay );
  711. }
  712. if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
  713. this._mouseStarted = ( this._mouseStart( event ) !== false );
  714. if ( !this._mouseStarted ) {
  715. event.preventDefault();
  716. return true;
  717. }
  718. }
  719. // Click event may never have fired (Gecko & Opera)
  720. if ( true === $.data( event.target, this.widgetName + ".preventClickEvent" ) ) {
  721. $.removeData( event.target, this.widgetName + ".preventClickEvent" );
  722. }
  723. // These delegates are required to keep context
  724. this._mouseMoveDelegate = function( event ) {
  725. return that._mouseMove( event );
  726. };
  727. this._mouseUpDelegate = function( event ) {
  728. return that._mouseUp( event );
  729. };
  730. this.document
  731. .on( "mousemove." + this.widgetName, this._mouseMoveDelegate )
  732. .on( "mouseup." + this.widgetName, this._mouseUpDelegate );
  733. event.preventDefault();
  734. mouseHandled = true;
  735. return true;
  736. },
  737. _mouseMove: function( event ) {
  738. // Only check for mouseups outside the document if you've moved inside the document
  739. // at least once. This prevents the firing of mouseup in the case of IE<9, which will
  740. // fire a mousemove event if content is placed under the cursor. See #7778
  741. // Support: IE <9
  742. if ( this._mouseMoved ) {
  743. // IE mouseup check - mouseup happened when mouse was out of window
  744. if ( $.ui.ie && ( !document.documentMode || document.documentMode < 9 ) &&
  745. !event.button ) {
  746. return this._mouseUp( event );
  747. // Iframe mouseup check - mouseup occurred in another document
  748. } else if ( !event.which ) {
  749. // Support: Safari <=8 - 9
  750. // Safari sets which to 0 if you press any of the following keys
  751. // during a drag (#14461)
  752. if ( event.originalEvent.altKey || event.originalEvent.ctrlKey ||
  753. event.originalEvent.metaKey || event.originalEvent.shiftKey ) {
  754. this.ignoreMissingWhich = true;
  755. } else if ( !this.ignoreMissingWhich ) {
  756. return this._mouseUp( event );
  757. }
  758. }
  759. }
  760. if ( event.which || event.button ) {
  761. this._mouseMoved = true;
  762. }
  763. if ( this._mouseStarted ) {
  764. this._mouseDrag( event );
  765. return event.preventDefault();
  766. }
  767. if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
  768. this._mouseStarted =
  769. ( this._mouseStart( this._mouseDownEvent, event ) !== false );
  770. ( this._mouseStarted ? this._mouseDrag( event ) : this._mouseUp( event ) );
  771. }
  772. return !this._mouseStarted;
  773. },
  774. _mouseUp: function( event ) {
  775. this.document
  776. .off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
  777. .off( "mouseup." + this.widgetName, this._mouseUpDelegate );
  778. if ( this._mouseStarted ) {
  779. this._mouseStarted = false;
  780. if ( event.target === this._mouseDownEvent.target ) {
  781. $.data( event.target, this.widgetName + ".preventClickEvent", true );
  782. }
  783. this._mouseStop( event );
  784. }
  785. if ( this._mouseDelayTimer ) {
  786. clearTimeout( this._mouseDelayTimer );
  787. delete this._mouseDelayTimer;
  788. }
  789. this.ignoreMissingWhich = false;
  790. mouseHandled = false;
  791. event.preventDefault();
  792. },
  793. _mouseDistanceMet: function( event ) {
  794. return ( Math.max(
  795. Math.abs( this._mouseDownEvent.pageX - event.pageX ),
  796. Math.abs( this._mouseDownEvent.pageY - event.pageY )
  797. ) >= this.options.distance
  798. );
  799. },
  800. _mouseDelayMet: function( /* event */ ) {
  801. return this.mouseDelayMet;
  802. },
  803. // These are placeholder methods, to be overriden by extending plugin
  804. _mouseStart: function( /* event */ ) {},
  805. _mouseDrag: function( /* event */ ) {},
  806. _mouseStop: function( /* event */ ) {},
  807. _mouseCapture: function( /* event */ ) { return true; }
  808. } );
  809. /*!
  810. * jQuery UI Slider 1.12.1
  811. * http://jqueryui.com
  812. *
  813. * Copyright jQuery Foundation and other contributors
  814. * Released under the MIT license.
  815. * http://jquery.org/license
  816. */
  817. //>>label: Slider
  818. //>>group: Widgets
  819. //>>description: Displays a flexible slider with ranges and accessibility via keyboard.
  820. //>>docs: http://api.jqueryui.com/slider/
  821. //>>demos: http://jqueryui.com/slider/
  822. //>>css.structure: ../../themes/base/core.css
  823. //>>css.structure: ../../themes/base/slider.css
  824. //>>css.theme: ../../themes/base/theme.css
  825. var widgetsSlider = $.widget( "ui.slider", $.ui.mouse, {
  826. version: "1.12.1",
  827. widgetEventPrefix: "slide",
  828. options: {
  829. animate: false,
  830. classes: {
  831. "ui-slider": "ui-corner-all",
  832. "ui-slider-handle": "ui-corner-all",
  833. // Note: ui-widget-header isn't the most fittingly semantic framework class for this
  834. // element, but worked best visually with a variety of themes
  835. "ui-slider-range": "ui-corner-all ui-widget-header"
  836. },
  837. distance: 0,
  838. max: 100,
  839. min: 0,
  840. orientation: "horizontal",
  841. range: false,
  842. step: 1,
  843. value: 0,
  844. values: null,
  845. // Callbacks
  846. change: null,
  847. slide: null,
  848. start: null,
  849. stop: null
  850. },
  851. // Number of pages in a slider
  852. // (how many times can you page up/down to go through the whole range)
  853. numPages: 5,
  854. _create: function() {
  855. this._keySliding = false;
  856. this._mouseSliding = false;
  857. this._animateOff = true;
  858. this._handleIndex = null;
  859. this._detectOrientation();
  860. this._mouseInit();
  861. this._calculateNewMax();
  862. this._addClass( "ui-slider ui-slider-" + this.orientation,
  863. "ui-widget ui-widget-content" );
  864. this._refresh();
  865. this._animateOff = false;
  866. },
  867. _refresh: function() {
  868. this._createRange();
  869. this._createHandles();
  870. this._setupEvents();
  871. this._refreshValue();
  872. },
  873. _createHandles: function() {
  874. var i, handleCount,
  875. options = this.options,
  876. existingHandles = this.element.find( ".ui-slider-handle" ),
  877. handle = "<span tabindex='0'></span>",
  878. handles = [];
  879. handleCount = ( options.values && options.values.length ) || 1;
  880. if ( existingHandles.length > handleCount ) {
  881. existingHandles.slice( handleCount ).remove();
  882. existingHandles = existingHandles.slice( 0, handleCount );
  883. }
  884. for ( i = existingHandles.length; i < handleCount; i++ ) {
  885. handles.push( handle );
  886. }
  887. this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
  888. this._addClass( this.handles, "ui-slider-handle", "ui-state-default" );
  889. this.handle = this.handles.eq( 0 );
  890. this.handles.each( function( i ) {
  891. $( this )
  892. .data( "ui-slider-handle-index", i )
  893. .attr( "tabIndex", 0 );
  894. } );
  895. },
  896. _createRange: function() {
  897. var options = this.options;
  898. if ( options.range ) {
  899. if ( options.range === true ) {
  900. if ( !options.values ) {
  901. options.values = [ this._valueMin(), this._valueMin() ];
  902. } else if ( options.values.length && options.values.length !== 2 ) {
  903. options.values = [ options.values[ 0 ], options.values[ 0 ] ];
  904. } else if ( $.isArray( options.values ) ) {
  905. options.values = options.values.slice( 0 );
  906. }
  907. }
  908. if ( !this.range || !this.range.length ) {
  909. this.range = $( "<div>" )
  910. .appendTo( this.element );
  911. this._addClass( this.range, "ui-slider-range" );
  912. } else {
  913. this._removeClass( this.range, "ui-slider-range-min ui-slider-range-max" );
  914. // Handle range switching from true to min/max
  915. this.range.css( {
  916. "left": "",
  917. "bottom": ""
  918. } );
  919. }
  920. if ( options.range === "min" || options.range === "max" ) {
  921. this._addClass( this.range, "ui-slider-range-" + options.range );
  922. }
  923. } else {
  924. if ( this.range ) {
  925. this.range.remove();
  926. }
  927. this.range = null;
  928. }
  929. },
  930. _setupEvents: function() {
  931. this._off( this.handles );
  932. this._on( this.handles, this._handleEvents );
  933. this._hoverable( this.handles );
  934. this._focusable( this.handles );
  935. },
  936. _destroy: function() {
  937. this.handles.remove();
  938. if ( this.range ) {
  939. this.range.remove();
  940. }
  941. this._mouseDestroy();
  942. },
  943. _mouseCapture: function( event ) {
  944. var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
  945. that = this,
  946. o = this.options;
  947. if ( o.disabled ) {
  948. return false;
  949. }
  950. this.elementSize = {
  951. width: this.element.outerWidth(),
  952. height: this.element.outerHeight()
  953. };
  954. this.elementOffset = this.element.offset();
  955. position = { x: event.pageX, y: event.pageY };
  956. normValue = this._normValueFromMouse( position );
  957. distance = this._valueMax() - this._valueMin() + 1;
  958. this.handles.each( function( i ) {
  959. var thisDistance = Math.abs( normValue - that.values( i ) );
  960. if ( ( distance > thisDistance ) ||
  961. ( distance === thisDistance &&
  962. ( i === that._lastChangedValue || that.values( i ) === o.min ) ) ) {
  963. distance = thisDistance;
  964. closestHandle = $( this );
  965. index = i;
  966. }
  967. } );
  968. allowed = this._start( event, index );
  969. if ( allowed === false ) {
  970. return false;
  971. }
  972. this._mouseSliding = true;
  973. this._handleIndex = index;
  974. this._addClass( closestHandle, null, "ui-state-active" );
  975. closestHandle.trigger( "focus" );
  976. offset = closestHandle.offset();
  977. mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
  978. this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
  979. left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
  980. top: event.pageY - offset.top -
  981. ( closestHandle.height() / 2 ) -
  982. ( parseInt( closestHandle.css( "borderTopWidth" ), 10 ) || 0 ) -
  983. ( parseInt( closestHandle.css( "borderBottomWidth" ), 10 ) || 0 ) +
  984. ( parseInt( closestHandle.css( "marginTop" ), 10 ) || 0 )
  985. };
  986. if ( !this.handles.hasClass( "ui-state-hover" ) ) {
  987. this._slide( event, index, normValue );
  988. }
  989. this._animateOff = true;
  990. return true;
  991. },
  992. _mouseStart: function() {
  993. return true;
  994. },
  995. _mouseDrag: function( event ) {
  996. var position = { x: event.pageX, y: event.pageY },
  997. normValue = this._normValueFromMouse( position );
  998. this._slide( event, this._handleIndex, normValue );
  999. return false;
  1000. },
  1001. _mouseStop: function( event ) {
  1002. this._removeClass( this.handles, null, "ui-state-active" );
  1003. this._mouseSliding = false;
  1004. this._stop( event, this._handleIndex );
  1005. this._change( event, this._handleIndex );
  1006. this._handleIndex = null;
  1007. this._clickOffset = null;
  1008. this._animateOff = false;
  1009. return false;
  1010. },
  1011. _detectOrientation: function() {
  1012. this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
  1013. },
  1014. _normValueFromMouse: function( position ) {
  1015. var pixelTotal,
  1016. pixelMouse,
  1017. percentMouse,
  1018. valueTotal,
  1019. valueMouse;
  1020. if ( this.orientation === "horizontal" ) {
  1021. pixelTotal = this.elementSize.width;
  1022. pixelMouse = position.x - this.elementOffset.left -
  1023. ( this._clickOffset ? this._clickOffset.left : 0 );
  1024. } else {
  1025. pixelTotal = this.elementSize.height;
  1026. pixelMouse = position.y - this.elementOffset.top -
  1027. ( this._clickOffset ? this._clickOffset.top : 0 );
  1028. }
  1029. percentMouse = ( pixelMouse / pixelTotal );
  1030. if ( percentMouse > 1 ) {
  1031. percentMouse = 1;
  1032. }
  1033. if ( percentMouse < 0 ) {
  1034. percentMouse = 0;
  1035. }
  1036. if ( this.orientation === "vertical" ) {
  1037. percentMouse = 1 - percentMouse;
  1038. }
  1039. valueTotal = this._valueMax() - this._valueMin();
  1040. valueMouse = this._valueMin() + percentMouse * valueTotal;
  1041. return this._trimAlignValue( valueMouse );
  1042. },
  1043. _uiHash: function( index, value, values ) {
  1044. var uiHash = {
  1045. handle: this.handles[ index ],
  1046. handleIndex: index,
  1047. value: value !== undefined ? value : this.value()
  1048. };
  1049. if ( this._hasMultipleValues() ) {
  1050. uiHash.value = value !== undefined ? value : this.values( index );
  1051. uiHash.values = values || this.values();
  1052. }
  1053. return uiHash;
  1054. },
  1055. _hasMultipleValues: function() {
  1056. return this.options.values && this.options.values.length;
  1057. },
  1058. _start: function( event, index ) {
  1059. return this._trigger( "start", event, this._uiHash( index ) );
  1060. },
  1061. _slide: function( event, index, newVal ) {
  1062. var allowed, otherVal,
  1063. currentValue = this.value(),
  1064. newValues = this.values();
  1065. if ( this._hasMultipleValues() ) {
  1066. otherVal = this.values( index ? 0 : 1 );
  1067. currentValue = this.values( index );
  1068. if ( this.options.values.length === 2 && this.options.range === true ) {
  1069. newVal = index === 0 ? Math.min( otherVal, newVal ) : Math.max( otherVal, newVal );
  1070. }
  1071. newValues[ index ] = newVal;
  1072. }
  1073. if ( newVal === currentValue ) {
  1074. return;
  1075. }
  1076. allowed = this._trigger( "slide", event, this._uiHash( index, newVal, newValues ) );
  1077. // A slide can be canceled by returning false from the slide callback
  1078. if ( allowed === false ) {
  1079. return;
  1080. }
  1081. if ( this._hasMultipleValues() ) {
  1082. this.values( index, newVal );
  1083. } else {
  1084. this.value( newVal );
  1085. }
  1086. },
  1087. _stop: function( event, index ) {
  1088. this._trigger( "stop", event, this._uiHash( index ) );
  1089. },
  1090. _change: function( event, index ) {
  1091. if ( !this._keySliding && !this._mouseSliding ) {
  1092. //store the last changed value index for reference when handles overlap
  1093. this._lastChangedValue = index;
  1094. this._trigger( "change", event, this._uiHash( index ) );
  1095. }
  1096. },
  1097. value: function( newValue ) {
  1098. if ( arguments.length ) {
  1099. this.options.value = this._trimAlignValue( newValue );
  1100. this._refreshValue();
  1101. this._change( null, 0 );
  1102. return;
  1103. }
  1104. return this._value();
  1105. },
  1106. values: function( index, newValue ) {
  1107. var vals,
  1108. newValues,
  1109. i;
  1110. if ( arguments.length > 1 ) {
  1111. this.options.values[ index ] = this._trimAlignValue( newValue );
  1112. this._refreshValue();
  1113. this._change( null, index );
  1114. return;
  1115. }
  1116. if ( arguments.length ) {
  1117. if ( $.isArray( arguments[ 0 ] ) ) {
  1118. vals = this.options.values;
  1119. newValues = arguments[ 0 ];
  1120. for ( i = 0; i < vals.length; i += 1 ) {
  1121. vals[ i ] = this._trimAlignValue( newValues[ i ] );
  1122. this._change( null, i );
  1123. }
  1124. this._refreshValue();
  1125. } else {
  1126. if ( this._hasMultipleValues() ) {
  1127. return this._values( index );
  1128. } else {
  1129. return this.value();
  1130. }
  1131. }
  1132. } else {
  1133. return this._values();
  1134. }
  1135. },
  1136. _setOption: function( key, value ) {
  1137. var i,
  1138. valsLength = 0;
  1139. if ( key === "range" && this.options.range === true ) {
  1140. if ( value === "min" ) {
  1141. this.options.value = this._values( 0 );
  1142. this.options.values = null;
  1143. } else if ( value === "max" ) {
  1144. this.options.value = this._values( this.options.values.length - 1 );
  1145. this.options.values = null;
  1146. }
  1147. }
  1148. if ( $.isArray( this.options.values ) ) {
  1149. valsLength = this.options.values.length;
  1150. }
  1151. this._super( key, value );
  1152. switch ( key ) {
  1153. case "orientation":
  1154. this._detectOrientation();
  1155. this._removeClass( "ui-slider-horizontal ui-slider-vertical" )
  1156. ._addClass( "ui-slider-" + this.orientation );
  1157. this._refreshValue();
  1158. if ( this.options.range ) {
  1159. this._refreshRange( value );
  1160. }
  1161. // Reset positioning from previous orientation
  1162. this.handles.css( value === "horizontal" ? "bottom" : "left", "" );
  1163. break;
  1164. case "value":
  1165. this._animateOff = true;
  1166. this._refreshValue();
  1167. this._change( null, 0 );
  1168. this._animateOff = false;
  1169. break;
  1170. case "values":
  1171. this._animateOff = true;
  1172. this._refreshValue();
  1173. // Start from the last handle to prevent unreachable handles (#9046)
  1174. for ( i = valsLength - 1; i >= 0; i-- ) {
  1175. this._change( null, i );
  1176. }
  1177. this._animateOff = false;
  1178. break;
  1179. case "step":
  1180. case "min":
  1181. case "max":
  1182. this._animateOff = true;
  1183. this._calculateNewMax();
  1184. this._refreshValue();
  1185. this._animateOff = false;
  1186. break;
  1187. case "range":
  1188. this._animateOff = true;
  1189. this._refresh();
  1190. this._animateOff = false;
  1191. break;
  1192. }
  1193. },
  1194. _setOptionDisabled: function( value ) {
  1195. this._super( value );
  1196. this._toggleClass( null, "ui-state-disabled", !!value );
  1197. },
  1198. //internal value getter
  1199. // _value() returns value trimmed by min and max, aligned by step
  1200. _value: function() {
  1201. var val = this.options.value;
  1202. val = this._trimAlignValue( val );
  1203. return val;
  1204. },
  1205. //internal values getter
  1206. // _values() returns array of values trimmed by min and max, aligned by step
  1207. // _values( index ) returns single value trimmed by min and max, aligned by step
  1208. _values: function( index ) {
  1209. var val,
  1210. vals,
  1211. i;
  1212. if ( arguments.length ) {
  1213. val = this.options.values[ index ];
  1214. val = this._trimAlignValue( val );
  1215. return val;
  1216. } else if ( this._hasMultipleValues() ) {
  1217. // .slice() creates a copy of the array
  1218. // this copy gets trimmed by min and max and then returned
  1219. vals = this.options.values.slice();
  1220. for ( i = 0; i < vals.length; i += 1 ) {
  1221. vals[ i ] = this._trimAlignValue( vals[ i ] );
  1222. }
  1223. return vals;
  1224. } else {
  1225. return [];
  1226. }
  1227. },
  1228. // Returns the step-aligned value that val is closest to, between (inclusive) min and max
  1229. _trimAlignValue: function( val ) {
  1230. if ( val <= this._valueMin() ) {
  1231. return this._valueMin();
  1232. }
  1233. if ( val >= this._valueMax() ) {
  1234. return this._valueMax();
  1235. }
  1236. var step = ( this.options.step > 0 ) ? this.options.step : 1,
  1237. valModStep = ( val - this._valueMin() ) % step,
  1238. alignValue = val - valModStep;
  1239. if ( Math.abs( valModStep ) * 2 >= step ) {
  1240. alignValue += ( valModStep > 0 ) ? step : ( -step );
  1241. }
  1242. // Since JavaScript has problems with large floats, round
  1243. // the final value to 5 digits after the decimal point (see #4124)
  1244. return parseFloat( alignValue.toFixed( 5 ) );
  1245. },
  1246. _calculateNewMax: function() {
  1247. var max = this.options.max,
  1248. min = this._valueMin(),
  1249. step = this.options.step,
  1250. aboveMin = Math.round( ( max - min ) / step ) * step;
  1251. max = aboveMin + min;
  1252. if ( max > this.options.max ) {
  1253. //If max is not divisible by step, rounding off may increase its value
  1254. max -= step;
  1255. }
  1256. this.max = parseFloat( max.toFixed( this._precision() ) );
  1257. },
  1258. _precision: function() {
  1259. var precision = this._precisionOf( this.options.step );
  1260. if ( this.options.min !== null ) {
  1261. precision = Math.max( precision, this._precisionOf( this.options.min ) );
  1262. }
  1263. return precision;
  1264. },
  1265. _precisionOf: function( num ) {
  1266. var str = num.toString(),
  1267. decimal = str.indexOf( "." );
  1268. return decimal === -1 ? 0 : str.length - decimal - 1;
  1269. },
  1270. _valueMin: function() {
  1271. return this.options.min;
  1272. },
  1273. _valueMax: function() {
  1274. return this.max;
  1275. },
  1276. _refreshRange: function( orientation ) {
  1277. if ( orientation === "vertical" ) {
  1278. this.range.css( { "width": "", "left": "" } );
  1279. }
  1280. if ( orientation === "horizontal" ) {
  1281. this.range.css( { "height": "", "bottom": "" } );
  1282. }
  1283. },
  1284. _refreshValue: function() {
  1285. var lastValPercent, valPercent, value, valueMin, valueMax,
  1286. oRange = this.options.range,
  1287. o = this.options,
  1288. that = this,
  1289. animate = ( !this._animateOff ) ? o.animate : false,
  1290. _set = {};
  1291. if ( this._hasMultipleValues() ) {
  1292. this.handles.each( function( i ) {
  1293. valPercent = ( that.values( i ) - that._valueMin() ) / ( that._valueMax() -
  1294. that._valueMin() ) * 100;
  1295. _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
  1296. $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
  1297. if ( that.options.range === true ) {
  1298. if ( that.orientation === "horizontal" ) {
  1299. if ( i === 0 ) {
  1300. that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
  1301. left: valPercent + "%"
  1302. }, o.animate );
  1303. }
  1304. if ( i === 1 ) {
  1305. that.range[ animate ? "animate" : "css" ]( {
  1306. width: ( valPercent - lastValPercent ) + "%"
  1307. }, {
  1308. queue: false,
  1309. duration: o.animate
  1310. } );
  1311. }
  1312. } else {
  1313. if ( i === 0 ) {
  1314. that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
  1315. bottom: ( valPercent ) + "%"
  1316. }, o.animate );
  1317. }
  1318. if ( i === 1 ) {
  1319. that.range[ animate ? "animate" : "css" ]( {
  1320. height: ( valPercent - lastValPercent ) + "%"
  1321. }, {
  1322. queue: false,
  1323. duration: o.animate
  1324. } );
  1325. }
  1326. }
  1327. }
  1328. lastValPercent = valPercent;
  1329. } );
  1330. } else {
  1331. value = this.value();
  1332. valueMin = this._valueMin();
  1333. valueMax = this._valueMax();
  1334. valPercent = ( valueMax !== valueMin ) ?
  1335. ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
  1336. 0;
  1337. _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
  1338. this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
  1339. if ( oRange === "min" && this.orientation === "horizontal" ) {
  1340. this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
  1341. width: valPercent + "%"
  1342. }, o.animate );
  1343. }
  1344. if ( oRange === "max" && this.orientation === "horizontal" ) {
  1345. this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
  1346. width: ( 100 - valPercent ) + "%"
  1347. }, o.animate );
  1348. }
  1349. if ( oRange === "min" && this.orientation === "vertical" ) {
  1350. this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
  1351. height: valPercent + "%"
  1352. }, o.animate );
  1353. }
  1354. if ( oRange === "max" && this.orientation === "vertical" ) {
  1355. this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
  1356. height: ( 100 - valPercent ) + "%"
  1357. }, o.animate );
  1358. }
  1359. }
  1360. },
  1361. _handleEvents: {
  1362. keydown: function( event ) {
  1363. var allowed, curVal, newVal, step,
  1364. index = $( event.target ).data( "ui-slider-handle-index" );
  1365. switch ( event.keyCode ) {
  1366. case $.ui.keyCode.HOME:
  1367. case $.ui.keyCode.END:
  1368. case $.ui.keyCode.PAGE_UP:
  1369. case $.ui.keyCode.PAGE_DOWN:
  1370. case $.ui.keyCode.UP:
  1371. case $.ui.keyCode.RIGHT:
  1372. case $.ui.keyCode.DOWN:
  1373. case $.ui.keyCode.LEFT:
  1374. event.preventDefault();
  1375. if ( !this._keySliding ) {
  1376. this._keySliding = true;
  1377. this._addClass( $( event.target ), null, "ui-state-active" );
  1378. allowed = this._start( event, index );
  1379. if ( allowed === false ) {
  1380. return;
  1381. }
  1382. }
  1383. break;
  1384. }
  1385. step = this.options.step;
  1386. if ( this._hasMultipleValues() ) {
  1387. curVal = newVal = this.values( index );
  1388. } else {
  1389. curVal = newVal = this.value();
  1390. }
  1391. switch ( event.keyCode ) {
  1392. case $.ui.keyCode.HOME:
  1393. newVal = this._valueMin();
  1394. break;
  1395. case $.ui.keyCode.END:
  1396. newVal = this._valueMax();
  1397. break;
  1398. case $.ui.keyCode.PAGE_UP:
  1399. newVal = this._trimAlignValue(
  1400. curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages )
  1401. );
  1402. break;
  1403. case $.ui.keyCode.PAGE_DOWN:
  1404. newVal = this._trimAlignValue(
  1405. curVal - ( ( this._valueMax() - this._valueMin() ) / this.numPages ) );
  1406. break;
  1407. case $.ui.keyCode.UP:
  1408. case $.ui.keyCode.RIGHT:
  1409. if ( curVal === this._valueMax() ) {
  1410. return;
  1411. }
  1412. newVal = this._trimAlignValue( curVal + step );
  1413. break;
  1414. case $.ui.keyCode.DOWN:
  1415. case $.ui.keyCode.LEFT:
  1416. if ( curVal === this._valueMin() ) {
  1417. return;
  1418. }
  1419. newVal = this._trimAlignValue( curVal - step );
  1420. break;
  1421. }
  1422. this._slide( event, index, newVal );
  1423. },
  1424. keyup: function( event ) {
  1425. var index = $( event.target ).data( "ui-slider-handle-index" );
  1426. if ( this._keySliding ) {
  1427. this._keySliding = false;
  1428. this._stop( event, index );
  1429. this._change( event, index );
  1430. this._removeClass( $( event.target ), null, "ui-state-active" );
  1431. }
  1432. }
  1433. }
  1434. } );
  1435. }));