forked from website/openpower.foundation
				
			
			You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			1524 lines
		
	
	
		
			49 KiB
		
	
	
	
		
			JavaScript
		
	
			
		
		
	
	
			1524 lines
		
	
	
		
			49 KiB
		
	
	
	
		
			JavaScript
		
	
| /*!
 | |
|  * # Semantic UI 2.3.0 - Popup
 | |
|  * http://github.com/semantic-org/semantic-ui/
 | |
|  *
 | |
|  *
 | |
|  * Released under the MIT license
 | |
|  * http://opensource.org/licenses/MIT
 | |
|  *
 | |
|  */
 | |
| 
 | |
| ;(function ($, window, document, undefined) {
 | |
| 
 | |
| "use strict";
 | |
| 
 | |
| window = (typeof window != 'undefined' && window.Math == Math)
 | |
|   ? window
 | |
|   : (typeof self != 'undefined' && self.Math == Math)
 | |
|     ? self
 | |
|     : Function('return this')()
 | |
| ;
 | |
| 
 | |
| $.fn.popup = function(parameters) {
 | |
|   var
 | |
|     $allModules    = $(this),
 | |
|     $document      = $(document),
 | |
|     $window        = $(window),
 | |
|     $body          = $('body'),
 | |
| 
 | |
|     moduleSelector = $allModules.selector || '',
 | |
| 
 | |
|     hasTouch       = (true),
 | |
|     time           = new Date().getTime(),
 | |
|     performance    = [],
 | |
| 
 | |
|     query          = arguments[0],
 | |
|     methodInvoked  = (typeof query == 'string'),
 | |
|     queryArguments = [].slice.call(arguments, 1),
 | |
| 
 | |
|     returnedValue
 | |
|   ;
 | |
|   $allModules
 | |
|     .each(function() {
 | |
|       var
 | |
|         settings        = ( $.isPlainObject(parameters) )
 | |
|           ? $.extend(true, {}, $.fn.popup.settings, parameters)
 | |
|           : $.extend({}, $.fn.popup.settings),
 | |
| 
 | |
|         selector           = settings.selector,
 | |
|         className          = settings.className,
 | |
|         error              = settings.error,
 | |
|         metadata           = settings.metadata,
 | |
|         namespace          = settings.namespace,
 | |
| 
 | |
|         eventNamespace     = '.' + settings.namespace,
 | |
|         moduleNamespace    = 'module-' + namespace,
 | |
| 
 | |
|         $module            = $(this),
 | |
|         $context           = $(settings.context),
 | |
|         $scrollContext     = $(settings.scrollContext),
 | |
|         $boundary          = $(settings.boundary),
 | |
|         $target            = (settings.target)
 | |
|           ? $(settings.target)
 | |
|           : $module,
 | |
| 
 | |
|         $popup,
 | |
|         $offsetParent,
 | |
| 
 | |
|         searchDepth        = 0,
 | |
|         triedPositions     = false,
 | |
|         openedWithTouch    = false,
 | |
| 
 | |
|         element            = this,
 | |
|         instance           = $module.data(moduleNamespace),
 | |
| 
 | |
|         documentObserver,
 | |
|         elementNamespace,
 | |
|         id,
 | |
|         module
 | |
|       ;
 | |
| 
 | |
|       module = {
 | |
| 
 | |
|         // binds events
 | |
|         initialize: function() {
 | |
|           module.debug('Initializing', $module);
 | |
|           module.createID();
 | |
|           module.bind.events();
 | |
|           if(!module.exists() && settings.preserve) {
 | |
|             module.create();
 | |
|           }
 | |
|           if(settings.observeChanges) {
 | |
|             module.observeChanges();
 | |
|           }
 | |
|           module.instantiate();
 | |
|         },
 | |
| 
 | |
|         instantiate: function() {
 | |
|           module.verbose('Storing instance', module);
 | |
|           instance = module;
 | |
|           $module
 | |
|             .data(moduleNamespace, instance)
 | |
|           ;
 | |
|         },
 | |
| 
 | |
|         observeChanges: function() {
 | |
|           if('MutationObserver' in window) {
 | |
|             documentObserver = new MutationObserver(module.event.documentChanged);
 | |
|             documentObserver.observe(document, {
 | |
|               childList : true,
 | |
|               subtree   : true
 | |
|             });
 | |
|             module.debug('Setting up mutation observer', documentObserver);
 | |
|           }
 | |
|         },
 | |
| 
 | |
|         refresh: function() {
 | |
|           if(settings.popup) {
 | |
|             $popup = $(settings.popup).eq(0);
 | |
|           }
 | |
|           else {
 | |
|             if(settings.inline) {
 | |
|               $popup = $target.nextAll(selector.popup).eq(0);
 | |
|               settings.popup = $popup;
 | |
|             }
 | |
|           }
 | |
|           if(settings.popup) {
 | |
|             $popup.addClass(className.loading);
 | |
|             $offsetParent = module.get.offsetParent();
 | |
|             $popup.removeClass(className.loading);
 | |
|             if(settings.movePopup && module.has.popup() && module.get.offsetParent($popup)[0] !== $offsetParent[0]) {
 | |
|               module.debug('Moving popup to the same offset parent as target');
 | |
|               $popup
 | |
|                 .detach()
 | |
|                 .appendTo($offsetParent)
 | |
|               ;
 | |
|             }
 | |
|           }
 | |
|           else {
 | |
|             $offsetParent = (settings.inline)
 | |
|               ? module.get.offsetParent($target)
 | |
|               : module.has.popup()
 | |
|                 ? module.get.offsetParent($popup)
 | |
|                 : $body
 | |
|             ;
 | |
|           }
 | |
|           if( $offsetParent.is('html') && $offsetParent[0] !== $body[0] ) {
 | |
|             module.debug('Setting page as offset parent');
 | |
|             $offsetParent = $body;
 | |
|           }
 | |
|           if( module.get.variation() ) {
 | |
|             module.set.variation();
 | |
|           }
 | |
|         },
 | |
| 
 | |
|         reposition: function() {
 | |
|           module.refresh();
 | |
|           module.set.position();
 | |
|         },
 | |
| 
 | |
|         destroy: function() {
 | |
|           module.debug('Destroying previous module');
 | |
|           if(documentObserver) {
 | |
|             documentObserver.disconnect();
 | |
|           }
 | |
|           // remove element only if was created dynamically
 | |
|           if($popup && !settings.preserve) {
 | |
|             module.removePopup();
 | |
|           }
 | |
|           // clear all timeouts
 | |
|           clearTimeout(module.hideTimer);
 | |
|           clearTimeout(module.showTimer);
 | |
|           // remove events
 | |
|           module.unbind.close();
 | |
|           module.unbind.events();
 | |
|           $module
 | |
|             .removeData(moduleNamespace)
 | |
|           ;
 | |
|         },
 | |
| 
 | |
|         event: {
 | |
|           start:  function(event) {
 | |
|             var
 | |
|               delay = ($.isPlainObject(settings.delay))
 | |
|                 ? settings.delay.show
 | |
|                 : settings.delay
 | |
|             ;
 | |
|             clearTimeout(module.hideTimer);
 | |
|             if(!openedWithTouch) {
 | |
|               module.showTimer = setTimeout(module.show, delay);
 | |
|             }
 | |
|           },
 | |
|           end:  function() {
 | |
|             var
 | |
|               delay = ($.isPlainObject(settings.delay))
 | |
|                 ? settings.delay.hide
 | |
|                 : settings.delay
 | |
|             ;
 | |
|             clearTimeout(module.showTimer);
 | |
|             module.hideTimer = setTimeout(module.hide, delay);
 | |
|           },
 | |
|           touchstart: function(event) {
 | |
|             openedWithTouch = true;
 | |
|             module.show();
 | |
|           },
 | |
|           resize: function() {
 | |
|             if( module.is.visible() ) {
 | |
|               module.set.position();
 | |
|             }
 | |
|           },
 | |
|           documentChanged: function(mutations) {
 | |
|             [].forEach.call(mutations, function(mutation) {
 | |
|               if(mutation.removedNodes) {
 | |
|                 [].forEach.call(mutation.removedNodes, function(node) {
 | |
|                   if(node == element || $(node).find(element).length > 0) {
 | |
|                     module.debug('Element removed from DOM, tearing down events');
 | |
|                     module.destroy();
 | |
|                   }
 | |
|                 });
 | |
|               }
 | |
|             });
 | |
|           },
 | |
|           hideGracefully: function(event) {
 | |
|             var
 | |
|               $target = $(event.target),
 | |
|               isInDOM = $.contains(document.documentElement, event.target),
 | |
|               inPopup = ($target.closest(selector.popup).length > 0)
 | |
|             ;
 | |
|             // don't close on clicks inside popup
 | |
|             if(event && !inPopup && isInDOM) {
 | |
|               module.debug('Click occurred outside popup hiding popup');
 | |
|               module.hide();
 | |
|             }
 | |
|             else {
 | |
|               module.debug('Click was inside popup, keeping popup open');
 | |
|             }
 | |
|           }
 | |
|         },
 | |
| 
 | |
|         // generates popup html from metadata
 | |
|         create: function() {
 | |
|           var
 | |
|             html      = module.get.html(),
 | |
|             title     = module.get.title(),
 | |
|             content   = module.get.content()
 | |
|           ;
 | |
| 
 | |
|           if(html || content || title) {
 | |
|             module.debug('Creating pop-up html');
 | |
|             if(!html) {
 | |
|               html = settings.templates.popup({
 | |
|                 title   : title,
 | |
|                 content : content
 | |
|               });
 | |
|             }
 | |
|             $popup = $('<div/>')
 | |
|               .addClass(className.popup)
 | |
|               .data(metadata.activator, $module)
 | |
|               .html(html)
 | |
|             ;
 | |
|             if(settings.inline) {
 | |
|               module.verbose('Inserting popup element inline', $popup);
 | |
|               $popup
 | |
|                 .insertAfter($module)
 | |
|               ;
 | |
|             }
 | |
|             else {
 | |
|               module.verbose('Appending popup element to body', $popup);
 | |
|               $popup
 | |
|                 .appendTo( $context )
 | |
|               ;
 | |
|             }
 | |
|             module.refresh();
 | |
|             module.set.variation();
 | |
| 
 | |
|             if(settings.hoverable) {
 | |
|               module.bind.popup();
 | |
|             }
 | |
|             settings.onCreate.call($popup, element);
 | |
|           }
 | |
|           else if($target.next(selector.popup).length !== 0) {
 | |
|             module.verbose('Pre-existing popup found');
 | |
|             settings.inline = true;
 | |
|             settings.popup  = $target.next(selector.popup).data(metadata.activator, $module);
 | |
|             module.refresh();
 | |
|             if(settings.hoverable) {
 | |
|               module.bind.popup();
 | |
|             }
 | |
|           }
 | |
|           else if(settings.popup) {
 | |
|             $(settings.popup).data(metadata.activator, $module);
 | |
|             module.verbose('Used popup specified in settings');
 | |
|             module.refresh();
 | |
|             if(settings.hoverable) {
 | |
|               module.bind.popup();
 | |
|             }
 | |
|           }
 | |
|           else {
 | |
|             module.debug('No content specified skipping display', element);
 | |
|           }
 | |
|         },
 | |
| 
 | |
|         createID: function() {
 | |
|           id = (Math.random().toString(16) + '000000000').substr(2, 8);
 | |
|           elementNamespace = '.' + id;
 | |
|           module.verbose('Creating unique id for element', id);
 | |
|         },
 | |
| 
 | |
|         // determines popup state
 | |
|         toggle: function() {
 | |
|           module.debug('Toggling pop-up');
 | |
|           if( module.is.hidden() ) {
 | |
|             module.debug('Popup is hidden, showing pop-up');
 | |
|             module.unbind.close();
 | |
|             module.show();
 | |
|           }
 | |
|           else {
 | |
|             module.debug('Popup is visible, hiding pop-up');
 | |
|             module.hide();
 | |
|           }
 | |
|         },
 | |
| 
 | |
|         show: function(callback) {
 | |
|           callback = callback || function(){};
 | |
|           module.debug('Showing pop-up', settings.transition);
 | |
|           if(module.is.hidden() && !( module.is.active() && module.is.dropdown()) ) {
 | |
|             if( !module.exists() ) {
 | |
|               module.create();
 | |
|             }
 | |
|             if(settings.onShow.call($popup, element) === false) {
 | |
|               module.debug('onShow callback returned false, cancelling popup animation');
 | |
|               return;
 | |
|             }
 | |
|             else if(!settings.preserve && !settings.popup) {
 | |
|               module.refresh();
 | |
|             }
 | |
|             if( $popup && module.set.position() ) {
 | |
|               module.save.conditions();
 | |
|               if(settings.exclusive) {
 | |
|                 module.hideAll();
 | |
|               }
 | |
|               module.animate.show(callback);
 | |
|             }
 | |
|           }
 | |
|         },
 | |
| 
 | |
| 
 | |
|         hide: function(callback) {
 | |
|           callback = callback || function(){};
 | |
|           if( module.is.visible() || module.is.animating() ) {
 | |
|             if(settings.onHide.call($popup, element) === false) {
 | |
|               module.debug('onHide callback returned false, cancelling popup animation');
 | |
|               return;
 | |
|             }
 | |
|             module.remove.visible();
 | |
|             module.unbind.close();
 | |
|             module.restore.conditions();
 | |
|             module.animate.hide(callback);
 | |
|           }
 | |
|         },
 | |
| 
 | |
|         hideAll: function() {
 | |
|           $(selector.popup)
 | |
|             .filter('.' + className.popupVisible)
 | |
|             .each(function() {
 | |
|               $(this)
 | |
|                 .data(metadata.activator)
 | |
|                   .popup('hide')
 | |
|               ;
 | |
|             })
 | |
|           ;
 | |
|         },
 | |
|         exists: function() {
 | |
|           if(!$popup) {
 | |
|             return false;
 | |
|           }
 | |
|           if(settings.inline || settings.popup) {
 | |
|             return ( module.has.popup() );
 | |
|           }
 | |
|           else {
 | |
|             return ( $popup.closest($context).length >= 1 )
 | |
|               ? true
 | |
|               : false
 | |
|             ;
 | |
|           }
 | |
|         },
 | |
| 
 | |
|         removePopup: function() {
 | |
|           if( module.has.popup() && !settings.popup) {
 | |
|             module.debug('Removing popup', $popup);
 | |
|             $popup.remove();
 | |
|             $popup = undefined;
 | |
|             settings.onRemove.call($popup, element);
 | |
|           }
 | |
|         },
 | |
| 
 | |
|         save: {
 | |
|           conditions: function() {
 | |
|             module.cache = {
 | |
|               title: $module.attr('title')
 | |
|             };
 | |
|             if (module.cache.title) {
 | |
|               $module.removeAttr('title');
 | |
|             }
 | |
|             module.verbose('Saving original attributes', module.cache.title);
 | |
|           }
 | |
|         },
 | |
|         restore: {
 | |
|           conditions: function() {
 | |
|             if(module.cache && module.cache.title) {
 | |
|               $module.attr('title', module.cache.title);
 | |
|               module.verbose('Restoring original attributes', module.cache.title);
 | |
|             }
 | |
|             return true;
 | |
|           }
 | |
|         },
 | |
|         supports: {
 | |
|           svg: function() {
 | |
|             return (typeof SVGGraphicsElement === 'undefined');
 | |
|           }
 | |
|         },
 | |
|         animate: {
 | |
|           show: function(callback) {
 | |
|             callback = $.isFunction(callback) ? callback : function(){};
 | |
|             if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
 | |
|               module.set.visible();
 | |
|               $popup
 | |
|                 .transition({
 | |
|                   animation  : settings.transition + ' in',
 | |
|                   queue      : false,
 | |
|                   debug      : settings.debug,
 | |
|                   verbose    : settings.verbose,
 | |
|                   duration   : settings.duration,
 | |
|                   onComplete : function() {
 | |
|                     module.bind.close();
 | |
|                     callback.call($popup, element);
 | |
|                     settings.onVisible.call($popup, element);
 | |
|                   }
 | |
|                 })
 | |
|               ;
 | |
|             }
 | |
|             else {
 | |
|               module.error(error.noTransition);
 | |
|             }
 | |
|           },
 | |
|           hide: function(callback) {
 | |
|             callback = $.isFunction(callback) ? callback : function(){};
 | |
|             module.debug('Hiding pop-up');
 | |
|             if(settings.onHide.call($popup, element) === false) {
 | |
|               module.debug('onHide callback returned false, cancelling popup animation');
 | |
|               return;
 | |
|             }
 | |
|             if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
 | |
|               $popup
 | |
|                 .transition({
 | |
|                   animation  : settings.transition + ' out',
 | |
|                   queue      : false,
 | |
|                   duration   : settings.duration,
 | |
|                   debug      : settings.debug,
 | |
|                   verbose    : settings.verbose,
 | |
|                   onComplete : function() {
 | |
|                     module.reset();
 | |
|                     callback.call($popup, element);
 | |
|                     settings.onHidden.call($popup, element);
 | |
|                   }
 | |
|                 })
 | |
|               ;
 | |
|             }
 | |
|             else {
 | |
|               module.error(error.noTransition);
 | |
|             }
 | |
|           }
 | |
|         },
 | |
| 
 | |
|         change: {
 | |
|           content: function(html) {
 | |
|             $popup.html(html);
 | |
|           }
 | |
|         },
 | |
| 
 | |
|         get: {
 | |
|           html: function() {
 | |
|             $module.removeData(metadata.html);
 | |
|             return $module.data(metadata.html) || settings.html;
 | |
|           },
 | |
|           title: function() {
 | |
|             $module.removeData(metadata.title);
 | |
|             return $module.data(metadata.title) || settings.title;
 | |
|           },
 | |
|           content: function() {
 | |
|             $module.removeData(metadata.content);
 | |
|             return $module.data(metadata.content) || settings.content || $module.attr('title');
 | |
|           },
 | |
|           variation: function() {
 | |
|             $module.removeData(metadata.variation);
 | |
|             return $module.data(metadata.variation) || settings.variation;
 | |
|           },
 | |
|           popup: function() {
 | |
|             return $popup;
 | |
|           },
 | |
|           popupOffset: function() {
 | |
|             return $popup.offset();
 | |
|           },
 | |
|           calculations: function() {
 | |
|             var
 | |
|               $popupOffsetParent = module.get.offsetParent($popup),
 | |
|               targetElement      = $target[0],
 | |
|               isWindow           = ($boundary[0] == window),
 | |
|               targetPosition     = (settings.inline || (settings.popup && settings.movePopup))
 | |
|                 ? $target.position()
 | |
|                 : $target.offset(),
 | |
|               screenPosition = (isWindow)
 | |
|                 ? { top: 0, left: 0 }
 | |
|                 : $boundary.offset(),
 | |
|               calculations   = {},
 | |
|               scroll = (isWindow)
 | |
|                 ? { top: $window.scrollTop(), left: $window.scrollLeft() }
 | |
|                 : { top: 0, left: 0},
 | |
|               screen
 | |
|             ;
 | |
|             calculations = {
 | |
|               // element which is launching popup
 | |
|               target : {
 | |
|                 element : $target[0],
 | |
|                 width   : $target.outerWidth(),
 | |
|                 height  : $target.outerHeight(),
 | |
|                 top     : targetPosition.top,
 | |
|                 left    : targetPosition.left,
 | |
|                 margin  : {}
 | |
|               },
 | |
|               // popup itself
 | |
|               popup : {
 | |
|                 width  : $popup.outerWidth(),
 | |
|                 height : $popup.outerHeight()
 | |
|               },
 | |
|               // offset container (or 3d context)
 | |
|               parent : {
 | |
|                 width  : $offsetParent.outerWidth(),
 | |
|                 height : $offsetParent.outerHeight()
 | |
|               },
 | |
|               // screen boundaries
 | |
|               screen : {
 | |
|                 top  : screenPosition.top,
 | |
|                 left : screenPosition.left,
 | |
|                 scroll: {
 | |
|                   top  : scroll.top,
 | |
|                   left : scroll.left
 | |
|                 },
 | |
|                 width  : $boundary.width(),
 | |
|                 height : $boundary.height()
 | |
|               }
 | |
|             };
 | |
| 
 | |
|             // if popup offset context is not same as target, then adjust calculations
 | |
|             if($popupOffsetParent.get(0) !== $offsetParent.get(0)) {
 | |
|               var
 | |
|                 popupOffset        = $popupOffsetParent.offset()
 | |
|               ;
 | |
|               calculations.target.top -= popupOffset.top;
 | |
|               calculations.target.left -= popupOffset.left;
 | |
|               calculations.parent.width = $popupOffsetParent.outerWidth();
 | |
|               calculations.parent.height = $popupOffsetParent.outerHeight();
 | |
|             }
 | |
| 
 | |
|             // add in container calcs if fluid
 | |
|             if( settings.setFluidWidth && module.is.fluid() ) {
 | |
|               calculations.container = {
 | |
|                 width: $popup.parent().outerWidth()
 | |
|               };
 | |
|               calculations.popup.width = calculations.container.width;
 | |
|             }
 | |
| 
 | |
|             // add in margins if inline
 | |
|             calculations.target.margin.top = (settings.inline)
 | |
|               ? parseInt( window.getComputedStyle(targetElement).getPropertyValue('margin-top'), 10)
 | |
|               : 0
 | |
|             ;
 | |
|             calculations.target.margin.left = (settings.inline)
 | |
|               ? module.is.rtl()
 | |
|                 ? parseInt( window.getComputedStyle(targetElement).getPropertyValue('margin-right'), 10)
 | |
|                 : parseInt( window.getComputedStyle(targetElement).getPropertyValue('margin-left'), 10)
 | |
|               : 0
 | |
|             ;
 | |
|             // calculate screen boundaries
 | |
|             screen = calculations.screen;
 | |
|             calculations.boundary = {
 | |
|               top    : screen.top + screen.scroll.top,
 | |
|               bottom : screen.top + screen.scroll.top + screen.height,
 | |
|               left   : screen.left + screen.scroll.left,
 | |
|               right  : screen.left + screen.scroll.left + screen.width
 | |
|             };
 | |
|             return calculations;
 | |
|           },
 | |
|           id: function() {
 | |
|             return id;
 | |
|           },
 | |
|           startEvent: function() {
 | |
|             if(settings.on == 'hover') {
 | |
|               return 'mouseenter';
 | |
|             }
 | |
|             else if(settings.on == 'focus') {
 | |
|               return 'focus';
 | |
|             }
 | |
|             return false;
 | |
|           },
 | |
|           scrollEvent: function() {
 | |
|             return 'scroll';
 | |
|           },
 | |
|           endEvent: function() {
 | |
|             if(settings.on == 'hover') {
 | |
|               return 'mouseleave';
 | |
|             }
 | |
|             else if(settings.on == 'focus') {
 | |
|               return 'blur';
 | |
|             }
 | |
|             return false;
 | |
|           },
 | |
|           distanceFromBoundary: function(offset, calculations) {
 | |
|             var
 | |
|               distanceFromBoundary = {},
 | |
|               popup,
 | |
|               boundary
 | |
|             ;
 | |
|             calculations = calculations || module.get.calculations();
 | |
| 
 | |
|             // shorthand
 | |
|             popup        = calculations.popup;
 | |
|             boundary     = calculations.boundary;
 | |
| 
 | |
|             if(offset) {
 | |
|               distanceFromBoundary = {
 | |
|                 top    : (offset.top - boundary.top),
 | |
|                 left   : (offset.left - boundary.left),
 | |
|                 right  : (boundary.right - (offset.left + popup.width) ),
 | |
|                 bottom : (boundary.bottom - (offset.top + popup.height) )
 | |
|               };
 | |
|               module.verbose('Distance from boundaries determined', offset, distanceFromBoundary);
 | |
|             }
 | |
|             return distanceFromBoundary;
 | |
|           },
 | |
|           offsetParent: function($element) {
 | |
|             var
 | |
|               element = ($element !== undefined)
 | |
|                 ? $element[0]
 | |
|                 : $target[0],
 | |
|               parentNode = element.parentNode,
 | |
|               $node    = $(parentNode)
 | |
|             ;
 | |
|             if(parentNode) {
 | |
|               var
 | |
|                 is2D     = ($node.css('transform') === 'none'),
 | |
|                 isStatic = ($node.css('position') === 'static'),
 | |
|                 isBody   = $node.is('body')
 | |
|               ;
 | |
|               while(parentNode && !isBody && isStatic && is2D) {
 | |
|                 parentNode = parentNode.parentNode;
 | |
|                 $node    = $(parentNode);
 | |
|                 is2D     = ($node.css('transform') === 'none');
 | |
|                 isStatic = ($node.css('position') === 'static');
 | |
|                 isBody   = $node.is('body');
 | |
|               }
 | |
|             }
 | |
|             return ($node && $node.length > 0)
 | |
|               ? $node
 | |
|               : $()
 | |
|             ;
 | |
|           },
 | |
|           positions: function() {
 | |
|             return {
 | |
|               'top left'      : false,
 | |
|               'top center'    : false,
 | |
|               'top right'     : false,
 | |
|               'bottom left'   : false,
 | |
|               'bottom center' : false,
 | |
|               'bottom right'  : false,
 | |
|               'left center'   : false,
 | |
|               'right center'  : false
 | |
|             };
 | |
|           },
 | |
|           nextPosition: function(position) {
 | |
|             var
 | |
|               positions          = position.split(' '),
 | |
|               verticalPosition   = positions[0],
 | |
|               horizontalPosition = positions[1],
 | |
|               opposite = {
 | |
|                 top    : 'bottom',
 | |
|                 bottom : 'top',
 | |
|                 left   : 'right',
 | |
|                 right  : 'left'
 | |
|               },
 | |
|               adjacent = {
 | |
|                 left   : 'center',
 | |
|                 center : 'right',
 | |
|                 right  : 'left'
 | |
|               },
 | |
|               backup = {
 | |
|                 'top left'      : 'top center',
 | |
|                 'top center'    : 'top right',
 | |
|                 'top right'     : 'right center',
 | |
|                 'right center'  : 'bottom right',
 | |
|                 'bottom right'  : 'bottom center',
 | |
|                 'bottom center' : 'bottom left',
 | |
|                 'bottom left'   : 'left center',
 | |
|                 'left center'   : 'top left'
 | |
|               },
 | |
|               adjacentsAvailable = (verticalPosition == 'top' || verticalPosition == 'bottom'),
 | |
|               oppositeTried = false,
 | |
|               adjacentTried = false,
 | |
|               nextPosition  = false
 | |
|             ;
 | |
|             if(!triedPositions) {
 | |
|               module.verbose('All available positions available');
 | |
|               triedPositions = module.get.positions();
 | |
|             }
 | |
| 
 | |
|             module.debug('Recording last position tried', position);
 | |
|             triedPositions[position] = true;
 | |
| 
 | |
|             if(settings.prefer === 'opposite') {
 | |
|               nextPosition  = [opposite[verticalPosition], horizontalPosition];
 | |
|               nextPosition  = nextPosition.join(' ');
 | |
|               oppositeTried = (triedPositions[nextPosition] === true);
 | |
|               module.debug('Trying opposite strategy', nextPosition);
 | |
|             }
 | |
|             if((settings.prefer === 'adjacent') && adjacentsAvailable ) {
 | |
|               nextPosition  = [verticalPosition, adjacent[horizontalPosition]];
 | |
|               nextPosition  = nextPosition.join(' ');
 | |
|               adjacentTried = (triedPositions[nextPosition] === true);
 | |
|               module.debug('Trying adjacent strategy', nextPosition);
 | |
|             }
 | |
|             if(adjacentTried || oppositeTried) {
 | |
|               module.debug('Using backup position', nextPosition);
 | |
|               nextPosition = backup[position];
 | |
|             }
 | |
|             return nextPosition;
 | |
|           }
 | |
|         },
 | |
| 
 | |
|         set: {
 | |
|           position: function(position, calculations) {
 | |
| 
 | |
|             // exit conditions
 | |
|             if($target.length === 0 || $popup.length === 0) {
 | |
|               module.error(error.notFound);
 | |
|               return;
 | |
|             }
 | |
|             var
 | |
|               offset,
 | |
|               distanceAway,
 | |
|               target,
 | |
|               popup,
 | |
|               parent,
 | |
|               positioning,
 | |
|               popupOffset,
 | |
|               distanceFromBoundary
 | |
|             ;
 | |
| 
 | |
|             calculations = calculations || module.get.calculations();
 | |
|             position     = position     || $module.data(metadata.position) || settings.position;
 | |
| 
 | |
|             offset       = $module.data(metadata.offset) || settings.offset;
 | |
|             distanceAway = settings.distanceAway;
 | |
| 
 | |
|             // shorthand
 | |
|             target = calculations.target;
 | |
|             popup  = calculations.popup;
 | |
|             parent = calculations.parent;
 | |
| 
 | |
|             if(module.should.centerArrow(calculations)) {
 | |
|               module.verbose('Adjusting offset to center arrow on small target element');
 | |
|               if(position == 'top left' || position == 'bottom left') {
 | |
|                 offset += (target.width / 2)
 | |
|                 offset -= settings.arrowPixelsFromEdge;
 | |
|               }
 | |
|               if(position == 'top right' || position == 'bottom right') {
 | |
|                 offset -= (target.width / 2)
 | |
|                 offset += settings.arrowPixelsFromEdge;
 | |
|               }
 | |
|             }
 | |
| 
 | |
|             if(target.width === 0 && target.height === 0 && !module.is.svg(target.element)) {
 | |
|               module.debug('Popup target is hidden, no action taken');
 | |
|               return false;
 | |
|             }
 | |
| 
 | |
|             if(settings.inline) {
 | |
|               module.debug('Adding margin to calculation', target.margin);
 | |
|               if(position == 'left center' || position == 'right center') {
 | |
|                 offset       +=  target.margin.top;
 | |
|                 distanceAway += -target.margin.left;
 | |
|               }
 | |
|               else if (position == 'top left' || position == 'top center' || position == 'top right') {
 | |
|                 offset       += target.margin.left;
 | |
|                 distanceAway -= target.margin.top;
 | |
|               }
 | |
|               else {
 | |
|                 offset       += target.margin.left;
 | |
|                 distanceAway += target.margin.top;
 | |
|               }
 | |
|             }
 | |
| 
 | |
|             module.debug('Determining popup position from calculations', position, calculations);
 | |
| 
 | |
|             if (module.is.rtl()) {
 | |
|               position = position.replace(/left|right/g, function (match) {
 | |
|                 return (match == 'left')
 | |
|                   ? 'right'
 | |
|                   : 'left'
 | |
|                 ;
 | |
|               });
 | |
|               module.debug('RTL: Popup position updated', position);
 | |
|             }
 | |
| 
 | |
|             // if last attempt use specified last resort position
 | |
|             if(searchDepth == settings.maxSearchDepth && typeof settings.lastResort === 'string') {
 | |
|               position = settings.lastResort;
 | |
|             }
 | |
| 
 | |
|             switch (position) {
 | |
|               case 'top left':
 | |
|                 positioning = {
 | |
|                   top    : 'auto',
 | |
|                   bottom : parent.height - target.top + distanceAway,
 | |
|                   left   : target.left + offset,
 | |
|                   right  : 'auto'
 | |
|                 };
 | |
|               break;
 | |
|               case 'top center':
 | |
|                 positioning = {
 | |
|                   bottom : parent.height - target.top + distanceAway,
 | |
|                   left   : target.left + (target.width / 2) - (popup.width / 2) + offset,
 | |
|                   top    : 'auto',
 | |
|                   right  : 'auto'
 | |
|                 };
 | |
|               break;
 | |
|               case 'top right':
 | |
|                 positioning = {
 | |
|                   bottom :  parent.height - target.top + distanceAway,
 | |
|                   right  :  parent.width - target.left - target.width - offset,
 | |
|                   top    : 'auto',
 | |
|                   left   : 'auto'
 | |
|                 };
 | |
|               break;
 | |
|               case 'left center':
 | |
|                 positioning = {
 | |
|                   top    : target.top + (target.height / 2) - (popup.height / 2) + offset,
 | |
|                   right  : parent.width - target.left + distanceAway,
 | |
|                   left   : 'auto',
 | |
|                   bottom : 'auto'
 | |
|                 };
 | |
|               break;
 | |
|               case 'right center':
 | |
|                 positioning = {
 | |
|                   top    : target.top + (target.height / 2) - (popup.height / 2) + offset,
 | |
|                   left   : target.left + target.width + distanceAway,
 | |
|                   bottom : 'auto',
 | |
|                   right  : 'auto'
 | |
|                 };
 | |
|               break;
 | |
|               case 'bottom left':
 | |
|                 positioning = {
 | |
|                   top    : target.top + target.height + distanceAway,
 | |
|                   left   : target.left + offset,
 | |
|                   bottom : 'auto',
 | |
|                   right  : 'auto'
 | |
|                 };
 | |
|               break;
 | |
|               case 'bottom center':
 | |
|                 positioning = {
 | |
|                   top    : target.top + target.height + distanceAway,
 | |
|                   left   : target.left + (target.width / 2) - (popup.width / 2) + offset,
 | |
|                   bottom : 'auto',
 | |
|                   right  : 'auto'
 | |
|                 };
 | |
|               break;
 | |
|               case 'bottom right':
 | |
|                 positioning = {
 | |
|                   top    : target.top + target.height + distanceAway,
 | |
|                   right  : parent.width - target.left  - target.width - offset,
 | |
|                   left   : 'auto',
 | |
|                   bottom : 'auto'
 | |
|                 };
 | |
|               break;
 | |
|             }
 | |
|             if(positioning === undefined) {
 | |
|               module.error(error.invalidPosition, position);
 | |
|             }
 | |
| 
 | |
|             module.debug('Calculated popup positioning values', positioning);
 | |
| 
 | |
|             // tentatively place on stage
 | |
|             $popup
 | |
|               .css(positioning)
 | |
|               .removeClass(className.position)
 | |
|               .addClass(position)
 | |
|               .addClass(className.loading)
 | |
|             ;
 | |
| 
 | |
|             popupOffset = module.get.popupOffset();
 | |
| 
 | |
|             // see if any boundaries are surpassed with this tentative position
 | |
|             distanceFromBoundary = module.get.distanceFromBoundary(popupOffset, calculations);
 | |
| 
 | |
|             if( module.is.offstage(distanceFromBoundary, position) ) {
 | |
|               module.debug('Position is outside viewport', position);
 | |
|               if(searchDepth < settings.maxSearchDepth) {
 | |
|                 searchDepth++;
 | |
|                 position = module.get.nextPosition(position);
 | |
|                 module.debug('Trying new position', position);
 | |
|                 return ($popup)
 | |
|                   ? module.set.position(position, calculations)
 | |
|                   : false
 | |
|                 ;
 | |
|               }
 | |
|               else {
 | |
|                 if(settings.lastResort) {
 | |
|                   module.debug('No position found, showing with last position');
 | |
|                 }
 | |
|                 else {
 | |
|                   module.debug('Popup could not find a position to display', $popup);
 | |
|                   module.error(error.cannotPlace, element);
 | |
|                   module.remove.attempts();
 | |
|                   module.remove.loading();
 | |
|                   module.reset();
 | |
|                   settings.onUnplaceable.call($popup, element);
 | |
|                   return false;
 | |
|                 }
 | |
|               }
 | |
|             }
 | |
|             module.debug('Position is on stage', position);
 | |
|             module.remove.attempts();
 | |
|             module.remove.loading();
 | |
|             if( settings.setFluidWidth && module.is.fluid() ) {
 | |
|               module.set.fluidWidth(calculations);
 | |
|             }
 | |
|             return true;
 | |
|           },
 | |
| 
 | |
|           fluidWidth: function(calculations) {
 | |
|             calculations = calculations || module.get.calculations();
 | |
|             module.debug('Automatically setting element width to parent width', calculations.parent.width);
 | |
|             $popup.css('width', calculations.container.width);
 | |
|           },
 | |
| 
 | |
|           variation: function(variation) {
 | |
|             variation = variation || module.get.variation();
 | |
|             if(variation && module.has.popup() ) {
 | |
|               module.verbose('Adding variation to popup', variation);
 | |
|               $popup.addClass(variation);
 | |
|             }
 | |
|           },
 | |
| 
 | |
|           visible: function() {
 | |
|             $module.addClass(className.visible);
 | |
|           }
 | |
|         },
 | |
| 
 | |
|         remove: {
 | |
|           loading: function() {
 | |
|             $popup.removeClass(className.loading);
 | |
|           },
 | |
|           variation: function(variation) {
 | |
|             variation = variation || module.get.variation();
 | |
|             if(variation) {
 | |
|               module.verbose('Removing variation', variation);
 | |
|               $popup.removeClass(variation);
 | |
|             }
 | |
|           },
 | |
|           visible: function() {
 | |
|             $module.removeClass(className.visible);
 | |
|           },
 | |
|           attempts: function() {
 | |
|             module.verbose('Resetting all searched positions');
 | |
|             searchDepth    = 0;
 | |
|             triedPositions = false;
 | |
|           }
 | |
|         },
 | |
| 
 | |
|         bind: {
 | |
|           events: function() {
 | |
|             module.debug('Binding popup events to module');
 | |
|             if(settings.on == 'click') {
 | |
|               $module
 | |
|                 .on('click' + eventNamespace, module.toggle)
 | |
|               ;
 | |
|             }
 | |
|             if(settings.on == 'hover' && hasTouch) {
 | |
|               $module
 | |
|                 .on('touchstart' + eventNamespace, module.event.touchstart)
 | |
|               ;
 | |
|             }
 | |
|             if( module.get.startEvent() ) {
 | |
|               $module
 | |
|                 .on(module.get.startEvent() + eventNamespace, module.event.start)
 | |
|                 .on(module.get.endEvent() + eventNamespace, module.event.end)
 | |
|               ;
 | |
|             }
 | |
|             if(settings.target) {
 | |
|               module.debug('Target set to element', $target);
 | |
|             }
 | |
|             $window.on('resize' + elementNamespace, module.event.resize);
 | |
|           },
 | |
|           popup: function() {
 | |
|             module.verbose('Allowing hover events on popup to prevent closing');
 | |
|             if( $popup && module.has.popup() ) {
 | |
|               $popup
 | |
|                 .on('mouseenter' + eventNamespace, module.event.start)
 | |
|                 .on('mouseleave' + eventNamespace, module.event.end)
 | |
|               ;
 | |
|             }
 | |
|           },
 | |
|           close: function() {
 | |
|             if(settings.hideOnScroll === true || (settings.hideOnScroll == 'auto' && settings.on != 'click')) {
 | |
|               module.bind.closeOnScroll();
 | |
|             }
 | |
|             if(settings.on == 'hover' && openedWithTouch) {
 | |
|               module.bind.touchClose();
 | |
|             }
 | |
|             if(settings.on == 'click' && settings.closable) {
 | |
|               module.bind.clickaway();
 | |
|             }
 | |
|           },
 | |
|           closeOnScroll: function() {
 | |
|             module.verbose('Binding scroll close event to document');
 | |
|             $scrollContext
 | |
|               .one(module.get.scrollEvent() + elementNamespace, module.event.hideGracefully)
 | |
|             ;
 | |
|           },
 | |
|           touchClose: function() {
 | |
|             module.verbose('Binding popup touchclose event to document');
 | |
|             $document
 | |
|               .on('touchstart' + elementNamespace, function(event) {
 | |
|                 module.verbose('Touched away from popup');
 | |
|                 module.event.hideGracefully.call(element, event);
 | |
|               })
 | |
|             ;
 | |
|           },
 | |
|           clickaway: function() {
 | |
|             module.verbose('Binding popup close event to document');
 | |
|             $document
 | |
|               .on('click' + elementNamespace, function(event) {
 | |
|                 module.verbose('Clicked away from popup');
 | |
|                 module.event.hideGracefully.call(element, event);
 | |
|               })
 | |
|             ;
 | |
|           }
 | |
|         },
 | |
| 
 | |
|         unbind: {
 | |
|           events: function() {
 | |
|             $window
 | |
|               .off(elementNamespace)
 | |
|             ;
 | |
|             $module
 | |
|               .off(eventNamespace)
 | |
|             ;
 | |
|           },
 | |
|           close: function() {
 | |
|             $document
 | |
|               .off(elementNamespace)
 | |
|             ;
 | |
|             $scrollContext
 | |
|               .off(elementNamespace)
 | |
|             ;
 | |
|           },
 | |
|         },
 | |
| 
 | |
|         has: {
 | |
|           popup: function() {
 | |
|             return ($popup && $popup.length > 0);
 | |
|           }
 | |
|         },
 | |
| 
 | |
|         should: {
 | |
|           centerArrow: function(calculations) {
 | |
|             return !module.is.basic() && calculations.target.width <= (settings.arrowPixelsFromEdge * 2);
 | |
|           }
 | |
|         },
 | |
| 
 | |
|         is: {
 | |
|           offstage: function(distanceFromBoundary, position) {
 | |
|             var
 | |
|               offstage = []
 | |
|             ;
 | |
|             // return boundaries that have been surpassed
 | |
|             $.each(distanceFromBoundary, function(direction, distance) {
 | |
|               if(distance < -settings.jitter) {
 | |
|                 module.debug('Position exceeds allowable distance from edge', direction, distance, position);
 | |
|                 offstage.push(direction);
 | |
|               }
 | |
|             });
 | |
|             if(offstage.length > 0) {
 | |
|               return true;
 | |
|             }
 | |
|             else {
 | |
|               return false;
 | |
|             }
 | |
|           },
 | |
|           svg: function(element) {
 | |
|             return module.supports.svg() && (element instanceof SVGGraphicsElement);
 | |
|           },
 | |
|           basic: function() {
 | |
|             return $module.hasClass(className.basic);
 | |
|           },
 | |
|           active: function() {
 | |
|             return $module.hasClass(className.active);
 | |
|           },
 | |
|           animating: function() {
 | |
|             return ($popup !== undefined && $popup.hasClass(className.animating) );
 | |
|           },
 | |
|           fluid: function() {
 | |
|             return ($popup !== undefined && $popup.hasClass(className.fluid));
 | |
|           },
 | |
|           visible: function() {
 | |
|             return ($popup !== undefined && $popup.hasClass(className.popupVisible));
 | |
|           },
 | |
|           dropdown: function() {
 | |
|             return $module.hasClass(className.dropdown);
 | |
|           },
 | |
|           hidden: function() {
 | |
|             return !module.is.visible();
 | |
|           },
 | |
|           rtl: function () {
 | |
|             return $module.css('direction') == 'rtl';
 | |
|           }
 | |
|         },
 | |
| 
 | |
|         reset: function() {
 | |
|           module.remove.visible();
 | |
|           if(settings.preserve) {
 | |
|             if($.fn.transition !== undefined) {
 | |
|               $popup
 | |
|                 .transition('remove transition')
 | |
|               ;
 | |
|             }
 | |
|           }
 | |
|           else {
 | |
|             module.removePopup();
 | |
|           }
 | |
|         },
 | |
| 
 | |
|         setting: function(name, value) {
 | |
|           if( $.isPlainObject(name) ) {
 | |
|             $.extend(true, settings, name);
 | |
|           }
 | |
|           else if(value !== undefined) {
 | |
|             settings[name] = value;
 | |
|           }
 | |
|           else {
 | |
|             return settings[name];
 | |
|           }
 | |
|         },
 | |
|         internal: function(name, value) {
 | |
|           if( $.isPlainObject(name) ) {
 | |
|             $.extend(true, module, name);
 | |
|           }
 | |
|           else if(value !== undefined) {
 | |
|             module[name] = value;
 | |
|           }
 | |
|           else {
 | |
|             return module[name];
 | |
|           }
 | |
|         },
 | |
|         debug: function() {
 | |
|           if(!settings.silent && settings.debug) {
 | |
|             if(settings.performance) {
 | |
|               module.performance.log(arguments);
 | |
|             }
 | |
|             else {
 | |
|               module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
 | |
|               module.debug.apply(console, arguments);
 | |
|             }
 | |
|           }
 | |
|         },
 | |
|         verbose: function() {
 | |
|           if(!settings.silent && settings.verbose && settings.debug) {
 | |
|             if(settings.performance) {
 | |
|               module.performance.log(arguments);
 | |
|             }
 | |
|             else {
 | |
|               module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
 | |
|               module.verbose.apply(console, arguments);
 | |
|             }
 | |
|           }
 | |
|         },
 | |
|         error: function() {
 | |
|           if(!settings.silent) {
 | |
|             module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
 | |
|             module.error.apply(console, arguments);
 | |
|           }
 | |
|         },
 | |
|         performance: {
 | |
|           log: function(message) {
 | |
|             var
 | |
|               currentTime,
 | |
|               executionTime,
 | |
|               previousTime
 | |
|             ;
 | |
|             if(settings.performance) {
 | |
|               currentTime   = new Date().getTime();
 | |
|               previousTime  = time || currentTime;
 | |
|               executionTime = currentTime - previousTime;
 | |
|               time          = currentTime;
 | |
|               performance.push({
 | |
|                 'Name'           : message[0],
 | |
|                 'Arguments'      : [].slice.call(message, 1) || '',
 | |
|                 'Element'        : element,
 | |
|                 'Execution Time' : executionTime
 | |
|               });
 | |
|             }
 | |
|             clearTimeout(module.performance.timer);
 | |
|             module.performance.timer = setTimeout(module.performance.display, 500);
 | |
|           },
 | |
|           display: function() {
 | |
|             var
 | |
|               title = settings.name + ':',
 | |
|               totalTime = 0
 | |
|             ;
 | |
|             time = false;
 | |
|             clearTimeout(module.performance.timer);
 | |
|             $.each(performance, function(index, data) {
 | |
|               totalTime += data['Execution Time'];
 | |
|             });
 | |
|             title += ' ' + totalTime + 'ms';
 | |
|             if(moduleSelector) {
 | |
|               title += ' \'' + moduleSelector + '\'';
 | |
|             }
 | |
|             if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
 | |
|               console.groupCollapsed(title);
 | |
|               if(console.table) {
 | |
|                 console.table(performance);
 | |
|               }
 | |
|               else {
 | |
|                 $.each(performance, function(index, data) {
 | |
|                   console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
 | |
|                 });
 | |
|               }
 | |
|               console.groupEnd();
 | |
|             }
 | |
|             performance = [];
 | |
|           }
 | |
|         },
 | |
|         invoke: function(query, passedArguments, context) {
 | |
|           var
 | |
|             object = instance,
 | |
|             maxDepth,
 | |
|             found,
 | |
|             response
 | |
|           ;
 | |
|           passedArguments = passedArguments || queryArguments;
 | |
|           context         = element         || context;
 | |
|           if(typeof query == 'string' && object !== undefined) {
 | |
|             query    = query.split(/[\. ]/);
 | |
|             maxDepth = query.length - 1;
 | |
|             $.each(query, function(depth, value) {
 | |
|               var camelCaseValue = (depth != maxDepth)
 | |
|                 ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
 | |
|                 : query
 | |
|               ;
 | |
|               if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
 | |
|                 object = object[camelCaseValue];
 | |
|               }
 | |
|               else if( object[camelCaseValue] !== undefined ) {
 | |
|                 found = object[camelCaseValue];
 | |
|                 return false;
 | |
|               }
 | |
|               else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
 | |
|                 object = object[value];
 | |
|               }
 | |
|               else if( object[value] !== undefined ) {
 | |
|                 found = object[value];
 | |
|                 return false;
 | |
|               }
 | |
|               else {
 | |
|                 return false;
 | |
|               }
 | |
|             });
 | |
|           }
 | |
|           if ( $.isFunction( found ) ) {
 | |
|             response = found.apply(context, passedArguments);
 | |
|           }
 | |
|           else if(found !== undefined) {
 | |
|             response = found;
 | |
|           }
 | |
|           if($.isArray(returnedValue)) {
 | |
|             returnedValue.push(response);
 | |
|           }
 | |
|           else if(returnedValue !== undefined) {
 | |
|             returnedValue = [returnedValue, response];
 | |
|           }
 | |
|           else if(response !== undefined) {
 | |
|             returnedValue = response;
 | |
|           }
 | |
|           return found;
 | |
|         }
 | |
|       };
 | |
| 
 | |
|       if(methodInvoked) {
 | |
|         if(instance === undefined) {
 | |
|           module.initialize();
 | |
|         }
 | |
|         module.invoke(query);
 | |
|       }
 | |
|       else {
 | |
|         if(instance !== undefined) {
 | |
|           instance.invoke('destroy');
 | |
|         }
 | |
|         module.initialize();
 | |
|       }
 | |
|     })
 | |
|   ;
 | |
| 
 | |
|   return (returnedValue !== undefined)
 | |
|     ? returnedValue
 | |
|     : this
 | |
|   ;
 | |
| };
 | |
| 
 | |
| $.fn.popup.settings = {
 | |
| 
 | |
|   name           : 'Popup',
 | |
| 
 | |
|   // module settings
 | |
|   silent         : false,
 | |
|   debug          : false,
 | |
|   verbose        : false,
 | |
|   performance    : true,
 | |
|   namespace      : 'popup',
 | |
| 
 | |
|   // whether it should use dom mutation observers
 | |
|   observeChanges : true,
 | |
| 
 | |
|   // callback only when element added to dom
 | |
|   onCreate       : function(){},
 | |
| 
 | |
|   // callback before element removed from dom
 | |
|   onRemove       : function(){},
 | |
| 
 | |
|   // callback before show animation
 | |
|   onShow         : function(){},
 | |
| 
 | |
|   // callback after show animation
 | |
|   onVisible      : function(){},
 | |
| 
 | |
|   // callback before hide animation
 | |
|   onHide         : function(){},
 | |
| 
 | |
|   // callback when popup cannot be positioned in visible screen
 | |
|   onUnplaceable  : function(){},
 | |
| 
 | |
|   // callback after hide animation
 | |
|   onHidden       : function(){},
 | |
| 
 | |
|   // when to show popup
 | |
|   on             : 'hover',
 | |
| 
 | |
|   // element to use to determine if popup is out of boundary
 | |
|   boundary       : window,
 | |
| 
 | |
|   // whether to add touchstart events when using hover
 | |
|   addTouchEvents : true,
 | |
| 
 | |
|   // default position relative to element
 | |
|   position       : 'top left',
 | |
| 
 | |
|   // name of variation to use
 | |
|   variation      : '',
 | |
| 
 | |
|   // whether popup should be moved to context
 | |
|   movePopup      : true,
 | |
| 
 | |
|   // element which popup should be relative to
 | |
|   target         : false,
 | |
| 
 | |
|   // jq selector or element that should be used as popup
 | |
|   popup          : false,
 | |
| 
 | |
|   // popup should remain inline next to activator
 | |
|   inline         : false,
 | |
| 
 | |
|   // popup should be removed from page on hide
 | |
|   preserve       : false,
 | |
| 
 | |
|   // popup should not close when being hovered on
 | |
|   hoverable      : false,
 | |
| 
 | |
|   // explicitly set content
 | |
|   content        : false,
 | |
| 
 | |
|   // explicitly set html
 | |
|   html           : false,
 | |
| 
 | |
|   // explicitly set title
 | |
|   title          : false,
 | |
| 
 | |
|   // whether automatically close on clickaway when on click
 | |
|   closable       : true,
 | |
| 
 | |
|   // automatically hide on scroll
 | |
|   hideOnScroll   : 'auto',
 | |
| 
 | |
|   // hide other popups on show
 | |
|   exclusive      : false,
 | |
| 
 | |
|   // context to attach popups
 | |
|   context        : 'body',
 | |
| 
 | |
|   // context for binding scroll events
 | |
|   scrollContext  : window,
 | |
| 
 | |
|   // position to prefer when calculating new position
 | |
|   prefer         : 'opposite',
 | |
| 
 | |
|   // specify position to appear even if it doesn't fit
 | |
|   lastResort     : false,
 | |
| 
 | |
|   // number of pixels from edge of popup to pointing arrow center (used from centering)
 | |
|   arrowPixelsFromEdge: 20,
 | |
| 
 | |
|   // delay used to prevent accidental refiring of animations due to user error
 | |
|   delay : {
 | |
|     show : 50,
 | |
|     hide : 70
 | |
|   },
 | |
| 
 | |
|   // whether fluid variation should assign width explicitly
 | |
|   setFluidWidth  : true,
 | |
| 
 | |
|   // transition settings
 | |
|   duration       : 200,
 | |
|   transition     : 'scale',
 | |
| 
 | |
|   // distance away from activating element in px
 | |
|   distanceAway   : 0,
 | |
| 
 | |
|   // number of pixels an element is allowed to be "offstage" for a position to be chosen (allows for rounding)
 | |
|   jitter         : 2,
 | |
| 
 | |
|   // offset on aligning axis from calculated position
 | |
|   offset         : 0,
 | |
| 
 | |
|   // maximum times to look for a position before failing (9 positions total)
 | |
|   maxSearchDepth : 15,
 | |
| 
 | |
|   error: {
 | |
|     invalidPosition : 'The position you specified is not a valid position',
 | |
|     cannotPlace     : 'Popup does not fit within the boundaries of the viewport',
 | |
|     method          : 'The method you called is not defined.',
 | |
|     noTransition    : 'This module requires ui transitions <https://github.com/Semantic-Org/UI-Transition>',
 | |
|     notFound        : 'The target or popup you specified does not exist on the page'
 | |
|   },
 | |
| 
 | |
|   metadata: {
 | |
|     activator : 'activator',
 | |
|     content   : 'content',
 | |
|     html      : 'html',
 | |
|     offset    : 'offset',
 | |
|     position  : 'position',
 | |
|     title     : 'title',
 | |
|     variation : 'variation'
 | |
|   },
 | |
| 
 | |
|   className   : {
 | |
|     active       : 'active',
 | |
|     basic        : 'basic',
 | |
|     animating    : 'animating',
 | |
|     dropdown     : 'dropdown',
 | |
|     fluid        : 'fluid',
 | |
|     loading      : 'loading',
 | |
|     popup        : 'ui popup',
 | |
|     position     : 'top left center bottom right',
 | |
|     visible      : 'visible',
 | |
|     popupVisible : 'visible'
 | |
|   },
 | |
| 
 | |
|   selector    : {
 | |
|     popup    : '.ui.popup'
 | |
|   },
 | |
| 
 | |
|   templates: {
 | |
|     escape: function(string) {
 | |
|       var
 | |
|         badChars     = /[&<>"'`]/g,
 | |
|         shouldEscape = /[&<>"'`]/,
 | |
|         escape       = {
 | |
|           "&": "&",
 | |
|           "<": "<",
 | |
|           ">": ">",
 | |
|           '"': """,
 | |
|           "'": "'",
 | |
|           "`": "`"
 | |
|         },
 | |
|         escapedChar  = function(chr) {
 | |
|           return escape[chr];
 | |
|         }
 | |
|       ;
 | |
|       if(shouldEscape.test(string)) {
 | |
|         return string.replace(badChars, escapedChar);
 | |
|       }
 | |
|       return string;
 | |
|     },
 | |
|     popup: function(text) {
 | |
|       var
 | |
|         html   = '',
 | |
|         escape = $.fn.popup.settings.templates.escape
 | |
|       ;
 | |
|       if(typeof text !== undefined) {
 | |
|         if(typeof text.title !== undefined && text.title) {
 | |
|           text.title = escape(text.title);
 | |
|           html += '<div class="header">' + text.title + '</div>';
 | |
|         }
 | |
|         if(typeof text.content !== undefined && text.content) {
 | |
|           text.content = escape(text.content);
 | |
|           html += '<div class="content">' + text.content + '</div>';
 | |
|         }
 | |
|       }
 | |
|       return html;
 | |
|     }
 | |
|   }
 | |
| 
 | |
| };
 | |
| 
 | |
| 
 | |
| })( jQuery, window, document );
 |