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.

1048 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
  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.remove();
  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.debug('Popup could not find a position onstage', $popup);
  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. if($popup && $popup.size() > 0) {
  620. $popup
  621. .on('mouseenter' + eventNamespace, module.event.start)
  622. .on('mouseleave' + eventNamespace, module.event.end)
  623. ;
  624. }
  625. },
  626. close:function() {
  627. if(settings.hideOnScroll === true || settings.hideOnScroll == 'auto' && settings.on != 'click') {
  628. $document
  629. .one('touchmove' + eventNamespace, module.hideGracefully)
  630. .one('scroll' + eventNamespace, module.hideGracefully)
  631. ;
  632. $context
  633. .one('touchmove' + eventNamespace, module.hideGracefully)
  634. .one('scroll' + eventNamespace, module.hideGracefully)
  635. ;
  636. }
  637. if(settings.on == 'click' && settings.closable) {
  638. module.verbose('Binding popup close event to document');
  639. $document
  640. .on('click' + eventNamespace, function(event) {
  641. module.verbose('Pop-up clickaway intent detected');
  642. $.proxy(module.hideGracefully, element)(event);
  643. })
  644. ;
  645. }
  646. }
  647. },
  648. unbind: {
  649. close: function() {
  650. if(settings.hideOnScroll === true || settings.hideOnScroll == 'auto' && settings.on != 'click') {
  651. $document
  652. .off('scroll' + eventNamespace, module.hide)
  653. ;
  654. $context
  655. .off('scroll' + eventNamespace, module.hide)
  656. ;
  657. }
  658. if(settings.on == 'click' && settings.closable) {
  659. module.verbose('Removing close event from document');
  660. $document
  661. .off('click' + eventNamespace)
  662. ;
  663. }
  664. }
  665. },
  666. is: {
  667. active: function() {
  668. return $module.hasClass(className.active);
  669. },
  670. animating: function() {
  671. return ( $popup && $popup.is(':animated') || $popup.hasClass(className.animating) );
  672. },
  673. visible: function() {
  674. return $popup && $popup.is(':visible');
  675. },
  676. dropdown: function() {
  677. return $module.hasClass(className.dropdown);
  678. },
  679. hidden: function() {
  680. return !module.is.visible();
  681. }
  682. },
  683. reset: function() {
  684. module.remove.visible();
  685. if(settings.preserve || settings.popup) {
  686. if($.fn.transition !== undefined) {
  687. $popup
  688. .transition('remove transition')
  689. ;
  690. }
  691. }
  692. else {
  693. module.removePopup();
  694. }
  695. },
  696. setting: function(name, value) {
  697. if( $.isPlainObject(name) ) {
  698. $.extend(true, settings, name);
  699. }
  700. else if(value !== undefined) {
  701. settings[name] = value;
  702. }
  703. else {
  704. return settings[name];
  705. }
  706. },
  707. internal: function(name, value) {
  708. if( $.isPlainObject(name) ) {
  709. $.extend(true, module, name);
  710. }
  711. else if(value !== undefined) {
  712. module[name] = value;
  713. }
  714. else {
  715. return module[name];
  716. }
  717. },
  718. debug: function() {
  719. if(settings.debug) {
  720. if(settings.performance) {
  721. module.performance.log(arguments);
  722. }
  723. else {
  724. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  725. module.debug.apply(console, arguments);
  726. }
  727. }
  728. },
  729. verbose: function() {
  730. if(settings.verbose && settings.debug) {
  731. if(settings.performance) {
  732. module.performance.log(arguments);
  733. }
  734. else {
  735. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  736. module.verbose.apply(console, arguments);
  737. }
  738. }
  739. },
  740. error: function() {
  741. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  742. module.error.apply(console, arguments);
  743. },
  744. performance: {
  745. log: function(message) {
  746. var
  747. currentTime,
  748. executionTime,
  749. previousTime
  750. ;
  751. if(settings.performance) {
  752. currentTime = new Date().getTime();
  753. previousTime = time || currentTime;
  754. executionTime = currentTime - previousTime;
  755. time = currentTime;
  756. performance.push({
  757. 'Name' : message[0],
  758. 'Arguments' : [].slice.call(message, 1) || '',
  759. 'Element' : element,
  760. 'Execution Time' : executionTime
  761. });
  762. }
  763. clearTimeout(module.performance.timer);
  764. module.performance.timer = setTimeout(module.performance.display, 100);
  765. },
  766. display: function() {
  767. var
  768. title = settings.name + ':',
  769. totalTime = 0
  770. ;
  771. time = false;
  772. clearTimeout(module.performance.timer);
  773. $.each(performance, function(index, data) {
  774. totalTime += data['Execution Time'];
  775. });
  776. title += ' ' + totalTime + 'ms';
  777. if(moduleSelector) {
  778. title += ' \'' + moduleSelector + '\'';
  779. }
  780. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  781. console.groupCollapsed(title);
  782. if(console.table) {
  783. console.table(performance);
  784. }
  785. else {
  786. $.each(performance, function(index, data) {
  787. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  788. });
  789. }
  790. console.groupEnd();
  791. }
  792. performance = [];
  793. }
  794. },
  795. invoke: function(query, passedArguments, context) {
  796. var
  797. object = instance,
  798. maxDepth,
  799. found,
  800. response
  801. ;
  802. passedArguments = passedArguments || queryArguments;
  803. context = element || context;
  804. if(typeof query == 'string' && object !== undefined) {
  805. query = query.split(/[\. ]/);
  806. maxDepth = query.length - 1;
  807. $.each(query, function(depth, value) {
  808. var camelCaseValue = (depth != maxDepth)
  809. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  810. : query
  811. ;
  812. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  813. object = object[camelCaseValue];
  814. }
  815. else if( object[camelCaseValue] !== undefined ) {
  816. found = object[camelCaseValue];
  817. return false;
  818. }
  819. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  820. object = object[value];
  821. }
  822. else if( object[value] !== undefined ) {
  823. found = object[value];
  824. return false;
  825. }
  826. else {
  827. return false;
  828. }
  829. });
  830. }
  831. if ( $.isFunction( found ) ) {
  832. response = found.apply(context, passedArguments);
  833. }
  834. else if(found !== undefined) {
  835. response = found;
  836. }
  837. if($.isArray(returnedValue)) {
  838. returnedValue.push(response);
  839. }
  840. else if(returnedValue !== undefined) {
  841. returnedValue = [returnedValue, response];
  842. }
  843. else if(response !== undefined) {
  844. returnedValue = response;
  845. }
  846. return found;
  847. }
  848. };
  849. if(methodInvoked) {
  850. if(instance === undefined) {
  851. module.initialize();
  852. }
  853. module.invoke(query);
  854. }
  855. else {
  856. if(instance !== undefined) {
  857. module.destroy();
  858. }
  859. module.initialize();
  860. }
  861. })
  862. ;
  863. return (returnedValue !== undefined)
  864. ? returnedValue
  865. : this
  866. ;
  867. };
  868. $.fn.popup.settings = {
  869. name : 'Popup',
  870. debug : false,
  871. verbose : true,
  872. performance : true,
  873. namespace : 'popup',
  874. onCreate : function(){},
  875. onRemove : function(){},
  876. onShow : function(){},
  877. onVisible : function(){},
  878. onHide : function(){},
  879. onHidden : function(){},
  880. variation : '',
  881. content : false,
  882. html : false,
  883. title : false,
  884. on : 'hover',
  885. closable : true,
  886. hideOnScroll : 'auto',
  887. context : 'body',
  888. position : 'top left',
  889. delay : {
  890. show : 30,
  891. hide : 0
  892. },
  893. setFluidWidth : true,
  894. target : false,
  895. popup : false,
  896. inline : false,
  897. preserve : true,
  898. hoverable : false,
  899. duration : 200,
  900. easing : 'easeOutQuint',
  901. transition : 'scale',
  902. distanceAway : 0,
  903. offset : 0,
  904. maxSearchDepth : 10,
  905. error: {
  906. invalidPosition : 'The position you specified is not a valid position',
  907. method : 'The method you called is not defined.'
  908. },
  909. metadata: {
  910. content : 'content',
  911. html : 'html',
  912. offset : 'offset',
  913. position : 'position',
  914. title : 'title',
  915. variation : 'variation'
  916. },
  917. className : {
  918. active : 'active',
  919. animating : 'animating',
  920. dropdown : 'dropdown',
  921. fluid : 'fluid',
  922. loading : 'loading',
  923. popup : 'ui popup',
  924. position : 'top left center bottom right',
  925. visible : 'visible'
  926. },
  927. selector : {
  928. popup : '.ui.popup'
  929. },
  930. templates: {
  931. escape: function(string) {
  932. var
  933. badChars = /[&<>"'`]/g,
  934. shouldEscape = /[&<>"'`]/,
  935. escape = {
  936. "&": "&amp;",
  937. "<": "&lt;",
  938. ">": "&gt;",
  939. '"': "&quot;",
  940. "'": "&#x27;",
  941. "`": "&#x60;"
  942. },
  943. escapedChar = function(chr) {
  944. return escape[chr];
  945. }
  946. ;
  947. if(shouldEscape.test(string)) {
  948. return string.replace(badChars, escapedChar);
  949. }
  950. return string;
  951. },
  952. popup: function(text) {
  953. var
  954. html = '',
  955. escape = $.fn.popup.settings.templates.escape
  956. ;
  957. if(typeof text !== undefined) {
  958. if(typeof text.title !== undefined && text.title) {
  959. text.title = escape(text.title);
  960. html += '<div class="header">' + text.title + '</div>';
  961. }
  962. if(typeof text.content !== undefined && text.content) {
  963. text.content = escape(text.content);
  964. html += '<div class="content">' + text.content + '</div>';
  965. }
  966. }
  967. return html;
  968. }
  969. }
  970. };
  971. // Adds easing
  972. $.extend( $.easing, {
  973. easeOutQuad: function (x, t, b, c, d) {
  974. return -c *(t/=d)*(t-2) + b;
  975. }
  976. });
  977. })( jQuery, window , document );