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.

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