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.

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