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.

1047 lines
32 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. /*
  2. * # Semantic - Popup
  3. * http://github.com/jlukic/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. "use strict";
  13. $.fn.popup = function(parameters) {
  14. var
  15. $allModules = $(this),
  16. $document = $(document),
  17. moduleSelector = $allModules.selector || '',
  18. hasTouch = ('ontouchstart' in document.documentElement),
  19. time = new Date().getTime(),
  20. performance = [],
  21. query = arguments[0],
  22. methodInvoked = (typeof query == 'string'),
  23. queryArguments = [].slice.call(arguments, 1),
  24. returnedValue
  25. ;
  26. $allModules
  27. .each(function() {
  28. var
  29. settings = ( $.isPlainObject(parameters) )
  30. ? $.extend(true, {}, $.fn.popup.settings, parameters)
  31. : $.extend({}, $.fn.popup.settings),
  32. selector = settings.selector,
  33. className = settings.className,
  34. error = settings.error,
  35. metadata = settings.metadata,
  36. namespace = settings.namespace,
  37. eventNamespace = '.' + settings.namespace,
  38. moduleNamespace = 'module-' + namespace,
  39. $module = $(this),
  40. $context = $(settings.context),
  41. $target = (settings.target)
  42. ? $(settings.target)
  43. : $module,
  44. $window = $(window),
  45. $body = $('body'),
  46. $popup,
  47. $offsetParent,
  48. searchDepth = 0,
  49. element = this,
  50. instance = $module.data(moduleNamespace),
  51. module
  52. ;
  53. module = {
  54. // binds events
  55. initialize: function() {
  56. module.debug('Initializing module', $module);
  57. module.refresh();
  58. if(settings.on == 'click') {
  59. $module
  60. .on('click' + eventNamespace, module.toggle)
  61. ;
  62. }
  63. else if( module.get.startEvent() ) {
  64. $module
  65. .on(module.get.startEvent() + eventNamespace, module.event.start)
  66. .on(module.get.endEvent() + eventNamespace, module.event.end)
  67. ;
  68. }
  69. if(settings.target) {
  70. module.debug('Target set to element', $target);
  71. }
  72. $window
  73. .on('resize' + eventNamespace, module.event.resize)
  74. ;
  75. if( !module.exists() ) {
  76. module.create();
  77. }
  78. else if(settings.hoverable) {
  79. module.bind.popup();
  80. }
  81. module.instantiate();
  82. },
  83. instantiate: function() {
  84. module.verbose('Storing instance of module', module);
  85. instance = module;
  86. $module
  87. .data(moduleNamespace, instance)
  88. ;
  89. },
  90. refresh: function() {
  91. $popup = (settings.popup)
  92. ? $(settings.popup)
  93. : (settings.inline)
  94. ? $target.next(settings.selector.popup)
  95. : false
  96. ;
  97. if(settings.popup) {
  98. $popup.addClass(className.loading);
  99. $offsetParent = $popup.offsetParent();
  100. $popup.removeClass(className.loading);
  101. }
  102. else {
  103. $offsetParent = (settings.inline)
  104. ? $target.offsetParent()
  105. : $body
  106. ;
  107. }
  108. if( $offsetParent.is('html') ) {
  109. module.debug('Page is popups offset parent');
  110. $offsetParent = $body;
  111. }
  112. },
  113. reposition: function() {
  114. module.refresh();
  115. module.set.position();
  116. },
  117. destroy: function() {
  118. module.debug('Destroying previous module');
  119. if($popup && !settings.preserve) {
  120. module.removePopup();
  121. }
  122. $module
  123. .off(eventNamespace)
  124. .removeData(moduleNamespace)
  125. ;
  126. },
  127. event: {
  128. start: function(event) {
  129. var
  130. delay = ($.isPlainObject(settings.delay))
  131. ? settings.delay.show
  132. : settings.delay
  133. ;
  134. clearTimeout(module.hideTimer);
  135. module.showTimer = setTimeout(function() {
  136. if( module.is.hidden() && !( module.is.active() && module.is.dropdown()) ) {
  137. module.show();
  138. }
  139. }, delay);
  140. },
  141. end: function() {
  142. var
  143. delay = ($.isPlainObject(settings.delay))
  144. ? settings.delay.hide
  145. : settings.delay
  146. ;
  147. clearTimeout(module.showTimer);
  148. module.hideTimer = setTimeout(function() {
  149. if( module.is.visible() ) {
  150. module.hide();
  151. }
  152. }, delay);
  153. },
  154. resize: function() {
  155. if( module.is.visible() ) {
  156. module.set.position();
  157. }
  158. }
  159. },
  160. // generates popup html from metadata
  161. create: function() {
  162. var
  163. html = $module.data(metadata.html) || settings.html,
  164. variation = $module.data(metadata.variation) || settings.variation,
  165. title = $module.data(metadata.title) || settings.title,
  166. content = $module.data(metadata.content) || $module.attr('title') || settings.content
  167. ;
  168. if(html || content || title) {
  169. module.debug('Creating pop-up html');
  170. if(!html) {
  171. html = settings.templates.popup({
  172. title : title,
  173. content : content
  174. });
  175. }
  176. $popup = $('<div/>')
  177. .addClass(className.popup)
  178. .addClass(variation)
  179. .html(html)
  180. ;
  181. if(variation) {
  182. $popup
  183. .addClass(variation)
  184. ;
  185. }
  186. if(settings.inline) {
  187. module.verbose('Inserting popup element inline', $popup);
  188. $popup
  189. .insertAfter($module)
  190. ;
  191. }
  192. else {
  193. module.verbose('Appending popup element to body', $popup);
  194. $popup
  195. .appendTo( $context )
  196. ;
  197. }
  198. if(settings.hoverable) {
  199. module.bind.popup();
  200. }
  201. $.proxy(settings.onCreate, $popup)(element);
  202. }
  203. else if($target.next(settings.selector.popup).size() !== 0) {
  204. module.verbose('Pre-existing popup found, reverting to inline');
  205. settings.inline = true;
  206. module.refresh();
  207. if(settings.hoverable) {
  208. module.bind.popup();
  209. }
  210. }
  211. else {
  212. module.debug('No content specified skipping display', element);
  213. }
  214. },
  215. // determines popup state
  216. toggle: function() {
  217. module.debug('Toggling pop-up');
  218. if( module.is.hidden() ) {
  219. module.debug('Popup is hidden, showing pop-up');
  220. module.unbind.close();
  221. module.hideAll();
  222. module.show();
  223. }
  224. else {
  225. module.debug('Popup is visible, hiding pop-up');
  226. module.hide();
  227. }
  228. },
  229. show: function(callback) {
  230. callback = $.isFunction(callback) ? callback : function(){};
  231. module.debug('Showing pop-up', settings.transition);
  232. if(!settings.preserve && !settings.popup) {
  233. module.refresh();
  234. }
  235. if( !module.exists() ) {
  236. module.create();
  237. }
  238. if( $popup && module.set.position() ) {
  239. module.save.conditions();
  240. module.animate.show(callback);
  241. }
  242. },
  243. hide: function(callback) {
  244. callback = $.isFunction(callback) ? callback : function(){};
  245. module.remove.visible();
  246. module.unbind.close();
  247. if( module.is.visible() ) {
  248. module.restore.conditions();
  249. module.animate.hide(callback);
  250. }
  251. },
  252. hideAll: function() {
  253. $(selector.popup)
  254. .filter(':visible')
  255. .popup('hide')
  256. ;
  257. },
  258. hideGracefully: function(event) {
  259. // don't close on clicks inside popup
  260. if(event && $(event.target).closest(selector.popup).size() === 0) {
  261. module.debug('Click occurred outside popup hiding popup');
  262. module.hide();
  263. }
  264. else {
  265. module.debug('Click was inside popup, keeping popup open');
  266. }
  267. },
  268. exists: function() {
  269. if(!$popup) {
  270. return false;
  271. }
  272. if(settings.inline || settings.popup) {
  273. return ( $popup.size() !== 0 );
  274. }
  275. else {
  276. return ( $popup.closest($context).size() );
  277. }
  278. },
  279. removePopup: function() {
  280. module.debug('Removing popup');
  281. $.proxy(settings.onRemove, $popup)(element);
  282. $popup
  283. .removePopup()
  284. ;
  285. },
  286. save: {
  287. conditions: function() {
  288. module.cache = {
  289. title: $module.attr('title')
  290. };
  291. if (module.cache.title) {
  292. $module.removeAttr('title');
  293. }
  294. module.verbose('Saving original attributes', module.cache.title);
  295. }
  296. },
  297. restore: {
  298. conditions: function() {
  299. element.blur();
  300. if(module.cache && module.cache.title) {
  301. $module.attr('title', module.cache.title);
  302. module.verbose('Restoring original attributes', module.cache.title);
  303. }
  304. return true;
  305. }
  306. },
  307. animate: {
  308. show: function(callback) {
  309. callback = $.isFunction(callback) ? callback : function(){};
  310. if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
  311. module.set.visible();
  312. $popup
  313. .transition({
  314. animation : settings.transition + ' in',
  315. queue : false,
  316. debug : settings.debug,
  317. verbose : settings.verbose,
  318. duration : settings.duration,
  319. onComplete : function() {
  320. module.bind.close();
  321. $.proxy(callback, $popup)(element);
  322. $.proxy(settings.onVisible, $popup)(element);
  323. }
  324. })
  325. ;
  326. }
  327. else {
  328. module.set.visible();
  329. $popup
  330. .stop()
  331. .fadeIn(settings.duration, settings.easing, function() {
  332. module.bind.close();
  333. $.proxy(callback, element)();
  334. })
  335. ;
  336. }
  337. $.proxy(settings.onShow, $popup)(element);
  338. },
  339. hide: function(callback) {
  340. callback = $.isFunction(callback) ? callback : function(){};
  341. module.debug('Hiding pop-up');
  342. if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
  343. $popup
  344. .transition({
  345. animation : settings.transition + ' out',
  346. queue : false,
  347. duration : settings.duration,
  348. debug : settings.debug,
  349. verbose : settings.verbose,
  350. onComplete : function() {
  351. module.reset();
  352. $.proxy(callback, $popup)(element);
  353. $.proxy(settings.onHidden, $popup)(element);
  354. }
  355. })
  356. ;
  357. }
  358. else {
  359. $popup
  360. .stop()
  361. .fadeOut(settings.duration, settings.easing, function() {
  362. module.reset();
  363. callback();
  364. })
  365. ;
  366. }
  367. $.proxy(settings.onHide, $popup)(element);
  368. }
  369. },
  370. get: {
  371. startEvent: function() {
  372. if(settings.on == 'hover') {
  373. return 'mouseenter';
  374. }
  375. else if(settings.on == 'focus') {
  376. return 'focus';
  377. }
  378. return false;
  379. },
  380. endEvent: function() {
  381. if(settings.on == 'hover') {
  382. return 'mouseleave';
  383. }
  384. else if(settings.on == 'focus') {
  385. return 'blur';
  386. }
  387. return false;
  388. },
  389. offstagePosition: function(position) {
  390. var
  391. position = position || false,
  392. boundary = {
  393. top : $(window).scrollTop(),
  394. bottom : $(window).scrollTop() + $(window).height(),
  395. left : 0,
  396. right : $(window).width()
  397. },
  398. popup = {
  399. width : $popup.width(),
  400. height : $popup.height(),
  401. offset : $popup.offset()
  402. },
  403. offstage = {},
  404. offstagePositions = []
  405. ;
  406. if(popup.offset && position) {
  407. module.verbose('Checking if outside viewable area', popup.offset);
  408. offstage = {
  409. top : (popup.offset.top < boundary.top),
  410. bottom : (popup.offset.top + popup.height > boundary.bottom),
  411. right : (popup.offset.left + popup.width > boundary.right),
  412. left : false
  413. };
  414. }
  415. // return only boundaries that have been surpassed
  416. $.each(offstage, function(direction, isOffstage) {
  417. if(isOffstage) {
  418. offstagePositions.push(direction);
  419. }
  420. });
  421. return (offstagePositions.length > 0)
  422. ? offstagePositions.join(' ')
  423. : false
  424. ;
  425. },
  426. nextPosition: function(position) {
  427. switch(position) {
  428. case 'top left':
  429. position = 'bottom left';
  430. break;
  431. case 'bottom left':
  432. position = 'top right';
  433. break;
  434. case 'top right':
  435. position = 'bottom right';
  436. break;
  437. case 'bottom right':
  438. position = 'top center';
  439. break;
  440. case 'top center':
  441. position = 'bottom center';
  442. break;
  443. case 'bottom center':
  444. position = 'right center';
  445. break;
  446. case 'right center':
  447. position = 'left center';
  448. break;
  449. case 'left center':
  450. position = 'top center';
  451. break;
  452. }
  453. return position;
  454. }
  455. },
  456. set: {
  457. position: function(position, arrowOffset) {
  458. var
  459. windowWidth = $(window).width(),
  460. windowHeight = $(window).height(),
  461. targetWidth = $target.outerWidth(),
  462. targetHeight = $target.outerHeight(),
  463. popupWidth = $popup.outerWidth(),
  464. popupHeight = $popup.outerHeight(),
  465. parentWidth = $offsetParent.outerWidth(),
  466. parentHeight = $offsetParent.outerHeight(),
  467. distanceAway = settings.distanceAway,
  468. targetElement = $target[0],
  469. marginTop = (settings.inline)
  470. ? parseInt( window.getComputedStyle(targetElement).getPropertyValue('margin-top'), 10)
  471. : 0,
  472. marginLeft = (settings.inline)
  473. ? parseInt( window.getComputedStyle(targetElement).getPropertyValue('margin-left'), 10)
  474. : 0,
  475. target = (settings.inline || settings.popup)
  476. ? $target.position()
  477. : $target.offset(),
  478. positioning,
  479. offstagePosition
  480. ;
  481. position = position || $module.data(metadata.position) || settings.position;
  482. arrowOffset = arrowOffset || $module.data(metadata.offset) || settings.offset;
  483. if(settings.inline) {
  484. module.debug('Adding targets margin to calculation');
  485. if(position == 'left center' || position == 'right center') {
  486. arrowOffset += marginTop;
  487. distanceAway += -marginLeft;
  488. }
  489. else if (position == 'top left' || position == 'top center' || position == 'top right') {
  490. arrowOffset += marginLeft;
  491. distanceAway -= marginTop;
  492. }
  493. else {
  494. arrowOffset += marginLeft;
  495. distanceAway += marginTop;
  496. }
  497. }
  498. module.debug('Calculating popup positioning', position);
  499. switch(position) {
  500. case 'top left':
  501. positioning = {
  502. top : 'auto',
  503. bottom : parentHeight - target.top + distanceAway,
  504. left : target.left + arrowOffset,
  505. right : 'auto'
  506. };
  507. break;
  508. case 'top center':
  509. positioning = {
  510. bottom : parentHeight - target.top + distanceAway,
  511. left : target.left + (targetWidth / 2) - (popupWidth / 2) + arrowOffset,
  512. top : 'auto',
  513. right : 'auto'
  514. };
  515. break;
  516. case 'top right':
  517. positioning = {
  518. bottom : parentHeight - target.top + distanceAway,
  519. right : parentWidth - target.left - targetWidth - arrowOffset,
  520. top : 'auto',
  521. left : 'auto'
  522. };
  523. break;
  524. case 'left center':
  525. positioning = {
  526. top : target.top + (targetHeight / 2) - (popupHeight / 2) + arrowOffset,
  527. right : parentWidth - target.left + distanceAway,
  528. left : 'auto',
  529. bottom : 'auto'
  530. };
  531. break;
  532. case 'right center':
  533. positioning = {
  534. top : target.top + (targetHeight / 2) - (popupHeight / 2) + arrowOffset,
  535. left : target.left + targetWidth + distanceAway,
  536. bottom : 'auto',
  537. right : 'auto'
  538. };
  539. break;
  540. case 'bottom left':
  541. positioning = {
  542. top : target.top + targetHeight + distanceAway,
  543. left : target.left + arrowOffset,
  544. bottom : 'auto',
  545. right : 'auto'
  546. };
  547. break;
  548. case 'bottom center':
  549. positioning = {
  550. top : target.top + targetHeight + distanceAway,
  551. left : target.left + (targetWidth / 2) - (popupWidth / 2) + arrowOffset,
  552. bottom : 'auto',
  553. right : 'auto'
  554. };
  555. break;
  556. case 'bottom right':
  557. positioning = {
  558. top : target.top + targetHeight + distanceAway,
  559. right : parentWidth - target.left - targetWidth - arrowOffset,
  560. left : 'auto',
  561. bottom : 'auto'
  562. };
  563. break;
  564. }
  565. if(positioning === undefined) {
  566. module.error(error.invalidPosition);
  567. }
  568. // tentatively place on stage
  569. $popup
  570. .css(positioning)
  571. .removeClass(className.position)
  572. .addClass(position)
  573. .addClass(className.loading)
  574. ;
  575. // check if is offstage
  576. offstagePosition = module.get.offstagePosition(position);
  577. // recursively find new positioning
  578. if(offstagePosition) {
  579. module.debug('Element is outside boundaries', offstagePosition);
  580. if(searchDepth < settings.maxSearchDepth) {
  581. position = module.get.nextPosition(position);
  582. searchDepth++;
  583. module.debug('Trying new position', position);
  584. return ($popup)
  585. ? module.set.position(position)
  586. : false
  587. ;
  588. }
  589. else {
  590. module.error(error.recursion, element);
  591. searchDepth = 0;
  592. module.reset();
  593. $popup.removeClass(className.loading);
  594. return false;
  595. }
  596. }
  597. else {
  598. module.debug('Position is on stage', position);
  599. searchDepth = 0;
  600. if( settings.setFluidWidth && $popup.hasClass(className.fluid) ) {
  601. $popup.css('width', $offsetParent.width());
  602. }
  603. $popup.removeClass(className.loading);
  604. return true;
  605. }
  606. },
  607. visible: function() {
  608. $module.addClass(className.visible);
  609. }
  610. },
  611. remove: {
  612. visible: function() {
  613. $module.removeClass(className.visible);
  614. }
  615. },
  616. bind: {
  617. popup: function() {
  618. module.verbose('Allowing hover events on popup to prevent closing');
  619. $popup
  620. .on('mouseenter' + eventNamespace, module.event.start)
  621. .on('mouseleave' + eventNamespace, module.event.end)
  622. ;
  623. },
  624. close:function() {
  625. if(settings.hideOnScroll) {
  626. $document
  627. .on('touchmove' + eventNamespace, module.hideGracefully)
  628. .on('scroll' + eventNamespace, module.hideGracefully)
  629. ;
  630. $context
  631. .on('touchmove' + eventNamespace, module.hideGracefully)
  632. .on('scroll' + eventNamespace, module.hideGracefully)
  633. ;
  634. }
  635. if(settings.on == 'click' && settings.closable) {
  636. module.verbose('Binding popup close event to document');
  637. $document
  638. .on('click' + eventNamespace, function(event) {
  639. module.verbose('Pop-up clickaway intent detected');
  640. $.proxy(module.hideGracefully, element)(event);
  641. })
  642. ;
  643. }
  644. }
  645. },
  646. unbind: {
  647. close: function() {
  648. if(settings.hideOnScroll) {
  649. $document
  650. .off('scroll' + eventNamespace, module.hide)
  651. ;
  652. $context
  653. .off('scroll' + eventNamespace, module.hide)
  654. ;
  655. }
  656. if(settings.on == 'click' && settings.closable) {
  657. module.verbose('Removing close event from document');
  658. $document
  659. .off('click' + eventNamespace)
  660. ;
  661. }
  662. }
  663. },
  664. is: {
  665. active: function() {
  666. return $module.hasClass(className.active);
  667. },
  668. animating: function() {
  669. return ( $popup && $popup.is(':animated') || $popup.hasClass(className.animating) );
  670. },
  671. visible: function() {
  672. return $popup && $popup.is(':visible');
  673. },
  674. dropdown: function() {
  675. return $module.hasClass(className.dropdown);
  676. },
  677. hidden: function() {
  678. return !module.is.visible();
  679. }
  680. },
  681. reset: function() {
  682. module.remove.visible();
  683. if(settings.preserve || settings.popup) {
  684. if($.fn.transition !== undefined) {
  685. $popup
  686. .transition('remove transition')
  687. ;
  688. }
  689. }
  690. else {
  691. module.removePopup();
  692. }
  693. },
  694. setting: function(name, value) {
  695. if( $.isPlainObject(name) ) {
  696. $.extend(true, settings, name);
  697. }
  698. else if(value !== undefined) {
  699. settings[name] = value;
  700. }
  701. else {
  702. return settings[name];
  703. }
  704. },
  705. internal: function(name, value) {
  706. if( $.isPlainObject(name) ) {
  707. $.extend(true, module, name);
  708. }
  709. else if(value !== undefined) {
  710. module[name] = value;
  711. }
  712. else {
  713. return module[name];
  714. }
  715. },
  716. debug: function() {
  717. if(settings.debug) {
  718. if(settings.performance) {
  719. module.performance.log(arguments);
  720. }
  721. else {
  722. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  723. module.debug.apply(console, arguments);
  724. }
  725. }
  726. },
  727. verbose: function() {
  728. if(settings.verbose && settings.debug) {
  729. if(settings.performance) {
  730. module.performance.log(arguments);
  731. }
  732. else {
  733. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  734. module.verbose.apply(console, arguments);
  735. }
  736. }
  737. },
  738. error: function() {
  739. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  740. module.error.apply(console, arguments);
  741. },
  742. performance: {
  743. log: function(message) {
  744. var
  745. currentTime,
  746. executionTime,
  747. previousTime
  748. ;
  749. if(settings.performance) {
  750. currentTime = new Date().getTime();
  751. previousTime = time || currentTime;
  752. executionTime = currentTime - previousTime;
  753. time = currentTime;
  754. performance.push({
  755. 'Name' : message[0],
  756. 'Arguments' : [].slice.call(message, 1) || '',
  757. 'Element' : element,
  758. 'Execution Time' : executionTime
  759. });
  760. }
  761. clearTimeout(module.performance.timer);
  762. module.performance.timer = setTimeout(module.performance.display, 100);
  763. },
  764. display: function() {
  765. var
  766. title = settings.name + ':',
  767. totalTime = 0
  768. ;
  769. time = false;
  770. clearTimeout(module.performance.timer);
  771. $.each(performance, function(index, data) {
  772. totalTime += data['Execution Time'];
  773. });
  774. title += ' ' + totalTime + 'ms';
  775. if(moduleSelector) {
  776. title += ' \'' + moduleSelector + '\'';
  777. }
  778. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  779. console.groupCollapsed(title);
  780. if(console.table) {
  781. console.table(performance);
  782. }
  783. else {
  784. $.each(performance, function(index, data) {
  785. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  786. });
  787. }
  788. console.groupEnd();
  789. }
  790. performance = [];
  791. }
  792. },
  793. invoke: function(query, passedArguments, context) {
  794. var
  795. object = instance,
  796. maxDepth,
  797. found,
  798. response
  799. ;
  800. passedArguments = passedArguments || queryArguments;
  801. context = element || context;
  802. if(typeof query == 'string' && object !== undefined) {
  803. query = query.split(/[\. ]/);
  804. maxDepth = query.length - 1;
  805. $.each(query, function(depth, value) {
  806. var camelCaseValue = (depth != maxDepth)
  807. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  808. : query
  809. ;
  810. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  811. object = object[camelCaseValue];
  812. }
  813. else if( object[camelCaseValue] !== undefined ) {
  814. found = object[camelCaseValue];
  815. return false;
  816. }
  817. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  818. object = object[value];
  819. }
  820. else if( object[value] !== undefined ) {
  821. found = object[value];
  822. return false;
  823. }
  824. else {
  825. return false;
  826. }
  827. });
  828. }
  829. if ( $.isFunction( found ) ) {
  830. response = found.apply(context, passedArguments);
  831. }
  832. else if(found !== undefined) {
  833. response = found;
  834. }
  835. if($.isArray(returnedValue)) {
  836. returnedValue.push(response);
  837. }
  838. else if(returnedValue !== undefined) {
  839. returnedValue = [returnedValue, response];
  840. }
  841. else if(response !== undefined) {
  842. returnedValue = response;
  843. }
  844. return found;
  845. }
  846. };
  847. if(methodInvoked) {
  848. if(instance === undefined) {
  849. module.initialize();
  850. }
  851. module.invoke(query);
  852. }
  853. else {
  854. if(instance !== undefined) {
  855. module.destroy();
  856. }
  857. module.initialize();
  858. }
  859. })
  860. ;
  861. return (returnedValue !== undefined)
  862. ? returnedValue
  863. : this
  864. ;
  865. };
  866. $.fn.popup.settings = {
  867. name : 'Popup',
  868. debug : false,
  869. verbose : true,
  870. performance : true,
  871. namespace : 'popup',
  872. onCreate : function(){},
  873. onRemove : function(){},
  874. onShow : function(){},
  875. onVisible : function(){},
  876. onHide : function(){},
  877. onHidden : function(){},
  878. variation : '',
  879. content : false,
  880. html : false,
  881. title : false,
  882. on : 'hover',
  883. closable : true,
  884. hideOnScroll : true,
  885. context : 'body',
  886. position : 'top left',
  887. delay : {
  888. show : 30,
  889. hide : 0
  890. },
  891. setFluidWidth : true,
  892. target : false,
  893. popup : false,
  894. inline : false,
  895. preserve : true,
  896. hoverable : false,
  897. duration : 200,
  898. easing : 'easeOutQuint',
  899. transition : 'scale',
  900. distanceAway : 0,
  901. offset : 0,
  902. maxSearchDepth : 10,
  903. error: {
  904. invalidPosition : 'The position you specified is not a valid position',
  905. method : 'The method you called is not defined.',
  906. recursion : 'Popup attempted to reposition element to fit, but could not find an adequate position.'
  907. },
  908. metadata: {
  909. content : 'content',
  910. html : 'html',
  911. offset : 'offset',
  912. position : 'position',
  913. title : 'title',
  914. variation : 'variation'
  915. },
  916. className : {
  917. active : 'active',
  918. animating : 'animating',
  919. dropdown : 'dropdown',
  920. fluid : 'fluid',
  921. loading : 'loading',
  922. popup : 'ui popup',
  923. position : 'top left center bottom right',
  924. visible : 'visible'
  925. },
  926. selector : {
  927. popup : '.ui.popup'
  928. },
  929. templates: {
  930. escape: function(string) {
  931. var
  932. badChars = /[&<>"'`]/g,
  933. shouldEscape = /[&<>"'`]/,
  934. escape = {
  935. "&": "&amp;",
  936. "<": "&lt;",
  937. ">": "&gt;",
  938. '"': "&quot;",
  939. "'": "&#x27;",
  940. "`": "&#x60;"
  941. },
  942. escapedChar = function(chr) {
  943. return escape[chr];
  944. }
  945. ;
  946. if(shouldEscape.test(string)) {
  947. return string.replace(badChars, escapedChar);
  948. }
  949. return string;
  950. },
  951. popup: function(text) {
  952. var
  953. html = '',
  954. escape = $.fn.popup.settings.templates.escape
  955. ;
  956. if(typeof text !== undefined) {
  957. if(typeof text.title !== undefined && text.title) {
  958. text.title = escape(text.title);
  959. html += '<div class="header">' + text.title + '</div>';
  960. }
  961. if(typeof text.content !== undefined && text.content) {
  962. text.content = escape(text.content);
  963. html += '<div class="content">' + text.content + '</div>';
  964. }
  965. }
  966. return html;
  967. }
  968. }
  969. };
  970. // Adds easing
  971. $.extend( $.easing, {
  972. easeOutQuad: function (x, t, b, c, d) {
  973. return -c *(t/=d)*(t-2) + b;
  974. }
  975. });
  976. })( jQuery, window , document );