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.

1044 lines
32 KiB

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