transition.js 35 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109
  1. /*!
  2. * # Fomantic-UI - Transition
  3. * http://github.com/fomantic/Fomantic-UI/
  4. *
  5. *
  6. * Released under the MIT license
  7. * http://opensource.org/licenses/MIT
  8. *
  9. */
  10. ;(function ($, window, document, undefined) {
  11. 'use strict';
  12. $.isFunction = $.isFunction || function(obj) {
  13. return typeof obj === "function" && typeof obj.nodeType !== "number";
  14. };
  15. window = (typeof window != 'undefined' && window.Math == Math)
  16. ? window
  17. : (typeof self != 'undefined' && self.Math == Math)
  18. ? self
  19. : Function('return this')()
  20. ;
  21. $.fn.transition = function() {
  22. var
  23. $allModules = $(this),
  24. moduleSelector = $allModules.selector || '',
  25. time = new Date().getTime(),
  26. performance = [],
  27. moduleArguments = arguments,
  28. query = moduleArguments[0],
  29. queryArguments = [].slice.call(arguments, 1),
  30. methodInvoked = (typeof query === 'string'),
  31. returnedValue
  32. ;
  33. $allModules
  34. .each(function(index) {
  35. var
  36. $module = $(this),
  37. element = this,
  38. // set at run time
  39. settings,
  40. instance,
  41. error,
  42. className,
  43. metadata,
  44. animationEnd,
  45. moduleNamespace,
  46. eventNamespace,
  47. module
  48. ;
  49. module = {
  50. initialize: function() {
  51. // get full settings
  52. settings = module.get.settings.apply(element, moduleArguments);
  53. // shorthand
  54. className = settings.className;
  55. error = settings.error;
  56. metadata = settings.metadata;
  57. // define namespace
  58. eventNamespace = '.' + settings.namespace;
  59. moduleNamespace = 'module-' + settings.namespace;
  60. instance = $module.data(moduleNamespace) || module;
  61. // get vendor specific events
  62. animationEnd = module.get.animationEndEvent();
  63. if(methodInvoked) {
  64. methodInvoked = module.invoke(query);
  65. }
  66. // method not invoked, lets run an animation
  67. if(methodInvoked === false) {
  68. module.verbose('Converted arguments into settings object', settings);
  69. if(settings.interval) {
  70. module.delay(settings.animate);
  71. }
  72. else {
  73. module.animate();
  74. }
  75. module.instantiate();
  76. }
  77. },
  78. instantiate: function() {
  79. module.verbose('Storing instance of module', module);
  80. instance = module;
  81. $module
  82. .data(moduleNamespace, instance)
  83. ;
  84. },
  85. destroy: function() {
  86. module.verbose('Destroying previous module for', element);
  87. $module
  88. .removeData(moduleNamespace)
  89. ;
  90. },
  91. refresh: function() {
  92. module.verbose('Refreshing display type on next animation');
  93. delete module.displayType;
  94. },
  95. forceRepaint: function() {
  96. module.verbose('Forcing element repaint');
  97. var
  98. $parentElement = $module.parent(),
  99. $nextElement = $module.next()
  100. ;
  101. if($nextElement.length === 0) {
  102. $module.detach().appendTo($parentElement);
  103. }
  104. else {
  105. $module.detach().insertBefore($nextElement);
  106. }
  107. },
  108. repaint: function() {
  109. module.verbose('Repainting element');
  110. var
  111. fakeAssignment = element.offsetWidth
  112. ;
  113. },
  114. delay: function(interval) {
  115. var
  116. direction = module.get.animationDirection(),
  117. shouldReverse,
  118. delay
  119. ;
  120. if(!direction) {
  121. direction = module.can.transition()
  122. ? module.get.direction()
  123. : 'static'
  124. ;
  125. }
  126. interval = (interval !== undefined)
  127. ? interval
  128. : settings.interval
  129. ;
  130. shouldReverse = (settings.reverse == 'auto' && direction == className.outward);
  131. delay = (shouldReverse || settings.reverse == true)
  132. ? ($allModules.length - index) * settings.interval
  133. : index * settings.interval
  134. ;
  135. module.debug('Delaying animation by', delay);
  136. setTimeout(module.animate, delay);
  137. },
  138. animate: function(overrideSettings) {
  139. settings = overrideSettings || settings;
  140. if(!module.is.supported()) {
  141. module.error(error.support);
  142. return false;
  143. }
  144. module.debug('Preparing animation', settings.animation);
  145. if(module.is.animating()) {
  146. if(settings.queue) {
  147. if(!settings.allowRepeats && module.has.direction() && module.is.occurring() && module.queuing !== true) {
  148. module.debug('Animation is currently occurring, preventing queueing same animation', settings.animation);
  149. }
  150. else {
  151. module.queue(settings.animation);
  152. }
  153. return false;
  154. }
  155. else if(!settings.allowRepeats && module.is.occurring()) {
  156. module.debug('Animation is already occurring, will not execute repeated animation', settings.animation);
  157. return false;
  158. }
  159. else {
  160. module.debug('New animation started, completing previous early', settings.animation);
  161. instance.complete();
  162. }
  163. }
  164. if( module.can.animate() ) {
  165. module.set.animating(settings.animation);
  166. }
  167. else {
  168. module.error(error.noAnimation, settings.animation, element);
  169. }
  170. },
  171. reset: function() {
  172. module.debug('Resetting animation to beginning conditions');
  173. module.remove.animationCallbacks();
  174. module.restore.conditions();
  175. module.remove.animating();
  176. },
  177. queue: function(animation) {
  178. module.debug('Queueing animation of', animation);
  179. module.queuing = true;
  180. $module
  181. .one(animationEnd + '.queue' + eventNamespace, function() {
  182. module.queuing = false;
  183. module.repaint();
  184. module.animate.apply(this, settings);
  185. })
  186. ;
  187. },
  188. complete: function (event) {
  189. if(event && event.target === element) {
  190. event.stopPropagation();
  191. }
  192. module.debug('Animation complete', settings.animation);
  193. module.remove.completeCallback();
  194. module.remove.failSafe();
  195. if(!module.is.looping()) {
  196. if( module.is.outward() ) {
  197. module.verbose('Animation is outward, hiding element');
  198. module.restore.conditions();
  199. module.hide();
  200. }
  201. else if( module.is.inward() ) {
  202. module.verbose('Animation is outward, showing element');
  203. module.restore.conditions();
  204. module.show();
  205. }
  206. else {
  207. module.verbose('Static animation completed');
  208. module.restore.conditions();
  209. settings.onComplete.call(element);
  210. }
  211. }
  212. },
  213. force: {
  214. visible: function() {
  215. var
  216. style = $module.attr('style'),
  217. userStyle = module.get.userStyle(style),
  218. displayType = module.get.displayType(),
  219. overrideStyle = userStyle + 'display: ' + displayType + ' !important;',
  220. inlineDisplay = $module[0].style.display,
  221. mustStayHidden = !displayType || (inlineDisplay === 'none' && settings.skipInlineHidden) || $module[0].tagName.match(/(script|link|style)/i)
  222. ;
  223. if (mustStayHidden){
  224. module.remove.transition();
  225. return false;
  226. }
  227. module.verbose('Overriding default display to show element', displayType);
  228. $module
  229. .attr('style', overrideStyle)
  230. ;
  231. return true;
  232. },
  233. hidden: function() {
  234. var
  235. style = $module.attr('style'),
  236. currentDisplay = $module.css('display'),
  237. emptyStyle = (style === undefined || style === '')
  238. ;
  239. if(currentDisplay !== 'none' && !module.is.hidden()) {
  240. module.verbose('Overriding default display to hide element');
  241. $module
  242. .css('display', 'none')
  243. ;
  244. }
  245. else if(emptyStyle) {
  246. $module
  247. .removeAttr('style')
  248. ;
  249. }
  250. }
  251. },
  252. has: {
  253. direction: function(animation) {
  254. var
  255. hasDirection = false
  256. ;
  257. animation = animation || settings.animation;
  258. if(typeof animation === 'string') {
  259. animation = animation.split(' ');
  260. $.each(animation, function(index, word){
  261. if(word === className.inward || word === className.outward) {
  262. hasDirection = true;
  263. }
  264. });
  265. }
  266. return hasDirection;
  267. },
  268. inlineDisplay: function() {
  269. var
  270. style = $module.attr('style') || ''
  271. ;
  272. return Array.isArray(style.match(/display.*?;/, ''));
  273. }
  274. },
  275. set: {
  276. animating: function(animation) {
  277. // remove previous callbacks
  278. module.remove.completeCallback();
  279. // determine exact animation
  280. animation = animation || settings.animation;
  281. var animationClass = module.get.animationClass(animation);
  282. // save animation class in cache to restore class names
  283. module.save.animation(animationClass);
  284. if(module.force.visible()) {
  285. module.remove.hidden();
  286. module.remove.direction();
  287. module.start.animation(animationClass);
  288. }
  289. },
  290. duration: function(animationName, duration) {
  291. duration = duration || settings.duration;
  292. duration = (typeof duration == 'number')
  293. ? duration + 'ms'
  294. : duration
  295. ;
  296. if(duration || duration === 0) {
  297. module.verbose('Setting animation duration', duration);
  298. $module
  299. .css({
  300. 'animation-duration': duration
  301. })
  302. ;
  303. }
  304. },
  305. direction: function(direction) {
  306. direction = direction || module.get.direction();
  307. if(direction == className.inward) {
  308. module.set.inward();
  309. }
  310. else {
  311. module.set.outward();
  312. }
  313. },
  314. looping: function() {
  315. module.debug('Transition set to loop');
  316. $module
  317. .addClass(className.looping)
  318. ;
  319. },
  320. hidden: function() {
  321. $module
  322. .addClass(className.transition)
  323. .addClass(className.hidden)
  324. ;
  325. },
  326. inward: function() {
  327. module.debug('Setting direction to inward');
  328. $module
  329. .removeClass(className.outward)
  330. .addClass(className.inward)
  331. ;
  332. },
  333. outward: function() {
  334. module.debug('Setting direction to outward');
  335. $module
  336. .removeClass(className.inward)
  337. .addClass(className.outward)
  338. ;
  339. },
  340. visible: function() {
  341. $module
  342. .addClass(className.transition)
  343. .addClass(className.visible)
  344. ;
  345. }
  346. },
  347. start: {
  348. animation: function(animationClass) {
  349. animationClass = animationClass || module.get.animationClass();
  350. module.debug('Starting tween', animationClass);
  351. $module
  352. .addClass(animationClass)
  353. .one(animationEnd + '.complete' + eventNamespace, module.complete)
  354. ;
  355. if(settings.useFailSafe) {
  356. module.add.failSafe();
  357. }
  358. module.set.duration(settings.duration);
  359. settings.onStart.call(element);
  360. }
  361. },
  362. save: {
  363. animation: function(animation) {
  364. if(!module.cache) {
  365. module.cache = {};
  366. }
  367. module.cache.animation = animation;
  368. },
  369. displayType: function(displayType) {
  370. if(displayType !== 'none') {
  371. $module.data(metadata.displayType, displayType);
  372. }
  373. },
  374. transitionExists: function(animation, exists) {
  375. $.fn.transition.exists[animation] = exists;
  376. module.verbose('Saving existence of transition', animation, exists);
  377. }
  378. },
  379. restore: {
  380. conditions: function() {
  381. var
  382. animation = module.get.currentAnimation()
  383. ;
  384. if(animation) {
  385. $module
  386. .removeClass(animation)
  387. ;
  388. module.verbose('Removing animation class', module.cache);
  389. }
  390. module.remove.duration();
  391. }
  392. },
  393. add: {
  394. failSafe: function() {
  395. var
  396. duration = module.get.duration()
  397. ;
  398. module.timer = setTimeout(function() {
  399. $module.triggerHandler(animationEnd);
  400. }, duration + settings.failSafeDelay);
  401. module.verbose('Adding fail safe timer', module.timer);
  402. }
  403. },
  404. remove: {
  405. animating: function() {
  406. $module.removeClass(className.animating);
  407. },
  408. animationCallbacks: function() {
  409. module.remove.queueCallback();
  410. module.remove.completeCallback();
  411. },
  412. queueCallback: function() {
  413. $module.off('.queue' + eventNamespace);
  414. },
  415. completeCallback: function() {
  416. $module.off('.complete' + eventNamespace);
  417. },
  418. display: function() {
  419. $module.css('display', '');
  420. },
  421. direction: function() {
  422. $module
  423. .removeClass(className.inward)
  424. .removeClass(className.outward)
  425. ;
  426. },
  427. duration: function() {
  428. $module
  429. .css('animation-duration', '')
  430. ;
  431. },
  432. failSafe: function() {
  433. module.verbose('Removing fail safe timer', module.timer);
  434. if(module.timer) {
  435. clearTimeout(module.timer);
  436. }
  437. },
  438. hidden: function() {
  439. $module.removeClass(className.hidden);
  440. },
  441. visible: function() {
  442. $module.removeClass(className.visible);
  443. },
  444. looping: function() {
  445. module.debug('Transitions are no longer looping');
  446. if( module.is.looping() ) {
  447. module.reset();
  448. $module
  449. .removeClass(className.looping)
  450. ;
  451. }
  452. },
  453. transition: function() {
  454. $module
  455. .removeClass(className.transition)
  456. .removeClass(className.visible)
  457. .removeClass(className.hidden)
  458. ;
  459. }
  460. },
  461. get: {
  462. settings: function(animation, duration, onComplete) {
  463. // single settings object
  464. if(typeof animation == 'object') {
  465. return $.extend(true, {}, $.fn.transition.settings, animation);
  466. }
  467. // all arguments provided
  468. else if(typeof onComplete == 'function') {
  469. return $.extend({}, $.fn.transition.settings, {
  470. animation : animation,
  471. onComplete : onComplete,
  472. duration : duration
  473. });
  474. }
  475. // only duration provided
  476. else if(typeof duration == 'string' || typeof duration == 'number') {
  477. return $.extend({}, $.fn.transition.settings, {
  478. animation : animation,
  479. duration : duration
  480. });
  481. }
  482. // duration is actually settings object
  483. else if(typeof duration == 'object') {
  484. return $.extend({}, $.fn.transition.settings, duration, {
  485. animation : animation
  486. });
  487. }
  488. // duration is actually callback
  489. else if(typeof duration == 'function') {
  490. return $.extend({}, $.fn.transition.settings, {
  491. animation : animation,
  492. onComplete : duration
  493. });
  494. }
  495. // only animation provided
  496. else {
  497. return $.extend({}, $.fn.transition.settings, {
  498. animation : animation
  499. });
  500. }
  501. },
  502. animationClass: function(animation) {
  503. var
  504. animationClass = animation || settings.animation,
  505. directionClass = (module.can.transition() && !module.has.direction())
  506. ? module.get.direction() + ' '
  507. : ''
  508. ;
  509. return className.animating + ' '
  510. + className.transition + ' '
  511. + directionClass
  512. + animationClass
  513. ;
  514. },
  515. currentAnimation: function() {
  516. return (module.cache && module.cache.animation !== undefined)
  517. ? module.cache.animation
  518. : false
  519. ;
  520. },
  521. currentDirection: function() {
  522. return module.is.inward()
  523. ? className.inward
  524. : className.outward
  525. ;
  526. },
  527. direction: function() {
  528. return module.is.hidden() || !module.is.visible()
  529. ? className.inward
  530. : className.outward
  531. ;
  532. },
  533. animationDirection: function(animation) {
  534. var
  535. direction
  536. ;
  537. animation = animation || settings.animation;
  538. if(typeof animation === 'string') {
  539. animation = animation.split(' ');
  540. // search animation name for out/in class
  541. $.each(animation, function(index, word){
  542. if(word === className.inward) {
  543. direction = className.inward;
  544. }
  545. else if(word === className.outward) {
  546. direction = className.outward;
  547. }
  548. });
  549. }
  550. // return found direction
  551. if(direction) {
  552. return direction;
  553. }
  554. return false;
  555. },
  556. duration: function(duration) {
  557. duration = duration || settings.duration;
  558. if(duration === false) {
  559. duration = $module.css('animation-duration') || 0;
  560. }
  561. return (typeof duration === 'string')
  562. ? (duration.indexOf('ms') > -1)
  563. ? parseFloat(duration)
  564. : parseFloat(duration) * 1000
  565. : duration
  566. ;
  567. },
  568. displayType: function(shouldDetermine) {
  569. shouldDetermine = (shouldDetermine !== undefined)
  570. ? shouldDetermine
  571. : true
  572. ;
  573. if(settings.displayType) {
  574. return settings.displayType;
  575. }
  576. if(shouldDetermine && $module.data(metadata.displayType) === undefined) {
  577. var currentDisplay = $module.css('display');
  578. if(currentDisplay === '' || currentDisplay === 'none'){
  579. // create fake element to determine display state
  580. module.can.transition(true);
  581. } else {
  582. module.save.displayType(currentDisplay);
  583. }
  584. }
  585. return $module.data(metadata.displayType);
  586. },
  587. userStyle: function(style) {
  588. style = style || $module.attr('style') || '';
  589. return style.replace(/display.*?;/, '');
  590. },
  591. transitionExists: function(animation) {
  592. return $.fn.transition.exists[animation];
  593. },
  594. animationStartEvent: function() {
  595. var
  596. element = document.createElement('div'),
  597. animations = {
  598. 'animation' :'animationstart',
  599. 'OAnimation' :'oAnimationStart',
  600. 'MozAnimation' :'mozAnimationStart',
  601. 'WebkitAnimation' :'webkitAnimationStart'
  602. },
  603. animation
  604. ;
  605. for(animation in animations){
  606. if( element.style[animation] !== undefined ){
  607. return animations[animation];
  608. }
  609. }
  610. return false;
  611. },
  612. animationEndEvent: function() {
  613. var
  614. element = document.createElement('div'),
  615. animations = {
  616. 'animation' :'animationend',
  617. 'OAnimation' :'oAnimationEnd',
  618. 'MozAnimation' :'mozAnimationEnd',
  619. 'WebkitAnimation' :'webkitAnimationEnd'
  620. },
  621. animation
  622. ;
  623. for(animation in animations){
  624. if( element.style[animation] !== undefined ){
  625. return animations[animation];
  626. }
  627. }
  628. return false;
  629. }
  630. },
  631. can: {
  632. transition: function(forced) {
  633. var
  634. animation = settings.animation,
  635. transitionExists = module.get.transitionExists(animation),
  636. displayType = module.get.displayType(false),
  637. elementClass,
  638. tagName,
  639. $clone,
  640. currentAnimation,
  641. inAnimation,
  642. directionExists
  643. ;
  644. if( transitionExists === undefined || forced) {
  645. module.verbose('Determining whether animation exists');
  646. elementClass = $module.attr('class');
  647. tagName = $module.prop('tagName');
  648. $clone = $('<' + tagName + ' />').addClass( elementClass ).insertAfter($module);
  649. currentAnimation = $clone
  650. .addClass(animation)
  651. .removeClass(className.inward)
  652. .removeClass(className.outward)
  653. .addClass(className.animating)
  654. .addClass(className.transition)
  655. .css('animationName')
  656. ;
  657. inAnimation = $clone
  658. .addClass(className.inward)
  659. .css('animationName')
  660. ;
  661. if(!displayType) {
  662. displayType = $clone
  663. .attr('class', elementClass)
  664. .removeAttr('style')
  665. .removeClass(className.hidden)
  666. .removeClass(className.visible)
  667. .show()
  668. .css('display')
  669. ;
  670. module.verbose('Determining final display state', displayType);
  671. module.save.displayType(displayType);
  672. }
  673. $clone.remove();
  674. if(currentAnimation != inAnimation) {
  675. module.debug('Direction exists for animation', animation);
  676. directionExists = true;
  677. }
  678. else if(currentAnimation == 'none' || !currentAnimation) {
  679. module.debug('No animation defined in css', animation);
  680. return;
  681. }
  682. else {
  683. module.debug('Static animation found', animation, displayType);
  684. directionExists = false;
  685. }
  686. module.save.transitionExists(animation, directionExists);
  687. }
  688. return (transitionExists !== undefined)
  689. ? transitionExists
  690. : directionExists
  691. ;
  692. },
  693. animate: function() {
  694. // can transition does not return a value if animation does not exist
  695. return (module.can.transition() !== undefined);
  696. }
  697. },
  698. is: {
  699. animating: function() {
  700. return $module.hasClass(className.animating);
  701. },
  702. inward: function() {
  703. return $module.hasClass(className.inward);
  704. },
  705. outward: function() {
  706. return $module.hasClass(className.outward);
  707. },
  708. looping: function() {
  709. return $module.hasClass(className.looping);
  710. },
  711. occurring: function(animation) {
  712. animation = animation || settings.animation;
  713. animation = '.' + animation.replace(' ', '.');
  714. return ( $module.filter(animation).length > 0 );
  715. },
  716. visible: function() {
  717. return $module.is(':visible');
  718. },
  719. hidden: function() {
  720. return $module.css('visibility') === 'hidden';
  721. },
  722. supported: function() {
  723. return(animationEnd !== false);
  724. }
  725. },
  726. hide: function() {
  727. module.verbose('Hiding element');
  728. if( module.is.animating() ) {
  729. module.reset();
  730. }
  731. element.blur(); // IE will trigger focus change if element is not blurred before hiding
  732. module.remove.display();
  733. module.remove.visible();
  734. if($.isFunction(settings.onBeforeHide)){
  735. settings.onBeforeHide.call(element,function(){
  736. module.hideNow();
  737. });
  738. } else {
  739. module.hideNow();
  740. }
  741. },
  742. hideNow: function() {
  743. module.set.hidden();
  744. module.force.hidden();
  745. settings.onHide.call(element);
  746. settings.onComplete.call(element);
  747. // module.repaint();
  748. },
  749. show: function(display) {
  750. module.verbose('Showing element', display);
  751. if(module.force.visible()) {
  752. module.remove.hidden();
  753. module.set.visible();
  754. settings.onShow.call(element);
  755. settings.onComplete.call(element);
  756. // module.repaint();
  757. }
  758. },
  759. toggle: function() {
  760. if( module.is.visible() ) {
  761. module.hide();
  762. }
  763. else {
  764. module.show();
  765. }
  766. },
  767. stop: function() {
  768. module.debug('Stopping current animation');
  769. $module.triggerHandler(animationEnd);
  770. },
  771. stopAll: function() {
  772. module.debug('Stopping all animation');
  773. module.remove.queueCallback();
  774. $module.triggerHandler(animationEnd);
  775. },
  776. clear: {
  777. queue: function() {
  778. module.debug('Clearing animation queue');
  779. module.remove.queueCallback();
  780. }
  781. },
  782. enable: function() {
  783. module.verbose('Starting animation');
  784. $module.removeClass(className.disabled);
  785. },
  786. disable: function() {
  787. module.debug('Stopping animation');
  788. $module.addClass(className.disabled);
  789. },
  790. setting: function(name, value) {
  791. module.debug('Changing setting', name, value);
  792. if( $.isPlainObject(name) ) {
  793. $.extend(true, settings, name);
  794. }
  795. else if(value !== undefined) {
  796. if($.isPlainObject(settings[name])) {
  797. $.extend(true, settings[name], value);
  798. }
  799. else {
  800. settings[name] = value;
  801. }
  802. }
  803. else {
  804. return settings[name];
  805. }
  806. },
  807. internal: function(name, value) {
  808. if( $.isPlainObject(name) ) {
  809. $.extend(true, module, name);
  810. }
  811. else if(value !== undefined) {
  812. module[name] = value;
  813. }
  814. else {
  815. return module[name];
  816. }
  817. },
  818. debug: function() {
  819. if(!settings.silent && settings.debug) {
  820. if(settings.performance) {
  821. module.performance.log(arguments);
  822. }
  823. else {
  824. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  825. module.debug.apply(console, arguments);
  826. }
  827. }
  828. },
  829. verbose: function() {
  830. if(!settings.silent && settings.verbose && settings.debug) {
  831. if(settings.performance) {
  832. module.performance.log(arguments);
  833. }
  834. else {
  835. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  836. module.verbose.apply(console, arguments);
  837. }
  838. }
  839. },
  840. error: function() {
  841. if(!settings.silent) {
  842. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  843. module.error.apply(console, arguments);
  844. }
  845. },
  846. performance: {
  847. log: function(message) {
  848. var
  849. currentTime,
  850. executionTime,
  851. previousTime
  852. ;
  853. if(settings.performance) {
  854. currentTime = new Date().getTime();
  855. previousTime = time || currentTime;
  856. executionTime = currentTime - previousTime;
  857. time = currentTime;
  858. performance.push({
  859. 'Name' : message[0],
  860. 'Arguments' : [].slice.call(message, 1) || '',
  861. 'Element' : element,
  862. 'Execution Time' : executionTime
  863. });
  864. }
  865. clearTimeout(module.performance.timer);
  866. module.performance.timer = setTimeout(module.performance.display, 500);
  867. },
  868. display: function() {
  869. var
  870. title = settings.name + ':',
  871. totalTime = 0
  872. ;
  873. time = false;
  874. clearTimeout(module.performance.timer);
  875. $.each(performance, function(index, data) {
  876. totalTime += data['Execution Time'];
  877. });
  878. title += ' ' + totalTime + 'ms';
  879. if(moduleSelector) {
  880. title += ' \'' + moduleSelector + '\'';
  881. }
  882. if($allModules.length > 1) {
  883. title += ' ' + '(' + $allModules.length + ')';
  884. }
  885. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  886. console.groupCollapsed(title);
  887. if(console.table) {
  888. console.table(performance);
  889. }
  890. else {
  891. $.each(performance, function(index, data) {
  892. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  893. });
  894. }
  895. console.groupEnd();
  896. }
  897. performance = [];
  898. }
  899. },
  900. // modified for transition to return invoke success
  901. invoke: function(query, passedArguments, context) {
  902. var
  903. object = instance,
  904. maxDepth,
  905. found,
  906. response
  907. ;
  908. passedArguments = passedArguments || queryArguments;
  909. context = element || context;
  910. if(typeof query == 'string' && object !== undefined) {
  911. query = query.split(/[\. ]/);
  912. maxDepth = query.length - 1;
  913. $.each(query, function(depth, value) {
  914. var camelCaseValue = (depth != maxDepth)
  915. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  916. : query
  917. ;
  918. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  919. object = object[camelCaseValue];
  920. }
  921. else if( object[camelCaseValue] !== undefined ) {
  922. found = object[camelCaseValue];
  923. return false;
  924. }
  925. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  926. object = object[value];
  927. }
  928. else if( object[value] !== undefined ) {
  929. found = object[value];
  930. return false;
  931. }
  932. else {
  933. return false;
  934. }
  935. });
  936. }
  937. if ( $.isFunction( found ) ) {
  938. response = found.apply(context, passedArguments);
  939. }
  940. else if(found !== undefined) {
  941. response = found;
  942. }
  943. if(Array.isArray(returnedValue)) {
  944. returnedValue.push(response);
  945. }
  946. else if(returnedValue !== undefined) {
  947. returnedValue = [returnedValue, response];
  948. }
  949. else if(response !== undefined) {
  950. returnedValue = response;
  951. }
  952. return (found !== undefined)
  953. ? found
  954. : false
  955. ;
  956. }
  957. };
  958. module.initialize();
  959. })
  960. ;
  961. return (returnedValue !== undefined)
  962. ? returnedValue
  963. : this
  964. ;
  965. };
  966. // Records if CSS transition is available
  967. $.fn.transition.exists = {};
  968. $.fn.transition.settings = {
  969. // module info
  970. name : 'Transition',
  971. // hide all output from this component regardless of other settings
  972. silent : false,
  973. // debug content outputted to console
  974. debug : false,
  975. // verbose debug output
  976. verbose : false,
  977. // performance data output
  978. performance : true,
  979. // event namespace
  980. namespace : 'transition',
  981. // delay between animations in group
  982. interval : 0,
  983. // whether group animations should be reversed
  984. reverse : 'auto',
  985. // animation callback event
  986. onStart : function() {},
  987. onComplete : function() {},
  988. onShow : function() {},
  989. onHide : function() {},
  990. // whether timeout should be used to ensure callback fires in cases animationend does not
  991. useFailSafe : true,
  992. // delay in ms for fail safe
  993. failSafeDelay : 100,
  994. // whether EXACT animation can occur twice in a row
  995. allowRepeats : false,
  996. // Override final display type on visible
  997. displayType : false,
  998. // animation duration
  999. animation : 'fade',
  1000. duration : false,
  1001. // new animations will occur after previous ones
  1002. queue : true,
  1003. // whether initially inline hidden objects should be skipped for transition
  1004. skipInlineHidden: false,
  1005. metadata : {
  1006. displayType: 'display'
  1007. },
  1008. className : {
  1009. animating : 'animating',
  1010. disabled : 'disabled',
  1011. hidden : 'hidden',
  1012. inward : 'in',
  1013. loading : 'loading',
  1014. looping : 'looping',
  1015. outward : 'out',
  1016. transition : 'transition',
  1017. visible : 'visible'
  1018. },
  1019. // possible errors
  1020. error: {
  1021. noAnimation : 'Element is no longer attached to DOM. Unable to animate. Use silent setting to surpress this warning in production.',
  1022. repeated : 'That animation is already occurring, cancelling repeated animation',
  1023. method : 'The method you called is not defined',
  1024. support : 'This browser does not support CSS animations'
  1025. }
  1026. };
  1027. })( jQuery, window, document );