You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

901 lines
27 KiB

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
  1. /*
  2. * # Semantic - Dropdown
  3. * http://github.com/jlukic/semantic-ui/
  4. *
  5. *
  6. * Copyright 2013 Contributors
  7. * Released under the MIT license
  8. * http://opensource.org/licenses/MIT
  9. *
  10. */
  11. ;(function ( $, window, document, undefined ) {
  12. $.fn.dropdown = function(parameters) {
  13. var
  14. $allModules = $(this),
  15. $document = $(document),
  16. moduleSelector = $allModules.selector || '',
  17. hasTouch = ('ontouchstart' in document.documentElement),
  18. time = new Date().getTime(),
  19. performance = [],
  20. query = arguments[0],
  21. methodInvoked = (typeof query == 'string'),
  22. queryArguments = [].slice.call(arguments, 1),
  23. returnedValue
  24. ;
  25. $allModules
  26. .each(function() {
  27. var
  28. settings = ( $.isPlainObject(parameters) )
  29. ? $.extend(true, {}, $.fn.dropdown.settings, parameters)
  30. : $.extend({}, $.fn.dropdown.settings),
  31. className = settings.className,
  32. metadata = settings.metadata,
  33. namespace = settings.namespace,
  34. selector = settings.selector,
  35. error = settings.error,
  36. eventNamespace = '.' + namespace,
  37. moduleNamespace = 'module-' + namespace,
  38. $module = $(this),
  39. $item = $module.find(selector.item),
  40. $text = $module.find(selector.text),
  41. $input = $module.find(selector.input),
  42. $menu = $module.children(selector.menu),
  43. element = this,
  44. instance = $module.data(moduleNamespace),
  45. module
  46. ;
  47. module = {
  48. initialize: function() {
  49. module.debug('Initializing dropdown', settings);
  50. module.save.defaults();
  51. module.set.selected();
  52. if(hasTouch) {
  53. module.bind.touchEvents();
  54. }
  55. module.bind.mouseEvents();
  56. module.instantiate();
  57. },
  58. instantiate: function() {
  59. module.verbose('Storing instance of dropdown', module);
  60. instance = module;
  61. $module
  62. .data(moduleNamespace, module)
  63. ;
  64. },
  65. destroy: function() {
  66. module.verbose('Destroying previous dropdown for', $module);
  67. $item
  68. .off(eventNamespace)
  69. ;
  70. $module
  71. .off(eventNamespace)
  72. .removeData(moduleNamespace)
  73. ;
  74. },
  75. bind: {
  76. touchEvents: function() {
  77. module.debug('Touch device detected binding touch events');
  78. $module
  79. .on('touchstart' + eventNamespace, module.event.test.toggle)
  80. ;
  81. $item
  82. .on('touchstart' + eventNamespace, module.event.item.mouseenter)
  83. .on('touchstart' + eventNamespace, module.event.item.click)
  84. ;
  85. },
  86. mouseEvents: function() {
  87. module.verbose('Mouse detected binding mouse events');
  88. if(settings.on == 'click') {
  89. $module
  90. .on('click' + eventNamespace, module.event.test.toggle)
  91. ;
  92. }
  93. else if(settings.on == 'hover') {
  94. $module
  95. .on('mouseenter' + eventNamespace, module.delay.show)
  96. .on('mouseleave' + eventNamespace, module.delay.hide)
  97. ;
  98. }
  99. else {
  100. $module
  101. .on(settings.on + eventNamespace, module.toggle)
  102. ;
  103. }
  104. $item
  105. .on('mouseenter' + eventNamespace, module.event.item.mouseenter)
  106. .on('mouseleave' + eventNamespace, module.event.item.mouseleave)
  107. .on('click' + eventNamespace, module.event.item.click)
  108. ;
  109. },
  110. intent: function() {
  111. module.verbose('Binding hide intent event to document');
  112. if(hasTouch) {
  113. $document
  114. .on('touchstart' + eventNamespace, module.event.test.touch)
  115. .on('touchmove' + eventNamespace, module.event.test.touch)
  116. ;
  117. }
  118. $document
  119. .on('click' + eventNamespace, module.event.test.hide)
  120. ;
  121. }
  122. },
  123. unbind: {
  124. intent: function() {
  125. module.verbose('Removing hide intent event from document');
  126. if(hasTouch) {
  127. $document
  128. .off('touchstart' + eventNamespace)
  129. .off('touchmove' + eventNamespace)
  130. ;
  131. }
  132. $document
  133. .off('click' + eventNamespace)
  134. ;
  135. }
  136. },
  137. event: {
  138. test: {
  139. toggle: function(event) {
  140. if( module.determine.intent(event, module.toggle) ) {
  141. event.preventDefault();
  142. }
  143. },
  144. touch: function(event) {
  145. module.determine.intent(event, function() {
  146. if(event.type == 'touchstart') {
  147. module.timer = setTimeout(module.hide, settings.delay.touch);
  148. }
  149. else if(event.type == 'touchmove') {
  150. clearTimeout(module.timer);
  151. }
  152. });
  153. event.stopPropagation();
  154. },
  155. hide: function(event) {
  156. module.determine.intent(event, module.hide);
  157. }
  158. },
  159. item: {
  160. mouseenter: function(event) {
  161. var
  162. $currentMenu = $(this).find(selector.menu),
  163. $otherMenus = $(this).siblings(selector.item).children(selector.menu)
  164. ;
  165. if( $currentMenu.size() > 0 ) {
  166. clearTimeout(module.itemTimer);
  167. module.itemTimer = setTimeout(function() {
  168. module.animate.hide(false, $otherMenus);
  169. module.verbose('Showing sub-menu', $currentMenu);
  170. module.animate.show(false, $currentMenu);
  171. }, settings.delay.show * 2);
  172. event.preventDefault();
  173. }
  174. },
  175. mouseleave: function(event) {
  176. var
  177. $currentMenu = $(this).find(selector.menu)
  178. ;
  179. if($currentMenu.size() > 0) {
  180. clearTimeout(module.itemTimer);
  181. module.itemTimer = setTimeout(function() {
  182. module.verbose('Hiding sub-menu', $currentMenu);
  183. module.animate.hide(false, $currentMenu);
  184. }, settings.delay.hide);
  185. }
  186. },
  187. click: function (event) {
  188. var
  189. $choice = $(this),
  190. text = ( $choice.data(metadata.text) !== undefined )
  191. ? $choice.data(metadata.text)
  192. : $choice.text(),
  193. value = ( $choice.data(metadata.value) !== undefined)
  194. ? $choice.data(metadata.value)
  195. : text.toLowerCase(),
  196. callback = function() {
  197. module.determine.selectAction(text, value);
  198. $.proxy(settings.onChange, element)(value, text);
  199. }
  200. ;
  201. if( $choice.find(selector.menu).size() === 0 ) {
  202. if(event.type == 'touchstart') {
  203. $choice.one('click', callback);
  204. }
  205. else {
  206. callback();
  207. }
  208. }
  209. }
  210. },
  211. resetStyle: function() {
  212. $(this).removeAttr('style');
  213. }
  214. },
  215. determine: {
  216. selectAction: function(text, value) {
  217. module.verbose('Determining action', settings.action);
  218. if( $.isFunction( module.action[settings.action] ) ) {
  219. module.verbose('Triggering preset action', settings.action, text, value);
  220. module.action[ settings.action ](text, value);
  221. }
  222. else if( $.isFunction(settings.action) ) {
  223. module.verbose('Triggering user action', settings.action, text, value);
  224. settings.action(text, value);
  225. }
  226. else {
  227. module.error(error.action, settings.action);
  228. }
  229. },
  230. intent: function(event, callback) {
  231. module.debug('Determining whether event occurred in dropdown', event.target);
  232. callback = callback || function(){};
  233. if( $(event.target).closest($menu).size() === 0 ) {
  234. module.verbose('Triggering event', callback);
  235. callback();
  236. return true;
  237. }
  238. else {
  239. module.verbose('Event occurred in dropdown, canceling callback');
  240. return false;
  241. }
  242. }
  243. },
  244. action: {
  245. nothing: function() {},
  246. hide: function() {
  247. module.hide();
  248. },
  249. activate: function(text, value) {
  250. value = (value !== undefined)
  251. ? value
  252. : text
  253. ;
  254. module.set.selected(value);
  255. module.set.value(value);
  256. module.hide();
  257. },
  258. /* Deprecated */
  259. auto: function(text, value) {
  260. value = (value !== undefined)
  261. ? value
  262. : text
  263. ;
  264. module.set.selected(value);
  265. module.set.value(value);
  266. module.hide();
  267. },
  268. /* Deprecated */
  269. changeText: function(text, value) {
  270. value = (value !== undefined)
  271. ? value
  272. : text
  273. ;
  274. module.set.selected(value);
  275. module.hide();
  276. },
  277. /* Deprecated */
  278. updateForm: function(text, value) {
  279. value = (value !== undefined)
  280. ? value
  281. : text
  282. ;
  283. module.set.selected(value);
  284. module.set.value(value);
  285. module.hide();
  286. }
  287. },
  288. get: {
  289. text: function() {
  290. return $text.text();
  291. },
  292. value: function() {
  293. return ($input.size() > 0)
  294. ? $input.val()
  295. : $module.data(metadata.value)
  296. ;
  297. },
  298. item: function(value) {
  299. var
  300. $selectedItem = false
  301. ;
  302. value = (value !== undefined)
  303. ? value
  304. : ( module.get.value() !== undefined)
  305. ? module.get.value()
  306. : module.get.text()
  307. ;
  308. if(value !== undefined) {
  309. $item
  310. .each(function() {
  311. var
  312. $choice = $(this),
  313. optionText = ( $choice.data(metadata.text) !== undefined )
  314. ? $choice.data(metadata.text)
  315. : $choice.text(),
  316. optionValue = ( $choice.data(metadata.value) !== undefined )
  317. ? $choice.data(metadata.value)
  318. : optionText.toLowerCase()
  319. ;
  320. if( optionValue == value ) {
  321. $selectedItem = $(this);
  322. }
  323. else if( !$selectedItem && optionText == value ) {
  324. $selectedItem = $(this);
  325. }
  326. })
  327. ;
  328. }
  329. else {
  330. value = module.get.text();
  331. }
  332. return $selectedItem || false;
  333. }
  334. },
  335. restore: {
  336. defaults: function() {
  337. module.restore.defaultText();
  338. module.restore.defaultValue();
  339. },
  340. defaultText: function() {
  341. var
  342. defaultText = $module.data(metadata.defaultText)
  343. ;
  344. module.debug('Restoring default text', defaultText);
  345. module.set.text(defaultText);
  346. },
  347. defaultValue: function() {
  348. var
  349. defaultValue = $module.data(metadata.defaultValue)
  350. ;
  351. if(defaultValue !== undefined) {
  352. module.debug('Restoring default value', defaultValue);
  353. module.set.selected(defaultValue);
  354. module.set.value(defaultValue);
  355. }
  356. }
  357. },
  358. save: {
  359. defaults: function() {
  360. module.save.defaultText();
  361. module.save.defaultValue();
  362. },
  363. defaultValue: function() {
  364. $module.data(metadata.defaultValue, module.get.value() );
  365. },
  366. defaultText: function() {
  367. $module.data(metadata.defaultText, $text.text() );
  368. }
  369. },
  370. set: {
  371. text: function(text) {
  372. module.debug('Changing text', text, $text);
  373. $text.removeClass(className.placeholder);
  374. $text.text(text);
  375. },
  376. value: function(value) {
  377. module.debug('Adding selected value to hidden input', value, $input);
  378. if($input.size() > 0) {
  379. $input.val(value);
  380. }
  381. else {
  382. $module.data(metadata.value, value);
  383. }
  384. },
  385. active: function() {
  386. $module.addClass(className.active);
  387. },
  388. visible: function() {
  389. $module.addClass(className.visible);
  390. },
  391. selected: function(value) {
  392. var
  393. $selectedItem = module.get.item(value),
  394. selectedText
  395. ;
  396. if($selectedItem) {
  397. module.debug('Setting selected menu item to', $selectedItem);
  398. selectedText = ($selectedItem.data(metadata.text) !== undefined)
  399. ? $selectedItem.data(metadata.text)
  400. : $selectedItem.text()
  401. ;
  402. $item
  403. .removeClass(className.active)
  404. ;
  405. $selectedItem
  406. .addClass(className.active)
  407. ;
  408. module.set.text(selectedText);
  409. }
  410. }
  411. },
  412. remove: {
  413. active: function() {
  414. $module.removeClass(className.active);
  415. },
  416. visible: function() {
  417. $module.removeClass(className.visible);
  418. }
  419. },
  420. is: {
  421. selection: function() {
  422. return $module.hasClass(className.selection);
  423. },
  424. animated: function($subMenu) {
  425. return ($subMenu)
  426. ? $subMenu.is(':animated') || $subMenu.transition('is animating')
  427. : $menu.is(':animated') || $menu.transition('is animating')
  428. ;
  429. },
  430. visible: function($subMenu) {
  431. return ($subMenu)
  432. ? $subMenu.is(':visible')
  433. : $menu.is(':visible')
  434. ;
  435. },
  436. hidden: function($subMenu) {
  437. return ($subMenu)
  438. ? $subMenu.is(':not(:visible)')
  439. : $menu.is(':not(:visible)')
  440. ;
  441. }
  442. },
  443. can: {
  444. click: function() {
  445. return (hasTouch || settings.on == 'click');
  446. },
  447. show: function() {
  448. return !$module.hasClass(className.disabled);
  449. }
  450. },
  451. animate: {
  452. show: function(callback, $subMenu) {
  453. var
  454. $currentMenu = $subMenu || $menu
  455. ;
  456. callback = callback || function(){};
  457. if( module.is.hidden($currentMenu) ) {
  458. module.verbose('Doing menu show animation', $currentMenu);
  459. if(settings.transition == 'none') {
  460. callback();
  461. }
  462. else if($.fn.transition !== undefined && $module.transition('is supported')) {
  463. $currentMenu
  464. .transition({
  465. animation : settings.transition + ' in',
  466. duration : settings.duration,
  467. complete : callback,
  468. queue : false
  469. })
  470. ;
  471. }
  472. else if(settings.transition == 'slide down') {
  473. $currentMenu
  474. .hide()
  475. .clearQueue()
  476. .children()
  477. .clearQueue()
  478. .css('opacity', 0)
  479. .delay(50)
  480. .animate({
  481. opacity : 1
  482. }, settings.duration, 'easeOutQuad', module.event.resetStyle)
  483. .end()
  484. .slideDown(100, 'easeOutQuad', function() {
  485. $.proxy(module.event.resetStyle, this)();
  486. callback();
  487. })
  488. ;
  489. }
  490. else if(settings.transition == 'fade') {
  491. $currentMenu
  492. .hide()
  493. .clearQueue()
  494. .fadeIn(settings.duration, function() {
  495. $.proxy(module.event.resetStyle, this)();
  496. callback();
  497. })
  498. ;
  499. }
  500. else {
  501. module.error(error.transition, settings.transition);
  502. }
  503. }
  504. },
  505. hide: function(callback, $subMenu) {
  506. var
  507. $currentMenu = $subMenu || $menu
  508. ;
  509. callback = callback || function(){};
  510. if(module.is.visible($currentMenu) ) {
  511. module.verbose('Doing menu hide animation', $currentMenu);
  512. if($.fn.transition !== undefined && $module.transition('is supported')) {
  513. $currentMenu
  514. .transition({
  515. animation : settings.transition + ' out',
  516. duration : settings.duration,
  517. complete : callback,
  518. queue : false
  519. })
  520. ;
  521. }
  522. else if(settings.transition == 'none') {
  523. callback();
  524. }
  525. else if(settings.transition == 'slide down') {
  526. $currentMenu
  527. .show()
  528. .clearQueue()
  529. .children()
  530. .clearQueue()
  531. .css('opacity', 1)
  532. .animate({
  533. opacity : 0
  534. }, 100, 'easeOutQuad', module.event.resetStyle)
  535. .end()
  536. .delay(50)
  537. .slideUp(100, 'easeOutQuad', function() {
  538. $.proxy(module.event.resetStyle, this)();
  539. callback();
  540. })
  541. ;
  542. }
  543. else if(settings.transition == 'fade') {
  544. $currentMenu
  545. .show()
  546. .clearQueue()
  547. .fadeOut(150, function() {
  548. $.proxy(module.event.resetStyle, this)();
  549. callback();
  550. })
  551. ;
  552. }
  553. else {
  554. module.error(error.transition);
  555. }
  556. }
  557. }
  558. },
  559. show: function() {
  560. module.debug('Checking if dropdown can show');
  561. if( module.is.hidden() ) {
  562. module.hideOthers();
  563. module.set.active();
  564. module.animate.show(function() {
  565. if( module.can.click() ) {
  566. module.bind.intent();
  567. }
  568. module.set.visible();
  569. });
  570. $.proxy(settings.onShow, element)();
  571. }
  572. },
  573. hide: function() {
  574. if( !module.is.animated() && module.is.visible() ) {
  575. module.debug('Hiding dropdown');
  576. if( module.can.click() ) {
  577. module.unbind.intent();
  578. }
  579. module.remove.active();
  580. module.animate.hide(module.remove.visible);
  581. $.proxy(settings.onHide, element)();
  582. }
  583. },
  584. delay: {
  585. show: function() {
  586. module.verbose('Delaying show event to ensure user intent');
  587. clearTimeout(module.timer);
  588. module.timer = setTimeout(module.show, settings.delay.show);
  589. },
  590. hide: function() {
  591. module.verbose('Delaying hide event to ensure user intent');
  592. clearTimeout(module.timer);
  593. module.timer = setTimeout(module.hide, settings.delay.hide);
  594. }
  595. },
  596. hideOthers: function() {
  597. module.verbose('Finding other dropdowns to hide');
  598. $allModules
  599. .not($module)
  600. .has(selector.menu + ':visible')
  601. .dropdown('hide')
  602. ;
  603. },
  604. toggle: function() {
  605. module.verbose('Toggling menu visibility');
  606. if( module.is.hidden() ) {
  607. module.show();
  608. }
  609. else {
  610. module.hide();
  611. }
  612. },
  613. setting: function(name, value) {
  614. if( $.isPlainObject(name) ) {
  615. $.extend(true, settings, name);
  616. }
  617. else if(value !== undefined) {
  618. settings[name] = value;
  619. }
  620. else {
  621. return settings[name];
  622. }
  623. },
  624. internal: function(name, value) {
  625. if( $.isPlainObject(name) ) {
  626. $.extend(true, module, name);
  627. }
  628. else if(value !== undefined) {
  629. module[name] = value;
  630. }
  631. else {
  632. return module[name];
  633. }
  634. },
  635. debug: function() {
  636. if(settings.debug) {
  637. if(settings.performance) {
  638. module.performance.log(arguments);
  639. }
  640. else {
  641. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  642. module.debug.apply(console, arguments);
  643. }
  644. }
  645. },
  646. verbose: function() {
  647. if(settings.verbose && settings.debug) {
  648. if(settings.performance) {
  649. module.performance.log(arguments);
  650. }
  651. else {
  652. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  653. module.verbose.apply(console, arguments);
  654. }
  655. }
  656. },
  657. error: function() {
  658. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  659. module.error.apply(console, arguments);
  660. },
  661. performance: {
  662. log: function(message) {
  663. var
  664. currentTime,
  665. executionTime,
  666. previousTime
  667. ;
  668. if(settings.performance) {
  669. currentTime = new Date().getTime();
  670. previousTime = time || currentTime;
  671. executionTime = currentTime - previousTime;
  672. time = currentTime;
  673. performance.push({
  674. 'Element' : element,
  675. 'Name' : message[0],
  676. 'Arguments' : [].slice.call(message, 1) || '',
  677. 'Execution Time' : executionTime
  678. });
  679. }
  680. clearTimeout(module.performance.timer);
  681. module.performance.timer = setTimeout(module.performance.display, 100);
  682. },
  683. display: function() {
  684. var
  685. title = settings.name + ':',
  686. totalTime = 0
  687. ;
  688. time = false;
  689. clearTimeout(module.performance.timer);
  690. $.each(performance, function(index, data) {
  691. totalTime += data['Execution Time'];
  692. });
  693. title += ' ' + totalTime + 'ms';
  694. if(moduleSelector) {
  695. title += ' \'' + moduleSelector + '\'';
  696. }
  697. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  698. console.groupCollapsed(title);
  699. if(console.table) {
  700. console.table(performance);
  701. }
  702. else {
  703. $.each(performance, function(index, data) {
  704. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  705. });
  706. }
  707. console.groupEnd();
  708. }
  709. performance = [];
  710. }
  711. },
  712. invoke: function(query, passedArguments, context) {
  713. var
  714. object = instance,
  715. maxDepth,
  716. found,
  717. response
  718. ;
  719. passedArguments = passedArguments || queryArguments;
  720. context = element || context;
  721. if(typeof query == 'string' && object !== undefined) {
  722. query = query.split(/[\. ]/);
  723. maxDepth = query.length - 1;
  724. $.each(query, function(depth, value) {
  725. var camelCaseValue = (depth != maxDepth)
  726. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  727. : query
  728. ;
  729. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  730. object = object[camelCaseValue];
  731. }
  732. else if( object[camelCaseValue] !== undefined ) {
  733. found = object[camelCaseValue];
  734. return false;
  735. }
  736. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  737. object = object[value];
  738. }
  739. else if( object[value] !== undefined ) {
  740. found = object[value];
  741. return false;
  742. }
  743. else {
  744. module.error(error.method, query);
  745. return false;
  746. }
  747. });
  748. }
  749. if ( $.isFunction( found ) ) {
  750. response = found.apply(context, passedArguments);
  751. }
  752. else if(found !== undefined) {
  753. response = found;
  754. }
  755. if($.isArray(returnedValue)) {
  756. returnedValue.push(response);
  757. }
  758. else if(returnedValue !== undefined) {
  759. returnedValue = [returnedValue, response];
  760. }
  761. else if(response !== undefined) {
  762. returnedValue = response;
  763. }
  764. return found;
  765. }
  766. };
  767. if(methodInvoked) {
  768. if(instance === undefined) {
  769. module.initialize();
  770. }
  771. module.invoke(query);
  772. }
  773. else {
  774. if(instance !== undefined) {
  775. module.destroy();
  776. }
  777. module.initialize();
  778. }
  779. })
  780. ;
  781. return (returnedValue)
  782. ? returnedValue
  783. : this
  784. ;
  785. };
  786. $.fn.dropdown.settings = {
  787. name : 'Dropdown',
  788. namespace : 'dropdown',
  789. verbose : true,
  790. debug : true,
  791. performance : true,
  792. on : 'click',
  793. action : 'activate',
  794. delay: {
  795. show : 200,
  796. hide : 300,
  797. touch : 50
  798. },
  799. transition : 'slide down',
  800. duration : 250,
  801. onChange : function(value, text){},
  802. onShow : function(){},
  803. onHide : function(){},
  804. error : {
  805. action : 'You called a dropdown action that was not defined',
  806. method : 'The method you called is not defined.',
  807. transition : 'The requested transition was not found'
  808. },
  809. metadata: {
  810. defaultText : 'defaultText',
  811. defaultValue : 'defaultValue',
  812. text : 'text',
  813. value : 'value'
  814. },
  815. selector : {
  816. menu : '.menu',
  817. item : '.menu > .item',
  818. text : '> .text',
  819. input : '> input[type="hidden"]'
  820. },
  821. className : {
  822. active : 'active',
  823. placeholder : 'default',
  824. disabled : 'disabled',
  825. visible : 'visible',
  826. selection : 'selection'
  827. }
  828. };
  829. // Adds easing
  830. $.extend( $.easing, {
  831. easeOutQuad: function (x, t, b, c, d) {
  832. return -c *(t/=d)*(t-2) + b;
  833. },
  834. });
  835. })( jQuery, window , document );