From 3ace76128383f6dfdcd40684f3e7aeae2d31f692 Mon Sep 17 00:00:00 2001 From: Pusher Robot Date: Wed, 1 Jul 2015 15:31:55 -0400 Subject: [PATCH] Updated component to version 2.0.0 --- RELEASE-NOTES.md | 18 ++ composer.json | 2 +- index.js | 519 +++++++++++++++++++++++++++++------------------ package.js | 2 +- package.json | 12 +- popup.css | 105 +++++++--- popup.js | 519 +++++++++++++++++++++++++++++------------------ popup.min.css | 6 +- popup.min.js | 6 +- 9 files changed, 762 insertions(+), 427 deletions(-) diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 85562a2..8873695 100755 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -1,3 +1,21 @@ +### Version 2.0.0 - June 30, 2015 + +- **Popup** - Popups are no longer exclusive by default. Opening a popup will not necessarily close other visible popups. You can change this behavior by using the setting `exclusive: true`. Additionally the default theme now uses `1rem` size for standard popups. +- **Popup** - Popup has been rewritten to drastically improve performance, especially when testing multiple positions. +- **Transition** - Fallback javascript animations have been removed from UI components like dropdown and popup to increase performance. This removes need for expensive pseudo selectors like `:visible`, `:animated` and `:hidden` and reduces filesize. +- **Popup** - Popup now defines a `transform-origin` so animations will be affected by the direction the element is placed +- **Popup** - `onShow` and `onHide` callback can now cancel popup from showing or hiding by returning false +- **Popup** - Added more size variations for popup `mini`, `tiny` +- **Popup** - Popup now correctly adjusts if `data` attributes change +- **Popup** - Fixes issue with `min-width` in firefox exceeding `max-width` causing element to not wrap correctly +- **Popup** - Popup will now produce an error message and not mistakenly appear in the top left corner of page, if called with a `popup` or `target` that does not exist. +- **Popup** - Popup will no longer appear incorrectly if the targeted element is not visible on page +- **Popup** - Fixed bug which could cause pre-existing inline popup to be removed from DOM after hiding +- **Popup** - Fixes popup offstage position calculations with pages including horizontal scrollbars +- **Popup** - Added `addTouchEvents` to specify whether touch events should be added to trigger popup on mobile +- **Popup** - Popups now default to `exclusive: false` and will not hide other popups when opening +- **Popup** - Popup no longer produces a console error when a position cannot be found on the page. + ### Version 1.12.1 - April 26, 2015 - **Popup** - Removes `min-width: moz-max-content` from popups, which may cause display differences between chrome and FF diff --git a/composer.json b/composer.json index 0ae6fd1..69a3b75 100755 --- a/composer.json +++ b/composer.json @@ -15,5 +15,5 @@ "framework" ], "license": "MIT", - "version": "1.12.3" + "version": "2.0.0" } \ No newline at end of file diff --git a/index.js b/index.js index 9f964ac..18feb7d 100755 --- a/index.js +++ b/index.js @@ -1,9 +1,9 @@ /*! - * # Semantic UI 1.12.3 - Popup + * # Semantic UI 2.0.0 - Popup * http://github.com/semantic-org/semantic-ui/ * * - * Copyright 2014 Contributors + * Copyright 2015 Contributors * Released under the MIT license * http://opensource.org/licenses/MIT * @@ -18,6 +18,8 @@ module.exports = function(parameters) { var $allModules = $(this), $document = $(document), + $window = $(window), + $body = $('body'), moduleSelector = $allModules.selector || '', @@ -53,13 +55,12 @@ module.exports = function(parameters) { ? $(settings.target) : $module, - $window = $(window), - $body = $('body'), $popup, $offsetParent, searchDepth = 0, triedPositions = false, + openedWithTouch = false, element = this, instance = $module.data(moduleNamespace), @@ -97,6 +98,7 @@ module.exports = function(parameters) { else { if(settings.inline) { $popup = $target.next(selector.popup).eq(0); + settings.popup = $popup; } } if(settings.popup) { @@ -155,11 +157,7 @@ module.exports = function(parameters) { : settings.delay ; clearTimeout(module.hideTimer); - module.showTimer = setTimeout(function() { - if(module.is.hidden() && !( module.is.active() && module.is.dropdown()) ) { - module.show(); - } - }, delay); + module.showTimer = setTimeout(module.show, delay); }, end: function() { var @@ -168,27 +166,38 @@ module.exports = function(parameters) { : settings.delay ; clearTimeout(module.showTimer); - module.hideTimer = setTimeout(function() { - if(module.is.visible() ) { - module.hide(); - } - }, delay); + module.hideTimer = setTimeout(module.hide, delay); + }, + touchstart: function(event) { + openedWithTouch = true; + module.event.start(); }, resize: function() { if( module.is.visible() ) { module.set.position(); } + }, + hideGracefully: function(event) { + // don't close on clicks inside popup + if(event && $(event.target).closest(selector.popup).length === 0) { + 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.data(metadata.html) || settings.html, - variation = $module.data(metadata.variation) || settings.variation, - title = $module.data(metadata.title) || settings.title, - content = $module.data(metadata.content) || $module.attr('title') || settings.content + html = module.get.html(), + variation = module.get.variation(), + title = module.get.title(), + content = module.get.content() ; + if(html || content || title) { module.debug('Creating pop-up html'); if(!html) { @@ -229,14 +238,14 @@ module.exports = function(parameters) { 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); + settings.popups = $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); + $(settings.popup).data(metadata.activator, $module); module.verbose('Used popup specified in settings'); module.refresh(); if(settings.hoverable) { @@ -269,29 +278,40 @@ module.exports = function(parameters) { }, show: function(callback) { - callback = $.isFunction(callback) ? callback : function(){}; + callback = callback || function(){}; module.debug('Showing pop-up', settings.transition); - if( !module.exists() ) { - module.create(); - } - else if(!settings.preserve && !settings.popup) { - module.refresh(); - } - if( $popup && module.set.position() ) { - module.save.conditions(); - if(settings.exclusive) { - module.hideAll(); + + 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); } - module.animate.show(callback); } }, hide: function(callback) { - callback = $.isFunction(callback) ? callback : function(){}; - module.remove.visible(); - module.unbind.close(); - if( module.is.visible() ) { + 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); } @@ -308,18 +328,6 @@ module.exports = function(parameters) { }) ; }, - - hideGracefully: function(event) { - // don't close on clicks inside popup - if(event && $(event.target).closest(selector.popup).length === 0) { - module.debug('Click occurred outside popup hiding popup'); - module.hide(); - } - else { - module.debug('Click was inside popup, keeping popup open'); - } - }, - exists: function() { if(!$popup) { return false; @@ -385,21 +393,16 @@ module.exports = function(parameters) { ; } else { - module.set.visible(); - $popup - .stop() - .fadeIn(settings.duration, settings.easing, function() { - module.bind.close(); - callback.call($popup, element); - settings.onVisible.call($popup, element); - }) - ; + module.error(error.noTransition); } - settings.onShow.call($popup, element); }, hide: function(callback) { callback = $.isFunction(callback) ? callback : function(){}; module.debug('Hiding pop-up'); + if(settings.onShow.call($popup, element) === false) { + module.debug('onShow callback returned false, cancelling popup animation'); + return; + } if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) { $popup .transition({ @@ -417,29 +420,95 @@ module.exports = function(parameters) { ; } else { - $popup - .stop() - .fadeOut(settings.duration, settings.easing, function() { - module.reset(); - callback.call($popup, element); - settings.onHidden.call($popup, element); - }) - ; + module.error(error.noTransition); } - settings.onHide.call($popup, element); } }, 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) || $module.attr('title') || settings.content; + }, + variation: function() { + $module.removeData(metadata.variation); + return $module.data(metadata.variation) || settings.variation; + }, + calculations: function() { + var + targetElement = $target[0], + targetPosition = (settings.inline || settings.popup) + ? $target.position() + : $target.offset(), + calculations = {}, + 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 : { + scroll: { + top : $window.scrollTop(), + left : $window.scrollLeft() + }, + width : $window.width(), + height : $window.height() + } + }; + + // 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.scroll.top, + bottom : screen.scroll.top + screen.height, + left : screen.scroll.left, + right : screen.scroll.left + screen.width + }; + return calculations; + }, id: function() { return id; }, startEvent: function() { if(settings.on == 'hover') { - return (hasTouch) - ? 'touchstart mouseenter' - : 'mouseenter' - ; + return 'mouseenter'; } else if(settings.on == 'focus') { return 'focus'; @@ -447,10 +516,7 @@ module.exports = function(parameters) { return false; }, scrollEvent: function() { - return (hasTouch) - ? 'touchmove scroll' - : 'scroll' - ; + return 'scroll'; }, endEvent: function() { if(settings.on == 'hover') { @@ -488,31 +554,28 @@ module.exports = function(parameters) { : $() ; }, - offstagePosition: function(position) { + offstagePosition: function(position, calculations) { var - boundary = { - top : $(window).scrollTop(), - bottom : $(window).scrollTop() + $(window).height(), - left : 0, - right : $(window).width() - }, - popup = { - width : $popup.width(), - height : $popup.height(), - offset : $popup.offset() - }, - offstage = {}, - offstagePositions = [] + offset = $popup.offset(), + offstage = {}, + offstagePositions = [], + popup, + boundary ; - position = position || false; - if(popup.offset && position) { - module.verbose('Checking if outside viewable area', popup.offset); + position = position || false; + calculations = calculations || module.get.calculations(); + // shorthand + popup = calculations.popup; + boundary = calculations.boundary; + + if(offset && position) { offstage = { - top : (popup.offset.top < boundary.top), - bottom : (popup.offset.top + popup.height > boundary.bottom), - right : (popup.offset.left + popup.width > boundary.right), - left : (popup.offset.left < boundary.left) + top : (offset.top < boundary.top), + bottom : (offset.top + popup.height > boundary.bottom), + right : (offset.left + popup.width > boundary.right), + left : (offset.left < boundary.left) }; + module.verbose('Offstage positions determined', offset, offstage); } // return only boundaries that have been surpassed $.each(offstage, function(direction, isOffstage) { @@ -597,135 +660,133 @@ module.exports = function(parameters) { }, set: { - position: function(position, arrowOffset) { - var - windowWidth = $(window).width(), - windowHeight = $(window).height(), - - targetWidth = $target.outerWidth(), - targetHeight = $target.outerHeight(), - - popupWidth = $popup.outerWidth(), - popupHeight = $popup.outerHeight(), - - parentWidth = $offsetParent.outerWidth(), - parentHeight = $offsetParent.outerHeight(), - - distanceAway = settings.distanceAway, - - targetElement = $target[0], - - marginTop = (settings.inline) - ? parseInt( window.getComputedStyle(targetElement).getPropertyValue('margin-top'), 10) - : 0, - marginLeft = (settings.inline) - ? parseInt( window.getComputedStyle(targetElement).getPropertyValue(module.is.rtl() ? 'margin-right' : 'margin-left'), 10) - : 0, - - target = (settings.inline || settings.popup) - ? $target.position() - : $target.offset(), + position: function(position, calculations) { + // exit conditions + if($target.length === 0 || $popup.length === 0) { + module.error(error.notFound); + return; + } + var + offset, + distanceAway, + target, + popup, + parent, computedPosition, positioning, offstagePosition ; - position = position || $module.data(metadata.position) || settings.position; - arrowOffset = arrowOffset || $module.data(metadata.offset) || settings.offset; + calculations = calculations || module.get.calculations(); + position = position || $module.data(metadata.position) || settings.position; - if(searchDepth == settings.maxSearchDepth && settings.lastResort) { - module.debug('Using last resort position to display', settings.lastResort); - position = settings.lastResort; + offset = $module.data(metadata.offset) || settings.offset; + distanceAway = settings.distanceAway; + + // shorthand + target = calculations.target; + popup = calculations.popup; + parent = calculations.parent; + + if(target.top === 0 && target.left === 0) { + module.debug('Popup target is hidden, no action taken'); + return false; } if(settings.inline) { - module.debug('Adding targets margin to calculation'); + module.debug('Adding margin to calculation', target.margin); if(position == 'left center' || position == 'right center') { - arrowOffset += marginTop; - distanceAway += -marginLeft; + offset += target.margin.top; + distanceAway += -target.margin.left; } else if (position == 'top left' || position == 'top center' || position == 'top right') { - arrowOffset += marginLeft; - distanceAway -= marginTop; + offset += target.margin.left; + distanceAway -= target.margin.top; } else { - arrowOffset += marginLeft; - distanceAway += marginTop; + offset += target.margin.left; + distanceAway += target.margin.top; } } - module.debug('Calculating popup positioning', position); - computedPosition = position; + module.debug('Determining popup position from calculations', position, calculations); + if (module.is.rtl()) { - computedPosition = computedPosition.replace(/left|right/g, function (match) { + position = position.replace(/left|right/g, function (match) { return (match == 'left') ? 'right' : 'left' ; }); - module.debug('RTL: Popup positioning updated', computedPosition); + module.debug('RTL: Popup position updated', position); + } + + if(searchDepth == settings.maxSearchDepth && settings.lastResort) { + module.debug('Using "last resort" position to display', settings.lastResort); + position = settings.lastResort; } - switch (computedPosition) { + + switch (position) { case 'top left': positioning = { top : 'auto', - bottom : parentHeight - target.top + distanceAway, - left : target.left + arrowOffset, + bottom : parent.height - target.top + distanceAway, + left : target.left + offset, right : 'auto' }; break; case 'top center': positioning = { - bottom : parentHeight - target.top + distanceAway, - left : target.left + (targetWidth / 2) - (popupWidth / 2) + arrowOffset, + 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 : parentHeight - target.top + distanceAway, - right : parentWidth - target.left - targetWidth - arrowOffset, + 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 + (targetHeight / 2) - (popupHeight / 2) + arrowOffset, - right : parentWidth - target.left + distanceAway, + 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 + (targetHeight / 2) - (popupHeight / 2) + arrowOffset, - left : target.left + targetWidth + distanceAway, + 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 + targetHeight + distanceAway, - left : target.left + arrowOffset, + top : target.top + target.height + distanceAway, + left : target.left + offset, bottom : 'auto', right : 'auto' }; break; case 'bottom center': positioning = { - top : target.top + targetHeight + distanceAway, - left : target.left + (targetWidth / 2) - (popupWidth / 2) + arrowOffset, + 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 + targetHeight + distanceAway, - right : parentWidth - target.left - targetWidth - arrowOffset, + top : target.top + target.height + distanceAway, + right : parent.width - target.left - target.width - offset, left : 'auto', bottom : 'auto' }; @@ -745,17 +806,17 @@ module.exports = function(parameters) { .addClass(className.loading) ; // check if is offstage - offstagePosition = module.get.offstagePosition(position); + offstagePosition = module.get.offstagePosition(position, calculations); // recursively find new positioning if(offstagePosition) { - module.debug('Popup cant fit into viewport', offstagePosition); + module.debug('Popup cant fit into viewport', position, offstagePosition); if(searchDepth < settings.maxSearchDepth) { searchDepth++; position = module.get.nextPosition(position); module.debug('Trying new position', position); return ($popup) - ? module.set.position(position) + ? module.set.position(position, calculations) : false ; } @@ -771,14 +832,15 @@ module.exports = function(parameters) { module.debug('Position is on stage', position); module.remove.attempts(); - module.set.fluidWidth(); + module.set.fluidWidth(calculations); module.remove.loading(); return true; }, - fluidWidth: function() { + fluidWidth: function(calculations) { + calculations = calculations || module.get.calculations(); if( settings.setFluidWidth && $popup.hasClass(className.fluid) ) { - $popup.css('width', $offsetParent.width()); + $popup.css('width', calculations.parent.width); } }, @@ -809,6 +871,11 @@ module.exports = function(parameters) { .on('click' + eventNamespace, module.toggle) ; } + if(settings.on == 'hover' && hasTouch) { + $module + .on('touchstart' + eventNamespace, module.event.touchstart) + ; + } else if( module.get.startEvent() ) { $module .on(module.get.startEvent() + eventNamespace, module.event.start) @@ -829,21 +896,30 @@ module.exports = function(parameters) { ; } }, - close:function() { - if(settings.hideOnScroll === true || settings.hideOnScroll == 'auto' && settings.on != 'click') { + close: function() { + if(settings.hideOnScroll === true || (settings.hideOnScroll == 'auto' && settings.on != 'click')) { $document - .one(module.get.scrollEvent() + elementNamespace, module.hideGracefully) + .one(module.get.scrollEvent() + elementNamespace, module.event.hideGracefully) ; $context - .one(module.get.scrollEvent() + elementNamespace, module.hideGracefully) + .one(module.get.scrollEvent() + elementNamespace, module.event.hideGracefully) + ; + } + if(settings.on == 'hover' && openedWithTouch) { + module.verbose('Binding popup close event to document'); + $document + .on('touchstart' + elementNamespace, function(event) { + module.verbose('Touched away from popup'); + module.event.hideGracefully.call(element, event); + }) ; } if(settings.on == 'click' && settings.closable) { module.verbose('Binding popup close event to document'); $document .on('click' + elementNamespace, function(event) { - module.verbose('Pop-up clickaway intent detected'); - module.hideGracefully.call(element, event); + module.verbose('Clicked away from popup'); + module.event.hideGracefully.call(element, event); }) ; } @@ -852,7 +928,7 @@ module.exports = function(parameters) { unbind: { close: function() { - if(settings.hideOnScroll === true || settings.hideOnScroll == 'auto' && settings.on != 'click') { + if(settings.hideOnScroll === true || (settings.hideOnScroll == 'auto' && settings.on != 'click')) { $document .off('scroll' + elementNamespace, module.hide) ; @@ -860,6 +936,12 @@ module.exports = function(parameters) { .off('scroll' + elementNamespace, module.hide) ; } + if(settings.on == 'hover' && openedWithTouch) { + $document + .off('touchstart' + elementNamespace) + ; + openedWithTouch = false; + } if(settings.on == 'click' && settings.closable) { module.verbose('Removing close event from document'); $document @@ -880,10 +962,10 @@ module.exports = function(parameters) { return $module.hasClass(className.active); }, animating: function() { - return ( $popup && $popup.is(':animated') || $popup.hasClass(className.animating) ); + return ( $popup && $popup.hasClass(className.animating) ); }, visible: function() { - return $popup && $popup.is(':visible'); + return $popup && $popup.hasClass(className.visible); }, dropdown: function() { return $module.hasClass(className.dropdown); @@ -978,7 +1060,7 @@ module.exports = function(parameters) { }); } clearTimeout(module.performance.timer); - module.performance.timer = setTimeout(module.performance.display, 100); + module.performance.timer = setTimeout(module.performance.display, 500); }, display: function() { var @@ -1089,61 +1171,115 @@ module.exports.settings = { name : 'Popup', + // module settings debug : false, - verbose : true, + verbose : false, performance : true, namespace : 'popup', + // 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 after hide animation onHidden : function(){}, + // when to show popup + on : 'hover', + + // 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 : true, + + // 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, - on : 'hover', + // whether automatically close on clickaway when on click closable : true, + + // automatically hide on scroll hideOnScroll : 'auto', - exclusive : true, + // hide other popups on show + exclusive : false, + + // context to attach popups context : 'body', - position : 'top left', + // position to prefer when calculating new position prefer : 'opposite', + + // specify position to appear even if it doesn't fit lastResort : false, + // delay used to prevent accidental refiring of animations due to user error delay : { - show : 30, - hide : 0 + show : 50, + hide : 70 }, + // whether fluid variation should assign width explicitly setFluidWidth : true, - movePopup : true, - - target : false, - popup : false, - inline : false, - preserve : false, - hoverable : false, + // transition settings duration : 200, - easing : 'easeOutQuint', transition : 'scale', + // distance away from activating element in px distanceAway : 0, + + // offset on aligning axis from calculated position offset : 0, + + // maximum times to look for a position before failing (9 positions total) maxSearchDepth : 20, error: { invalidPosition : 'The position you specified is not a valid position', cannotPlace : 'No visible position could be found for the popup', - method : 'The method you called is not defined.' + method : 'The method you called is not defined.', + noTransition : 'This module requires ui transitions ', + notFound : 'The target or popup you specified does not exist on the page' }, metadata: { @@ -1214,12 +1350,5 @@ module.exports.settings = { }; -// Adds easing -$.extend( $.easing, { - easeOutQuad: function (x, t, b, c, d) { - return -c *(t/=d)*(t-2) + b; - } -}); - })( require("jquery"), window , document ); diff --git a/package.js b/package.js index 68948aa..7744952 100755 --- a/package.js +++ b/package.js @@ -2,7 +2,7 @@ Package.describe({ name : 'semantic:ui-popup', summary : 'Semantic UI - Popup: Single component release', - version : '1.12.3', + version : '2.0.0', git : 'git://github.com/Semantic-Org/UI-Popup.git', }); diff --git a/package.json b/package.json index 39c4a79..5d96785 100755 --- a/package.json +++ b/package.json @@ -1,17 +1,17 @@ { - "name": "semantic-ui-popup", - "version": "1.12.3", - "title": "Semantic UI - Popup", - "description": "Single component release of popup", + "name": "semantic", + "version": "1.0.0", + "title": "Semantic UI", + "description": "Semantic empowers designers and developers by creating a shared vocabulary for UI.", "homepage": "http://www.semantic-ui.com", "author": "Jack Lukic ", "license": "MIT", "repository": { "type": "git", - "url": "https://github.com/Semantic-Org/UI-Popup.git" + "url": "git://github.com/Semantic-Org/Semantic-UI.git" }, "bugs": { "url": "https://github.com/Semantic-Org/Semantic-UI/issues" }, "devDependencies": {} -} \ No newline at end of file +} diff --git a/popup.css b/popup.css index 3856b7d..5a58a6c 100755 --- a/popup.css +++ b/popup.css @@ -1,9 +1,9 @@ /*! - * # Semantic UI 1.12.3 - Popup + * # Semantic UI 2.0.0 - Popup * http://github.com/semantic-org/semantic-ui/ * * - * Copyright 2014 Contributors + * Copyright 2015 Contributors * Released under the MIT license * http://opensource.org/licenses/MIT * @@ -19,16 +19,22 @@ position: absolute; top: 0px; right: 0px; + +/* Fixes content being squished when inline (moz only) */ + min-width: -webkit-min-content; + min-width: -moz-min-content; + min-width: min-content; z-index: 1900; - border: 1px solid #cccccc; + border: 1px solid #d4d4d5; + line-height: 1.4285em; max-width: 250px; background-color: #ffffff; padding: 0.833em 1em; font-weight: normal; font-style: normal; - color: rgba(0, 0, 0, 0.8); - border-radius: 0.2857rem; - box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.1); + color: rgba(0, 0, 0, 0.87); + border-radius: 0.28571429rem; + box-shadow: 0px 2px 4px 0px rgba(34, 36, 38, 0.12), 0px 2px 10px 0px rgba(34, 36, 38, 0.08); } .ui.popup > .header { padding: 0em; @@ -50,7 +56,7 @@ -ms-transform: rotate(45deg); transform: rotate(45deg); z-index: 2; - box-shadow: 1px 1px 0px 0px #b3b3b3; + box-shadow: 1px 1px 0px 0px #bababc; } @@ -66,17 +72,59 @@ .ui.popup { margin: 0em; } -.ui.popup.bottom { - margin: 0.75em 0em 0em; -} -.ui.popup.top { + +/* Extending from Top */ +.ui.top.popup { margin: 0em 0em 0.75em; } -.ui.popup.left.center { +.ui.top.left.popup { + -webkit-transform-origin: left bottom; + -ms-transform-origin: left bottom; + transform-origin: left bottom; +} +.ui.top.center.popup { + -webkit-transform-origin: center bottom; + -ms-transform-origin: center bottom; + transform-origin: center bottom; +} +.ui.top.right.popup { + -webkit-transform-origin: right bottom; + -ms-transform-origin: right bottom; + transform-origin: right bottom; +} + +/* Extending from Vertical Center */ +.ui.left.center.popup { margin: 0em 0.75em 0em 0em; + -webkit-transform-origin: right 50%; + -ms-transform-origin: right 50%; + transform-origin: right 50%; } -.ui.popup.right.center { +.ui.right.center.popup { margin: 0em 0em 0em 0.75em; + -webkit-transform-origin: left 50%; + -ms-transform-origin: left 50%; + transform-origin: left 50%; +} + +/* Extending from Bottom */ +.ui.bottom.popup { + margin: 0.75em 0em 0em; +} +.ui.bottom.left.popup { + -webkit-transform-origin: left top; + -ms-transform-origin: left top; + transform-origin: left top; +} +.ui.bottom.center.popup { + -webkit-transform-origin: center top; + -ms-transform-origin: center top; + transform-origin: center top; +} +.ui.bottom.right.popup { + -webkit-transform-origin: right top; + -ms-transform-origin: right top; + transform-origin: right top; } /*-------------- @@ -92,7 +140,7 @@ left: 50%; right: auto; bottom: auto; - box-shadow: -1px -1px 0px 0px #b3b3b3; + box-shadow: -1px -1px 0px 0px #bababc; } .ui.bottom.left.popup { margin-left: 0em; @@ -103,7 +151,7 @@ right: auto; bottom: auto; margin-left: 0em; - box-shadow: -1px -1px 0px 0px #b3b3b3; + box-shadow: -1px -1px 0px 0px #bababc; } .ui.bottom.right.popup { margin-right: 0em; @@ -114,7 +162,7 @@ bottom: auto; left: auto; margin-left: 0em; - box-shadow: -1px -1px 0px 0px #b3b3b3; + box-shadow: -1px -1px 0px 0px #bababc; } /*--- Above ---*/ @@ -155,7 +203,7 @@ bottom: auto; left: auto; margin-top: -0.325em; - box-shadow: 1px -1px 0px 0px #b3b3b3; + box-shadow: 1px -1px 0px 0px #bababc; } /*--- Right Center ---*/ @@ -166,7 +214,7 @@ bottom: auto; right: auto; margin-top: -0.325em; - box-shadow: -1px 1px 0px 0px #b3b3b3; + box-shadow: -1px 1px 0px 0px #bababc; } @@ -177,7 +225,6 @@ /* Immediate Nested Grid */ .ui.popup > .ui.grid:not(.padded) { - width: -webkit-calc(100% + 1.75rem); width: calc(100% + 1.75rem); margin: -0.7rem -0.875rem; } @@ -196,6 +243,12 @@ .ui.visible.popup { display: block; } +.ui.visible.popup { + -webkit-transform: translateZ(0px); + transform: translateZ(0px); + -webkit-backface-visibility: hidden; + backface-visibility: hidden; +} /******************************* @@ -264,17 +317,23 @@ Sizes ---------------*/ +.ui.mini.popup { + font-size: 0.71428571rem; +} +.ui.tiny.popup { + font-size: 0.85714286rem; +} .ui.small.popup { - font-size: 0.785714rem; + font-size: 0.92857143rem; } .ui.popup { - font-size: 0.85714rem; + font-size: 1rem; } .ui.large.popup { - font-size: 1rem; + font-size: 1.14285714rem; } .ui.huge.popup { - font-size: 1.14285rem; + font-size: 1.42857143rem; } diff --git a/popup.js b/popup.js index a7496b2..e47e595 100755 --- a/popup.js +++ b/popup.js @@ -1,9 +1,9 @@ /*! - * # Semantic UI 1.12.3 - Popup + * # Semantic UI 2.0.0 - Popup * http://github.com/semantic-org/semantic-ui/ * * - * Copyright 2014 Contributors + * Copyright 2015 Contributors * Released under the MIT license * http://opensource.org/licenses/MIT * @@ -17,6 +17,8 @@ $.fn.popup = function(parameters) { var $allModules = $(this), $document = $(document), + $window = $(window), + $body = $('body'), moduleSelector = $allModules.selector || '', @@ -52,13 +54,12 @@ $.fn.popup = function(parameters) { ? $(settings.target) : $module, - $window = $(window), - $body = $('body'), $popup, $offsetParent, searchDepth = 0, triedPositions = false, + openedWithTouch = false, element = this, instance = $module.data(moduleNamespace), @@ -96,6 +97,7 @@ $.fn.popup = function(parameters) { else { if(settings.inline) { $popup = $target.next(selector.popup).eq(0); + settings.popup = $popup; } } if(settings.popup) { @@ -154,11 +156,7 @@ $.fn.popup = function(parameters) { : settings.delay ; clearTimeout(module.hideTimer); - module.showTimer = setTimeout(function() { - if(module.is.hidden() && !( module.is.active() && module.is.dropdown()) ) { - module.show(); - } - }, delay); + module.showTimer = setTimeout(module.show, delay); }, end: function() { var @@ -167,27 +165,38 @@ $.fn.popup = function(parameters) { : settings.delay ; clearTimeout(module.showTimer); - module.hideTimer = setTimeout(function() { - if(module.is.visible() ) { - module.hide(); - } - }, delay); + module.hideTimer = setTimeout(module.hide, delay); + }, + touchstart: function(event) { + openedWithTouch = true; + module.event.start(); }, resize: function() { if( module.is.visible() ) { module.set.position(); } + }, + hideGracefully: function(event) { + // don't close on clicks inside popup + if(event && $(event.target).closest(selector.popup).length === 0) { + 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.data(metadata.html) || settings.html, - variation = $module.data(metadata.variation) || settings.variation, - title = $module.data(metadata.title) || settings.title, - content = $module.data(metadata.content) || $module.attr('title') || settings.content + html = module.get.html(), + variation = module.get.variation(), + title = module.get.title(), + content = module.get.content() ; + if(html || content || title) { module.debug('Creating pop-up html'); if(!html) { @@ -228,14 +237,14 @@ $.fn.popup = function(parameters) { 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); + settings.popups = $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); + $(settings.popup).data(metadata.activator, $module); module.verbose('Used popup specified in settings'); module.refresh(); if(settings.hoverable) { @@ -268,29 +277,40 @@ $.fn.popup = function(parameters) { }, show: function(callback) { - callback = $.isFunction(callback) ? callback : function(){}; + callback = callback || function(){}; module.debug('Showing pop-up', settings.transition); - if( !module.exists() ) { - module.create(); - } - else if(!settings.preserve && !settings.popup) { - module.refresh(); - } - if( $popup && module.set.position() ) { - module.save.conditions(); - if(settings.exclusive) { - module.hideAll(); + + 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); } - module.animate.show(callback); } }, hide: function(callback) { - callback = $.isFunction(callback) ? callback : function(){}; - module.remove.visible(); - module.unbind.close(); - if( module.is.visible() ) { + 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); } @@ -307,18 +327,6 @@ $.fn.popup = function(parameters) { }) ; }, - - hideGracefully: function(event) { - // don't close on clicks inside popup - if(event && $(event.target).closest(selector.popup).length === 0) { - module.debug('Click occurred outside popup hiding popup'); - module.hide(); - } - else { - module.debug('Click was inside popup, keeping popup open'); - } - }, - exists: function() { if(!$popup) { return false; @@ -384,21 +392,16 @@ $.fn.popup = function(parameters) { ; } else { - module.set.visible(); - $popup - .stop() - .fadeIn(settings.duration, settings.easing, function() { - module.bind.close(); - callback.call($popup, element); - settings.onVisible.call($popup, element); - }) - ; + module.error(error.noTransition); } - settings.onShow.call($popup, element); }, hide: function(callback) { callback = $.isFunction(callback) ? callback : function(){}; module.debug('Hiding pop-up'); + if(settings.onShow.call($popup, element) === false) { + module.debug('onShow callback returned false, cancelling popup animation'); + return; + } if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) { $popup .transition({ @@ -416,29 +419,95 @@ $.fn.popup = function(parameters) { ; } else { - $popup - .stop() - .fadeOut(settings.duration, settings.easing, function() { - module.reset(); - callback.call($popup, element); - settings.onHidden.call($popup, element); - }) - ; + module.error(error.noTransition); } - settings.onHide.call($popup, element); } }, 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) || $module.attr('title') || settings.content; + }, + variation: function() { + $module.removeData(metadata.variation); + return $module.data(metadata.variation) || settings.variation; + }, + calculations: function() { + var + targetElement = $target[0], + targetPosition = (settings.inline || settings.popup) + ? $target.position() + : $target.offset(), + calculations = {}, + 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 : { + scroll: { + top : $window.scrollTop(), + left : $window.scrollLeft() + }, + width : $window.width(), + height : $window.height() + } + }; + + // 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.scroll.top, + bottom : screen.scroll.top + screen.height, + left : screen.scroll.left, + right : screen.scroll.left + screen.width + }; + return calculations; + }, id: function() { return id; }, startEvent: function() { if(settings.on == 'hover') { - return (hasTouch) - ? 'touchstart mouseenter' - : 'mouseenter' - ; + return 'mouseenter'; } else if(settings.on == 'focus') { return 'focus'; @@ -446,10 +515,7 @@ $.fn.popup = function(parameters) { return false; }, scrollEvent: function() { - return (hasTouch) - ? 'touchmove scroll' - : 'scroll' - ; + return 'scroll'; }, endEvent: function() { if(settings.on == 'hover') { @@ -487,31 +553,28 @@ $.fn.popup = function(parameters) { : $() ; }, - offstagePosition: function(position) { + offstagePosition: function(position, calculations) { var - boundary = { - top : $(window).scrollTop(), - bottom : $(window).scrollTop() + $(window).height(), - left : 0, - right : $(window).width() - }, - popup = { - width : $popup.width(), - height : $popup.height(), - offset : $popup.offset() - }, - offstage = {}, - offstagePositions = [] + offset = $popup.offset(), + offstage = {}, + offstagePositions = [], + popup, + boundary ; - position = position || false; - if(popup.offset && position) { - module.verbose('Checking if outside viewable area', popup.offset); + position = position || false; + calculations = calculations || module.get.calculations(); + // shorthand + popup = calculations.popup; + boundary = calculations.boundary; + + if(offset && position) { offstage = { - top : (popup.offset.top < boundary.top), - bottom : (popup.offset.top + popup.height > boundary.bottom), - right : (popup.offset.left + popup.width > boundary.right), - left : (popup.offset.left < boundary.left) + top : (offset.top < boundary.top), + bottom : (offset.top + popup.height > boundary.bottom), + right : (offset.left + popup.width > boundary.right), + left : (offset.left < boundary.left) }; + module.verbose('Offstage positions determined', offset, offstage); } // return only boundaries that have been surpassed $.each(offstage, function(direction, isOffstage) { @@ -596,135 +659,133 @@ $.fn.popup = function(parameters) { }, set: { - position: function(position, arrowOffset) { - var - windowWidth = $(window).width(), - windowHeight = $(window).height(), - - targetWidth = $target.outerWidth(), - targetHeight = $target.outerHeight(), - - popupWidth = $popup.outerWidth(), - popupHeight = $popup.outerHeight(), - - parentWidth = $offsetParent.outerWidth(), - parentHeight = $offsetParent.outerHeight(), - - distanceAway = settings.distanceAway, - - targetElement = $target[0], - - marginTop = (settings.inline) - ? parseInt( window.getComputedStyle(targetElement).getPropertyValue('margin-top'), 10) - : 0, - marginLeft = (settings.inline) - ? parseInt( window.getComputedStyle(targetElement).getPropertyValue(module.is.rtl() ? 'margin-right' : 'margin-left'), 10) - : 0, - - target = (settings.inline || settings.popup) - ? $target.position() - : $target.offset(), + position: function(position, calculations) { + // exit conditions + if($target.length === 0 || $popup.length === 0) { + module.error(error.notFound); + return; + } + var + offset, + distanceAway, + target, + popup, + parent, computedPosition, positioning, offstagePosition ; - position = position || $module.data(metadata.position) || settings.position; - arrowOffset = arrowOffset || $module.data(metadata.offset) || settings.offset; + calculations = calculations || module.get.calculations(); + position = position || $module.data(metadata.position) || settings.position; - if(searchDepth == settings.maxSearchDepth && settings.lastResort) { - module.debug('Using last resort position to display', settings.lastResort); - position = settings.lastResort; + offset = $module.data(metadata.offset) || settings.offset; + distanceAway = settings.distanceAway; + + // shorthand + target = calculations.target; + popup = calculations.popup; + parent = calculations.parent; + + if(target.top === 0 && target.left === 0) { + module.debug('Popup target is hidden, no action taken'); + return false; } if(settings.inline) { - module.debug('Adding targets margin to calculation'); + module.debug('Adding margin to calculation', target.margin); if(position == 'left center' || position == 'right center') { - arrowOffset += marginTop; - distanceAway += -marginLeft; + offset += target.margin.top; + distanceAway += -target.margin.left; } else if (position == 'top left' || position == 'top center' || position == 'top right') { - arrowOffset += marginLeft; - distanceAway -= marginTop; + offset += target.margin.left; + distanceAway -= target.margin.top; } else { - arrowOffset += marginLeft; - distanceAway += marginTop; + offset += target.margin.left; + distanceAway += target.margin.top; } } - module.debug('Calculating popup positioning', position); - computedPosition = position; + module.debug('Determining popup position from calculations', position, calculations); + if (module.is.rtl()) { - computedPosition = computedPosition.replace(/left|right/g, function (match) { + position = position.replace(/left|right/g, function (match) { return (match == 'left') ? 'right' : 'left' ; }); - module.debug('RTL: Popup positioning updated', computedPosition); + module.debug('RTL: Popup position updated', position); + } + + if(searchDepth == settings.maxSearchDepth && settings.lastResort) { + module.debug('Using "last resort" position to display', settings.lastResort); + position = settings.lastResort; } - switch (computedPosition) { + + switch (position) { case 'top left': positioning = { top : 'auto', - bottom : parentHeight - target.top + distanceAway, - left : target.left + arrowOffset, + bottom : parent.height - target.top + distanceAway, + left : target.left + offset, right : 'auto' }; break; case 'top center': positioning = { - bottom : parentHeight - target.top + distanceAway, - left : target.left + (targetWidth / 2) - (popupWidth / 2) + arrowOffset, + 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 : parentHeight - target.top + distanceAway, - right : parentWidth - target.left - targetWidth - arrowOffset, + 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 + (targetHeight / 2) - (popupHeight / 2) + arrowOffset, - right : parentWidth - target.left + distanceAway, + 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 + (targetHeight / 2) - (popupHeight / 2) + arrowOffset, - left : target.left + targetWidth + distanceAway, + 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 + targetHeight + distanceAway, - left : target.left + arrowOffset, + top : target.top + target.height + distanceAway, + left : target.left + offset, bottom : 'auto', right : 'auto' }; break; case 'bottom center': positioning = { - top : target.top + targetHeight + distanceAway, - left : target.left + (targetWidth / 2) - (popupWidth / 2) + arrowOffset, + 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 + targetHeight + distanceAway, - right : parentWidth - target.left - targetWidth - arrowOffset, + top : target.top + target.height + distanceAway, + right : parent.width - target.left - target.width - offset, left : 'auto', bottom : 'auto' }; @@ -744,17 +805,17 @@ $.fn.popup = function(parameters) { .addClass(className.loading) ; // check if is offstage - offstagePosition = module.get.offstagePosition(position); + offstagePosition = module.get.offstagePosition(position, calculations); // recursively find new positioning if(offstagePosition) { - module.debug('Popup cant fit into viewport', offstagePosition); + module.debug('Popup cant fit into viewport', position, offstagePosition); if(searchDepth < settings.maxSearchDepth) { searchDepth++; position = module.get.nextPosition(position); module.debug('Trying new position', position); return ($popup) - ? module.set.position(position) + ? module.set.position(position, calculations) : false ; } @@ -770,14 +831,15 @@ $.fn.popup = function(parameters) { module.debug('Position is on stage', position); module.remove.attempts(); - module.set.fluidWidth(); + module.set.fluidWidth(calculations); module.remove.loading(); return true; }, - fluidWidth: function() { + fluidWidth: function(calculations) { + calculations = calculations || module.get.calculations(); if( settings.setFluidWidth && $popup.hasClass(className.fluid) ) { - $popup.css('width', $offsetParent.width()); + $popup.css('width', calculations.parent.width); } }, @@ -808,6 +870,11 @@ $.fn.popup = function(parameters) { .on('click' + eventNamespace, module.toggle) ; } + if(settings.on == 'hover' && hasTouch) { + $module + .on('touchstart' + eventNamespace, module.event.touchstart) + ; + } else if( module.get.startEvent() ) { $module .on(module.get.startEvent() + eventNamespace, module.event.start) @@ -828,21 +895,30 @@ $.fn.popup = function(parameters) { ; } }, - close:function() { - if(settings.hideOnScroll === true || settings.hideOnScroll == 'auto' && settings.on != 'click') { + close: function() { + if(settings.hideOnScroll === true || (settings.hideOnScroll == 'auto' && settings.on != 'click')) { $document - .one(module.get.scrollEvent() + elementNamespace, module.hideGracefully) + .one(module.get.scrollEvent() + elementNamespace, module.event.hideGracefully) ; $context - .one(module.get.scrollEvent() + elementNamespace, module.hideGracefully) + .one(module.get.scrollEvent() + elementNamespace, module.event.hideGracefully) + ; + } + if(settings.on == 'hover' && openedWithTouch) { + module.verbose('Binding popup close event to document'); + $document + .on('touchstart' + elementNamespace, function(event) { + module.verbose('Touched away from popup'); + module.event.hideGracefully.call(element, event); + }) ; } if(settings.on == 'click' && settings.closable) { module.verbose('Binding popup close event to document'); $document .on('click' + elementNamespace, function(event) { - module.verbose('Pop-up clickaway intent detected'); - module.hideGracefully.call(element, event); + module.verbose('Clicked away from popup'); + module.event.hideGracefully.call(element, event); }) ; } @@ -851,7 +927,7 @@ $.fn.popup = function(parameters) { unbind: { close: function() { - if(settings.hideOnScroll === true || settings.hideOnScroll == 'auto' && settings.on != 'click') { + if(settings.hideOnScroll === true || (settings.hideOnScroll == 'auto' && settings.on != 'click')) { $document .off('scroll' + elementNamespace, module.hide) ; @@ -859,6 +935,12 @@ $.fn.popup = function(parameters) { .off('scroll' + elementNamespace, module.hide) ; } + if(settings.on == 'hover' && openedWithTouch) { + $document + .off('touchstart' + elementNamespace) + ; + openedWithTouch = false; + } if(settings.on == 'click' && settings.closable) { module.verbose('Removing close event from document'); $document @@ -879,10 +961,10 @@ $.fn.popup = function(parameters) { return $module.hasClass(className.active); }, animating: function() { - return ( $popup && $popup.is(':animated') || $popup.hasClass(className.animating) ); + return ( $popup && $popup.hasClass(className.animating) ); }, visible: function() { - return $popup && $popup.is(':visible'); + return $popup && $popup.hasClass(className.visible); }, dropdown: function() { return $module.hasClass(className.dropdown); @@ -977,7 +1059,7 @@ $.fn.popup = function(parameters) { }); } clearTimeout(module.performance.timer); - module.performance.timer = setTimeout(module.performance.display, 100); + module.performance.timer = setTimeout(module.performance.display, 500); }, display: function() { var @@ -1088,61 +1170,115 @@ $.fn.popup.settings = { name : 'Popup', + // module settings debug : false, - verbose : true, + verbose : false, performance : true, namespace : 'popup', + // 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 after hide animation onHidden : function(){}, + // when to show popup + on : 'hover', + + // 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 : true, + + // 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, - on : 'hover', + // whether automatically close on clickaway when on click closable : true, + + // automatically hide on scroll hideOnScroll : 'auto', - exclusive : true, + // hide other popups on show + exclusive : false, + + // context to attach popups context : 'body', - position : 'top left', + // position to prefer when calculating new position prefer : 'opposite', + + // specify position to appear even if it doesn't fit lastResort : false, + // delay used to prevent accidental refiring of animations due to user error delay : { - show : 30, - hide : 0 + show : 50, + hide : 70 }, + // whether fluid variation should assign width explicitly setFluidWidth : true, - movePopup : true, - - target : false, - popup : false, - inline : false, - preserve : false, - hoverable : false, + // transition settings duration : 200, - easing : 'easeOutQuint', transition : 'scale', + // distance away from activating element in px distanceAway : 0, + + // offset on aligning axis from calculated position offset : 0, + + // maximum times to look for a position before failing (9 positions total) maxSearchDepth : 20, error: { invalidPosition : 'The position you specified is not a valid position', cannotPlace : 'No visible position could be found for the popup', - method : 'The method you called is not defined.' + method : 'The method you called is not defined.', + noTransition : 'This module requires ui transitions ', + notFound : 'The target or popup you specified does not exist on the page' }, metadata: { @@ -1213,12 +1349,5 @@ $.fn.popup.settings = { }; -// Adds easing -$.extend( $.easing, { - easeOutQuad: function (x, t, b, c, d) { - return -c *(t/=d)*(t-2) + b; - } -}); - })( jQuery, window , document ); diff --git a/popup.min.css b/popup.min.css index 5519bf9..20383d7 100755 --- a/popup.min.css +++ b/popup.min.css @@ -1,10 +1,10 @@ /*! - * # Semantic UI 1.12.3 - Popup + * # Semantic UI 2.0.0 - Popup * http://github.com/semantic-org/semantic-ui/ * * - * Copyright 2014 Contributors + * Copyright 2015 Contributors * Released under the MIT license * http://opensource.org/licenses/MIT * - */.ui.popup{display:none;position:absolute;top:0;right:0;z-index:1900;border:1px solid #ccc;max-width:250px;background-color:#fff;padding:.833em 1em;font-weight:400;font-style:normal;color:rgba(0,0,0,.8);border-radius:.2857rem;box-shadow:0 2px 4px rgba(0,0,0,.1);margin:0}.ui.popup>.header{padding:0;font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;font-size:1.125em;line-height:1.2;font-weight:700}.ui.popup>.header+.content{padding-top:.5em}.ui.popup:before{position:absolute;content:'';width:.75em;height:.75em;background:#fff;-webkit-transform:rotate(45deg);-ms-transform:rotate(45deg);transform:rotate(45deg);z-index:2;box-shadow:1px 1px 0 0 #b3b3b3}.ui.popup.bottom{margin:.75em 0 0}.ui.popup.top{margin:0 0 .75em}.ui.popup.left.center{margin:0 .75em 0 0}.ui.popup.right.center{margin:0 0 0 .75em}.ui.bottom.center.popup:before{margin-left:-.325em;top:-.325em;left:50%;right:auto;bottom:auto;box-shadow:-1px -1px 0 0 #b3b3b3}.ui.bottom.left.popup{margin-left:0}.ui.bottom.left.popup:before{top:-.325em;left:1em;right:auto;bottom:auto;margin-left:0;box-shadow:-1px -1px 0 0 #b3b3b3}.ui.bottom.right.popup{margin-right:0}.ui.bottom.right.popup:before{top:-.325em;right:1em;bottom:auto;left:auto;margin-left:0;box-shadow:-1px -1px 0 0 #b3b3b3}.ui.top.center.popup:before{top:auto;right:auto;bottom:-.325em;left:50%;margin-left:-.325em}.ui.top.left.popup{margin-left:0}.ui.top.left.popup:before{bottom:-.325em;left:1em;top:auto;right:auto;margin-left:0}.ui.top.right.popup{margin-right:0}.ui.top.right.popup:before{bottom:-.325em;right:1em;top:auto;left:auto;margin-left:0}.ui.left.center.popup:before{top:50%;right:-.325em;bottom:auto;left:auto;margin-top:-.325em;box-shadow:1px -1px 0 0 #b3b3b3}.ui.right.center.popup:before{top:50%;left:-.325em;bottom:auto;right:auto;margin-top:-.325em;box-shadow:-1px 1px 0 0 #b3b3b3}.ui.popup>.ui.grid:not(.padded){width:-webkit-calc(100% + 1.75rem);width:calc(100% + 1.75rem);margin:-.7rem -.875rem}.ui.loading.popup{display:block;visibility:hidden;z-index:-1}.ui.animating.popup,.ui.visible.popup{display:block}.ui.basic.popup:before{display:none}.ui.wide.popup{max-width:350px}.ui[class*="very wide"].popup{max-width:550px}.ui.fluid.popup{width:100%;max-width:none}.ui.inverted.popup{background:#1b1c1d;color:#fff;border:none;box-shadow:none}.ui.inverted.popup .header{background-color:none;color:#fff}.ui.inverted.popup:before{background-color:#1b1c1d;box-shadow:none!important}.ui.flowing.popup{max-width:none}.ui.small.popup{font-size:.785714rem}.ui.popup{font-size:.85714rem}.ui.large.popup{font-size:1rem}.ui.huge.popup{font-size:1.14285rem} \ No newline at end of file + */.ui.popup{display:none;position:absolute;top:0;right:0;min-width:-webkit-min-content;min-width:-moz-min-content;min-width:min-content;z-index:1900;border:1px solid #d4d4d5;line-height:1.4285em;max-width:250px;background-color:#fff;padding:.833em 1em;font-weight:400;font-style:normal;color:rgba(0,0,0,.87);border-radius:.28571429rem;box-shadow:0 2px 4px 0 rgba(34,36,38,.12),0 2px 10px 0 rgba(34,36,38,.08);margin:0}.ui.popup>.header{padding:0;font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;font-size:1.125em;line-height:1.2;font-weight:700}.ui.popup>.header+.content{padding-top:.5em}.ui.popup:before{position:absolute;content:'';width:.75em;height:.75em;background:#fff;-webkit-transform:rotate(45deg);-ms-transform:rotate(45deg);transform:rotate(45deg);z-index:2;box-shadow:1px 1px 0 0 #bababc}.ui.top.popup{margin:0 0 .75em}.ui.top.left.popup{-webkit-transform-origin:left bottom;-ms-transform-origin:left bottom;transform-origin:left bottom}.ui.top.center.popup{-webkit-transform-origin:center bottom;-ms-transform-origin:center bottom;transform-origin:center bottom}.ui.top.right.popup{-webkit-transform-origin:right bottom;-ms-transform-origin:right bottom;transform-origin:right bottom}.ui.left.center.popup{margin:0 .75em 0 0;-webkit-transform-origin:right 50%;-ms-transform-origin:right 50%;transform-origin:right 50%}.ui.right.center.popup{margin:0 0 0 .75em;-webkit-transform-origin:left 50%;-ms-transform-origin:left 50%;transform-origin:left 50%}.ui.bottom.popup{margin:.75em 0 0}.ui.bottom.left.popup{-webkit-transform-origin:left top;-ms-transform-origin:left top;transform-origin:left top}.ui.bottom.center.popup{-webkit-transform-origin:center top;-ms-transform-origin:center top;transform-origin:center top}.ui.bottom.right.popup{-webkit-transform-origin:right top;-ms-transform-origin:right top;transform-origin:right top;margin-right:0}.ui.bottom.center.popup:before{margin-left:-.325em;top:-.325em;left:50%;right:auto;bottom:auto;box-shadow:-1px -1px 0 0 #bababc}.ui.bottom.left.popup{margin-left:0}.ui.bottom.left.popup:before{top:-.325em;left:1em;right:auto;bottom:auto;margin-left:0;box-shadow:-1px -1px 0 0 #bababc}.ui.bottom.right.popup:before{top:-.325em;right:1em;bottom:auto;left:auto;margin-left:0;box-shadow:-1px -1px 0 0 #bababc}.ui.top.center.popup:before{top:auto;right:auto;bottom:-.325em;left:50%;margin-left:-.325em}.ui.top.left.popup{margin-left:0}.ui.top.left.popup:before{bottom:-.325em;left:1em;top:auto;right:auto;margin-left:0}.ui.top.right.popup{margin-right:0}.ui.top.right.popup:before{bottom:-.325em;right:1em;top:auto;left:auto;margin-left:0}.ui.left.center.popup:before{top:50%;right:-.325em;bottom:auto;left:auto;margin-top:-.325em;box-shadow:1px -1px 0 0 #bababc}.ui.right.center.popup:before{top:50%;left:-.325em;bottom:auto;right:auto;margin-top:-.325em;box-shadow:-1px 1px 0 0 #bababc}.ui.popup>.ui.grid:not(.padded){width:calc(100% + 1.75rem);margin:-.7rem -.875rem}.ui.loading.popup{display:block;visibility:hidden;z-index:-1}.ui.animating.popup,.ui.visible.popup{display:block}.ui.visible.popup{-webkit-transform:translateZ(0);transform:translateZ(0);-webkit-backface-visibility:hidden;backface-visibility:hidden}.ui.basic.popup:before{display:none}.ui.wide.popup{max-width:350px}.ui[class*="very wide"].popup{max-width:550px}.ui.fluid.popup{width:100%;max-width:none}.ui.inverted.popup{background:#1b1c1d;color:#fff;border:none;box-shadow:none}.ui.inverted.popup .header{background-color:none;color:#fff}.ui.inverted.popup:before{background-color:#1b1c1d;box-shadow:none!important}.ui.flowing.popup{max-width:none}.ui.mini.popup{font-size:.71428571rem}.ui.tiny.popup{font-size:.85714286rem}.ui.small.popup{font-size:.92857143rem}.ui.popup{font-size:1rem}.ui.large.popup{font-size:1.14285714rem}.ui.huge.popup{font-size:1.42857143rem} \ No newline at end of file diff --git a/popup.min.js b/popup.min.js index 901099c..a0d487e 100755 --- a/popup.min.js +++ b/popup.min.js @@ -1,11 +1,11 @@ /*! - * # Semantic UI 1.12.3 - Popup + * # Semantic UI 2.0.0 - Popup * http://github.com/semantic-org/semantic-ui/ * * - * Copyright 2014 Contributors + * Copyright 2015 Contributors * Released under the MIT license * http://opensource.org/licenses/MIT * */ -!function(e,t,o,n){"use strict";e.fn.popup=function(i){var r,s=e(this),a=e(o),p=s.selector||"",l="ontouchstart"in o.documentElement,u=(new Date).getTime(),c=[],d=arguments[0],f="string"==typeof d,g=[].slice.call(arguments,1);return s.each(function(){var o,s,h,m,b,v=e.isPlainObject(i)?e.extend(!0,{},e.fn.popup.settings,i):e.extend({},e.fn.popup.settings),y=v.selector,w=v.className,P=v.error,T=v.metadata,C=v.namespace,x="."+v.namespace,k="module-"+C,S=e(this),O=e(v.context),E=v.target?e(v.target):S,j=e(t),A=e("body"),R=0,F=!1,D=this,H=S.data(k);b={initialize:function(){b.debug("Initializing",S),b.createID(),b.bind.events(),!b.exists()&&v.preserve&&b.create(),b.instantiate()},instantiate:function(){b.verbose("Storing instance",b),H=b,S.data(k,H)},refresh:function(){v.popup?o=e(v.popup).eq(0):v.inline&&(o=E.next(y.popup).eq(0)),v.popup?(o.addClass(w.loading),s=b.get.offsetParent(),o.removeClass(w.loading),v.movePopup&&b.has.popup()&&b.get.offsetParent(o)[0]!==s[0]&&(b.debug("Moving popup to the same offset parent as activating element"),o.detach().appendTo(s))):s=v.inline?b.get.offsetParent(E):b.has.popup()?b.get.offsetParent(o):A,s.is("html")&&(b.debug("Setting page as offset parent"),s=A)},reposition:function(){b.refresh(),b.set.position()},destroy:function(){b.debug("Destroying previous module"),o&&!v.preserve&&b.removePopup(),clearTimeout(b.hideTimer),clearTimeout(b.showTimer),j.off(h),S.off(x).removeData(k)},event:{start:function(t){var o=e.isPlainObject(v.delay)?v.delay.show:v.delay;clearTimeout(b.hideTimer),b.showTimer=setTimeout(function(){!b.is.hidden()||b.is.active()&&b.is.dropdown()||b.show()},o)},end:function(){var t=e.isPlainObject(v.delay)?v.delay.hide:v.delay;clearTimeout(b.showTimer),b.hideTimer=setTimeout(function(){b.is.visible()&&b.hide()},t)},resize:function(){b.is.visible()&&b.set.position()}},create:function(){var t=S.data(T.html)||v.html,n=S.data(T.variation)||v.variation,i=S.data(T.title)||v.title,r=S.data(T.content)||S.attr("title")||v.content;t||r||i?(b.debug("Creating pop-up html"),t||(t=v.templates.popup({title:i,content:r})),o=e("
").addClass(w.popup).addClass(n).data(T.activator,S).html(t),n&&o.addClass(n),v.inline?(b.verbose("Inserting popup element inline",o),o.insertAfter(S)):(b.verbose("Appending popup element to body",o),o.appendTo(O)),b.refresh(),v.hoverable&&b.bind.popup(),v.onCreate.call(o,D)):0!==E.next(y.popup).length?(b.verbose("Pre-existing popup found"),v.inline=!0,v.popup=E.next(y.popup).data(T.activator,S),b.refresh(),v.hoverable&&b.bind.popup()):v.popup?(v.popup.data(T.activator,S),b.verbose("Used popup specified in settings"),b.refresh(),v.hoverable&&b.bind.popup()):b.debug("No content specified skipping display",D)},createID:function(){m=(Math.random().toString(16)+"000000000").substr(2,8),h="."+m,b.verbose("Creating unique id for element",m)},toggle:function(){b.debug("Toggling pop-up"),b.is.hidden()?(b.debug("Popup is hidden, showing pop-up"),b.unbind.close(),b.show()):(b.debug("Popup is visible, hiding pop-up"),b.hide())},show:function(t){t=e.isFunction(t)?t:function(){},b.debug("Showing pop-up",v.transition),b.exists()?v.preserve||v.popup||b.refresh():b.create(),o&&b.set.position()&&(b.save.conditions(),v.exclusive&&b.hideAll(),b.animate.show(t))},hide:function(t){t=e.isFunction(t)?t:function(){},b.remove.visible(),b.unbind.close(),b.is.visible()&&(b.restore.conditions(),b.animate.hide(t))},hideAll:function(){e(y.popup).filter("."+w.visible).each(function(){e(this).data(T.activator).popup("hide")})},hideGracefully:function(t){t&&0===e(t.target).closest(y.popup).length?(b.debug("Click occurred outside popup hiding popup"),b.hide()):b.debug("Click was inside popup, keeping popup open")},exists:function(){return o?v.inline||v.popup?b.has.popup():o.closest(O).length>=1?!0:!1:!1},removePopup:function(){b.debug("Removing popup",o),b.has.popup()&&!v.popup&&(o.remove(),o=n),v.onRemove.call(o,D)},save:{conditions:function(){b.cache={title:S.attr("title")},b.cache.title&&S.removeAttr("title"),b.verbose("Saving original attributes",b.cache.title)}},restore:{conditions:function(){return b.cache&&b.cache.title&&(S.attr("title",b.cache.title),b.verbose("Restoring original attributes",b.cache.title)),!0}},animate:{show:function(t){t=e.isFunction(t)?t:function(){},v.transition&&e.fn.transition!==n&&S.transition("is supported")?(b.set.visible(),o.transition({animation:v.transition+" in",queue:!1,debug:v.debug,verbose:v.verbose,duration:v.duration,onComplete:function(){b.bind.close(),t.call(o,D),v.onVisible.call(o,D)}})):(b.set.visible(),o.stop().fadeIn(v.duration,v.easing,function(){b.bind.close(),t.call(o,D),v.onVisible.call(o,D)})),v.onShow.call(o,D)},hide:function(t){t=e.isFunction(t)?t:function(){},b.debug("Hiding pop-up"),v.transition&&e.fn.transition!==n&&S.transition("is supported")?o.transition({animation:v.transition+" out",queue:!1,duration:v.duration,debug:v.debug,verbose:v.verbose,onComplete:function(){b.reset(),t.call(o,D),v.onHidden.call(o,D)}}):o.stop().fadeOut(v.duration,v.easing,function(){b.reset(),t.call(o,D),v.onHidden.call(o,D)}),v.onHide.call(o,D)}},get:{id:function(){return m},startEvent:function(){return"hover"==v.on?l?"touchstart mouseenter":"mouseenter":"focus"==v.on?"focus":!1},scrollEvent:function(){return l?"touchmove scroll":"scroll"},endEvent:function(){return"hover"==v.on?"mouseleave":"focus"==v.on?"blur":!1},offsetParent:function(t){var o=t!==n?t[0]:S[0],i=o.parentNode,r=e(i);if(i)for(var s="none"===r.css("transform"),a="static"===r.css("position"),p=r.is("html");i&&!p&&a&&s;)i=i.parentNode,r=e(i),s="none"===r.css("transform"),a="static"===r.css("position"),p=r.is("html");return r&&r.length>0?r:e()},offstagePosition:function(n){var i={top:e(t).scrollTop(),bottom:e(t).scrollTop()+e(t).height(),left:0,right:e(t).width()},r={width:o.width(),height:o.height(),offset:o.offset()},s={},a=[];return n=n||!1,r.offset&&n&&(b.verbose("Checking if outside viewable area",r.offset),s={top:r.offset.topi.bottom,right:r.offset.left+r.width>i.right,left:r.offset.left0?a.join(" "):!1},positions:function(){return{"top left":!1,"top center":!1,"top right":!1,"bottom left":!1,"bottom center":!1,"bottom right":!1,"left center":!1,"right center":!1}},nextPosition:function(e){var t=e.split(" "),o=t[0],n=t[1],i={top:"bottom",bottom:"top",left:"right",right:"left"},r={left:"center",center:"right",right:"left"},s={"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"},a="top"==o||"bottom"==o,p=!1,l=!1,u=!1;return F||(b.verbose("All available positions available"),F=b.get.positions()),b.debug("Recording last position tried",e),F[e]=!0,"opposite"===v.prefer&&(u=[i[o],n],u=u.join(" "),p=F[u]===!0,b.debug("Trying opposite strategy",u)),"adjacent"===v.prefer&&a&&(u=[o,r[n]],u=u.join(" "),l=F[u]===!0,b.debug("Trying adjacent strategy",u)),(l||p)&&(b.debug("Using backup position",u),u=s[e]),u}},set:{position:function(i,r){var a,p,l,u=(e(t).width(),e(t).height(),E.outerWidth()),c=E.outerHeight(),d=o.outerWidth(),f=o.outerHeight(),g=s.outerWidth(),h=s.outerHeight(),m=v.distanceAway,y=E[0],C=v.inline?parseInt(t.getComputedStyle(y).getPropertyValue("margin-top"),10):0,x=v.inline?parseInt(t.getComputedStyle(y).getPropertyValue(b.is.rtl()?"margin-right":"margin-left"),10):0,k=v.inline||v.popup?E.position():E.offset();switch(i=i||S.data(T.position)||v.position,r=r||S.data(T.offset)||v.offset,R==v.maxSearchDepth&&v.lastResort&&(b.debug("Using last resort position to display",v.lastResort),i=v.lastResort),v.inline&&(b.debug("Adding targets margin to calculation"),"left center"==i||"right center"==i?(r+=C,m+=-x):"top left"==i||"top center"==i||"top right"==i?(r+=x,m-=C):(r+=x,m+=C)),b.debug("Calculating popup positioning",i),a=i,b.is.rtl()&&(a=a.replace(/left|right/g,function(e){return"left"==e?"right":"left"}),b.debug("RTL: Popup positioning updated",a)),a){case"top left":p={top:"auto",bottom:h-k.top+m,left:k.left+r,right:"auto"};break;case"top center":p={bottom:h-k.top+m,left:k.left+u/2-d/2+r,top:"auto",right:"auto"};break;case"top right":p={bottom:h-k.top+m,right:g-k.left-u-r,top:"auto",left:"auto"};break;case"left center":p={top:k.top+c/2-f/2+r,right:g-k.left+m,left:"auto",bottom:"auto"};break;case"right center":p={top:k.top+c/2-f/2+r,left:k.left+u+m,bottom:"auto",right:"auto"};break;case"bottom left":p={top:k.top+c+m,left:k.left+r,bottom:"auto",right:"auto"};break;case"bottom center":p={top:k.top+c+m,left:k.left+u/2-d/2+r,bottom:"auto",right:"auto"};break;case"bottom right":p={top:k.top+c+m,right:g-k.left-u-r,left:"auto",bottom:"auto"}}if(p===n&&b.error(P.invalidPosition,i),b.debug("Calculated popup positioning values",p),o.css(p).removeClass(w.position).addClass(i).addClass(w.loading),l=b.get.offstagePosition(i)){if(b.debug("Popup cant fit into viewport",l),R0}},is:{active:function(){return S.hasClass(w.active)},animating:function(){return o&&o.is(":animated")||o.hasClass(w.animating)},visible:function(){return o&&o.is(":visible")},dropdown:function(){return S.hasClass(w.dropdown)},hidden:function(){return!b.is.visible()},rtl:function(){return"rtl"==S.css("direction")}},reset:function(){b.remove.visible(),v.preserve?e.fn.transition!==n&&o.transition("remove transition"):b.removePopup()},setting:function(t,o){if(e.isPlainObject(t))e.extend(!0,v,t);else{if(o===n)return v[t];v[t]=o}},internal:function(t,o){if(e.isPlainObject(t))e.extend(!0,b,t);else{if(o===n)return b[t];b[t]=o}},debug:function(){v.debug&&(v.performance?b.performance.log(arguments):(b.debug=Function.prototype.bind.call(console.info,console,v.name+":"),b.debug.apply(console,arguments)))},verbose:function(){v.verbose&&v.debug&&(v.performance?b.performance.log(arguments):(b.verbose=Function.prototype.bind.call(console.info,console,v.name+":"),b.verbose.apply(console,arguments)))},error:function(){b.error=Function.prototype.bind.call(console.error,console,v.name+":"),b.error.apply(console,arguments)},performance:{log:function(e){var t,o,n;v.performance&&(t=(new Date).getTime(),n=u||t,o=t-n,u=t,c.push({Name:e[0],Arguments:[].slice.call(e,1)||"",Element:D,"Execution Time":o})),clearTimeout(b.performance.timer),b.performance.timer=setTimeout(b.performance.display,100)},display:function(){var t=v.name+":",o=0;u=!1,clearTimeout(b.performance.timer),e.each(c,function(e,t){o+=t["Execution Time"]}),t+=" "+o+"ms",p&&(t+=" '"+p+"'"),(console.group!==n||console.table!==n)&&c.length>0&&(console.groupCollapsed(t),console.table?console.table(c):e.each(c,function(e,t){console.log(t.Name+": "+t["Execution Time"]+"ms")}),console.groupEnd()),c=[]}},invoke:function(t,o,i){var s,a,p,l=H;return o=o||g,i=D||i,"string"==typeof t&&l!==n&&(t=t.split(/[\. ]/),s=t.length-1,e.each(t,function(o,i){var r=o!=s?i+t[o+1].charAt(0).toUpperCase()+t[o+1].slice(1):t;if(e.isPlainObject(l[r])&&o!=s)l=l[r];else{if(l[r]!==n)return a=l[r],!1;if(!e.isPlainObject(l[i])||o==s)return l[i]!==n?(a=l[i],!1):!1;l=l[i]}})),e.isFunction(a)?p=a.apply(i,o):a!==n&&(p=a),e.isArray(r)?r.push(p):r!==n?r=[r,p]:p!==n&&(r=p),a}},f?(H===n&&b.initialize(),b.invoke(d)):(H!==n&&H.invoke("destroy"),b.initialize())}),r!==n?r:this},e.fn.popup.settings={name:"Popup",debug:!1,verbose:!0,performance:!0,namespace:"popup",onCreate:function(){},onRemove:function(){},onShow:function(){},onVisible:function(){},onHide:function(){},onHidden:function(){},variation:"",content:!1,html:!1,title:!1,on:"hover",closable:!0,hideOnScroll:"auto",exclusive:!0,context:"body",position:"top left",prefer:"opposite",lastResort:!1,delay:{show:30,hide:0},setFluidWidth:!0,movePopup:!0,target:!1,popup:!1,inline:!1,preserve:!1,hoverable:!1,duration:200,easing:"easeOutQuint",transition:"scale",distanceAway:0,offset:0,maxSearchDepth:20,error:{invalidPosition:"The position you specified is not a valid position",cannotPlace:"No visible position could be found for the popup",method:"The method you called is not defined."},metadata:{activator:"activator",content:"content",html:"html",offset:"offset",position:"position",title:"title",variation:"variation"},className:{active:"active",animating:"animating",dropdown:"dropdown",fluid:"fluid",loading:"loading",popup:"ui popup",position:"top left center bottom right",visible:"visible"},selector:{popup:".ui.popup"},templates:{escape:function(e){var t=/[&<>"'`]/g,o=/[&<>"'`]/,n={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},i=function(e){return n[e]};return o.test(e)?e.replace(t,i):e},popup:function(t){var o="",i=e.fn.popup.settings.templates.escape;return typeof t!==n&&(typeof t.title!==n&&t.title&&(t.title=i(t.title),o+='
'+t.title+"
"),typeof t.content!==n&&t.content&&(t.content=i(t.content),o+='
'+t.content+"
")),o}}},e.extend(e.easing,{easeOutQuad:function(e,t,o,n,i){return-n*(t/=i)*(t-2)+o}})}(jQuery,window,document); \ No newline at end of file +!function(t,e,o,n){"use strict";t.fn.popup=function(i){var r,a=t(this),s=t(o),p=t(e),l=t("body"),u=a.selector||"",c="ontouchstart"in o.documentElement,d=(new Date).getTime(),f=[],g=arguments[0],h="string"==typeof g,m=[].slice.call(arguments,1);return a.each(function(){var o,a,v,b,y,w=t.isPlainObject(i)?t.extend(!0,{},t.fn.popup.settings,i):t.extend({},t.fn.popup.settings),T=w.selector,P=w.className,C=w.error,k=w.metadata,x=w.namespace,S="."+w.namespace,E="module-"+x,D=t(this),O=t(w.context),j=w.target?t(w.target):D,A=0,R=!1,F=!1,H=this,I=D.data(E);y={initialize:function(){y.debug("Initializing",D),y.createID(),y.bind.events(),!y.exists()&&w.preserve&&y.create(),y.instantiate()},instantiate:function(){y.verbose("Storing instance",y),I=y,D.data(E,I)},refresh:function(){w.popup?o=t(w.popup).eq(0):w.inline&&(o=j.next(T.popup).eq(0),w.popup=o),w.popup?(o.addClass(P.loading),a=y.get.offsetParent(),o.removeClass(P.loading),w.movePopup&&y.has.popup()&&y.get.offsetParent(o)[0]!==a[0]&&(y.debug("Moving popup to the same offset parent as activating element"),o.detach().appendTo(a))):a=w.inline?y.get.offsetParent(j):y.has.popup()?y.get.offsetParent(o):l,a.is("html")&&(y.debug("Setting page as offset parent"),a=l)},reposition:function(){y.refresh(),y.set.position()},destroy:function(){y.debug("Destroying previous module"),o&&!w.preserve&&y.removePopup(),clearTimeout(y.hideTimer),clearTimeout(y.showTimer),p.off(v),D.off(S).removeData(E)},event:{start:function(e){var o=t.isPlainObject(w.delay)?w.delay.show:w.delay;clearTimeout(y.hideTimer),y.showTimer=setTimeout(y.show,o)},end:function(){var e=t.isPlainObject(w.delay)?w.delay.hide:w.delay;clearTimeout(y.showTimer),y.hideTimer=setTimeout(y.hide,e)},touchstart:function(t){F=!0,y.event.start()},resize:function(){y.is.visible()&&y.set.position()},hideGracefully:function(e){e&&0===t(e.target).closest(T.popup).length?(y.debug("Click occurred outside popup hiding popup"),y.hide()):y.debug("Click was inside popup, keeping popup open")}},create:function(){var e=y.get.html(),n=y.get.variation(),i=y.get.title(),r=y.get.content();e||r||i?(y.debug("Creating pop-up html"),e||(e=w.templates.popup({title:i,content:r})),o=t("
").addClass(P.popup).addClass(n).data(k.activator,D).html(e),n&&o.addClass(n),w.inline?(y.verbose("Inserting popup element inline",o),o.insertAfter(D)):(y.verbose("Appending popup element to body",o),o.appendTo(O)),y.refresh(),w.hoverable&&y.bind.popup(),w.onCreate.call(o,H)):0!==j.next(T.popup).length?(y.verbose("Pre-existing popup found"),w.inline=!0,w.popups=j.next(T.popup).data(k.activator,D),y.refresh(),w.hoverable&&y.bind.popup()):w.popup?(t(w.popup).data(k.activator,D),y.verbose("Used popup specified in settings"),y.refresh(),w.hoverable&&y.bind.popup()):y.debug("No content specified skipping display",H)},createID:function(){b=(Math.random().toString(16)+"000000000").substr(2,8),v="."+b,y.verbose("Creating unique id for element",b)},toggle:function(){y.debug("Toggling pop-up"),y.is.hidden()?(y.debug("Popup is hidden, showing pop-up"),y.unbind.close(),y.show()):(y.debug("Popup is visible, hiding pop-up"),y.hide())},show:function(t){if(t=t||function(){},y.debug("Showing pop-up",w.transition),y.is.hidden()&&(!y.is.active()||!y.is.dropdown())){if(y.exists()||y.create(),w.onShow.call(o,H)===!1)return void y.debug("onShow callback returned false, cancelling popup animation");w.preserve||w.popup||y.refresh(),o&&y.set.position()&&(y.save.conditions(),w.exclusive&&y.hideAll(),y.animate.show(t))}},hide:function(t){if(t=t||function(){},y.is.visible()||y.is.animating()){if(w.onHide.call(o,H)===!1)return void y.debug("onHide callback returned false, cancelling popup animation");y.remove.visible(),y.unbind.close(),y.restore.conditions(),y.animate.hide(t)}},hideAll:function(){t(T.popup).filter("."+P.visible).each(function(){t(this).data(k.activator).popup("hide")})},exists:function(){return o?w.inline||w.popup?y.has.popup():o.closest(O).length>=1?!0:!1:!1},removePopup:function(){y.debug("Removing popup",o),y.has.popup()&&!w.popup&&(o.remove(),o=n),w.onRemove.call(o,H)},save:{conditions:function(){y.cache={title:D.attr("title")},y.cache.title&&D.removeAttr("title"),y.verbose("Saving original attributes",y.cache.title)}},restore:{conditions:function(){return y.cache&&y.cache.title&&(D.attr("title",y.cache.title),y.verbose("Restoring original attributes",y.cache.title)),!0}},animate:{show:function(e){e=t.isFunction(e)?e:function(){},w.transition&&t.fn.transition!==n&&D.transition("is supported")?(y.set.visible(),o.transition({animation:w.transition+" in",queue:!1,debug:w.debug,verbose:w.verbose,duration:w.duration,onComplete:function(){y.bind.close(),e.call(o,H),w.onVisible.call(o,H)}})):y.error(C.noTransition)},hide:function(e){return e=t.isFunction(e)?e:function(){},y.debug("Hiding pop-up"),w.onShow.call(o,H)===!1?void y.debug("onShow callback returned false, cancelling popup animation"):void(w.transition&&t.fn.transition!==n&&D.transition("is supported")?o.transition({animation:w.transition+" out",queue:!1,duration:w.duration,debug:w.debug,verbose:w.verbose,onComplete:function(){y.reset(),e.call(o,H),w.onHidden.call(o,H)}}):y.error(C.noTransition))}},get:{html:function(){return D.removeData(k.html),D.data(k.html)||w.html},title:function(){return D.removeData(k.title),D.data(k.title)||w.title},content:function(){return D.removeData(k.content),D.data(k.content)||D.attr("title")||w.content},variation:function(){return D.removeData(k.variation),D.data(k.variation)||w.variation},calculations:function(){var t,n=j[0],i=w.inline||w.popup?j.position():j.offset(),r={};return r={target:{element:j[0],width:j.outerWidth(),height:j.outerHeight(),top:i.top,left:i.left,margin:{}},popup:{width:o.outerWidth(),height:o.outerHeight()},parent:{width:a.outerWidth(),height:a.outerHeight()},screen:{scroll:{top:p.scrollTop(),left:p.scrollLeft()},width:p.width(),height:p.height()}},r.target.margin.top=w.inline?parseInt(e.getComputedStyle(n).getPropertyValue("margin-top"),10):0,r.target.margin.left=w.inline?y.is.rtl()?parseInt(e.getComputedStyle(n).getPropertyValue("margin-right"),10):parseInt(e.getComputedStyle(n).getPropertyValue("margin-left"),10):0,t=r.screen,r.boundary={top:t.scroll.top,bottom:t.scroll.top+t.height,left:t.scroll.left,right:t.scroll.left+t.width},r},id:function(){return b},startEvent:function(){return"hover"==w.on?"mouseenter":"focus"==w.on?"focus":!1},scrollEvent:function(){return"scroll"},endEvent:function(){return"hover"==w.on?"mouseleave":"focus"==w.on?"blur":!1},offsetParent:function(e){var o=e!==n?e[0]:D[0],i=o.parentNode,r=t(i);if(i)for(var a="none"===r.css("transform"),s="static"===r.css("position"),p=r.is("html");i&&!p&&s&&a;)i=i.parentNode,r=t(i),a="none"===r.css("transform"),s="static"===r.css("position"),p=r.is("html");return r&&r.length>0?r:t()},offstagePosition:function(e,n){var i,r,a=o.offset(),s={},p=[];return e=e||!1,n=n||y.get.calculations(),i=n.popup,r=n.boundary,a&&e&&(s={top:a.topr.bottom,right:a.left+i.width>r.right,left:a.left0?p.join(" "):!1},positions:function(){return{"top left":!1,"top center":!1,"top right":!1,"bottom left":!1,"bottom center":!1,"bottom right":!1,"left center":!1,"right center":!1}},nextPosition:function(t){var e=t.split(" "),o=e[0],n=e[1],i={top:"bottom",bottom:"top",left:"right",right:"left"},r={left:"center",center:"right",right:"left"},a={"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"},s="top"==o||"bottom"==o,p=!1,l=!1,u=!1;return R||(y.verbose("All available positions available"),R=y.get.positions()),y.debug("Recording last position tried",t),R[t]=!0,"opposite"===w.prefer&&(u=[i[o],n],u=u.join(" "),p=R[u]===!0,y.debug("Trying opposite strategy",u)),"adjacent"===w.prefer&&s&&(u=[o,r[n]],u=u.join(" "),l=R[u]===!0,y.debug("Trying adjacent strategy",u)),(l||p)&&(y.debug("Using backup position",u),u=a[t]),u}},set:{position:function(t,e){if(0===j.length||0===o.length)return void y.error(C.notFound);var i,r,a,s,p,l,u;if(e=e||y.get.calculations(),t=t||D.data(k.position)||w.position,i=D.data(k.offset)||w.offset,r=w.distanceAway,a=e.target,s=e.popup,p=e.parent,0===a.top&&0===a.left)return y.debug("Popup target is hidden, no action taken"),!1;switch(w.inline&&(y.debug("Adding margin to calculation",a.margin),"left center"==t||"right center"==t?(i+=a.margin.top,r+=-a.margin.left):"top left"==t||"top center"==t||"top right"==t?(i+=a.margin.left,r-=a.margin.top):(i+=a.margin.left,r+=a.margin.top)),y.debug("Determining popup position from calculations",t,e),y.is.rtl()&&(t=t.replace(/left|right/g,function(t){return"left"==t?"right":"left"}),y.debug("RTL: Popup position updated",t)),A==w.maxSearchDepth&&w.lastResort&&(y.debug('Using "last resort" position to display',w.lastResort),t=w.lastResort),t){case"top left":l={top:"auto",bottom:p.height-a.top+r,left:a.left+i,right:"auto"};break;case"top center":l={bottom:p.height-a.top+r,left:a.left+a.width/2-s.width/2+i,top:"auto",right:"auto"};break;case"top right":l={bottom:p.height-a.top+r,right:p.width-a.left-a.width-i,top:"auto",left:"auto"};break;case"left center":l={top:a.top+a.height/2-s.height/2+i,right:p.width-a.left+r,left:"auto",bottom:"auto"};break;case"right center":l={top:a.top+a.height/2-s.height/2+i,left:a.left+a.width+r,bottom:"auto",right:"auto"};break;case"bottom left":l={top:a.top+a.height+r,left:a.left+i,bottom:"auto",right:"auto"};break;case"bottom center":l={top:a.top+a.height+r,left:a.left+a.width/2-s.width/2+i,bottom:"auto",right:"auto"};break;case"bottom right":l={top:a.top+a.height+r,right:p.width-a.left-a.width-i,left:"auto",bottom:"auto"}}if(l===n&&y.error(C.invalidPosition,t),y.debug("Calculated popup positioning values",l),o.css(l).removeClass(P.position).addClass(t).addClass(P.loading),u=y.get.offstagePosition(t,e)){if(y.debug("Popup cant fit into viewport",t,u),A0}},is:{active:function(){return D.hasClass(P.active)},animating:function(){return o&&o.hasClass(P.animating)},visible:function(){return o&&o.hasClass(P.visible)},dropdown:function(){return D.hasClass(P.dropdown)},hidden:function(){return!y.is.visible()},rtl:function(){return"rtl"==D.css("direction")}},reset:function(){y.remove.visible(),w.preserve?t.fn.transition!==n&&o.transition("remove transition"):y.removePopup()},setting:function(e,o){if(t.isPlainObject(e))t.extend(!0,w,e);else{if(o===n)return w[e];w[e]=o}},internal:function(e,o){if(t.isPlainObject(e))t.extend(!0,y,e);else{if(o===n)return y[e];y[e]=o}},debug:function(){w.debug&&(w.performance?y.performance.log(arguments):(y.debug=Function.prototype.bind.call(console.info,console,w.name+":"),y.debug.apply(console,arguments)))},verbose:function(){w.verbose&&w.debug&&(w.performance?y.performance.log(arguments):(y.verbose=Function.prototype.bind.call(console.info,console,w.name+":"),y.verbose.apply(console,arguments)))},error:function(){y.error=Function.prototype.bind.call(console.error,console,w.name+":"),y.error.apply(console,arguments)},performance:{log:function(t){var e,o,n;w.performance&&(e=(new Date).getTime(),n=d||e,o=e-n,d=e,f.push({Name:t[0],Arguments:[].slice.call(t,1)||"",Element:H,"Execution Time":o})),clearTimeout(y.performance.timer),y.performance.timer=setTimeout(y.performance.display,500)},display:function(){var e=w.name+":",o=0;d=!1,clearTimeout(y.performance.timer),t.each(f,function(t,e){o+=e["Execution Time"]}),e+=" "+o+"ms",u&&(e+=" '"+u+"'"),(console.group!==n||console.table!==n)&&f.length>0&&(console.groupCollapsed(e),console.table?console.table(f):t.each(f,function(t,e){console.log(e.Name+": "+e["Execution Time"]+"ms")}),console.groupEnd()),f=[]}},invoke:function(e,o,i){var a,s,p,l=I;return o=o||m,i=H||i,"string"==typeof e&&l!==n&&(e=e.split(/[\. ]/),a=e.length-1,t.each(e,function(o,i){var r=o!=a?i+e[o+1].charAt(0).toUpperCase()+e[o+1].slice(1):e;if(t.isPlainObject(l[r])&&o!=a)l=l[r];else{if(l[r]!==n)return s=l[r],!1;if(!t.isPlainObject(l[i])||o==a)return l[i]!==n?(s=l[i],!1):!1;l=l[i]}})),t.isFunction(s)?p=s.apply(i,o):s!==n&&(p=s),t.isArray(r)?r.push(p):r!==n?r=[r,p]:p!==n&&(r=p),s}},h?(I===n&&y.initialize(),y.invoke(g)):(I!==n&&I.invoke("destroy"),y.initialize())}),r!==n?r:this},t.fn.popup.settings={name:"Popup",debug:!1,verbose:!1,performance:!0,namespace:"popup",onCreate:function(){},onRemove:function(){},onShow:function(){},onVisible:function(){},onHide:function(){},onHidden:function(){},on:"hover",addTouchEvents:!0,position:"top left",variation:"",movePopup:!0,target:!1,popup:!1,inline:!1,preserve:!0,hoverable:!1,content:!1,html:!1,title:!1,closable:!0,hideOnScroll:"auto",exclusive:!1,context:"body",prefer:"opposite",lastResort:!1,delay:{show:50,hide:70},setFluidWidth:!0,duration:200,transition:"scale",distanceAway:0,offset:0,maxSearchDepth:20,error:{invalidPosition:"The position you specified is not a valid position",cannotPlace:"No visible position could be found for the popup",method:"The method you called is not defined.",noTransition:"This module requires ui transitions ",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",animating:"animating",dropdown:"dropdown",fluid:"fluid",loading:"loading",popup:"ui popup",position:"top left center bottom right",visible:"visible"},selector:{popup:".ui.popup"},templates:{escape:function(t){var e=/[&<>"'`]/g,o=/[&<>"'`]/,n={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},i=function(t){return n[t]};return o.test(t)?t.replace(e,i):t},popup:function(e){var o="",i=t.fn.popup.settings.templates.escape;return typeof e!==n&&(typeof e.title!==n&&e.title&&(e.title=i(e.title),o+='
'+e.title+"
"),typeof e.content!==n&&e.content&&(e.content=i(e.content),o+='
'+e.content+"
")),o}}}}(jQuery,window,document); \ No newline at end of file