From c5d327c6192993ecb5700e28e367bb6a7e3263ce Mon Sep 17 00:00:00 2001 From: jlukic Date: Wed, 29 Oct 2014 13:24:56 -0400 Subject: [PATCH 01/22] Updated component version to 1.0.0 --- RELEASE-NOTES.md | 59 +++ bower.json | 16 + package.json | 20 + popup.css | 285 ++++++++++++++ popup.js | 997 +++++++++++++++++++++++++++++++++++++++++++++++ popup.min.css | 11 + popup.min.js | 11 + 7 files changed, 1399 insertions(+) create mode 100644 RELEASE-NOTES.md create mode 100644 bower.json create mode 100644 package.json create mode 100755 popup.css create mode 100644 popup.js create mode 100755 popup.min.css create mode 100644 popup.min.js diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md new file mode 100644 index 0000000..020ae0c --- /dev/null +++ b/RELEASE-NOTES.md @@ -0,0 +1,59 @@ +### Version 1.0.0 - XX XX, 2014 + +- **Popup** - Popup can now allow itself not to be closed when hovered over +- **Popup** - A popup element can now be specified on initialization. +- **Popup** - Positioned popups will now extend in the opposite direction to fit better with floated content + +### Version 0.12.5 - Feb 04, 2014 + +- **Popup** - Fixes issue where popups using ``title`` attribute to store data were losing title content instead of correctly restoring it + +### Merry Christmas! + +-**Popup** - Fixes popup sometimes opening and closing when ``event:click`` is used and a user double clicks + +### Version 0.10.3 - Dec 22, 2013 + +- **Popup** - Native browser popups no longer if using ``title`` attribute + +### Version 0.9.2 - Nov 8, 2013 + +**Fixes** - Fixes popup not repositioning itself when offstage. + +### Version 0.9.1 - Nov 7, 2013 + +- **Popup** - Adds context option for popup (thanks jefmathiot) + +### Version 0.7.1 - Oct 23, 2013 + +- **Popup** - Fixes issue with popup's using setting inline: true + +### Version 0.7.0 - Oct 22, 2013 + +- **List** - Popups can now have a different target than itself +- **Popup** - Popup .toggle() now always hides/shows popup correctly +- **Popup** - Popup fixed a bug where "top right" placed popup might sometimes be too large +- **Popup** - Popup will not reshow a visible popup on hover +- **Popup** - Popup border now uses RGBA to look sexier on dark backgrounds +- **Popup** - Popup default duration is now 200ms (slighty slower) +- **Popup** - Popup metadata attribute arrowOffset is now offset for simplicities sake +- **Popup** - Popup no-longer receives class name 'visible' on show, this allows popups to be used on dropdowns and other elements with a visible state +- **Popup** - Popups are no longer inline by default + +### Version 0.5.0 - Oct 10, 2013 + +- Fixes regression where popup was overriding variation class name on positioning +- Fixes an issue where popup that was set to inline: false was being removed prematurely +- Adds an example to popup where inline is set to false +- Added onCreate to popup module + +### Version 0.3.6 - Oct 7, 2013 + +- Fixes popup position sometimes appearing off-stage on second apperance +- Fixes popup positions top left, top right, bottom left, bottom right being flipped + +### Version 0.3.3 - Oct 2, 2013 + +- Fixes issue with popup display in some edge cases Issue #128 + +### Version 0.1.0 - Sep 25, 2013 \ No newline at end of file diff --git a/bower.json b/bower.json new file mode 100644 index 0000000..a889385 --- /dev/null +++ b/bower.json @@ -0,0 +1,16 @@ +{ + "name": "UI-Popup", + "description": "Popup - Semantic UI", + "homepage": "http://beta.semantic-ui.com", + "author": { + "name": "Jack Lukic", + "web": "http://www.jacklukic.com" + }, + "keywords": ["semantic", "ui", "css3", "framework"], + "license": ["http://semantic-ui.mit-license.org/"], + "ignore": ["docs", "node", "server", "spec", "src", "test"], + "main": ["popup.js", "popup.css"], + "dependencies": { + "jquery": ">=1.8" + } +} \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..070d255 --- /dev/null +++ b/package.json @@ -0,0 +1,20 @@ +{ + "name": "UI-Popup", + "version": "1.0.0", + "title": "Semantic UI - Popup", + "description": "Single component release of popup", + "homepage": "http://www.semantic-ui.com", + "author": "Jack Lukic ", + "license": "MIT", + "repository": { + "type": "git", + "url": "git@github.com:Semantic-Org/UI-Popup.git" + }, + "bugs": { + "url": "https://github.com/Semantic-Org/Semantic-UI/issues" + }, + "dependencies": { + "jquery": "x.x.x" + }, + "devDependencies": {} +} \ No newline at end of file diff --git a/popup.css b/popup.css new file mode 100755 index 0000000..b8a2f16 --- /dev/null +++ b/popup.css @@ -0,0 +1,285 @@ + /* + * # Semantic UI + * git://github.com/Semantic-Org/Semantic-UI.git#1.0 + * + * + * Copyright 2014 Contributors + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + + + +/******************************* + Popup +*******************************/ + +.ui.popup { + display: none; + position: absolute; + top: 0px; + right: 0px; + z-index: 900; + border: 1px solid #cccccc; + max-width: 250px; + background-color: #ffffff; + padding: 0.8em 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); +} +.ui.popup > .header { + padding: 0em; + font-family: 'Lato', 'Helvetica Neue', Arial, Helvetica, sans-serif; + font-size: 1.125em; + line-height: 1.2; + font-weight: bold; +} +.ui.popup > .header + .content { + padding-top: 0.5em; +} +.ui.popup:before { + position: absolute; + content: ''; + width: 0.75em; + height: 0.75em; + background: #ffffff; + -webkit-transform: rotate(45deg); + -ms-transform: rotate(45deg); + transform: rotate(45deg); + z-index: 2; + box-shadow: 1px 1px 0px 0px #b3b3b3; +} + + +/******************************* + Types +*******************************/ + + +/*-------------- + Spacing +---------------*/ + +.ui.popup { + margin: 0em; +} +.ui.popup.bottom { + margin: 0.75em 0em 0em; +} +.ui.popup.top { + margin: 0em 0em 0.75em; +} +.ui.popup.left.center { + margin: 0em 0.75em 0em 0em; +} +.ui.popup.right.center { + margin: 0em 0em 0em 0.75em; +} + +/*-------------- + Pointer +---------------*/ + + +/*--- Below ---*/ + +.ui.bottom.center.popup:before { + margin-left: -0.325em; + top: -0.325em; + left: 50%; + right: auto; + bottom: auto; + box-shadow: -1px -1px 0px 0px #b3b3b3; +} +.ui.bottom.left.popup { + margin-left: 0em; +} +.ui.bottom.left.popup:before { + top: -0.325em; + left: 1em; + right: auto; + bottom: auto; + margin-left: 0em; + box-shadow: -1px -1px 0px 0px #b3b3b3; +} +.ui.bottom.right.popup { + margin-right: 0em; +} +.ui.bottom.right.popup:before { + top: -0.325em; + right: 1em; + bottom: auto; + left: auto; + margin-left: 0em; + box-shadow: -1px -1px 0px 0px #b3b3b3; +} + +/*--- Above ---*/ + +.ui.top.center.popup:before { + top: auto; + right: auto; + bottom: -0.325em; + left: 50%; + margin-left: -0.325em; +} +.ui.top.left.popup { + margin-left: 0em; +} +.ui.top.left.popup:before { + bottom: -0.325em; + left: 1em; + top: auto; + right: auto; + margin-left: 0em; +} +.ui.top.right.popup { + margin-right: 0em; +} +.ui.top.right.popup:before { + bottom: -0.325em; + right: 1em; + top: auto; + left: auto; + margin-left: 0em; +} + +/*--- Left Center ---*/ + +.ui.left.center.popup:before { + top: 50%; + right: -0.325em; + bottom: auto; + left: auto; + margin-top: -0.325em; + box-shadow: 1px -1px 0px 0px #b3b3b3; +} + +/*--- Right Center ---*/ + +.ui.right.center.popup:before { + top: 50%; + left: -0.325em; + bottom: auto; + right: auto; + margin-top: -0.325em; + box-shadow: -1px 1px 0px 0px #b3b3b3; +} + + +/******************************* + Coupling +*******************************/ + + +/* 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; +} + + +/******************************* + States +*******************************/ + +.ui.loading.popup { + display: block; + visibility: hidden; + z-index: -1; +} +.ui.animating.popup, +.ui.visible.popup { + display: block; +} + + +/******************************* + Variations +*******************************/ + + +/*-------------- + Wide +---------------*/ + +.ui.wide.popup { + width: 350px; + max-width: 350px; +} +.ui[class*="very wide"].popup { + width: 550px; + max-width: 550px; +} + +/*-------------- + Fluid +---------------*/ + +.ui.fluid.popup { + width: 100%; + max-width: 99999px; +} + +/*-------------- + Colors +---------------*/ + + +/* Inverted colors */ +.ui.inverted.popup { + background: #1b1c1d; + color: #ffffff; + border: none; + box-shadow: none; +} +.ui.inverted.popup .header { + background-color: none; + color: #ffffff; +} +.ui.inverted.popup:before { + background-color: #1b1c1d; + box-shadow: none; +} + +/*-------------- + Flowing +---------------*/ + +.ui.flowing.popup { + max-width: 9999px; +} + +/*-------------- + Sizes +---------------*/ + +.ui.small.popup { + font-size: 0.8rem; +} +.ui.popup { + font-size: 0.875rem; +} +.ui.large.popup { + font-size: 1rem; +} +.ui.huge.popup { + font-size: 1.1rem; +} + + +/******************************* + Theme Overrides +*******************************/ + + + +/******************************* + User Overrides +*******************************/ + diff --git a/popup.js b/popup.js new file mode 100644 index 0000000..3dae337 --- /dev/null +++ b/popup.js @@ -0,0 +1,997 @@ +/* + * # Semantic - Popup + * http://github.com/jlukic/semantic-ui/ + * + * + * Copyright 2014 Contributor + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +;(function ($, window, document, undefined) { + +"use strict"; + +$.fn.popup = function(parameters) { + var + $allModules = $(this), + $document = $(document), + + moduleSelector = $allModules.selector || '', + + hasTouch = ('ontouchstart' in document.documentElement), + 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), + $target = (settings.target) + ? $(settings.target) + : $module, + + $window = $(window), + $body = $('body'), + $popup, + $offsetParent, + + searchDepth = 0, + + element = this, + instance = $module.data(moduleNamespace), + module + ; + + module = { + + // binds events + initialize: function() { + module.debug('Initializing module', $module); + module.refresh(); + if(settings.on == 'click') { + $module + .on('click' + eventNamespace, module.toggle) + ; + } + else 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' + eventNamespace, module.event.resize) + ; + if( !module.exists() ) { + module.create(); + } + else if(settings.hoverable) { + module.bind.popup(); + } + module.instantiate(); + }, + + instantiate: function() { + module.verbose('Storing instance of module', module); + instance = module; + $module + .data(moduleNamespace, instance) + ; + }, + + refresh: function() { + $popup = (settings.popup) + ? $(settings.popup) + : (settings.inline) + ? $target.next(settings.selector.popup) + : false + ; + $offsetParent = (settings.popup) + ? $popup.offsetParent() + : (settings.inline) + ? $target.offsetParent() + : $body + ; + }, + + destroy: function() { + module.debug('Destroying previous module'); + if($popup && !settings.preserve) { + module.remove(); + } + $module + .off(eventNamespace) + .removeData(moduleNamespace) + ; + }, + + event: { + start: function(event) { + var + delay = ($.isPlainObject(settings.delay)) + ? settings.delay.show + : settings.delay + ; + clearTimeout(module.hideTimer); + module.showTimer = setTimeout(function() { + if( module.is.hidden() && !( module.is.active() && module.is.dropdown()) ) { + module.show(); + } + }, delay); + }, + end: function() { + var + delay = ($.isPlainObject(settings.delay)) + ? settings.delay.hide + : settings.delay + ; + clearTimeout(module.showTimer); + module.hideTimer = setTimeout(function() { + if( module.is.visible() ) { + module.hide(); + } + }, delay); + }, + resize: function() { + if( module.is.visible() ) { + module.set.position(); + } + } + }, + + // 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 + ; + if(html || content || title) { + module.debug('Creating pop-up html'); + if(!html) { + html = settings.templates.popup({ + title : title, + content : content + }); + } + $popup = $('
') + .addClass(className.popup) + .addClass(variation) + .html(html) + ; + if(variation) { + $popup + .addClass(variation) + ; + } + 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 ) + ; + } + if(settings.hoverable) { + module.bind.popup(); + } + $.proxy(settings.onCreate, $popup)(); + } + else if($target.next(settings.selector.popup).size() !== 0) { + module.verbose('Pre-existing popup found, reverting to inline'); + settings.inline = true; + module.refresh(); + if(settings.hoverable) { + module.bind.popup(); + } + } + else { + module.debug('No content specified skipping display', element); + } + }, + + // 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.hideAll(); + 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(!settings.preserve && !settings.popup) { + module.refresh(); + } + if( !module.exists() ) { + module.create(); + } + if( $popup && module.set.position() ) { + module.save.conditions(); + module.animate.show(callback); + } + }, + + + hide: function(callback) { + callback = callback || function(){}; + $module + .removeClass(className.visible) + ; + module.unbind.close(); + if( module.is.visible() ) { + module.restore.conditions(); + module.animate.hide(callback); + } + }, + + hideAll: function() { + $(selector.popup) + .filter(':visible') + .popup('hide') + ; + }, + + hideGracefully: function(event) { + // don't close on clicks inside popup + if(event && $(event.target).closest(selector.popup).size() === 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; + } + if(settings.inline || settings.popup) { + return ( $popup.size() !== 0 ); + } + else { + return ( $popup.closest($context).size() ); + } + }, + + remove: function() { + module.debug('Removing popup'); + $popup + .remove() + ; + }, + + 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; + } + }, + animate: { + show: function(callback) { + callback = callback || function(){}; + if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) { + $popup + .transition({ + animation : settings.transition + ' in', + queue : false, + duration : settings.duration, + start: function() { + $module + .addClass(className.visible) + ; + }, + complete : function() { + module.bind.close(); + $.proxy(callback, element)(); + } + }) + ; + } + else { + $module + .addClass(className.visible) + ; + $popup + .stop() + .fadeIn(settings.duration, settings.easing, function() { + module.bind.close(); + $.proxy(callback, element)(); + }) + ; + } + $.proxy(settings.onShow, element)(); + }, + hide: function(callback) { + callback = callback || function(){}; + module.debug('Hiding pop-up'); + if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) { + $popup + .transition({ + animation : settings.transition + ' out', + queue : false, + duration : settings.duration, + complete : function() { + module.reset(); + callback(); + } + }) + ; + } + else { + $popup + .stop() + .fadeOut(settings.duration, settings.easing, function() { + module.reset(); + callback(); + }) + ; + } + $.proxy(settings.onHide, element)(); + } + }, + + get: { + startEvent: function() { + if(settings.on == 'hover') { + return 'mouseenter'; + } + else if(settings.on == 'focus') { + return 'focus'; + } + return false; + }, + endEvent: function() { + if(settings.on == 'hover') { + return 'mouseleave'; + } + else if(settings.on == 'focus') { + return 'blur'; + } + return false; + }, + offstagePosition: function() { + var + boundary = { + top : $(window).scrollTop(), + bottom : $(window).scrollTop() + $(window).height(), + left : 0, + right : $(window).width() + }, + popup = { + width : $popup.width(), + height : $popup.outerHeight(), + offset : $popup.offset() + }, + offstage = {}, + offstagePositions = [] + ; + if(popup.offset) { + 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) + }; + } + module.verbose('Checking if outside viewable area', popup.offset); + // return only boundaries that have been surpassed + $.each(offstage, function(direction, isOffstage) { + if(isOffstage) { + offstagePositions.push(direction); + } + }); + return (offstagePositions.length > 0) + ? offstagePositions.join(' ') + : false + ; + }, + nextPosition: function(position) { + switch(position) { + case 'top left': + position = 'bottom left'; + break; + case 'bottom left': + position = 'top right'; + break; + case 'top right': + position = 'bottom right'; + break; + case 'bottom right': + position = 'top center'; + break; + case 'top center': + position = 'bottom center'; + break; + case 'bottom center': + position = 'right center'; + break; + case 'right center': + position = 'left center'; + break; + case 'left center': + position = 'top center'; + break; + } + return position; + } + }, + + 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('margin-left'), 10) + : 0, + + target = (settings.inline || settings.popup) + ? $target.position() + : $target.offset(), + + positioning, + offstagePosition + ; + position = position || $module.data(metadata.position) || settings.position; + arrowOffset = arrowOffset || $module.data(metadata.offset) || settings.offset; + + if(settings.inline) { + module.debug('Adding targets margin to calculation'); + if(position == 'left center' || position == 'right center') { + arrowOffset += marginTop; + distanceAway += -marginLeft; + } + else if (position == 'top left' || position == 'top center' || position == 'top right') { + arrowOffset += marginLeft; + distanceAway -= marginTop; + } + else { + arrowOffset += marginLeft; + distanceAway += marginTop; + } + } + module.debug('Calculating popup positioning', position); + switch(position) { + case 'top left': + positioning = { + top : 'auto', + bottom : parentHeight - target.top + distanceAway, + left : target.left + arrowOffset, + right : 'auto' + }; + break; + case 'top center': + positioning = { + bottom : parentHeight - target.top + distanceAway, + left : target.left + (targetWidth / 2) - (popupWidth / 2) + arrowOffset, + top : 'auto', + right : 'auto' + }; + break; + case 'top right': + positioning = { + bottom : parentHeight - target.top + distanceAway, + right : parentWidth - target.left - targetWidth - arrowOffset, + top : 'auto', + left : 'auto' + }; + break; + case 'left center': + positioning = { + top : target.top + (targetHeight / 2) - (popupHeight / 2) + arrowOffset, + right : parentWidth - 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, + bottom : 'auto', + right : 'auto' + }; + break; + case 'bottom left': + positioning = { + top : target.top + targetHeight + distanceAway, + left : target.left + arrowOffset, + bottom : 'auto', + right : 'auto' + }; + break; + case 'bottom center': + positioning = { + top : target.top + targetHeight + distanceAway, + left : target.left + (targetWidth / 2) - (popupWidth / 2) + arrowOffset, + bottom : 'auto', + right : 'auto' + }; + break; + case 'bottom right': + positioning = { + top : target.top + targetHeight + distanceAway, + right : parentWidth - target.left - targetWidth - arrowOffset, + left : 'auto', + bottom : 'auto' + }; + break; + } + if(positioning === undefined) { + module.error(error.invalidPosition); + } + // tentatively place on stage + $popup + .css(positioning) + .removeClass(className.position) + .addClass(position) + .addClass(className.loading) + ; + // check if is offstage + offstagePosition = module.get.offstagePosition(); + // recursively find new positioning + if(offstagePosition) { + module.debug('Element is outside boundaries', offstagePosition); + if(searchDepth < settings.maxSearchDepth) { + position = module.get.nextPosition(position); + searchDepth++; + module.debug('Trying new position', position); + return ($popup) + ? module.set.position(position) + : false + ; + } + else { + module.error(error.recursion); + searchDepth = 0; + module.reset(); + $popup.removeClass(className.loading); + return false; + } + } + else { + module.debug('Position is on stage', position); + searchDepth = 0; + $popup.removeClass(className.loading); + return true; + } + } + + }, + + bind: { + popup: function() { + module.verbose('Allowing hover events on popup to prevent closing'); + $popup + .on('mouseenter', module.event.start) + .on('mouseleave', module.event.end) + ; + }, + close:function() { + if(settings.on == 'click' && settings.closable) { + module.verbose('Binding popup close event to document'); + $document + .on('click' + eventNamespace, function(event) { + module.verbose('Pop-up clickaway intent detected'); + $.proxy(module.hideGracefully, element)(event); + }) + ; + } + } + }, + + unbind: { + close: function() { + if(settings.on == 'click' && settings.closable) { + module.verbose('Removing close event from document'); + $document + .off('click' + eventNamespace) + ; + } + } + }, + + is: { + active: function() { + return $module.hasClass(className.active); + }, + animating: function() { + return ( $popup && $popup.is(':animated') || $popup.hasClass(className.animating) ); + }, + visible: function() { + return $popup && $popup.is(':visible'); + }, + dropdown: function() { + return $module.hasClass(className.dropdown); + }, + hidden: function() { + return !module.is.visible(); + } + }, + + reset: function() { + $popup + .removeClass(className.visible) + ; + if(settings.preserve || settings.popup) { + if($.fn.transition !== undefined) { + $popup + .transition('remove transition') + ; + } + } + else { + module.remove(); + } + }, + + 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.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.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() { + 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, 100); + }, + 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) { + module.destroy(); + } + module.initialize(); + } + }) + ; + + return (returnedValue !== undefined) + ? returnedValue + : this + ; +}; + +$.fn.popup.settings = { + + name : 'Popup', + + debug : false, + verbose : false, + performance : false, + namespace : 'popup', + + onCreate : function(){}, + onRemove : function(){}, + onShow : function(){}, + onHide : function(){}, + + variation : '', + content : false, + html : false, + title : false, + + on : 'hover', + closable : true, + + context : 'body', + position : 'top left', + delay : { + show : 30, + hide : 0 + }, + + target : false, + popup : false, + inline : false, + preserve : true, + hoverable : false, + + duration : 200, + easing : 'easeOutQuint', + transition : 'scale', + + distanceAway : 0, + offset : 0, + maxSearchDepth : 10, + + error: { + invalidPosition : 'The position you specified is not a valid position', + method : 'The method you called is not defined.', + recursion : 'Popup attempted to reposition element to fit, but could not find an adequate position.' + }, + + metadata: { + content : 'content', + html : 'html', + offset : 'offset', + position : 'position', + title : 'title', + variation : 'variation' + }, + + className : { + active : 'active', + animating : 'animating', + dropdown : 'dropdown', + loading : 'loading', + popup : 'ui popup', + position : 'top left center bottom right', + visible : '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 += '
' + text.title + '
'; + } + if(typeof text.content !== undefined && text.content) { + text.content = escape(text.content); + html += '
' + text.content + '
'; + } + } + return html; + } + } + +}; + +// 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 new file mode 100755 index 0000000..507946a --- /dev/null +++ b/popup.min.css @@ -0,0 +1,11 @@ + /* + * # Semantic UI + * git://github.com/Semantic-Org/Semantic-UI.git#1.0 + * + * + * Copyright 2014 Contributors + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ +.ui.popup{display:none;position:absolute;top:0;right:0;z-index:900;border:1px solid #ccc;max-width:250px;background-color:#fff;padding:.8em 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)}.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{margin:0}.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.wide.popup{width:350px;max-width:350px}.ui[class*="very wide"].popup{width:550px;max-width:550px}.ui.fluid.popup{width:100%;max-width:99999px}.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}.ui.flowing.popup{max-width:9999px}.ui.small.popup{font-size:.8rem}.ui.popup{font-size:.875rem}.ui.large.popup{font-size:1rem}.ui.huge.popup{font-size:1.1rem} \ No newline at end of file diff --git a/popup.min.js b/popup.min.js new file mode 100644 index 0000000..d45c44c --- /dev/null +++ b/popup.min.js @@ -0,0 +1,11 @@ + /* + * # Semantic UI + * git://github.com/Semantic-Org/Semantic-UI.git#1.0 + * + * + * Copyright 2014 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||"",u=("ontouchstart"in o.documentElement,(new Date).getTime()),c=[],l=arguments[0],d="string"==typeof l,f=[].slice.call(arguments,1);return s.each(function(){var o,s,g,m=e.isPlainObject(i)?e.extend(!0,{},e.fn.popup.settings,i):e.extend({},e.fn.popup.settings),h=m.selector,b=m.className,v=m.error,y=m.metadata,w=m.namespace,k="."+m.namespace,x="module-"+w,C=e(this),P=e(m.context),T=m.target?e(m.target):C,A=e(t),E=e("body"),z=0,O=this,j=C.data(x);g={initialize:function(){g.debug("Initializing module",C),g.refresh(),"click"==m.on?C.on("click"+k,g.toggle):g.get.startEvent()&&C.on(g.get.startEvent()+k,g.event.start).on(g.get.endEvent()+k,g.event.end),m.target&&g.debug("Target set to element",T),A.on("resize"+k,g.event.resize),g.exists()?m.hoverable&&g.bind.popup():g.create(),g.instantiate()},instantiate:function(){g.verbose("Storing instance of module",g),j=g,C.data(x,j)},refresh:function(){o=m.popup?e(m.popup):m.inline?T.next(m.selector.popup):!1,s=m.popup?o.offsetParent():m.inline?T.offsetParent():E},destroy:function(){g.debug("Destroying previous module"),o&&!m.preserve&&g.remove(),C.off(k).removeData(x)},event:{start:function(){var t=e.isPlainObject(m.delay)?m.delay.show:m.delay;clearTimeout(g.hideTimer),g.showTimer=setTimeout(function(){!g.is.hidden()||g.is.active()&&g.is.dropdown()||g.show()},t)},end:function(){var t=e.isPlainObject(m.delay)?m.delay.hide:m.delay;clearTimeout(g.showTimer),g.hideTimer=setTimeout(function(){g.is.visible()&&g.hide()},t)},resize:function(){g.is.visible()&&g.set.position()}},create:function(){var t=C.data(y.html)||m.html,n=C.data(y.variation)||m.variation,i=C.data(y.title)||m.title,r=C.data(y.content)||C.attr("title")||m.content;t||r||i?(g.debug("Creating pop-up html"),t||(t=m.templates.popup({title:i,content:r})),o=e("
").addClass(b.popup).addClass(n).html(t),n&&o.addClass(n),m.inline?(g.verbose("Inserting popup element inline",o),o.insertAfter(C)):(g.verbose("Appending popup element to body",o),o.appendTo(P)),m.hoverable&&g.bind.popup(),e.proxy(m.onCreate,o)()):0!==T.next(m.selector.popup).size()?(g.verbose("Pre-existing popup found, reverting to inline"),m.inline=!0,g.refresh(),m.hoverable&&g.bind.popup()):g.debug("No content specified skipping display",O)},toggle:function(){g.debug("Toggling pop-up"),g.is.hidden()?(g.debug("Popup is hidden, showing pop-up"),g.unbind.close(),g.hideAll(),g.show()):(g.debug("Popup is visible, hiding pop-up"),g.hide())},show:function(e){e=e||function(){},g.debug("Showing pop-up",m.transition),m.preserve||m.popup||g.refresh(),g.exists()||g.create(),o&&g.set.position()&&(g.save.conditions(),g.animate.show(e))},hide:function(e){e=e||function(){},C.removeClass(b.visible),g.unbind.close(),g.is.visible()&&(g.restore.conditions(),g.animate.hide(e))},hideAll:function(){e(h.popup).filter(":visible").popup("hide")},hideGracefully:function(t){t&&0===e(t.target).closest(h.popup).size()?(g.debug("Click occurred outside popup hiding popup"),g.hide()):g.debug("Click was inside popup, keeping popup open")},exists:function(){return o?m.inline||m.popup?0!==o.size():o.closest(P).size():!1},remove:function(){g.debug("Removing popup"),o.remove()},save:{conditions:function(){g.cache={title:C.attr("title")},g.cache.title&&C.removeAttr("title"),g.verbose("Saving original attributes",g.cache.title)}},restore:{conditions:function(){return g.cache&&g.cache.title&&(C.attr("title",g.cache.title),g.verbose("Restoring original attributes",g.cache.title)),!0}},animate:{show:function(t){t=t||function(){},m.transition&&e.fn.transition!==n&&C.transition("is supported")?o.transition({animation:m.transition+" in",queue:!1,duration:m.duration,start:function(){C.addClass(b.visible)},complete:function(){g.bind.close(),e.proxy(t,O)()}}):(C.addClass(b.visible),o.stop().fadeIn(m.duration,m.easing,function(){g.bind.close(),e.proxy(t,O)()})),e.proxy(m.onShow,O)()},hide:function(t){t=t||function(){},g.debug("Hiding pop-up"),m.transition&&e.fn.transition!==n&&C.transition("is supported")?o.transition({animation:m.transition+" out",queue:!1,duration:m.duration,complete:function(){g.reset(),t()}}):o.stop().fadeOut(m.duration,m.easing,function(){g.reset(),t()}),e.proxy(m.onHide,O)()}},get:{startEvent:function(){return"hover"==m.on?"mouseenter":"focus"==m.on?"focus":!1},endEvent:function(){return"hover"==m.on?"mouseleave":"focus"==m.on?"blur":!1},offstagePosition:function(){var n={top:e(t).scrollTop(),bottom:e(t).scrollTop()+e(t).height(),left:0,right:e(t).width()},i={width:o.width(),height:o.outerHeight(),offset:o.offset()},r={},s=[];return i.offset&&(r={top:i.offset.topn.bottom,right:i.offset.left+i.width>n.right,left:i.offset.left0?s.join(" "):!1},nextPosition:function(e){switch(e){case"top left":e="bottom left";break;case"bottom left":e="top right";break;case"top right":e="bottom right";break;case"bottom right":e="top center";break;case"top center":e="bottom center";break;case"bottom center":e="right center";break;case"right center":e="left center";break;case"left center":e="top center"}return e}},set:{position:function(i,r){var a,p,u=(e(t).width(),e(t).height(),T.outerWidth()),c=T.outerHeight(),l=o.outerWidth(),d=o.outerHeight(),f=s.outerWidth(),h=s.outerHeight(),w=m.distanceAway,k=T[0],x=m.inline?parseInt(t.getComputedStyle(k).getPropertyValue("margin-top"),10):0,P=m.inline?parseInt(t.getComputedStyle(k).getPropertyValue("margin-left"),10):0,A=m.inline||m.popup?T.position():T.offset();switch(i=i||C.data(y.position)||m.position,r=r||C.data(y.offset)||m.offset,m.inline&&(g.debug("Adding targets margin to calculation"),"left center"==i||"right center"==i?(r+=x,w+=-P):"top left"==i||"top center"==i||"top right"==i?(r+=P,w-=x):(r+=P,w+=x)),g.debug("Calculating popup positioning",i),i){case"top left":a={top:"auto",bottom:h-A.top+w,left:A.left+r,right:"auto"};break;case"top center":a={bottom:h-A.top+w,left:A.left+u/2-l/2+r,top:"auto",right:"auto"};break;case"top right":a={bottom:h-A.top+w,right:f-A.left-u-r,top:"auto",left:"auto"};break;case"left center":a={top:A.top+c/2-d/2+r,right:f-A.left+w,left:"auto",bottom:"auto"};break;case"right center":a={top:A.top+c/2-d/2+r,left:A.left+u+w,bottom:"auto",right:"auto"};break;case"bottom left":a={top:A.top+c+w,left:A.left+r,bottom:"auto",right:"auto"};break;case"bottom center":a={top:A.top+c+w,left:A.left+u/2-l/2+r,bottom:"auto",right:"auto"};break;case"bottom right":a={top:A.top+c+w,right:f-A.left-u-r,left:"auto",bottom:"auto"}}return a===n&&g.error(v.invalidPosition),o.css(a).removeClass(b.position).addClass(i).addClass(b.loading),p=g.get.offstagePosition(),p?(g.debug("Element is outside boundaries",p),z0&&(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,u=j;return o=o||f,i=O||i,"string"==typeof t&&u!==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(u[r])&&o!=s)u=u[r];else{if(u[r]!==n)return a=u[r],!1;if(!e.isPlainObject(u[i])||o==s)return u[i]!==n?(a=u[i],!1):!1;u=u[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}},d?(j===n&&g.initialize(),g.invoke(l)):(j!==n&&g.destroy(),g.initialize())}),r!==n?r:this},e.fn.popup.settings={name:"Popup",debug:!1,verbose:!1,performance:!1,namespace:"popup",onCreate:function(){},onRemove:function(){},onShow:function(){},onHide:function(){},variation:"",content:!1,html:!1,title:!1,on:"hover",closable:!0,context:"body",position:"top left",delay:{show:30,hide:0},target:!1,popup:!1,inline:!1,preserve:!0,hoverable:!1,duration:200,easing:"easeOutQuint",transition:"scale",distanceAway:0,offset:0,maxSearchDepth:10,error:{invalidPosition:"The position you specified is not a valid position",method:"The method you called is not defined.",recursion:"Popup attempted to reposition element to fit, but could not find an adequate position."},metadata:{content:"content",html:"html",offset:"offset",position:"position",title:"title",variation:"variation"},className:{active:"active",animating:"animating",dropdown:"dropdown",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 From 4e739571763f35f0f61c8bb6a50d4d6465b3057e Mon Sep 17 00:00:00 2001 From: jlukic Date: Wed, 29 Oct 2014 13:56:27 -0400 Subject: [PATCH 02/22] Updated component version to 1.0.0 --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 070d255..a9208c4 100644 --- a/package.json +++ b/package.json @@ -16,5 +16,6 @@ "dependencies": { "jquery": "x.x.x" }, - "devDependencies": {} + "devDependencies": {}, + "main": "popup.js" } \ No newline at end of file From d0b4f02c64fe4f92856ae5bc7f00ee3a47f28e36 Mon Sep 17 00:00:00 2001 From: jlukic Date: Wed, 29 Oct 2014 18:25:38 -0400 Subject: [PATCH 03/22] Updated component release from Semantic-UI (Automatic) --- README.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100755 README.md diff --git a/README.md b/README.md new file mode 100755 index 0000000..9f4fc6b --- /dev/null +++ b/README.md @@ -0,0 +1,19 @@ +# Semantic {Component} + +## How to Use + +This repository contains pre-compiled {component} files using the default themes. This is intended for use in projects that do not need all the bells and whistles of Semantic UI, and want to keep file size to a minimum. + +Please consider checking out [all the benefits to theming](http://learnsemantic.com/guide/expert.html) before using these stand-alone releases. + +This element's definitions (required class names, html structures) are available in the [Beta UI Docs](http://beta.semantic-ui.com) + +To install with Bower +``` +bower install semantic-ui-{component} +``` + +To install with NPM +``` +npm install semantic-ui-{component} +``` From 063d89da4514243fd1e6245e29321b817d7b5ccb Mon Sep 17 00:00:00 2001 From: jlukic Date: Wed, 29 Oct 2014 19:27:30 -0400 Subject: [PATCH 04/22] Updated component release from Semantic-UI (Automatic) --- README.md | 24 +- bower.json | 2 +- composer.json | 18 + index.js | 999 ++++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 2 +- 5 files changed, 1032 insertions(+), 13 deletions(-) mode change 100644 => 100755 bower.json create mode 100755 composer.json create mode 100644 index.js diff --git a/README.md b/README.md index 9f4fc6b..7941fa0 100755 --- a/README.md +++ b/README.md @@ -1,19 +1,21 @@ -# Semantic {Component} +# Semantic Popup -## How to Use +This repository contains pre-compiled popup files using the default themes. This is intended for use in projects that do not need all the bells and whistles of Semantic UI, and want to keep file size to a minimum. -This repository contains pre-compiled {component} files using the default themes. This is intended for use in projects that do not need all the bells and whistles of Semantic UI, and want to keep file size to a minimum. +For the latest changes please see the Release Notes in this repository. -Please consider checking out [all the benefits to theming](http://learnsemantic.com/guide/expert.html) before using these stand-alone releases. - -This element's definitions (required class names, html structures) are available in the [Beta UI Docs](http://beta.semantic-ui.com) - -To install with Bower +#### To install with Bower ``` -bower install semantic-ui-{component} +bower install semantic-ui-popup ``` -To install with NPM +#### To install with NPM ``` -npm install semantic-ui-{component} +npm install semantic-ui-popup ``` + +## Addendum + +This element's definitions (required class names, html structures) are available in the [Beta UI Docs](http://beta.semantic-ui.com) + +Please consider checking out [all the benefits to theming](http://learnsemantic.com/guide/expert.html) before using these stand-alone releases. diff --git a/bower.json b/bower.json old mode 100644 new mode 100755 index a889385..ee1b4b7 --- a/bower.json +++ b/bower.json @@ -6,9 +6,9 @@ "name": "Jack Lukic", "web": "http://www.jacklukic.com" }, + "ignore": ["docs", "node", "server", "spec", "src", "test"], "keywords": ["semantic", "ui", "css3", "framework"], "license": ["http://semantic-ui.mit-license.org/"], - "ignore": ["docs", "node", "server", "spec", "src", "test"], "main": ["popup.js", "popup.css"], "dependencies": { "jquery": ">=1.8" diff --git a/composer.json b/composer.json new file mode 100755 index 0000000..188fb22 --- /dev/null +++ b/composer.json @@ -0,0 +1,18 @@ +{ + "name": "semantic/popup", + "description": "Single component release of popup", + "homepage": "http://www.semantic-ui.com", + "authors": [{ + "name": "Jack Lukic", + "email": "jacklukic@gmail.com", + "web": "http://www.jacklukic.com", + "role": "Creator" + }], + "keywords": ["semantic", "ui", "css", "framework"], + "license": "MIT", + "dependencies": { + "jquery": "x.x.x" + }, + "main": "popup.js", + "version": "1.0.0" +} \ No newline at end of file diff --git a/index.js b/index.js new file mode 100644 index 0000000..5c4f160 --- /dev/null +++ b/index.js @@ -0,0 +1,999 @@ +/* + * # Semantic - Popup + * http://github.com/jlukic/semantic-ui/ + * + * + * Copyright 2014 Contributor + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +;(function ($, window, document, undefined) { + +"use strict"; + +module.exports = function(parameters) { + var _module = module; + + var + $allModules = $(this), + $document = $(document), + + moduleSelector = $allModules.selector || '', + + hasTouch = ('ontouchstart' in document.documentElement), + 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, {}, _module.exports.settings, parameters) + : $.extend({}, _module.exports.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), + $target = (settings.target) + ? $(settings.target) + : $module, + + $window = $(window), + $body = $('body'), + $popup, + $offsetParent, + + searchDepth = 0, + + element = this, + instance = $module.data(moduleNamespace), + module + ; + + module = { + + // binds events + initialize: function() { + module.debug('Initializing module', $module); + module.refresh(); + if(settings.on == 'click') { + $module + .on('click' + eventNamespace, module.toggle) + ; + } + else 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' + eventNamespace, module.event.resize) + ; + if( !module.exists() ) { + module.create(); + } + else if(settings.hoverable) { + module.bind.popup(); + } + module.instantiate(); + }, + + instantiate: function() { + module.verbose('Storing instance of module', module); + instance = module; + $module + .data(moduleNamespace, instance) + ; + }, + + refresh: function() { + $popup = (settings.popup) + ? $(settings.popup) + : (settings.inline) + ? $target.next(settings.selector.popup) + : false + ; + $offsetParent = (settings.popup) + ? $popup.offsetParent() + : (settings.inline) + ? $target.offsetParent() + : $body + ; + }, + + destroy: function() { + module.debug('Destroying previous module'); + if($popup && !settings.preserve) { + module.remove(); + } + $module + .off(eventNamespace) + .removeData(moduleNamespace) + ; + }, + + event: { + start: function(event) { + var + delay = ($.isPlainObject(settings.delay)) + ? settings.delay.show + : settings.delay + ; + clearTimeout(module.hideTimer); + module.showTimer = setTimeout(function() { + if( module.is.hidden() && !( module.is.active() && module.is.dropdown()) ) { + module.show(); + } + }, delay); + }, + end: function() { + var + delay = ($.isPlainObject(settings.delay)) + ? settings.delay.hide + : settings.delay + ; + clearTimeout(module.showTimer); + module.hideTimer = setTimeout(function() { + if( module.is.visible() ) { + module.hide(); + } + }, delay); + }, + resize: function() { + if( module.is.visible() ) { + module.set.position(); + } + } + }, + + // 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 + ; + if(html || content || title) { + module.debug('Creating pop-up html'); + if(!html) { + html = settings.templates.popup({ + title : title, + content : content + }); + } + $popup = $('
') + .addClass(className.popup) + .addClass(variation) + .html(html) + ; + if(variation) { + $popup + .addClass(variation) + ; + } + 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 ) + ; + } + if(settings.hoverable) { + module.bind.popup(); + } + $.proxy(settings.onCreate, $popup)(); + } + else if($target.next(settings.selector.popup).size() !== 0) { + module.verbose('Pre-existing popup found, reverting to inline'); + settings.inline = true; + module.refresh(); + if(settings.hoverable) { + module.bind.popup(); + } + } + else { + module.debug('No content specified skipping display', element); + } + }, + + // 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.hideAll(); + 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(!settings.preserve && !settings.popup) { + module.refresh(); + } + if( !module.exists() ) { + module.create(); + } + if( $popup && module.set.position() ) { + module.save.conditions(); + module.animate.show(callback); + } + }, + + + hide: function(callback) { + callback = callback || function(){}; + $module + .removeClass(className.visible) + ; + module.unbind.close(); + if( module.is.visible() ) { + module.restore.conditions(); + module.animate.hide(callback); + } + }, + + hideAll: function() { + $(selector.popup) + .filter(':visible') + .popup('hide') + ; + }, + + hideGracefully: function(event) { + // don't close on clicks inside popup + if(event && $(event.target).closest(selector.popup).size() === 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; + } + if(settings.inline || settings.popup) { + return ( $popup.size() !== 0 ); + } + else { + return ( $popup.closest($context).size() ); + } + }, + + remove: function() { + module.debug('Removing popup'); + $popup + .remove() + ; + }, + + 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; + } + }, + animate: { + show: function(callback) { + callback = callback || function(){}; + if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) { + $popup + .transition({ + animation : settings.transition + ' in', + queue : false, + duration : settings.duration, + start: function() { + $module + .addClass(className.visible) + ; + }, + complete : function() { + module.bind.close(); + $.proxy(callback, element)(); + } + }) + ; + } + else { + $module + .addClass(className.visible) + ; + $popup + .stop() + .fadeIn(settings.duration, settings.easing, function() { + module.bind.close(); + $.proxy(callback, element)(); + }) + ; + } + $.proxy(settings.onShow, element)(); + }, + hide: function(callback) { + callback = callback || function(){}; + module.debug('Hiding pop-up'); + if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) { + $popup + .transition({ + animation : settings.transition + ' out', + queue : false, + duration : settings.duration, + complete : function() { + module.reset(); + callback(); + } + }) + ; + } + else { + $popup + .stop() + .fadeOut(settings.duration, settings.easing, function() { + module.reset(); + callback(); + }) + ; + } + $.proxy(settings.onHide, element)(); + } + }, + + get: { + startEvent: function() { + if(settings.on == 'hover') { + return 'mouseenter'; + } + else if(settings.on == 'focus') { + return 'focus'; + } + return false; + }, + endEvent: function() { + if(settings.on == 'hover') { + return 'mouseleave'; + } + else if(settings.on == 'focus') { + return 'blur'; + } + return false; + }, + offstagePosition: function() { + var + boundary = { + top : $(window).scrollTop(), + bottom : $(window).scrollTop() + $(window).height(), + left : 0, + right : $(window).width() + }, + popup = { + width : $popup.width(), + height : $popup.outerHeight(), + offset : $popup.offset() + }, + offstage = {}, + offstagePositions = [] + ; + if(popup.offset) { + 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) + }; + } + module.verbose('Checking if outside viewable area', popup.offset); + // return only boundaries that have been surpassed + $.each(offstage, function(direction, isOffstage) { + if(isOffstage) { + offstagePositions.push(direction); + } + }); + return (offstagePositions.length > 0) + ? offstagePositions.join(' ') + : false + ; + }, + nextPosition: function(position) { + switch(position) { + case 'top left': + position = 'bottom left'; + break; + case 'bottom left': + position = 'top right'; + break; + case 'top right': + position = 'bottom right'; + break; + case 'bottom right': + position = 'top center'; + break; + case 'top center': + position = 'bottom center'; + break; + case 'bottom center': + position = 'right center'; + break; + case 'right center': + position = 'left center'; + break; + case 'left center': + position = 'top center'; + break; + } + return position; + } + }, + + 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('margin-left'), 10) + : 0, + + target = (settings.inline || settings.popup) + ? $target.position() + : $target.offset(), + + positioning, + offstagePosition + ; + position = position || $module.data(metadata.position) || settings.position; + arrowOffset = arrowOffset || $module.data(metadata.offset) || settings.offset; + + if(settings.inline) { + module.debug('Adding targets margin to calculation'); + if(position == 'left center' || position == 'right center') { + arrowOffset += marginTop; + distanceAway += -marginLeft; + } + else if (position == 'top left' || position == 'top center' || position == 'top right') { + arrowOffset += marginLeft; + distanceAway -= marginTop; + } + else { + arrowOffset += marginLeft; + distanceAway += marginTop; + } + } + module.debug('Calculating popup positioning', position); + switch(position) { + case 'top left': + positioning = { + top : 'auto', + bottom : parentHeight - target.top + distanceAway, + left : target.left + arrowOffset, + right : 'auto' + }; + break; + case 'top center': + positioning = { + bottom : parentHeight - target.top + distanceAway, + left : target.left + (targetWidth / 2) - (popupWidth / 2) + arrowOffset, + top : 'auto', + right : 'auto' + }; + break; + case 'top right': + positioning = { + bottom : parentHeight - target.top + distanceAway, + right : parentWidth - target.left - targetWidth - arrowOffset, + top : 'auto', + left : 'auto' + }; + break; + case 'left center': + positioning = { + top : target.top + (targetHeight / 2) - (popupHeight / 2) + arrowOffset, + right : parentWidth - 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, + bottom : 'auto', + right : 'auto' + }; + break; + case 'bottom left': + positioning = { + top : target.top + targetHeight + distanceAway, + left : target.left + arrowOffset, + bottom : 'auto', + right : 'auto' + }; + break; + case 'bottom center': + positioning = { + top : target.top + targetHeight + distanceAway, + left : target.left + (targetWidth / 2) - (popupWidth / 2) + arrowOffset, + bottom : 'auto', + right : 'auto' + }; + break; + case 'bottom right': + positioning = { + top : target.top + targetHeight + distanceAway, + right : parentWidth - target.left - targetWidth - arrowOffset, + left : 'auto', + bottom : 'auto' + }; + break; + } + if(positioning === undefined) { + module.error(error.invalidPosition); + } + // tentatively place on stage + $popup + .css(positioning) + .removeClass(className.position) + .addClass(position) + .addClass(className.loading) + ; + // check if is offstage + offstagePosition = module.get.offstagePosition(); + // recursively find new positioning + if(offstagePosition) { + module.debug('Element is outside boundaries', offstagePosition); + if(searchDepth < settings.maxSearchDepth) { + position = module.get.nextPosition(position); + searchDepth++; + module.debug('Trying new position', position); + return ($popup) + ? module.set.position(position) + : false + ; + } + else { + module.error(error.recursion); + searchDepth = 0; + module.reset(); + $popup.removeClass(className.loading); + return false; + } + } + else { + module.debug('Position is on stage', position); + searchDepth = 0; + $popup.removeClass(className.loading); + return true; + } + } + + }, + + bind: { + popup: function() { + module.verbose('Allowing hover events on popup to prevent closing'); + $popup + .on('mouseenter', module.event.start) + .on('mouseleave', module.event.end) + ; + }, + close:function() { + if(settings.on == 'click' && settings.closable) { + module.verbose('Binding popup close event to document'); + $document + .on('click' + eventNamespace, function(event) { + module.verbose('Pop-up clickaway intent detected'); + $.proxy(module.hideGracefully, element)(event); + }) + ; + } + } + }, + + unbind: { + close: function() { + if(settings.on == 'click' && settings.closable) { + module.verbose('Removing close event from document'); + $document + .off('click' + eventNamespace) + ; + } + } + }, + + is: { + active: function() { + return $module.hasClass(className.active); + }, + animating: function() { + return ( $popup && $popup.is(':animated') || $popup.hasClass(className.animating) ); + }, + visible: function() { + return $popup && $popup.is(':visible'); + }, + dropdown: function() { + return $module.hasClass(className.dropdown); + }, + hidden: function() { + return !module.is.visible(); + } + }, + + reset: function() { + $popup + .removeClass(className.visible) + ; + if(settings.preserve || settings.popup) { + if($.fn.transition !== undefined) { + $popup + .transition('remove transition') + ; + } + } + else { + module.remove(); + } + }, + + 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.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.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() { + 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, 100); + }, + 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) { + module.destroy(); + } + module.initialize(); + } + }) + ; + + return (returnedValue !== undefined) + ? returnedValue + : this + ; +}; + +module.exports.settings = { + + name : 'Popup', + + debug : false, + verbose : false, + performance : false, + namespace : 'popup', + + onCreate : function(){}, + onRemove : function(){}, + onShow : function(){}, + onHide : function(){}, + + variation : '', + content : false, + html : false, + title : false, + + on : 'hover', + closable : true, + + context : 'body', + position : 'top left', + delay : { + show : 30, + hide : 0 + }, + + target : false, + popup : false, + inline : false, + preserve : true, + hoverable : false, + + duration : 200, + easing : 'easeOutQuint', + transition : 'scale', + + distanceAway : 0, + offset : 0, + maxSearchDepth : 10, + + error: { + invalidPosition : 'The position you specified is not a valid position', + method : 'The method you called is not defined.', + recursion : 'Popup attempted to reposition element to fit, but could not find an adequate position.' + }, + + metadata: { + content : 'content', + html : 'html', + offset : 'offset', + position : 'position', + title : 'title', + variation : 'variation' + }, + + className : { + active : 'active', + animating : 'animating', + dropdown : 'dropdown', + loading : 'loading', + popup : 'ui popup', + position : 'top left center bottom right', + visible : '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 = _module.exports.settings.templates.escape + ; + if(typeof text !== undefined) { + if(typeof text.title !== undefined && text.title) { + text.title = escape(text.title); + html += '
' + text.title + '
'; + } + if(typeof text.content !== undefined && text.content) { + text.content = escape(text.content); + html += '
' + text.content + '
'; + } + } + return html; + } + } + +}; + +// 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.json b/package.json index a9208c4..93599d1 100644 --- a/package.json +++ b/package.json @@ -17,5 +17,5 @@ "jquery": "x.x.x" }, "devDependencies": {}, - "main": "popup.js" + "main": "index.js" } \ No newline at end of file From 242737ffd172ae61205113547f4500827aec0a2d Mon Sep 17 00:00:00 2001 From: jlukic Date: Wed, 29 Oct 2014 20:13:01 -0400 Subject: [PATCH 05/22] Updated component release from Semantic-UI (Automatic) --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 7941fa0..4b6a921 100755 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ This repository contains pre-compiled popup files using the default themes. This For the latest changes please see the Release Notes in this repository. +If you're looking for the full version including all components and build tools [check out the main project repository](https://github.com/Semantic-Org/Semantic-UI/tree/1.0) + #### To install with Bower ``` bower install semantic-ui-popup From 852d0fba84781c8a475c8f370389526f09bd4672 Mon Sep 17 00:00:00 2001 From: jlukic Date: Wed, 29 Oct 2014 20:17:06 -0400 Subject: [PATCH 06/22] Updated component release from Semantic-UI (Automatic) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4b6a921..b8cda02 100755 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ This repository contains pre-compiled popup files using the default themes. This For the latest changes please see the Release Notes in this repository. -If you're looking for the full version including all components and build tools [check out the main project repository](https://github.com/Semantic-Org/Semantic-UI/tree/1.0) +If you're looking for the full version of Semantic including all components and build tools [check out the main project repository](https://github.com/Semantic-Org/Semantic-UI/tree/1.0) #### To install with Bower ``` From 41dd0d28be5da72e7a5c94a719fdfe87821de19f Mon Sep 17 00:00:00 2001 From: Pusher Robot Date: Wed, 29 Oct 2014 21:08:28 -0400 Subject: [PATCH 07/22] Updated component release from Semantic-UI (Automatic) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b8cda02..fa9c0e8 100755 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ This repository contains pre-compiled popup files using the default themes. This is intended for use in projects that do not need all the bells and whistles of Semantic UI, and want to keep file size to a minimum. -For the latest changes please see the Release Notes in this repository. +For the latest changes please see the [Release Notes](https://github.com/Semantic-Org/UI-Popup/blob/master/RELEASE-NOTES.md) If you're looking for the full version of Semantic including all components and build tools [check out the main project repository](https://github.com/Semantic-Org/Semantic-UI/tree/1.0) From 48dfdaf05b08338dee5d78fc2eaced879c42df73 Mon Sep 17 00:00:00 2001 From: Pusher Robot Date: Fri, 31 Oct 2014 16:00:57 -0400 Subject: [PATCH 08/22] Updated component release from Semantic-UI (Automatic) --- README.md | 23 ++ RELEASE-NOTES.md | 59 +++ bower.json | 16 + composer.json | 18 + index.js | 999 +++++++++++++++++++++++++++++++++++++++++++++++ package.json | 21 + popup.css | 279 +++++++++++++ popup.js | 997 ++++++++++++++++++++++++++++++++++++++++++++++ popup.min.css | 11 + popup.min.js | 11 + 10 files changed, 2434 insertions(+) create mode 100755 README.md create mode 100755 RELEASE-NOTES.md create mode 100755 bower.json create mode 100755 composer.json create mode 100755 index.js create mode 100755 package.json create mode 100755 popup.css create mode 100755 popup.js create mode 100755 popup.min.css create mode 100755 popup.min.js diff --git a/README.md b/README.md new file mode 100755 index 0000000..fa9c0e8 --- /dev/null +++ b/README.md @@ -0,0 +1,23 @@ +# Semantic Popup + +This repository contains pre-compiled popup files using the default themes. This is intended for use in projects that do not need all the bells and whistles of Semantic UI, and want to keep file size to a minimum. + +For the latest changes please see the [Release Notes](https://github.com/Semantic-Org/UI-Popup/blob/master/RELEASE-NOTES.md) + +If you're looking for the full version of Semantic including all components and build tools [check out the main project repository](https://github.com/Semantic-Org/Semantic-UI/tree/1.0) + +#### To install with Bower +``` +bower install semantic-ui-popup +``` + +#### To install with NPM +``` +npm install semantic-ui-popup +``` + +## Addendum + +This element's definitions (required class names, html structures) are available in the [Beta UI Docs](http://beta.semantic-ui.com) + +Please consider checking out [all the benefits to theming](http://learnsemantic.com/guide/expert.html) before using these stand-alone releases. diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md new file mode 100755 index 0000000..020ae0c --- /dev/null +++ b/RELEASE-NOTES.md @@ -0,0 +1,59 @@ +### Version 1.0.0 - XX XX, 2014 + +- **Popup** - Popup can now allow itself not to be closed when hovered over +- **Popup** - A popup element can now be specified on initialization. +- **Popup** - Positioned popups will now extend in the opposite direction to fit better with floated content + +### Version 0.12.5 - Feb 04, 2014 + +- **Popup** - Fixes issue where popups using ``title`` attribute to store data were losing title content instead of correctly restoring it + +### Merry Christmas! + +-**Popup** - Fixes popup sometimes opening and closing when ``event:click`` is used and a user double clicks + +### Version 0.10.3 - Dec 22, 2013 + +- **Popup** - Native browser popups no longer if using ``title`` attribute + +### Version 0.9.2 - Nov 8, 2013 + +**Fixes** - Fixes popup not repositioning itself when offstage. + +### Version 0.9.1 - Nov 7, 2013 + +- **Popup** - Adds context option for popup (thanks jefmathiot) + +### Version 0.7.1 - Oct 23, 2013 + +- **Popup** - Fixes issue with popup's using setting inline: true + +### Version 0.7.0 - Oct 22, 2013 + +- **List** - Popups can now have a different target than itself +- **Popup** - Popup .toggle() now always hides/shows popup correctly +- **Popup** - Popup fixed a bug where "top right" placed popup might sometimes be too large +- **Popup** - Popup will not reshow a visible popup on hover +- **Popup** - Popup border now uses RGBA to look sexier on dark backgrounds +- **Popup** - Popup default duration is now 200ms (slighty slower) +- **Popup** - Popup metadata attribute arrowOffset is now offset for simplicities sake +- **Popup** - Popup no-longer receives class name 'visible' on show, this allows popups to be used on dropdowns and other elements with a visible state +- **Popup** - Popups are no longer inline by default + +### Version 0.5.0 - Oct 10, 2013 + +- Fixes regression where popup was overriding variation class name on positioning +- Fixes an issue where popup that was set to inline: false was being removed prematurely +- Adds an example to popup where inline is set to false +- Added onCreate to popup module + +### Version 0.3.6 - Oct 7, 2013 + +- Fixes popup position sometimes appearing off-stage on second apperance +- Fixes popup positions top left, top right, bottom left, bottom right being flipped + +### Version 0.3.3 - Oct 2, 2013 + +- Fixes issue with popup display in some edge cases Issue #128 + +### Version 0.1.0 - Sep 25, 2013 \ No newline at end of file diff --git a/bower.json b/bower.json new file mode 100755 index 0000000..ee1b4b7 --- /dev/null +++ b/bower.json @@ -0,0 +1,16 @@ +{ + "name": "UI-Popup", + "description": "Popup - Semantic UI", + "homepage": "http://beta.semantic-ui.com", + "author": { + "name": "Jack Lukic", + "web": "http://www.jacklukic.com" + }, + "ignore": ["docs", "node", "server", "spec", "src", "test"], + "keywords": ["semantic", "ui", "css3", "framework"], + "license": ["http://semantic-ui.mit-license.org/"], + "main": ["popup.js", "popup.css"], + "dependencies": { + "jquery": ">=1.8" + } +} \ No newline at end of file diff --git a/composer.json b/composer.json new file mode 100755 index 0000000..188fb22 --- /dev/null +++ b/composer.json @@ -0,0 +1,18 @@ +{ + "name": "semantic/popup", + "description": "Single component release of popup", + "homepage": "http://www.semantic-ui.com", + "authors": [{ + "name": "Jack Lukic", + "email": "jacklukic@gmail.com", + "web": "http://www.jacklukic.com", + "role": "Creator" + }], + "keywords": ["semantic", "ui", "css", "framework"], + "license": "MIT", + "dependencies": { + "jquery": "x.x.x" + }, + "main": "popup.js", + "version": "1.0.0" +} \ No newline at end of file diff --git a/index.js b/index.js new file mode 100755 index 0000000..5c4f160 --- /dev/null +++ b/index.js @@ -0,0 +1,999 @@ +/* + * # Semantic - Popup + * http://github.com/jlukic/semantic-ui/ + * + * + * Copyright 2014 Contributor + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +;(function ($, window, document, undefined) { + +"use strict"; + +module.exports = function(parameters) { + var _module = module; + + var + $allModules = $(this), + $document = $(document), + + moduleSelector = $allModules.selector || '', + + hasTouch = ('ontouchstart' in document.documentElement), + 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, {}, _module.exports.settings, parameters) + : $.extend({}, _module.exports.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), + $target = (settings.target) + ? $(settings.target) + : $module, + + $window = $(window), + $body = $('body'), + $popup, + $offsetParent, + + searchDepth = 0, + + element = this, + instance = $module.data(moduleNamespace), + module + ; + + module = { + + // binds events + initialize: function() { + module.debug('Initializing module', $module); + module.refresh(); + if(settings.on == 'click') { + $module + .on('click' + eventNamespace, module.toggle) + ; + } + else 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' + eventNamespace, module.event.resize) + ; + if( !module.exists() ) { + module.create(); + } + else if(settings.hoverable) { + module.bind.popup(); + } + module.instantiate(); + }, + + instantiate: function() { + module.verbose('Storing instance of module', module); + instance = module; + $module + .data(moduleNamespace, instance) + ; + }, + + refresh: function() { + $popup = (settings.popup) + ? $(settings.popup) + : (settings.inline) + ? $target.next(settings.selector.popup) + : false + ; + $offsetParent = (settings.popup) + ? $popup.offsetParent() + : (settings.inline) + ? $target.offsetParent() + : $body + ; + }, + + destroy: function() { + module.debug('Destroying previous module'); + if($popup && !settings.preserve) { + module.remove(); + } + $module + .off(eventNamespace) + .removeData(moduleNamespace) + ; + }, + + event: { + start: function(event) { + var + delay = ($.isPlainObject(settings.delay)) + ? settings.delay.show + : settings.delay + ; + clearTimeout(module.hideTimer); + module.showTimer = setTimeout(function() { + if( module.is.hidden() && !( module.is.active() && module.is.dropdown()) ) { + module.show(); + } + }, delay); + }, + end: function() { + var + delay = ($.isPlainObject(settings.delay)) + ? settings.delay.hide + : settings.delay + ; + clearTimeout(module.showTimer); + module.hideTimer = setTimeout(function() { + if( module.is.visible() ) { + module.hide(); + } + }, delay); + }, + resize: function() { + if( module.is.visible() ) { + module.set.position(); + } + } + }, + + // 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 + ; + if(html || content || title) { + module.debug('Creating pop-up html'); + if(!html) { + html = settings.templates.popup({ + title : title, + content : content + }); + } + $popup = $('
') + .addClass(className.popup) + .addClass(variation) + .html(html) + ; + if(variation) { + $popup + .addClass(variation) + ; + } + 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 ) + ; + } + if(settings.hoverable) { + module.bind.popup(); + } + $.proxy(settings.onCreate, $popup)(); + } + else if($target.next(settings.selector.popup).size() !== 0) { + module.verbose('Pre-existing popup found, reverting to inline'); + settings.inline = true; + module.refresh(); + if(settings.hoverable) { + module.bind.popup(); + } + } + else { + module.debug('No content specified skipping display', element); + } + }, + + // 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.hideAll(); + 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(!settings.preserve && !settings.popup) { + module.refresh(); + } + if( !module.exists() ) { + module.create(); + } + if( $popup && module.set.position() ) { + module.save.conditions(); + module.animate.show(callback); + } + }, + + + hide: function(callback) { + callback = callback || function(){}; + $module + .removeClass(className.visible) + ; + module.unbind.close(); + if( module.is.visible() ) { + module.restore.conditions(); + module.animate.hide(callback); + } + }, + + hideAll: function() { + $(selector.popup) + .filter(':visible') + .popup('hide') + ; + }, + + hideGracefully: function(event) { + // don't close on clicks inside popup + if(event && $(event.target).closest(selector.popup).size() === 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; + } + if(settings.inline || settings.popup) { + return ( $popup.size() !== 0 ); + } + else { + return ( $popup.closest($context).size() ); + } + }, + + remove: function() { + module.debug('Removing popup'); + $popup + .remove() + ; + }, + + 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; + } + }, + animate: { + show: function(callback) { + callback = callback || function(){}; + if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) { + $popup + .transition({ + animation : settings.transition + ' in', + queue : false, + duration : settings.duration, + start: function() { + $module + .addClass(className.visible) + ; + }, + complete : function() { + module.bind.close(); + $.proxy(callback, element)(); + } + }) + ; + } + else { + $module + .addClass(className.visible) + ; + $popup + .stop() + .fadeIn(settings.duration, settings.easing, function() { + module.bind.close(); + $.proxy(callback, element)(); + }) + ; + } + $.proxy(settings.onShow, element)(); + }, + hide: function(callback) { + callback = callback || function(){}; + module.debug('Hiding pop-up'); + if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) { + $popup + .transition({ + animation : settings.transition + ' out', + queue : false, + duration : settings.duration, + complete : function() { + module.reset(); + callback(); + } + }) + ; + } + else { + $popup + .stop() + .fadeOut(settings.duration, settings.easing, function() { + module.reset(); + callback(); + }) + ; + } + $.proxy(settings.onHide, element)(); + } + }, + + get: { + startEvent: function() { + if(settings.on == 'hover') { + return 'mouseenter'; + } + else if(settings.on == 'focus') { + return 'focus'; + } + return false; + }, + endEvent: function() { + if(settings.on == 'hover') { + return 'mouseleave'; + } + else if(settings.on == 'focus') { + return 'blur'; + } + return false; + }, + offstagePosition: function() { + var + boundary = { + top : $(window).scrollTop(), + bottom : $(window).scrollTop() + $(window).height(), + left : 0, + right : $(window).width() + }, + popup = { + width : $popup.width(), + height : $popup.outerHeight(), + offset : $popup.offset() + }, + offstage = {}, + offstagePositions = [] + ; + if(popup.offset) { + 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) + }; + } + module.verbose('Checking if outside viewable area', popup.offset); + // return only boundaries that have been surpassed + $.each(offstage, function(direction, isOffstage) { + if(isOffstage) { + offstagePositions.push(direction); + } + }); + return (offstagePositions.length > 0) + ? offstagePositions.join(' ') + : false + ; + }, + nextPosition: function(position) { + switch(position) { + case 'top left': + position = 'bottom left'; + break; + case 'bottom left': + position = 'top right'; + break; + case 'top right': + position = 'bottom right'; + break; + case 'bottom right': + position = 'top center'; + break; + case 'top center': + position = 'bottom center'; + break; + case 'bottom center': + position = 'right center'; + break; + case 'right center': + position = 'left center'; + break; + case 'left center': + position = 'top center'; + break; + } + return position; + } + }, + + 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('margin-left'), 10) + : 0, + + target = (settings.inline || settings.popup) + ? $target.position() + : $target.offset(), + + positioning, + offstagePosition + ; + position = position || $module.data(metadata.position) || settings.position; + arrowOffset = arrowOffset || $module.data(metadata.offset) || settings.offset; + + if(settings.inline) { + module.debug('Adding targets margin to calculation'); + if(position == 'left center' || position == 'right center') { + arrowOffset += marginTop; + distanceAway += -marginLeft; + } + else if (position == 'top left' || position == 'top center' || position == 'top right') { + arrowOffset += marginLeft; + distanceAway -= marginTop; + } + else { + arrowOffset += marginLeft; + distanceAway += marginTop; + } + } + module.debug('Calculating popup positioning', position); + switch(position) { + case 'top left': + positioning = { + top : 'auto', + bottom : parentHeight - target.top + distanceAway, + left : target.left + arrowOffset, + right : 'auto' + }; + break; + case 'top center': + positioning = { + bottom : parentHeight - target.top + distanceAway, + left : target.left + (targetWidth / 2) - (popupWidth / 2) + arrowOffset, + top : 'auto', + right : 'auto' + }; + break; + case 'top right': + positioning = { + bottom : parentHeight - target.top + distanceAway, + right : parentWidth - target.left - targetWidth - arrowOffset, + top : 'auto', + left : 'auto' + }; + break; + case 'left center': + positioning = { + top : target.top + (targetHeight / 2) - (popupHeight / 2) + arrowOffset, + right : parentWidth - 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, + bottom : 'auto', + right : 'auto' + }; + break; + case 'bottom left': + positioning = { + top : target.top + targetHeight + distanceAway, + left : target.left + arrowOffset, + bottom : 'auto', + right : 'auto' + }; + break; + case 'bottom center': + positioning = { + top : target.top + targetHeight + distanceAway, + left : target.left + (targetWidth / 2) - (popupWidth / 2) + arrowOffset, + bottom : 'auto', + right : 'auto' + }; + break; + case 'bottom right': + positioning = { + top : target.top + targetHeight + distanceAway, + right : parentWidth - target.left - targetWidth - arrowOffset, + left : 'auto', + bottom : 'auto' + }; + break; + } + if(positioning === undefined) { + module.error(error.invalidPosition); + } + // tentatively place on stage + $popup + .css(positioning) + .removeClass(className.position) + .addClass(position) + .addClass(className.loading) + ; + // check if is offstage + offstagePosition = module.get.offstagePosition(); + // recursively find new positioning + if(offstagePosition) { + module.debug('Element is outside boundaries', offstagePosition); + if(searchDepth < settings.maxSearchDepth) { + position = module.get.nextPosition(position); + searchDepth++; + module.debug('Trying new position', position); + return ($popup) + ? module.set.position(position) + : false + ; + } + else { + module.error(error.recursion); + searchDepth = 0; + module.reset(); + $popup.removeClass(className.loading); + return false; + } + } + else { + module.debug('Position is on stage', position); + searchDepth = 0; + $popup.removeClass(className.loading); + return true; + } + } + + }, + + bind: { + popup: function() { + module.verbose('Allowing hover events on popup to prevent closing'); + $popup + .on('mouseenter', module.event.start) + .on('mouseleave', module.event.end) + ; + }, + close:function() { + if(settings.on == 'click' && settings.closable) { + module.verbose('Binding popup close event to document'); + $document + .on('click' + eventNamespace, function(event) { + module.verbose('Pop-up clickaway intent detected'); + $.proxy(module.hideGracefully, element)(event); + }) + ; + } + } + }, + + unbind: { + close: function() { + if(settings.on == 'click' && settings.closable) { + module.verbose('Removing close event from document'); + $document + .off('click' + eventNamespace) + ; + } + } + }, + + is: { + active: function() { + return $module.hasClass(className.active); + }, + animating: function() { + return ( $popup && $popup.is(':animated') || $popup.hasClass(className.animating) ); + }, + visible: function() { + return $popup && $popup.is(':visible'); + }, + dropdown: function() { + return $module.hasClass(className.dropdown); + }, + hidden: function() { + return !module.is.visible(); + } + }, + + reset: function() { + $popup + .removeClass(className.visible) + ; + if(settings.preserve || settings.popup) { + if($.fn.transition !== undefined) { + $popup + .transition('remove transition') + ; + } + } + else { + module.remove(); + } + }, + + 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.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.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() { + 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, 100); + }, + 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) { + module.destroy(); + } + module.initialize(); + } + }) + ; + + return (returnedValue !== undefined) + ? returnedValue + : this + ; +}; + +module.exports.settings = { + + name : 'Popup', + + debug : false, + verbose : false, + performance : false, + namespace : 'popup', + + onCreate : function(){}, + onRemove : function(){}, + onShow : function(){}, + onHide : function(){}, + + variation : '', + content : false, + html : false, + title : false, + + on : 'hover', + closable : true, + + context : 'body', + position : 'top left', + delay : { + show : 30, + hide : 0 + }, + + target : false, + popup : false, + inline : false, + preserve : true, + hoverable : false, + + duration : 200, + easing : 'easeOutQuint', + transition : 'scale', + + distanceAway : 0, + offset : 0, + maxSearchDepth : 10, + + error: { + invalidPosition : 'The position you specified is not a valid position', + method : 'The method you called is not defined.', + recursion : 'Popup attempted to reposition element to fit, but could not find an adequate position.' + }, + + metadata: { + content : 'content', + html : 'html', + offset : 'offset', + position : 'position', + title : 'title', + variation : 'variation' + }, + + className : { + active : 'active', + animating : 'animating', + dropdown : 'dropdown', + loading : 'loading', + popup : 'ui popup', + position : 'top left center bottom right', + visible : '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 = _module.exports.settings.templates.escape + ; + if(typeof text !== undefined) { + if(typeof text.title !== undefined && text.title) { + text.title = escape(text.title); + html += '
' + text.title + '
'; + } + if(typeof text.content !== undefined && text.content) { + text.content = escape(text.content); + html += '
' + text.content + '
'; + } + } + return html; + } + } + +}; + +// 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.json b/package.json new file mode 100755 index 0000000..93599d1 --- /dev/null +++ b/package.json @@ -0,0 +1,21 @@ +{ + "name": "UI-Popup", + "version": "1.0.0", + "title": "Semantic UI - Popup", + "description": "Single component release of popup", + "homepage": "http://www.semantic-ui.com", + "author": "Jack Lukic ", + "license": "MIT", + "repository": { + "type": "git", + "url": "git@github.com:Semantic-Org/UI-Popup.git" + }, + "bugs": { + "url": "https://github.com/Semantic-Org/Semantic-UI/issues" + }, + "dependencies": { + "jquery": "x.x.x" + }, + "devDependencies": {}, + "main": "index.js" +} \ No newline at end of file diff --git a/popup.css b/popup.css new file mode 100755 index 0000000..bfcfa4c --- /dev/null +++ b/popup.css @@ -0,0 +1,279 @@ + /* + * # Semantic UI + * https://github.com/Semantic-Org/Semantic-UI + * http://beta.semantic-ui.com/ + * + * Copyright 2014 Contributors + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + + + +/******************************* + Popup +*******************************/ + +.ui.popup { + display: none; + position: absolute; + top: 0px; + right: 0px; + z-index: 900; + border: 1px solid #cccccc; + max-width: 250px; + background-color: #ffffff; + padding: 0.8em 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); +} +.ui.popup > .header { + padding: 0em; + font-family: 'Lato', 'Helvetica Neue', Arial, Helvetica, sans-serif; + font-size: 1.125em; + line-height: 1.2; + font-weight: bold; +} +.ui.popup > .header + .content { + padding-top: 0.5em; +} +.ui.popup:before { + position: absolute; + content: ''; + width: 0.75em; + height: 0.75em; + background: #ffffff; + -webkit-transform: rotate(45deg); + -ms-transform: rotate(45deg); + transform: rotate(45deg); + z-index: 2; + box-shadow: 1px 1px 0px 0px #b3b3b3; +} + + +/******************************* + Types +*******************************/ + + +/*-------------- + Spacing +---------------*/ + +.ui.popup { + margin: 0em; +} +.ui.popup.bottom { + margin: 0.75em 0em 0em; +} +.ui.popup.top { + margin: 0em 0em 0.75em; +} +.ui.popup.left.center { + margin: 0em 0.75em 0em 0em; +} +.ui.popup.right.center { + margin: 0em 0em 0em 0.75em; +} + +/*-------------- + Pointer +---------------*/ + + +/*--- Below ---*/ + +.ui.bottom.center.popup:before { + margin-left: -0.325em; + top: -0.325em; + left: 50%; + right: auto; + bottom: auto; + box-shadow: -1px -1px 0px 0px #b3b3b3; +} +.ui.bottom.left.popup { + margin-left: 0em; +} +.ui.bottom.left.popup:before { + top: -0.325em; + left: 1em; + right: auto; + bottom: auto; + margin-left: 0em; + box-shadow: -1px -1px 0px 0px #b3b3b3; +} +.ui.bottom.right.popup { + margin-right: 0em; +} +.ui.bottom.right.popup:before { + top: -0.325em; + right: 1em; + bottom: auto; + left: auto; + margin-left: 0em; + box-shadow: -1px -1px 0px 0px #b3b3b3; +} + +/*--- Above ---*/ + +.ui.top.center.popup:before { + top: auto; + right: auto; + bottom: -0.325em; + left: 50%; + margin-left: -0.325em; +} +.ui.top.left.popup { + margin-left: 0em; +} +.ui.top.left.popup:before { + bottom: -0.325em; + left: 1em; + top: auto; + right: auto; + margin-left: 0em; +} +.ui.top.right.popup { + margin-right: 0em; +} +.ui.top.right.popup:before { + bottom: -0.325em; + right: 1em; + top: auto; + left: auto; + margin-left: 0em; +} + +/*--- Left Center ---*/ + +.ui.left.center.popup:before { + top: 50%; + right: -0.325em; + bottom: auto; + left: auto; + margin-top: -0.325em; + box-shadow: 1px -1px 0px 0px #b3b3b3; +} + +/*--- Right Center ---*/ + +.ui.right.center.popup:before { + top: 50%; + left: -0.325em; + bottom: auto; + right: auto; + margin-top: -0.325em; + box-shadow: -1px 1px 0px 0px #b3b3b3; +} + + +/******************************* + Coupling +*******************************/ + + +/* 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; +} + + +/******************************* + States +*******************************/ + +.ui.loading.popup { + display: block; + visibility: hidden; + z-index: -1; +} +.ui.animating.popup, +.ui.visible.popup { + display: block; +} + + +/******************************* + Variations +*******************************/ + + +/*-------------- + Wide +---------------*/ + +.ui.wide.popup { + width: 350px; + max-width: 350px; +} +.ui[class*="very wide"].popup { + width: 550px; + max-width: 550px; +} + +/*-------------- + Fluid +---------------*/ + +.ui.fluid.popup { + width: 100%; + max-width: 99999px; +} + +/*-------------- + Colors +---------------*/ + + +/* Inverted colors */ +.ui.inverted.popup { + background: #1b1c1d; + color: #ffffff; + border: none; + box-shadow: none; +} +.ui.inverted.popup .header { + background-color: none; + color: #ffffff; +} +.ui.inverted.popup:before { + background-color: #1b1c1d; + box-shadow: none; +} + +/*-------------- + Flowing +---------------*/ + +.ui.flowing.popup { + max-width: 9999px; +} + +/*-------------- + Sizes +---------------*/ + +.ui.small.popup { + font-size: 0.8rem; +} +.ui.popup { + font-size: 0.875rem; +} +.ui.large.popup { + font-size: 1rem; +} +.ui.huge.popup { + font-size: 1.1rem; +} + + +/******************************* + Theme Overrides +*******************************/ + diff --git a/popup.js b/popup.js new file mode 100755 index 0000000..3dae337 --- /dev/null +++ b/popup.js @@ -0,0 +1,997 @@ +/* + * # Semantic - Popup + * http://github.com/jlukic/semantic-ui/ + * + * + * Copyright 2014 Contributor + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +;(function ($, window, document, undefined) { + +"use strict"; + +$.fn.popup = function(parameters) { + var + $allModules = $(this), + $document = $(document), + + moduleSelector = $allModules.selector || '', + + hasTouch = ('ontouchstart' in document.documentElement), + 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), + $target = (settings.target) + ? $(settings.target) + : $module, + + $window = $(window), + $body = $('body'), + $popup, + $offsetParent, + + searchDepth = 0, + + element = this, + instance = $module.data(moduleNamespace), + module + ; + + module = { + + // binds events + initialize: function() { + module.debug('Initializing module', $module); + module.refresh(); + if(settings.on == 'click') { + $module + .on('click' + eventNamespace, module.toggle) + ; + } + else 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' + eventNamespace, module.event.resize) + ; + if( !module.exists() ) { + module.create(); + } + else if(settings.hoverable) { + module.bind.popup(); + } + module.instantiate(); + }, + + instantiate: function() { + module.verbose('Storing instance of module', module); + instance = module; + $module + .data(moduleNamespace, instance) + ; + }, + + refresh: function() { + $popup = (settings.popup) + ? $(settings.popup) + : (settings.inline) + ? $target.next(settings.selector.popup) + : false + ; + $offsetParent = (settings.popup) + ? $popup.offsetParent() + : (settings.inline) + ? $target.offsetParent() + : $body + ; + }, + + destroy: function() { + module.debug('Destroying previous module'); + if($popup && !settings.preserve) { + module.remove(); + } + $module + .off(eventNamespace) + .removeData(moduleNamespace) + ; + }, + + event: { + start: function(event) { + var + delay = ($.isPlainObject(settings.delay)) + ? settings.delay.show + : settings.delay + ; + clearTimeout(module.hideTimer); + module.showTimer = setTimeout(function() { + if( module.is.hidden() && !( module.is.active() && module.is.dropdown()) ) { + module.show(); + } + }, delay); + }, + end: function() { + var + delay = ($.isPlainObject(settings.delay)) + ? settings.delay.hide + : settings.delay + ; + clearTimeout(module.showTimer); + module.hideTimer = setTimeout(function() { + if( module.is.visible() ) { + module.hide(); + } + }, delay); + }, + resize: function() { + if( module.is.visible() ) { + module.set.position(); + } + } + }, + + // 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 + ; + if(html || content || title) { + module.debug('Creating pop-up html'); + if(!html) { + html = settings.templates.popup({ + title : title, + content : content + }); + } + $popup = $('
') + .addClass(className.popup) + .addClass(variation) + .html(html) + ; + if(variation) { + $popup + .addClass(variation) + ; + } + 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 ) + ; + } + if(settings.hoverable) { + module.bind.popup(); + } + $.proxy(settings.onCreate, $popup)(); + } + else if($target.next(settings.selector.popup).size() !== 0) { + module.verbose('Pre-existing popup found, reverting to inline'); + settings.inline = true; + module.refresh(); + if(settings.hoverable) { + module.bind.popup(); + } + } + else { + module.debug('No content specified skipping display', element); + } + }, + + // 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.hideAll(); + 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(!settings.preserve && !settings.popup) { + module.refresh(); + } + if( !module.exists() ) { + module.create(); + } + if( $popup && module.set.position() ) { + module.save.conditions(); + module.animate.show(callback); + } + }, + + + hide: function(callback) { + callback = callback || function(){}; + $module + .removeClass(className.visible) + ; + module.unbind.close(); + if( module.is.visible() ) { + module.restore.conditions(); + module.animate.hide(callback); + } + }, + + hideAll: function() { + $(selector.popup) + .filter(':visible') + .popup('hide') + ; + }, + + hideGracefully: function(event) { + // don't close on clicks inside popup + if(event && $(event.target).closest(selector.popup).size() === 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; + } + if(settings.inline || settings.popup) { + return ( $popup.size() !== 0 ); + } + else { + return ( $popup.closest($context).size() ); + } + }, + + remove: function() { + module.debug('Removing popup'); + $popup + .remove() + ; + }, + + 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; + } + }, + animate: { + show: function(callback) { + callback = callback || function(){}; + if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) { + $popup + .transition({ + animation : settings.transition + ' in', + queue : false, + duration : settings.duration, + start: function() { + $module + .addClass(className.visible) + ; + }, + complete : function() { + module.bind.close(); + $.proxy(callback, element)(); + } + }) + ; + } + else { + $module + .addClass(className.visible) + ; + $popup + .stop() + .fadeIn(settings.duration, settings.easing, function() { + module.bind.close(); + $.proxy(callback, element)(); + }) + ; + } + $.proxy(settings.onShow, element)(); + }, + hide: function(callback) { + callback = callback || function(){}; + module.debug('Hiding pop-up'); + if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) { + $popup + .transition({ + animation : settings.transition + ' out', + queue : false, + duration : settings.duration, + complete : function() { + module.reset(); + callback(); + } + }) + ; + } + else { + $popup + .stop() + .fadeOut(settings.duration, settings.easing, function() { + module.reset(); + callback(); + }) + ; + } + $.proxy(settings.onHide, element)(); + } + }, + + get: { + startEvent: function() { + if(settings.on == 'hover') { + return 'mouseenter'; + } + else if(settings.on == 'focus') { + return 'focus'; + } + return false; + }, + endEvent: function() { + if(settings.on == 'hover') { + return 'mouseleave'; + } + else if(settings.on == 'focus') { + return 'blur'; + } + return false; + }, + offstagePosition: function() { + var + boundary = { + top : $(window).scrollTop(), + bottom : $(window).scrollTop() + $(window).height(), + left : 0, + right : $(window).width() + }, + popup = { + width : $popup.width(), + height : $popup.outerHeight(), + offset : $popup.offset() + }, + offstage = {}, + offstagePositions = [] + ; + if(popup.offset) { + 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) + }; + } + module.verbose('Checking if outside viewable area', popup.offset); + // return only boundaries that have been surpassed + $.each(offstage, function(direction, isOffstage) { + if(isOffstage) { + offstagePositions.push(direction); + } + }); + return (offstagePositions.length > 0) + ? offstagePositions.join(' ') + : false + ; + }, + nextPosition: function(position) { + switch(position) { + case 'top left': + position = 'bottom left'; + break; + case 'bottom left': + position = 'top right'; + break; + case 'top right': + position = 'bottom right'; + break; + case 'bottom right': + position = 'top center'; + break; + case 'top center': + position = 'bottom center'; + break; + case 'bottom center': + position = 'right center'; + break; + case 'right center': + position = 'left center'; + break; + case 'left center': + position = 'top center'; + break; + } + return position; + } + }, + + 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('margin-left'), 10) + : 0, + + target = (settings.inline || settings.popup) + ? $target.position() + : $target.offset(), + + positioning, + offstagePosition + ; + position = position || $module.data(metadata.position) || settings.position; + arrowOffset = arrowOffset || $module.data(metadata.offset) || settings.offset; + + if(settings.inline) { + module.debug('Adding targets margin to calculation'); + if(position == 'left center' || position == 'right center') { + arrowOffset += marginTop; + distanceAway += -marginLeft; + } + else if (position == 'top left' || position == 'top center' || position == 'top right') { + arrowOffset += marginLeft; + distanceAway -= marginTop; + } + else { + arrowOffset += marginLeft; + distanceAway += marginTop; + } + } + module.debug('Calculating popup positioning', position); + switch(position) { + case 'top left': + positioning = { + top : 'auto', + bottom : parentHeight - target.top + distanceAway, + left : target.left + arrowOffset, + right : 'auto' + }; + break; + case 'top center': + positioning = { + bottom : parentHeight - target.top + distanceAway, + left : target.left + (targetWidth / 2) - (popupWidth / 2) + arrowOffset, + top : 'auto', + right : 'auto' + }; + break; + case 'top right': + positioning = { + bottom : parentHeight - target.top + distanceAway, + right : parentWidth - target.left - targetWidth - arrowOffset, + top : 'auto', + left : 'auto' + }; + break; + case 'left center': + positioning = { + top : target.top + (targetHeight / 2) - (popupHeight / 2) + arrowOffset, + right : parentWidth - 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, + bottom : 'auto', + right : 'auto' + }; + break; + case 'bottom left': + positioning = { + top : target.top + targetHeight + distanceAway, + left : target.left + arrowOffset, + bottom : 'auto', + right : 'auto' + }; + break; + case 'bottom center': + positioning = { + top : target.top + targetHeight + distanceAway, + left : target.left + (targetWidth / 2) - (popupWidth / 2) + arrowOffset, + bottom : 'auto', + right : 'auto' + }; + break; + case 'bottom right': + positioning = { + top : target.top + targetHeight + distanceAway, + right : parentWidth - target.left - targetWidth - arrowOffset, + left : 'auto', + bottom : 'auto' + }; + break; + } + if(positioning === undefined) { + module.error(error.invalidPosition); + } + // tentatively place on stage + $popup + .css(positioning) + .removeClass(className.position) + .addClass(position) + .addClass(className.loading) + ; + // check if is offstage + offstagePosition = module.get.offstagePosition(); + // recursively find new positioning + if(offstagePosition) { + module.debug('Element is outside boundaries', offstagePosition); + if(searchDepth < settings.maxSearchDepth) { + position = module.get.nextPosition(position); + searchDepth++; + module.debug('Trying new position', position); + return ($popup) + ? module.set.position(position) + : false + ; + } + else { + module.error(error.recursion); + searchDepth = 0; + module.reset(); + $popup.removeClass(className.loading); + return false; + } + } + else { + module.debug('Position is on stage', position); + searchDepth = 0; + $popup.removeClass(className.loading); + return true; + } + } + + }, + + bind: { + popup: function() { + module.verbose('Allowing hover events on popup to prevent closing'); + $popup + .on('mouseenter', module.event.start) + .on('mouseleave', module.event.end) + ; + }, + close:function() { + if(settings.on == 'click' && settings.closable) { + module.verbose('Binding popup close event to document'); + $document + .on('click' + eventNamespace, function(event) { + module.verbose('Pop-up clickaway intent detected'); + $.proxy(module.hideGracefully, element)(event); + }) + ; + } + } + }, + + unbind: { + close: function() { + if(settings.on == 'click' && settings.closable) { + module.verbose('Removing close event from document'); + $document + .off('click' + eventNamespace) + ; + } + } + }, + + is: { + active: function() { + return $module.hasClass(className.active); + }, + animating: function() { + return ( $popup && $popup.is(':animated') || $popup.hasClass(className.animating) ); + }, + visible: function() { + return $popup && $popup.is(':visible'); + }, + dropdown: function() { + return $module.hasClass(className.dropdown); + }, + hidden: function() { + return !module.is.visible(); + } + }, + + reset: function() { + $popup + .removeClass(className.visible) + ; + if(settings.preserve || settings.popup) { + if($.fn.transition !== undefined) { + $popup + .transition('remove transition') + ; + } + } + else { + module.remove(); + } + }, + + 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.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.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() { + 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, 100); + }, + 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) { + module.destroy(); + } + module.initialize(); + } + }) + ; + + return (returnedValue !== undefined) + ? returnedValue + : this + ; +}; + +$.fn.popup.settings = { + + name : 'Popup', + + debug : false, + verbose : false, + performance : false, + namespace : 'popup', + + onCreate : function(){}, + onRemove : function(){}, + onShow : function(){}, + onHide : function(){}, + + variation : '', + content : false, + html : false, + title : false, + + on : 'hover', + closable : true, + + context : 'body', + position : 'top left', + delay : { + show : 30, + hide : 0 + }, + + target : false, + popup : false, + inline : false, + preserve : true, + hoverable : false, + + duration : 200, + easing : 'easeOutQuint', + transition : 'scale', + + distanceAway : 0, + offset : 0, + maxSearchDepth : 10, + + error: { + invalidPosition : 'The position you specified is not a valid position', + method : 'The method you called is not defined.', + recursion : 'Popup attempted to reposition element to fit, but could not find an adequate position.' + }, + + metadata: { + content : 'content', + html : 'html', + offset : 'offset', + position : 'position', + title : 'title', + variation : 'variation' + }, + + className : { + active : 'active', + animating : 'animating', + dropdown : 'dropdown', + loading : 'loading', + popup : 'ui popup', + position : 'top left center bottom right', + visible : '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 += '
' + text.title + '
'; + } + if(typeof text.content !== undefined && text.content) { + text.content = escape(text.content); + html += '
' + text.content + '
'; + } + } + return html; + } + } + +}; + +// 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 new file mode 100755 index 0000000..f36dd2f --- /dev/null +++ b/popup.min.css @@ -0,0 +1,11 @@ + /* + * # Semantic UI + * https://github.com/Semantic-Org/Semantic-UI + * http://beta.semantic-ui.com/ + * + * Copyright 2014 Contributors + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ +.ui.popup{display:none;position:absolute;top:0;right:0;z-index:900;border:1px solid #ccc;max-width:250px;background-color:#fff;padding:.8em 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)}.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{margin:0}.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.wide.popup{width:350px;max-width:350px}.ui[class*="very wide"].popup{width:550px;max-width:550px}.ui.fluid.popup{width:100%;max-width:99999px}.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}.ui.flowing.popup{max-width:9999px}.ui.small.popup{font-size:.8rem}.ui.popup{font-size:.875rem}.ui.large.popup{font-size:1rem}.ui.huge.popup{font-size:1.1rem} \ No newline at end of file diff --git a/popup.min.js b/popup.min.js new file mode 100755 index 0000000..c9b288e --- /dev/null +++ b/popup.min.js @@ -0,0 +1,11 @@ + /* + * # Semantic UI + * https://github.com/Semantic-Org/Semantic-UI + * http://beta.semantic-ui.com/ + * + * Copyright 2014 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||"",u=("ontouchstart"in o.documentElement,(new Date).getTime()),c=[],l=arguments[0],d="string"==typeof l,f=[].slice.call(arguments,1);return s.each(function(){var o,s,g,m=e.isPlainObject(i)?e.extend(!0,{},e.fn.popup.settings,i):e.extend({},e.fn.popup.settings),h=m.selector,b=m.className,v=m.error,y=m.metadata,w=m.namespace,k="."+m.namespace,x="module-"+w,C=e(this),P=e(m.context),T=m.target?e(m.target):C,A=e(t),E=e("body"),z=0,O=this,j=C.data(x);g={initialize:function(){g.debug("Initializing module",C),g.refresh(),"click"==m.on?C.on("click"+k,g.toggle):g.get.startEvent()&&C.on(g.get.startEvent()+k,g.event.start).on(g.get.endEvent()+k,g.event.end),m.target&&g.debug("Target set to element",T),A.on("resize"+k,g.event.resize),g.exists()?m.hoverable&&g.bind.popup():g.create(),g.instantiate()},instantiate:function(){g.verbose("Storing instance of module",g),j=g,C.data(x,j)},refresh:function(){o=m.popup?e(m.popup):m.inline?T.next(m.selector.popup):!1,s=m.popup?o.offsetParent():m.inline?T.offsetParent():E},destroy:function(){g.debug("Destroying previous module"),o&&!m.preserve&&g.remove(),C.off(k).removeData(x)},event:{start:function(){var t=e.isPlainObject(m.delay)?m.delay.show:m.delay;clearTimeout(g.hideTimer),g.showTimer=setTimeout(function(){!g.is.hidden()||g.is.active()&&g.is.dropdown()||g.show()},t)},end:function(){var t=e.isPlainObject(m.delay)?m.delay.hide:m.delay;clearTimeout(g.showTimer),g.hideTimer=setTimeout(function(){g.is.visible()&&g.hide()},t)},resize:function(){g.is.visible()&&g.set.position()}},create:function(){var t=C.data(y.html)||m.html,n=C.data(y.variation)||m.variation,i=C.data(y.title)||m.title,r=C.data(y.content)||C.attr("title")||m.content;t||r||i?(g.debug("Creating pop-up html"),t||(t=m.templates.popup({title:i,content:r})),o=e("
").addClass(b.popup).addClass(n).html(t),n&&o.addClass(n),m.inline?(g.verbose("Inserting popup element inline",o),o.insertAfter(C)):(g.verbose("Appending popup element to body",o),o.appendTo(P)),m.hoverable&&g.bind.popup(),e.proxy(m.onCreate,o)()):0!==T.next(m.selector.popup).size()?(g.verbose("Pre-existing popup found, reverting to inline"),m.inline=!0,g.refresh(),m.hoverable&&g.bind.popup()):g.debug("No content specified skipping display",O)},toggle:function(){g.debug("Toggling pop-up"),g.is.hidden()?(g.debug("Popup is hidden, showing pop-up"),g.unbind.close(),g.hideAll(),g.show()):(g.debug("Popup is visible, hiding pop-up"),g.hide())},show:function(e){e=e||function(){},g.debug("Showing pop-up",m.transition),m.preserve||m.popup||g.refresh(),g.exists()||g.create(),o&&g.set.position()&&(g.save.conditions(),g.animate.show(e))},hide:function(e){e=e||function(){},C.removeClass(b.visible),g.unbind.close(),g.is.visible()&&(g.restore.conditions(),g.animate.hide(e))},hideAll:function(){e(h.popup).filter(":visible").popup("hide")},hideGracefully:function(t){t&&0===e(t.target).closest(h.popup).size()?(g.debug("Click occurred outside popup hiding popup"),g.hide()):g.debug("Click was inside popup, keeping popup open")},exists:function(){return o?m.inline||m.popup?0!==o.size():o.closest(P).size():!1},remove:function(){g.debug("Removing popup"),o.remove()},save:{conditions:function(){g.cache={title:C.attr("title")},g.cache.title&&C.removeAttr("title"),g.verbose("Saving original attributes",g.cache.title)}},restore:{conditions:function(){return g.cache&&g.cache.title&&(C.attr("title",g.cache.title),g.verbose("Restoring original attributes",g.cache.title)),!0}},animate:{show:function(t){t=t||function(){},m.transition&&e.fn.transition!==n&&C.transition("is supported")?o.transition({animation:m.transition+" in",queue:!1,duration:m.duration,start:function(){C.addClass(b.visible)},complete:function(){g.bind.close(),e.proxy(t,O)()}}):(C.addClass(b.visible),o.stop().fadeIn(m.duration,m.easing,function(){g.bind.close(),e.proxy(t,O)()})),e.proxy(m.onShow,O)()},hide:function(t){t=t||function(){},g.debug("Hiding pop-up"),m.transition&&e.fn.transition!==n&&C.transition("is supported")?o.transition({animation:m.transition+" out",queue:!1,duration:m.duration,complete:function(){g.reset(),t()}}):o.stop().fadeOut(m.duration,m.easing,function(){g.reset(),t()}),e.proxy(m.onHide,O)()}},get:{startEvent:function(){return"hover"==m.on?"mouseenter":"focus"==m.on?"focus":!1},endEvent:function(){return"hover"==m.on?"mouseleave":"focus"==m.on?"blur":!1},offstagePosition:function(){var n={top:e(t).scrollTop(),bottom:e(t).scrollTop()+e(t).height(),left:0,right:e(t).width()},i={width:o.width(),height:o.outerHeight(),offset:o.offset()},r={},s=[];return i.offset&&(r={top:i.offset.topn.bottom,right:i.offset.left+i.width>n.right,left:i.offset.left0?s.join(" "):!1},nextPosition:function(e){switch(e){case"top left":e="bottom left";break;case"bottom left":e="top right";break;case"top right":e="bottom right";break;case"bottom right":e="top center";break;case"top center":e="bottom center";break;case"bottom center":e="right center";break;case"right center":e="left center";break;case"left center":e="top center"}return e}},set:{position:function(i,r){var a,p,u=(e(t).width(),e(t).height(),T.outerWidth()),c=T.outerHeight(),l=o.outerWidth(),d=o.outerHeight(),f=s.outerWidth(),h=s.outerHeight(),w=m.distanceAway,k=T[0],x=m.inline?parseInt(t.getComputedStyle(k).getPropertyValue("margin-top"),10):0,P=m.inline?parseInt(t.getComputedStyle(k).getPropertyValue("margin-left"),10):0,A=m.inline||m.popup?T.position():T.offset();switch(i=i||C.data(y.position)||m.position,r=r||C.data(y.offset)||m.offset,m.inline&&(g.debug("Adding targets margin to calculation"),"left center"==i||"right center"==i?(r+=x,w+=-P):"top left"==i||"top center"==i||"top right"==i?(r+=P,w-=x):(r+=P,w+=x)),g.debug("Calculating popup positioning",i),i){case"top left":a={top:"auto",bottom:h-A.top+w,left:A.left+r,right:"auto"};break;case"top center":a={bottom:h-A.top+w,left:A.left+u/2-l/2+r,top:"auto",right:"auto"};break;case"top right":a={bottom:h-A.top+w,right:f-A.left-u-r,top:"auto",left:"auto"};break;case"left center":a={top:A.top+c/2-d/2+r,right:f-A.left+w,left:"auto",bottom:"auto"};break;case"right center":a={top:A.top+c/2-d/2+r,left:A.left+u+w,bottom:"auto",right:"auto"};break;case"bottom left":a={top:A.top+c+w,left:A.left+r,bottom:"auto",right:"auto"};break;case"bottom center":a={top:A.top+c+w,left:A.left+u/2-l/2+r,bottom:"auto",right:"auto"};break;case"bottom right":a={top:A.top+c+w,right:f-A.left-u-r,left:"auto",bottom:"auto"}}return a===n&&g.error(v.invalidPosition),o.css(a).removeClass(b.position).addClass(i).addClass(b.loading),p=g.get.offstagePosition(),p?(g.debug("Element is outside boundaries",p),z0&&(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,u=j;return o=o||f,i=O||i,"string"==typeof t&&u!==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(u[r])&&o!=s)u=u[r];else{if(u[r]!==n)return a=u[r],!1;if(!e.isPlainObject(u[i])||o==s)return u[i]!==n?(a=u[i],!1):!1;u=u[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}},d?(j===n&&g.initialize(),g.invoke(l)):(j!==n&&g.destroy(),g.initialize())}),r!==n?r:this},e.fn.popup.settings={name:"Popup",debug:!1,verbose:!1,performance:!1,namespace:"popup",onCreate:function(){},onRemove:function(){},onShow:function(){},onHide:function(){},variation:"",content:!1,html:!1,title:!1,on:"hover",closable:!0,context:"body",position:"top left",delay:{show:30,hide:0},target:!1,popup:!1,inline:!1,preserve:!0,hoverable:!1,duration:200,easing:"easeOutQuint",transition:"scale",distanceAway:0,offset:0,maxSearchDepth:10,error:{invalidPosition:"The position you specified is not a valid position",method:"The method you called is not defined.",recursion:"Popup attempted to reposition element to fit, but could not find an adequate position."},metadata:{content:"content",html:"html",offset:"offset",position:"position",title:"title",variation:"variation"},className:{active:"active",animating:"animating",dropdown:"dropdown",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 From 238b39192a7c5ba21da361555a86c8edd26e8d22 Mon Sep 17 00:00:00 2001 From: Pusher Robot Date: Fri, 31 Oct 2014 17:08:05 -0400 Subject: [PATCH 09/22] Updated component release from Semantic-UI (Automatic) --- bower.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bower.json b/bower.json index ee1b4b7..4c15e08 100755 --- a/bower.json +++ b/bower.json @@ -1,5 +1,5 @@ { - "name": "UI-Popup", + "name": "semantic-ui-popup", "description": "Popup - Semantic UI", "homepage": "http://beta.semantic-ui.com", "author": { diff --git a/package.json b/package.json index 93599d1..bbf17d0 100755 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "UI-Popup", + "name": "semantic-ui-popup", "version": "1.0.0", "title": "Semantic UI - Popup", "description": "Single component release of popup", From 0d513be5e9c6fe27b2ce9ba84add4b1955f3363a Mon Sep 17 00:00:00 2001 From: Pusher Robot Date: Thu, 6 Nov 2014 22:53:06 -0500 Subject: [PATCH 10/22] Updated component release from Semantic-UI (Automatic) --- README.md | 0 bower.json | 2 +- composer.json | 2 +- index.js | 12 ++++++------ package.json | 6 +++--- popup.css | 6 +++--- popup.js | 12 ++++++------ popup.min.css | 6 +++--- popup.min.js | 6 +++--- 9 files changed, 26 insertions(+), 26 deletions(-) mode change 100755 => 100644 README.md mode change 100755 => 100644 bower.json mode change 100755 => 100644 composer.json diff --git a/README.md b/README.md old mode 100755 new mode 100644 diff --git a/bower.json b/bower.json old mode 100755 new mode 100644 index ee1b4b7..4c15e08 --- a/bower.json +++ b/bower.json @@ -1,5 +1,5 @@ { - "name": "UI-Popup", + "name": "semantic-ui-popup", "description": "Popup - Semantic UI", "homepage": "http://beta.semantic-ui.com", "author": { diff --git a/composer.json b/composer.json old mode 100755 new mode 100644 index 188fb22..a74338c --- a/composer.json +++ b/composer.json @@ -14,5 +14,5 @@ "jquery": "x.x.x" }, "main": "popup.js", - "version": "1.0.0" + "version": "1.0.0-beta" } \ No newline at end of file diff --git a/index.js b/index.js index 5c4f160..ff7c095 100644 --- a/index.js +++ b/index.js @@ -331,12 +331,12 @@ module.exports = function(parameters) { animation : settings.transition + ' in', queue : false, duration : settings.duration, - start: function() { + onStart : function() { $module .addClass(className.visible) ; }, - complete : function() { + onComplete : function() { module.bind.close(); $.proxy(callback, element)(); } @@ -363,10 +363,10 @@ module.exports = function(parameters) { if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) { $popup .transition({ - animation : settings.transition + ' out', - queue : false, - duration : settings.duration, - complete : function() { + animation : settings.transition + ' out', + queue : false, + duration : settings.duration, + onComplete : function() { module.reset(); callback(); } diff --git a/package.json b/package.json index 93599d1..a63034b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "UI-Popup", - "version": "1.0.0", + "name": "semantic-ui-popup", + "version": "1.0.0-beta", "title": "Semantic UI - Popup", "description": "Single component release of popup", "homepage": "http://www.semantic-ui.com", @@ -13,9 +13,9 @@ "bugs": { "url": "https://github.com/Semantic-Org/Semantic-UI/issues" }, + "devDependencies": {}, "dependencies": { "jquery": "x.x.x" }, - "devDependencies": {}, "main": "index.js" } \ No newline at end of file diff --git a/popup.css b/popup.css index b8a2f16..5cb7bb6 100755 --- a/popup.css +++ b/popup.css @@ -1,7 +1,7 @@ /* * # Semantic UI - * git://github.com/Semantic-Org/Semantic-UI.git#1.0 - * + * https://github.com/Semantic-Org/Semantic-UI + * http://beta.semantic-ui.com/ * * Copyright 2014 Contributors * Released under the MIT license @@ -244,7 +244,7 @@ } .ui.inverted.popup:before { background-color: #1b1c1d; - box-shadow: none; + box-shadow: none !important; } /*-------------- diff --git a/popup.js b/popup.js index 3dae337..9e8fde2 100644 --- a/popup.js +++ b/popup.js @@ -329,12 +329,12 @@ $.fn.popup = function(parameters) { animation : settings.transition + ' in', queue : false, duration : settings.duration, - start: function() { + onStart : function() { $module .addClass(className.visible) ; }, - complete : function() { + onComplete : function() { module.bind.close(); $.proxy(callback, element)(); } @@ -361,10 +361,10 @@ $.fn.popup = function(parameters) { if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) { $popup .transition({ - animation : settings.transition + ' out', - queue : false, - duration : settings.duration, - complete : function() { + animation : settings.transition + ' out', + queue : false, + duration : settings.duration, + onComplete : function() { module.reset(); callback(); } diff --git a/popup.min.css b/popup.min.css index 507946a..044c446 100755 --- a/popup.min.css +++ b/popup.min.css @@ -1,11 +1,11 @@ /* * # Semantic UI - * git://github.com/Semantic-Org/Semantic-UI.git#1.0 - * + * https://github.com/Semantic-Org/Semantic-UI + * http://beta.semantic-ui.com/ * * Copyright 2014 Contributors * Released under the MIT license * http://opensource.org/licenses/MIT * */ -.ui.popup{display:none;position:absolute;top:0;right:0;z-index:900;border:1px solid #ccc;max-width:250px;background-color:#fff;padding:.8em 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)}.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{margin:0}.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.wide.popup{width:350px;max-width:350px}.ui[class*="very wide"].popup{width:550px;max-width:550px}.ui.fluid.popup{width:100%;max-width:99999px}.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}.ui.flowing.popup{max-width:9999px}.ui.small.popup{font-size:.8rem}.ui.popup{font-size:.875rem}.ui.large.popup{font-size:1rem}.ui.huge.popup{font-size:1.1rem} \ No newline at end of file +.ui.popup{display:none;position:absolute;top:0;right:0;z-index:900;border:1px solid #ccc;max-width:250px;background-color:#fff;padding:.8em 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)}.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{margin:0}.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.wide.popup{width:350px;max-width:350px}.ui[class*="very wide"].popup{width:550px;max-width:550px}.ui.fluid.popup{width:100%;max-width:99999px}.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:9999px}.ui.small.popup{font-size:.8rem}.ui.popup{font-size:.875rem}.ui.large.popup{font-size:1rem}.ui.huge.popup{font-size:1.1rem} \ No newline at end of file diff --git a/popup.min.js b/popup.min.js index d45c44c..7082b4e 100644 --- a/popup.min.js +++ b/popup.min.js @@ -1,11 +1,11 @@ /* * # Semantic UI - * git://github.com/Semantic-Org/Semantic-UI.git#1.0 - * + * https://github.com/Semantic-Org/Semantic-UI + * http://beta.semantic-ui.com/ * * Copyright 2014 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||"",u=("ontouchstart"in o.documentElement,(new Date).getTime()),c=[],l=arguments[0],d="string"==typeof l,f=[].slice.call(arguments,1);return s.each(function(){var o,s,g,m=e.isPlainObject(i)?e.extend(!0,{},e.fn.popup.settings,i):e.extend({},e.fn.popup.settings),h=m.selector,b=m.className,v=m.error,y=m.metadata,w=m.namespace,k="."+m.namespace,x="module-"+w,C=e(this),P=e(m.context),T=m.target?e(m.target):C,A=e(t),E=e("body"),z=0,O=this,j=C.data(x);g={initialize:function(){g.debug("Initializing module",C),g.refresh(),"click"==m.on?C.on("click"+k,g.toggle):g.get.startEvent()&&C.on(g.get.startEvent()+k,g.event.start).on(g.get.endEvent()+k,g.event.end),m.target&&g.debug("Target set to element",T),A.on("resize"+k,g.event.resize),g.exists()?m.hoverable&&g.bind.popup():g.create(),g.instantiate()},instantiate:function(){g.verbose("Storing instance of module",g),j=g,C.data(x,j)},refresh:function(){o=m.popup?e(m.popup):m.inline?T.next(m.selector.popup):!1,s=m.popup?o.offsetParent():m.inline?T.offsetParent():E},destroy:function(){g.debug("Destroying previous module"),o&&!m.preserve&&g.remove(),C.off(k).removeData(x)},event:{start:function(){var t=e.isPlainObject(m.delay)?m.delay.show:m.delay;clearTimeout(g.hideTimer),g.showTimer=setTimeout(function(){!g.is.hidden()||g.is.active()&&g.is.dropdown()||g.show()},t)},end:function(){var t=e.isPlainObject(m.delay)?m.delay.hide:m.delay;clearTimeout(g.showTimer),g.hideTimer=setTimeout(function(){g.is.visible()&&g.hide()},t)},resize:function(){g.is.visible()&&g.set.position()}},create:function(){var t=C.data(y.html)||m.html,n=C.data(y.variation)||m.variation,i=C.data(y.title)||m.title,r=C.data(y.content)||C.attr("title")||m.content;t||r||i?(g.debug("Creating pop-up html"),t||(t=m.templates.popup({title:i,content:r})),o=e("
").addClass(b.popup).addClass(n).html(t),n&&o.addClass(n),m.inline?(g.verbose("Inserting popup element inline",o),o.insertAfter(C)):(g.verbose("Appending popup element to body",o),o.appendTo(P)),m.hoverable&&g.bind.popup(),e.proxy(m.onCreate,o)()):0!==T.next(m.selector.popup).size()?(g.verbose("Pre-existing popup found, reverting to inline"),m.inline=!0,g.refresh(),m.hoverable&&g.bind.popup()):g.debug("No content specified skipping display",O)},toggle:function(){g.debug("Toggling pop-up"),g.is.hidden()?(g.debug("Popup is hidden, showing pop-up"),g.unbind.close(),g.hideAll(),g.show()):(g.debug("Popup is visible, hiding pop-up"),g.hide())},show:function(e){e=e||function(){},g.debug("Showing pop-up",m.transition),m.preserve||m.popup||g.refresh(),g.exists()||g.create(),o&&g.set.position()&&(g.save.conditions(),g.animate.show(e))},hide:function(e){e=e||function(){},C.removeClass(b.visible),g.unbind.close(),g.is.visible()&&(g.restore.conditions(),g.animate.hide(e))},hideAll:function(){e(h.popup).filter(":visible").popup("hide")},hideGracefully:function(t){t&&0===e(t.target).closest(h.popup).size()?(g.debug("Click occurred outside popup hiding popup"),g.hide()):g.debug("Click was inside popup, keeping popup open")},exists:function(){return o?m.inline||m.popup?0!==o.size():o.closest(P).size():!1},remove:function(){g.debug("Removing popup"),o.remove()},save:{conditions:function(){g.cache={title:C.attr("title")},g.cache.title&&C.removeAttr("title"),g.verbose("Saving original attributes",g.cache.title)}},restore:{conditions:function(){return g.cache&&g.cache.title&&(C.attr("title",g.cache.title),g.verbose("Restoring original attributes",g.cache.title)),!0}},animate:{show:function(t){t=t||function(){},m.transition&&e.fn.transition!==n&&C.transition("is supported")?o.transition({animation:m.transition+" in",queue:!1,duration:m.duration,start:function(){C.addClass(b.visible)},complete:function(){g.bind.close(),e.proxy(t,O)()}}):(C.addClass(b.visible),o.stop().fadeIn(m.duration,m.easing,function(){g.bind.close(),e.proxy(t,O)()})),e.proxy(m.onShow,O)()},hide:function(t){t=t||function(){},g.debug("Hiding pop-up"),m.transition&&e.fn.transition!==n&&C.transition("is supported")?o.transition({animation:m.transition+" out",queue:!1,duration:m.duration,complete:function(){g.reset(),t()}}):o.stop().fadeOut(m.duration,m.easing,function(){g.reset(),t()}),e.proxy(m.onHide,O)()}},get:{startEvent:function(){return"hover"==m.on?"mouseenter":"focus"==m.on?"focus":!1},endEvent:function(){return"hover"==m.on?"mouseleave":"focus"==m.on?"blur":!1},offstagePosition:function(){var n={top:e(t).scrollTop(),bottom:e(t).scrollTop()+e(t).height(),left:0,right:e(t).width()},i={width:o.width(),height:o.outerHeight(),offset:o.offset()},r={},s=[];return i.offset&&(r={top:i.offset.topn.bottom,right:i.offset.left+i.width>n.right,left:i.offset.left0?s.join(" "):!1},nextPosition:function(e){switch(e){case"top left":e="bottom left";break;case"bottom left":e="top right";break;case"top right":e="bottom right";break;case"bottom right":e="top center";break;case"top center":e="bottom center";break;case"bottom center":e="right center";break;case"right center":e="left center";break;case"left center":e="top center"}return e}},set:{position:function(i,r){var a,p,u=(e(t).width(),e(t).height(),T.outerWidth()),c=T.outerHeight(),l=o.outerWidth(),d=o.outerHeight(),f=s.outerWidth(),h=s.outerHeight(),w=m.distanceAway,k=T[0],x=m.inline?parseInt(t.getComputedStyle(k).getPropertyValue("margin-top"),10):0,P=m.inline?parseInt(t.getComputedStyle(k).getPropertyValue("margin-left"),10):0,A=m.inline||m.popup?T.position():T.offset();switch(i=i||C.data(y.position)||m.position,r=r||C.data(y.offset)||m.offset,m.inline&&(g.debug("Adding targets margin to calculation"),"left center"==i||"right center"==i?(r+=x,w+=-P):"top left"==i||"top center"==i||"top right"==i?(r+=P,w-=x):(r+=P,w+=x)),g.debug("Calculating popup positioning",i),i){case"top left":a={top:"auto",bottom:h-A.top+w,left:A.left+r,right:"auto"};break;case"top center":a={bottom:h-A.top+w,left:A.left+u/2-l/2+r,top:"auto",right:"auto"};break;case"top right":a={bottom:h-A.top+w,right:f-A.left-u-r,top:"auto",left:"auto"};break;case"left center":a={top:A.top+c/2-d/2+r,right:f-A.left+w,left:"auto",bottom:"auto"};break;case"right center":a={top:A.top+c/2-d/2+r,left:A.left+u+w,bottom:"auto",right:"auto"};break;case"bottom left":a={top:A.top+c+w,left:A.left+r,bottom:"auto",right:"auto"};break;case"bottom center":a={top:A.top+c+w,left:A.left+u/2-l/2+r,bottom:"auto",right:"auto"};break;case"bottom right":a={top:A.top+c+w,right:f-A.left-u-r,left:"auto",bottom:"auto"}}return a===n&&g.error(v.invalidPosition),o.css(a).removeClass(b.position).addClass(i).addClass(b.loading),p=g.get.offstagePosition(),p?(g.debug("Element is outside boundaries",p),z0&&(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,u=j;return o=o||f,i=O||i,"string"==typeof t&&u!==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(u[r])&&o!=s)u=u[r];else{if(u[r]!==n)return a=u[r],!1;if(!e.isPlainObject(u[i])||o==s)return u[i]!==n?(a=u[i],!1):!1;u=u[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}},d?(j===n&&g.initialize(),g.invoke(l)):(j!==n&&g.destroy(),g.initialize())}),r!==n?r:this},e.fn.popup.settings={name:"Popup",debug:!1,verbose:!1,performance:!1,namespace:"popup",onCreate:function(){},onRemove:function(){},onShow:function(){},onHide:function(){},variation:"",content:!1,html:!1,title:!1,on:"hover",closable:!0,context:"body",position:"top left",delay:{show:30,hide:0},target:!1,popup:!1,inline:!1,preserve:!0,hoverable:!1,duration:200,easing:"easeOutQuint",transition:"scale",distanceAway:0,offset:0,maxSearchDepth:10,error:{invalidPosition:"The position you specified is not a valid position",method:"The method you called is not defined.",recursion:"Popup attempted to reposition element to fit, but could not find an adequate position."},metadata:{content:"content",html:"html",offset:"offset",position:"position",title:"title",variation:"variation"},className:{active:"active",animating:"animating",dropdown:"dropdown",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(e,t,o,n){"use strict";e.fn.popup=function(i){var r,s=e(this),a=e(o),p=s.selector||"",u=("ontouchstart"in o.documentElement,(new Date).getTime()),c=[],l=arguments[0],d="string"==typeof l,f=[].slice.call(arguments,1);return s.each(function(){var o,s,g,m=e.isPlainObject(i)?e.extend(!0,{},e.fn.popup.settings,i):e.extend({},e.fn.popup.settings),h=m.selector,b=m.className,v=m.error,y=m.metadata,w=m.namespace,k="."+m.namespace,x="module-"+w,C=e(this),P=e(m.context),T=m.target?e(m.target):C,A=e(t),E=e("body"),z=0,O=this,S=C.data(x);g={initialize:function(){g.debug("Initializing module",C),g.refresh(),"click"==m.on?C.on("click"+k,g.toggle):g.get.startEvent()&&C.on(g.get.startEvent()+k,g.event.start).on(g.get.endEvent()+k,g.event.end),m.target&&g.debug("Target set to element",T),A.on("resize"+k,g.event.resize),g.exists()?m.hoverable&&g.bind.popup():g.create(),g.instantiate()},instantiate:function(){g.verbose("Storing instance of module",g),S=g,C.data(x,S)},refresh:function(){o=m.popup?e(m.popup):m.inline?T.next(m.selector.popup):!1,s=m.popup?o.offsetParent():m.inline?T.offsetParent():E},destroy:function(){g.debug("Destroying previous module"),o&&!m.preserve&&g.remove(),C.off(k).removeData(x)},event:{start:function(){var t=e.isPlainObject(m.delay)?m.delay.show:m.delay;clearTimeout(g.hideTimer),g.showTimer=setTimeout(function(){!g.is.hidden()||g.is.active()&&g.is.dropdown()||g.show()},t)},end:function(){var t=e.isPlainObject(m.delay)?m.delay.hide:m.delay;clearTimeout(g.showTimer),g.hideTimer=setTimeout(function(){g.is.visible()&&g.hide()},t)},resize:function(){g.is.visible()&&g.set.position()}},create:function(){var t=C.data(y.html)||m.html,n=C.data(y.variation)||m.variation,i=C.data(y.title)||m.title,r=C.data(y.content)||C.attr("title")||m.content;t||r||i?(g.debug("Creating pop-up html"),t||(t=m.templates.popup({title:i,content:r})),o=e("
").addClass(b.popup).addClass(n).html(t),n&&o.addClass(n),m.inline?(g.verbose("Inserting popup element inline",o),o.insertAfter(C)):(g.verbose("Appending popup element to body",o),o.appendTo(P)),m.hoverable&&g.bind.popup(),e.proxy(m.onCreate,o)()):0!==T.next(m.selector.popup).size()?(g.verbose("Pre-existing popup found, reverting to inline"),m.inline=!0,g.refresh(),m.hoverable&&g.bind.popup()):g.debug("No content specified skipping display",O)},toggle:function(){g.debug("Toggling pop-up"),g.is.hidden()?(g.debug("Popup is hidden, showing pop-up"),g.unbind.close(),g.hideAll(),g.show()):(g.debug("Popup is visible, hiding pop-up"),g.hide())},show:function(e){e=e||function(){},g.debug("Showing pop-up",m.transition),m.preserve||m.popup||g.refresh(),g.exists()||g.create(),o&&g.set.position()&&(g.save.conditions(),g.animate.show(e))},hide:function(e){e=e||function(){},C.removeClass(b.visible),g.unbind.close(),g.is.visible()&&(g.restore.conditions(),g.animate.hide(e))},hideAll:function(){e(h.popup).filter(":visible").popup("hide")},hideGracefully:function(t){t&&0===e(t.target).closest(h.popup).size()?(g.debug("Click occurred outside popup hiding popup"),g.hide()):g.debug("Click was inside popup, keeping popup open")},exists:function(){return o?m.inline||m.popup?0!==o.size():o.closest(P).size():!1},remove:function(){g.debug("Removing popup"),o.remove()},save:{conditions:function(){g.cache={title:C.attr("title")},g.cache.title&&C.removeAttr("title"),g.verbose("Saving original attributes",g.cache.title)}},restore:{conditions:function(){return g.cache&&g.cache.title&&(C.attr("title",g.cache.title),g.verbose("Restoring original attributes",g.cache.title)),!0}},animate:{show:function(t){t=t||function(){},m.transition&&e.fn.transition!==n&&C.transition("is supported")?o.transition({animation:m.transition+" in",queue:!1,duration:m.duration,onStart:function(){C.addClass(b.visible)},onComplete:function(){g.bind.close(),e.proxy(t,O)()}}):(C.addClass(b.visible),o.stop().fadeIn(m.duration,m.easing,function(){g.bind.close(),e.proxy(t,O)()})),e.proxy(m.onShow,O)()},hide:function(t){t=t||function(){},g.debug("Hiding pop-up"),m.transition&&e.fn.transition!==n&&C.transition("is supported")?o.transition({animation:m.transition+" out",queue:!1,duration:m.duration,onComplete:function(){g.reset(),t()}}):o.stop().fadeOut(m.duration,m.easing,function(){g.reset(),t()}),e.proxy(m.onHide,O)()}},get:{startEvent:function(){return"hover"==m.on?"mouseenter":"focus"==m.on?"focus":!1},endEvent:function(){return"hover"==m.on?"mouseleave":"focus"==m.on?"blur":!1},offstagePosition:function(){var n={top:e(t).scrollTop(),bottom:e(t).scrollTop()+e(t).height(),left:0,right:e(t).width()},i={width:o.width(),height:o.outerHeight(),offset:o.offset()},r={},s=[];return i.offset&&(r={top:i.offset.topn.bottom,right:i.offset.left+i.width>n.right,left:i.offset.left0?s.join(" "):!1},nextPosition:function(e){switch(e){case"top left":e="bottom left";break;case"bottom left":e="top right";break;case"top right":e="bottom right";break;case"bottom right":e="top center";break;case"top center":e="bottom center";break;case"bottom center":e="right center";break;case"right center":e="left center";break;case"left center":e="top center"}return e}},set:{position:function(i,r){var a,p,u=(e(t).width(),e(t).height(),T.outerWidth()),c=T.outerHeight(),l=o.outerWidth(),d=o.outerHeight(),f=s.outerWidth(),h=s.outerHeight(),w=m.distanceAway,k=T[0],x=m.inline?parseInt(t.getComputedStyle(k).getPropertyValue("margin-top"),10):0,P=m.inline?parseInt(t.getComputedStyle(k).getPropertyValue("margin-left"),10):0,A=m.inline||m.popup?T.position():T.offset();switch(i=i||C.data(y.position)||m.position,r=r||C.data(y.offset)||m.offset,m.inline&&(g.debug("Adding targets margin to calculation"),"left center"==i||"right center"==i?(r+=x,w+=-P):"top left"==i||"top center"==i||"top right"==i?(r+=P,w-=x):(r+=P,w+=x)),g.debug("Calculating popup positioning",i),i){case"top left":a={top:"auto",bottom:h-A.top+w,left:A.left+r,right:"auto"};break;case"top center":a={bottom:h-A.top+w,left:A.left+u/2-l/2+r,top:"auto",right:"auto"};break;case"top right":a={bottom:h-A.top+w,right:f-A.left-u-r,top:"auto",left:"auto"};break;case"left center":a={top:A.top+c/2-d/2+r,right:f-A.left+w,left:"auto",bottom:"auto"};break;case"right center":a={top:A.top+c/2-d/2+r,left:A.left+u+w,bottom:"auto",right:"auto"};break;case"bottom left":a={top:A.top+c+w,left:A.left+r,bottom:"auto",right:"auto"};break;case"bottom center":a={top:A.top+c+w,left:A.left+u/2-l/2+r,bottom:"auto",right:"auto"};break;case"bottom right":a={top:A.top+c+w,right:f-A.left-u-r,left:"auto",bottom:"auto"}}return a===n&&g.error(v.invalidPosition),o.css(a).removeClass(b.position).addClass(i).addClass(b.loading),p=g.get.offstagePosition(),p?(g.debug("Element is outside boundaries",p),z0&&(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,u=S;return o=o||f,i=O||i,"string"==typeof t&&u!==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(u[r])&&o!=s)u=u[r];else{if(u[r]!==n)return a=u[r],!1;if(!e.isPlainObject(u[i])||o==s)return u[i]!==n?(a=u[i],!1):!1;u=u[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}},d?(S===n&&g.initialize(),g.invoke(l)):(S!==n&&g.destroy(),g.initialize())}),r!==n?r:this},e.fn.popup.settings={name:"Popup",debug:!1,verbose:!1,performance:!1,namespace:"popup",onCreate:function(){},onRemove:function(){},onShow:function(){},onHide:function(){},variation:"",content:!1,html:!1,title:!1,on:"hover",closable:!0,context:"body",position:"top left",delay:{show:30,hide:0},target:!1,popup:!1,inline:!1,preserve:!0,hoverable:!1,duration:200,easing:"easeOutQuint",transition:"scale",distanceAway:0,offset:0,maxSearchDepth:10,error:{invalidPosition:"The position you specified is not a valid position",method:"The method you called is not defined.",recursion:"Popup attempted to reposition element to fit, but could not find an adequate position."},metadata:{content:"content",html:"html",offset:"offset",position:"position",title:"title",variation:"variation"},className:{active:"active",animating:"animating",dropdown:"dropdown",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 From 5f1206cbd65600f871c4a74d8b6f01fc4bb4f77d Mon Sep 17 00:00:00 2001 From: Pusher Robot Date: Fri, 7 Nov 2014 14:13:37 -0500 Subject: [PATCH 11/22] Updated component release from Semantic-UI (Automatic) --- composer.json | 4 ---- index.js | 47 ++++++++++++++++++++++++++--------------------- package.json | 11 ----------- popup.css | 7 ------- popup.js | 47 ++++++++++++++++++++++++++--------------------- popup.min.css | 6 +----- popup.min.js | 6 +----- 7 files changed, 54 insertions(+), 74 deletions(-) mode change 100644 => 100755 index.js mode change 100644 => 100755 popup.js mode change 100644 => 100755 popup.min.js diff --git a/composer.json b/composer.json index 20862c6..a74338c 100644 --- a/composer.json +++ b/composer.json @@ -14,9 +14,5 @@ "jquery": "x.x.x" }, "main": "popup.js", -<<<<<<< HEAD "version": "1.0.0-beta" -======= - "version": "1.0.0" ->>>>>>> 238b39192a7c5ba21da361555a86c8edd26e8d22 } \ No newline at end of file diff --git a/index.js b/index.js old mode 100644 new mode 100755 index 379cf2d..4f5f3b5 --- a/index.js +++ b/index.js @@ -238,7 +238,7 @@ module.exports = function(parameters) { }, show: function(callback) { - callback = callback || function(){}; + callback = $.isFunction(callback) ? callback : function(){}; module.debug('Showing pop-up', settings.transition); if(!settings.preserve && !settings.popup) { module.refresh(); @@ -254,7 +254,7 @@ module.exports = function(parameters) { hide: function(callback) { - callback = callback || function(){}; + callback = $.isFunction(callback) ? callback : function(){}; $module .removeClass(className.visible) ; @@ -315,6 +315,7 @@ module.exports = function(parameters) { }, restore: { conditions: function() { + element.blur(); if(module.cache && module.cache.title) { $module.attr('title', module.cache.title); module.verbose('Restoring original attributes', module.cache.title); @@ -324,27 +325,19 @@ module.exports = function(parameters) { }, animate: { show: function(callback) { - callback = callback || function(){}; + callback = $.isFunction(callback) ? callback : function(){}; if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) { $popup .transition({ animation : settings.transition + ' in', queue : false, duration : settings.duration, -<<<<<<< HEAD onStart : function() { -======= - start: function() { ->>>>>>> 238b39192a7c5ba21da361555a86c8edd26e8d22 $module .addClass(className.visible) ; }, -<<<<<<< HEAD onComplete : function() { -======= - complete : function() { ->>>>>>> 238b39192a7c5ba21da361555a86c8edd26e8d22 module.bind.close(); $.proxy(callback, element)(); } @@ -366,22 +359,15 @@ module.exports = function(parameters) { $.proxy(settings.onShow, element)(); }, hide: function(callback) { - callback = callback || function(){}; + callback = $.isFunction(callback) ? callback : function(){}; module.debug('Hiding pop-up'); if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) { $popup .transition({ -<<<<<<< HEAD animation : settings.transition + ' out', queue : false, duration : settings.duration, onComplete : function() { -======= - animation : settings.transition + ' out', - queue : false, - duration : settings.duration, - complete : function() { ->>>>>>> 238b39192a7c5ba21da361555a86c8edd26e8d22 module.reset(); callback(); } @@ -651,11 +637,21 @@ module.exports = function(parameters) { popup: function() { module.verbose('Allowing hover events on popup to prevent closing'); $popup - .on('mouseenter', module.event.start) - .on('mouseleave', module.event.end) + .on('mouseenter' + eventNamespace, module.event.start) + .on('mouseleave' + eventNamespace, module.event.end) ; }, close:function() { + if(settings.hideOnScroll) { + $document + .on('touchmove' + eventNamespace, module.hideGracefully) + .on('scroll' + eventNamespace, module.hideGracefully) + ; + $context + .on('touchmove' + eventNamespace, module.hideGracefully) + .on('scroll' + eventNamespace, module.hideGracefully) + ; + } if(settings.on == 'click' && settings.closable) { module.verbose('Binding popup close event to document'); $document @@ -670,6 +666,14 @@ module.exports = function(parameters) { unbind: { close: function() { + if(settings.hideOnScroll) { + $document + .off('scroll' + eventNamespace, module.hide) + ; + $context + .off('scroll' + eventNamespace, module.hide) + ; + } if(settings.on == 'click' && settings.closable) { module.verbose('Removing close event from document'); $document @@ -909,6 +913,7 @@ module.exports.settings = { on : 'hover', closable : true, + hideOnScroll : true, context : 'body', position : 'top left', diff --git a/package.json b/package.json index 7ed3fe4..a63034b 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,6 @@ { "name": "semantic-ui-popup", -<<<<<<< HEAD "version": "1.0.0-beta", -======= - "version": "1.0.0", ->>>>>>> 238b39192a7c5ba21da361555a86c8edd26e8d22 "title": "Semantic UI - Popup", "description": "Single component release of popup", "homepage": "http://www.semantic-ui.com", @@ -17,16 +13,9 @@ "bugs": { "url": "https://github.com/Semantic-Org/Semantic-UI/issues" }, -<<<<<<< HEAD "devDependencies": {}, "dependencies": { "jquery": "x.x.x" }, -======= - "dependencies": { - "jquery": "x.x.x" - }, - "devDependencies": {}, ->>>>>>> 238b39192a7c5ba21da361555a86c8edd26e8d22 "main": "index.js" } \ No newline at end of file diff --git a/popup.css b/popup.css index d109c4e..5cb7bb6 100755 --- a/popup.css +++ b/popup.css @@ -244,11 +244,7 @@ } .ui.inverted.popup:before { background-color: #1b1c1d; -<<<<<<< HEAD box-shadow: none !important; -======= - box-shadow: none; ->>>>>>> 238b39192a7c5ba21da361555a86c8edd26e8d22 } /*-------------- @@ -281,12 +277,9 @@ Theme Overrides *******************************/ -<<<<<<< HEAD /******************************* User Overrides *******************************/ -======= ->>>>>>> 238b39192a7c5ba21da361555a86c8edd26e8d22 diff --git a/popup.js b/popup.js old mode 100644 new mode 100755 index a57cfe6..a19d1ab --- a/popup.js +++ b/popup.js @@ -236,7 +236,7 @@ $.fn.popup = function(parameters) { }, show: function(callback) { - callback = callback || function(){}; + callback = $.isFunction(callback) ? callback : function(){}; module.debug('Showing pop-up', settings.transition); if(!settings.preserve && !settings.popup) { module.refresh(); @@ -252,7 +252,7 @@ $.fn.popup = function(parameters) { hide: function(callback) { - callback = callback || function(){}; + callback = $.isFunction(callback) ? callback : function(){}; $module .removeClass(className.visible) ; @@ -313,6 +313,7 @@ $.fn.popup = function(parameters) { }, restore: { conditions: function() { + element.blur(); if(module.cache && module.cache.title) { $module.attr('title', module.cache.title); module.verbose('Restoring original attributes', module.cache.title); @@ -322,27 +323,19 @@ $.fn.popup = function(parameters) { }, animate: { show: function(callback) { - callback = callback || function(){}; + callback = $.isFunction(callback) ? callback : function(){}; if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) { $popup .transition({ animation : settings.transition + ' in', queue : false, duration : settings.duration, -<<<<<<< HEAD onStart : function() { -======= - start: function() { ->>>>>>> 238b39192a7c5ba21da361555a86c8edd26e8d22 $module .addClass(className.visible) ; }, -<<<<<<< HEAD onComplete : function() { -======= - complete : function() { ->>>>>>> 238b39192a7c5ba21da361555a86c8edd26e8d22 module.bind.close(); $.proxy(callback, element)(); } @@ -364,22 +357,15 @@ $.fn.popup = function(parameters) { $.proxy(settings.onShow, element)(); }, hide: function(callback) { - callback = callback || function(){}; + callback = $.isFunction(callback) ? callback : function(){}; module.debug('Hiding pop-up'); if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) { $popup .transition({ -<<<<<<< HEAD animation : settings.transition + ' out', queue : false, duration : settings.duration, onComplete : function() { -======= - animation : settings.transition + ' out', - queue : false, - duration : settings.duration, - complete : function() { ->>>>>>> 238b39192a7c5ba21da361555a86c8edd26e8d22 module.reset(); callback(); } @@ -649,11 +635,21 @@ $.fn.popup = function(parameters) { popup: function() { module.verbose('Allowing hover events on popup to prevent closing'); $popup - .on('mouseenter', module.event.start) - .on('mouseleave', module.event.end) + .on('mouseenter' + eventNamespace, module.event.start) + .on('mouseleave' + eventNamespace, module.event.end) ; }, close:function() { + if(settings.hideOnScroll) { + $document + .on('touchmove' + eventNamespace, module.hideGracefully) + .on('scroll' + eventNamespace, module.hideGracefully) + ; + $context + .on('touchmove' + eventNamespace, module.hideGracefully) + .on('scroll' + eventNamespace, module.hideGracefully) + ; + } if(settings.on == 'click' && settings.closable) { module.verbose('Binding popup close event to document'); $document @@ -668,6 +664,14 @@ $.fn.popup = function(parameters) { unbind: { close: function() { + if(settings.hideOnScroll) { + $document + .off('scroll' + eventNamespace, module.hide) + ; + $context + .off('scroll' + eventNamespace, module.hide) + ; + } if(settings.on == 'click' && settings.closable) { module.verbose('Removing close event from document'); $document @@ -907,6 +911,7 @@ $.fn.popup.settings = { on : 'hover', closable : true, + hideOnScroll : true, context : 'body', position : 'top left', diff --git a/popup.min.css b/popup.min.css index 86657f0..044c446 100755 --- a/popup.min.css +++ b/popup.min.css @@ -8,8 +8,4 @@ * http://opensource.org/licenses/MIT * */ -<<<<<<< HEAD -.ui.popup{display:none;position:absolute;top:0;right:0;z-index:900;border:1px solid #ccc;max-width:250px;background-color:#fff;padding:.8em 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)}.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{margin:0}.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.wide.popup{width:350px;max-width:350px}.ui[class*="very wide"].popup{width:550px;max-width:550px}.ui.fluid.popup{width:100%;max-width:99999px}.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:9999px}.ui.small.popup{font-size:.8rem}.ui.popup{font-size:.875rem}.ui.large.popup{font-size:1rem}.ui.huge.popup{font-size:1.1rem} -======= -.ui.popup{display:none;position:absolute;top:0;right:0;z-index:900;border:1px solid #ccc;max-width:250px;background-color:#fff;padding:.8em 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)}.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{margin:0}.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.wide.popup{width:350px;max-width:350px}.ui[class*="very wide"].popup{width:550px;max-width:550px}.ui.fluid.popup{width:100%;max-width:99999px}.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}.ui.flowing.popup{max-width:9999px}.ui.small.popup{font-size:.8rem}.ui.popup{font-size:.875rem}.ui.large.popup{font-size:1rem}.ui.huge.popup{font-size:1.1rem} ->>>>>>> 238b39192a7c5ba21da361555a86c8edd26e8d22 +.ui.popup{display:none;position:absolute;top:0;right:0;z-index:900;border:1px solid #ccc;max-width:250px;background-color:#fff;padding:.8em 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)}.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{margin:0}.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.wide.popup{width:350px;max-width:350px}.ui[class*="very wide"].popup{width:550px;max-width:550px}.ui.fluid.popup{width:100%;max-width:99999px}.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:9999px}.ui.small.popup{font-size:.8rem}.ui.popup{font-size:.875rem}.ui.large.popup{font-size:1rem}.ui.huge.popup{font-size:1.1rem} \ No newline at end of file diff --git a/popup.min.js b/popup.min.js old mode 100644 new mode 100755 index e98c81b..f649bfd --- a/popup.min.js +++ b/popup.min.js @@ -8,8 +8,4 @@ * http://opensource.org/licenses/MIT * */ -<<<<<<< HEAD -!function(e,t,o,n){"use strict";e.fn.popup=function(i){var r,s=e(this),a=e(o),p=s.selector||"",u=("ontouchstart"in o.documentElement,(new Date).getTime()),c=[],l=arguments[0],d="string"==typeof l,f=[].slice.call(arguments,1);return s.each(function(){var o,s,g,m=e.isPlainObject(i)?e.extend(!0,{},e.fn.popup.settings,i):e.extend({},e.fn.popup.settings),h=m.selector,b=m.className,v=m.error,y=m.metadata,w=m.namespace,k="."+m.namespace,x="module-"+w,C=e(this),P=e(m.context),T=m.target?e(m.target):C,A=e(t),E=e("body"),z=0,O=this,S=C.data(x);g={initialize:function(){g.debug("Initializing module",C),g.refresh(),"click"==m.on?C.on("click"+k,g.toggle):g.get.startEvent()&&C.on(g.get.startEvent()+k,g.event.start).on(g.get.endEvent()+k,g.event.end),m.target&&g.debug("Target set to element",T),A.on("resize"+k,g.event.resize),g.exists()?m.hoverable&&g.bind.popup():g.create(),g.instantiate()},instantiate:function(){g.verbose("Storing instance of module",g),S=g,C.data(x,S)},refresh:function(){o=m.popup?e(m.popup):m.inline?T.next(m.selector.popup):!1,s=m.popup?o.offsetParent():m.inline?T.offsetParent():E},destroy:function(){g.debug("Destroying previous module"),o&&!m.preserve&&g.remove(),C.off(k).removeData(x)},event:{start:function(){var t=e.isPlainObject(m.delay)?m.delay.show:m.delay;clearTimeout(g.hideTimer),g.showTimer=setTimeout(function(){!g.is.hidden()||g.is.active()&&g.is.dropdown()||g.show()},t)},end:function(){var t=e.isPlainObject(m.delay)?m.delay.hide:m.delay;clearTimeout(g.showTimer),g.hideTimer=setTimeout(function(){g.is.visible()&&g.hide()},t)},resize:function(){g.is.visible()&&g.set.position()}},create:function(){var t=C.data(y.html)||m.html,n=C.data(y.variation)||m.variation,i=C.data(y.title)||m.title,r=C.data(y.content)||C.attr("title")||m.content;t||r||i?(g.debug("Creating pop-up html"),t||(t=m.templates.popup({title:i,content:r})),o=e("
").addClass(b.popup).addClass(n).html(t),n&&o.addClass(n),m.inline?(g.verbose("Inserting popup element inline",o),o.insertAfter(C)):(g.verbose("Appending popup element to body",o),o.appendTo(P)),m.hoverable&&g.bind.popup(),e.proxy(m.onCreate,o)()):0!==T.next(m.selector.popup).size()?(g.verbose("Pre-existing popup found, reverting to inline"),m.inline=!0,g.refresh(),m.hoverable&&g.bind.popup()):g.debug("No content specified skipping display",O)},toggle:function(){g.debug("Toggling pop-up"),g.is.hidden()?(g.debug("Popup is hidden, showing pop-up"),g.unbind.close(),g.hideAll(),g.show()):(g.debug("Popup is visible, hiding pop-up"),g.hide())},show:function(e){e=e||function(){},g.debug("Showing pop-up",m.transition),m.preserve||m.popup||g.refresh(),g.exists()||g.create(),o&&g.set.position()&&(g.save.conditions(),g.animate.show(e))},hide:function(e){e=e||function(){},C.removeClass(b.visible),g.unbind.close(),g.is.visible()&&(g.restore.conditions(),g.animate.hide(e))},hideAll:function(){e(h.popup).filter(":visible").popup("hide")},hideGracefully:function(t){t&&0===e(t.target).closest(h.popup).size()?(g.debug("Click occurred outside popup hiding popup"),g.hide()):g.debug("Click was inside popup, keeping popup open")},exists:function(){return o?m.inline||m.popup?0!==o.size():o.closest(P).size():!1},remove:function(){g.debug("Removing popup"),o.remove()},save:{conditions:function(){g.cache={title:C.attr("title")},g.cache.title&&C.removeAttr("title"),g.verbose("Saving original attributes",g.cache.title)}},restore:{conditions:function(){return g.cache&&g.cache.title&&(C.attr("title",g.cache.title),g.verbose("Restoring original attributes",g.cache.title)),!0}},animate:{show:function(t){t=t||function(){},m.transition&&e.fn.transition!==n&&C.transition("is supported")?o.transition({animation:m.transition+" in",queue:!1,duration:m.duration,onStart:function(){C.addClass(b.visible)},onComplete:function(){g.bind.close(),e.proxy(t,O)()}}):(C.addClass(b.visible),o.stop().fadeIn(m.duration,m.easing,function(){g.bind.close(),e.proxy(t,O)()})),e.proxy(m.onShow,O)()},hide:function(t){t=t||function(){},g.debug("Hiding pop-up"),m.transition&&e.fn.transition!==n&&C.transition("is supported")?o.transition({animation:m.transition+" out",queue:!1,duration:m.duration,onComplete:function(){g.reset(),t()}}):o.stop().fadeOut(m.duration,m.easing,function(){g.reset(),t()}),e.proxy(m.onHide,O)()}},get:{startEvent:function(){return"hover"==m.on?"mouseenter":"focus"==m.on?"focus":!1},endEvent:function(){return"hover"==m.on?"mouseleave":"focus"==m.on?"blur":!1},offstagePosition:function(){var n={top:e(t).scrollTop(),bottom:e(t).scrollTop()+e(t).height(),left:0,right:e(t).width()},i={width:o.width(),height:o.outerHeight(),offset:o.offset()},r={},s=[];return i.offset&&(r={top:i.offset.topn.bottom,right:i.offset.left+i.width>n.right,left:i.offset.left0?s.join(" "):!1},nextPosition:function(e){switch(e){case"top left":e="bottom left";break;case"bottom left":e="top right";break;case"top right":e="bottom right";break;case"bottom right":e="top center";break;case"top center":e="bottom center";break;case"bottom center":e="right center";break;case"right center":e="left center";break;case"left center":e="top center"}return e}},set:{position:function(i,r){var a,p,u=(e(t).width(),e(t).height(),T.outerWidth()),c=T.outerHeight(),l=o.outerWidth(),d=o.outerHeight(),f=s.outerWidth(),h=s.outerHeight(),w=m.distanceAway,k=T[0],x=m.inline?parseInt(t.getComputedStyle(k).getPropertyValue("margin-top"),10):0,P=m.inline?parseInt(t.getComputedStyle(k).getPropertyValue("margin-left"),10):0,A=m.inline||m.popup?T.position():T.offset();switch(i=i||C.data(y.position)||m.position,r=r||C.data(y.offset)||m.offset,m.inline&&(g.debug("Adding targets margin to calculation"),"left center"==i||"right center"==i?(r+=x,w+=-P):"top left"==i||"top center"==i||"top right"==i?(r+=P,w-=x):(r+=P,w+=x)),g.debug("Calculating popup positioning",i),i){case"top left":a={top:"auto",bottom:h-A.top+w,left:A.left+r,right:"auto"};break;case"top center":a={bottom:h-A.top+w,left:A.left+u/2-l/2+r,top:"auto",right:"auto"};break;case"top right":a={bottom:h-A.top+w,right:f-A.left-u-r,top:"auto",left:"auto"};break;case"left center":a={top:A.top+c/2-d/2+r,right:f-A.left+w,left:"auto",bottom:"auto"};break;case"right center":a={top:A.top+c/2-d/2+r,left:A.left+u+w,bottom:"auto",right:"auto"};break;case"bottom left":a={top:A.top+c+w,left:A.left+r,bottom:"auto",right:"auto"};break;case"bottom center":a={top:A.top+c+w,left:A.left+u/2-l/2+r,bottom:"auto",right:"auto"};break;case"bottom right":a={top:A.top+c+w,right:f-A.left-u-r,left:"auto",bottom:"auto"}}return a===n&&g.error(v.invalidPosition),o.css(a).removeClass(b.position).addClass(i).addClass(b.loading),p=g.get.offstagePosition(),p?(g.debug("Element is outside boundaries",p),z0&&(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,u=S;return o=o||f,i=O||i,"string"==typeof t&&u!==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(u[r])&&o!=s)u=u[r];else{if(u[r]!==n)return a=u[r],!1;if(!e.isPlainObject(u[i])||o==s)return u[i]!==n?(a=u[i],!1):!1;u=u[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}},d?(S===n&&g.initialize(),g.invoke(l)):(S!==n&&g.destroy(),g.initialize())}),r!==n?r:this},e.fn.popup.settings={name:"Popup",debug:!1,verbose:!1,performance:!1,namespace:"popup",onCreate:function(){},onRemove:function(){},onShow:function(){},onHide:function(){},variation:"",content:!1,html:!1,title:!1,on:"hover",closable:!0,context:"body",position:"top left",delay:{show:30,hide:0},target:!1,popup:!1,inline:!1,preserve:!0,hoverable:!1,duration:200,easing:"easeOutQuint",transition:"scale",distanceAway:0,offset:0,maxSearchDepth:10,error:{invalidPosition:"The position you specified is not a valid position",method:"The method you called is not defined.",recursion:"Popup attempted to reposition element to fit, but could not find an adequate position."},metadata:{content:"content",html:"html",offset:"offset",position:"position",title:"title",variation:"variation"},className:{active:"active",animating:"animating",dropdown:"dropdown",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); -======= -!function(e,t,o,n){"use strict";e.fn.popup=function(i){var r,s=e(this),a=e(o),p=s.selector||"",u=("ontouchstart"in o.documentElement,(new Date).getTime()),c=[],l=arguments[0],d="string"==typeof l,f=[].slice.call(arguments,1);return s.each(function(){var o,s,g,m=e.isPlainObject(i)?e.extend(!0,{},e.fn.popup.settings,i):e.extend({},e.fn.popup.settings),h=m.selector,b=m.className,v=m.error,y=m.metadata,w=m.namespace,k="."+m.namespace,x="module-"+w,C=e(this),P=e(m.context),T=m.target?e(m.target):C,A=e(t),E=e("body"),z=0,O=this,j=C.data(x);g={initialize:function(){g.debug("Initializing module",C),g.refresh(),"click"==m.on?C.on("click"+k,g.toggle):g.get.startEvent()&&C.on(g.get.startEvent()+k,g.event.start).on(g.get.endEvent()+k,g.event.end),m.target&&g.debug("Target set to element",T),A.on("resize"+k,g.event.resize),g.exists()?m.hoverable&&g.bind.popup():g.create(),g.instantiate()},instantiate:function(){g.verbose("Storing instance of module",g),j=g,C.data(x,j)},refresh:function(){o=m.popup?e(m.popup):m.inline?T.next(m.selector.popup):!1,s=m.popup?o.offsetParent():m.inline?T.offsetParent():E},destroy:function(){g.debug("Destroying previous module"),o&&!m.preserve&&g.remove(),C.off(k).removeData(x)},event:{start:function(){var t=e.isPlainObject(m.delay)?m.delay.show:m.delay;clearTimeout(g.hideTimer),g.showTimer=setTimeout(function(){!g.is.hidden()||g.is.active()&&g.is.dropdown()||g.show()},t)},end:function(){var t=e.isPlainObject(m.delay)?m.delay.hide:m.delay;clearTimeout(g.showTimer),g.hideTimer=setTimeout(function(){g.is.visible()&&g.hide()},t)},resize:function(){g.is.visible()&&g.set.position()}},create:function(){var t=C.data(y.html)||m.html,n=C.data(y.variation)||m.variation,i=C.data(y.title)||m.title,r=C.data(y.content)||C.attr("title")||m.content;t||r||i?(g.debug("Creating pop-up html"),t||(t=m.templates.popup({title:i,content:r})),o=e("
").addClass(b.popup).addClass(n).html(t),n&&o.addClass(n),m.inline?(g.verbose("Inserting popup element inline",o),o.insertAfter(C)):(g.verbose("Appending popup element to body",o),o.appendTo(P)),m.hoverable&&g.bind.popup(),e.proxy(m.onCreate,o)()):0!==T.next(m.selector.popup).size()?(g.verbose("Pre-existing popup found, reverting to inline"),m.inline=!0,g.refresh(),m.hoverable&&g.bind.popup()):g.debug("No content specified skipping display",O)},toggle:function(){g.debug("Toggling pop-up"),g.is.hidden()?(g.debug("Popup is hidden, showing pop-up"),g.unbind.close(),g.hideAll(),g.show()):(g.debug("Popup is visible, hiding pop-up"),g.hide())},show:function(e){e=e||function(){},g.debug("Showing pop-up",m.transition),m.preserve||m.popup||g.refresh(),g.exists()||g.create(),o&&g.set.position()&&(g.save.conditions(),g.animate.show(e))},hide:function(e){e=e||function(){},C.removeClass(b.visible),g.unbind.close(),g.is.visible()&&(g.restore.conditions(),g.animate.hide(e))},hideAll:function(){e(h.popup).filter(":visible").popup("hide")},hideGracefully:function(t){t&&0===e(t.target).closest(h.popup).size()?(g.debug("Click occurred outside popup hiding popup"),g.hide()):g.debug("Click was inside popup, keeping popup open")},exists:function(){return o?m.inline||m.popup?0!==o.size():o.closest(P).size():!1},remove:function(){g.debug("Removing popup"),o.remove()},save:{conditions:function(){g.cache={title:C.attr("title")},g.cache.title&&C.removeAttr("title"),g.verbose("Saving original attributes",g.cache.title)}},restore:{conditions:function(){return g.cache&&g.cache.title&&(C.attr("title",g.cache.title),g.verbose("Restoring original attributes",g.cache.title)),!0}},animate:{show:function(t){t=t||function(){},m.transition&&e.fn.transition!==n&&C.transition("is supported")?o.transition({animation:m.transition+" in",queue:!1,duration:m.duration,start:function(){C.addClass(b.visible)},complete:function(){g.bind.close(),e.proxy(t,O)()}}):(C.addClass(b.visible),o.stop().fadeIn(m.duration,m.easing,function(){g.bind.close(),e.proxy(t,O)()})),e.proxy(m.onShow,O)()},hide:function(t){t=t||function(){},g.debug("Hiding pop-up"),m.transition&&e.fn.transition!==n&&C.transition("is supported")?o.transition({animation:m.transition+" out",queue:!1,duration:m.duration,complete:function(){g.reset(),t()}}):o.stop().fadeOut(m.duration,m.easing,function(){g.reset(),t()}),e.proxy(m.onHide,O)()}},get:{startEvent:function(){return"hover"==m.on?"mouseenter":"focus"==m.on?"focus":!1},endEvent:function(){return"hover"==m.on?"mouseleave":"focus"==m.on?"blur":!1},offstagePosition:function(){var n={top:e(t).scrollTop(),bottom:e(t).scrollTop()+e(t).height(),left:0,right:e(t).width()},i={width:o.width(),height:o.outerHeight(),offset:o.offset()},r={},s=[];return i.offset&&(r={top:i.offset.topn.bottom,right:i.offset.left+i.width>n.right,left:i.offset.left0?s.join(" "):!1},nextPosition:function(e){switch(e){case"top left":e="bottom left";break;case"bottom left":e="top right";break;case"top right":e="bottom right";break;case"bottom right":e="top center";break;case"top center":e="bottom center";break;case"bottom center":e="right center";break;case"right center":e="left center";break;case"left center":e="top center"}return e}},set:{position:function(i,r){var a,p,u=(e(t).width(),e(t).height(),T.outerWidth()),c=T.outerHeight(),l=o.outerWidth(),d=o.outerHeight(),f=s.outerWidth(),h=s.outerHeight(),w=m.distanceAway,k=T[0],x=m.inline?parseInt(t.getComputedStyle(k).getPropertyValue("margin-top"),10):0,P=m.inline?parseInt(t.getComputedStyle(k).getPropertyValue("margin-left"),10):0,A=m.inline||m.popup?T.position():T.offset();switch(i=i||C.data(y.position)||m.position,r=r||C.data(y.offset)||m.offset,m.inline&&(g.debug("Adding targets margin to calculation"),"left center"==i||"right center"==i?(r+=x,w+=-P):"top left"==i||"top center"==i||"top right"==i?(r+=P,w-=x):(r+=P,w+=x)),g.debug("Calculating popup positioning",i),i){case"top left":a={top:"auto",bottom:h-A.top+w,left:A.left+r,right:"auto"};break;case"top center":a={bottom:h-A.top+w,left:A.left+u/2-l/2+r,top:"auto",right:"auto"};break;case"top right":a={bottom:h-A.top+w,right:f-A.left-u-r,top:"auto",left:"auto"};break;case"left center":a={top:A.top+c/2-d/2+r,right:f-A.left+w,left:"auto",bottom:"auto"};break;case"right center":a={top:A.top+c/2-d/2+r,left:A.left+u+w,bottom:"auto",right:"auto"};break;case"bottom left":a={top:A.top+c+w,left:A.left+r,bottom:"auto",right:"auto"};break;case"bottom center":a={top:A.top+c+w,left:A.left+u/2-l/2+r,bottom:"auto",right:"auto"};break;case"bottom right":a={top:A.top+c+w,right:f-A.left-u-r,left:"auto",bottom:"auto"}}return a===n&&g.error(v.invalidPosition),o.css(a).removeClass(b.position).addClass(i).addClass(b.loading),p=g.get.offstagePosition(),p?(g.debug("Element is outside boundaries",p),z0&&(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,u=j;return o=o||f,i=O||i,"string"==typeof t&&u!==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(u[r])&&o!=s)u=u[r];else{if(u[r]!==n)return a=u[r],!1;if(!e.isPlainObject(u[i])||o==s)return u[i]!==n?(a=u[i],!1):!1;u=u[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}},d?(j===n&&g.initialize(),g.invoke(l)):(j!==n&&g.destroy(),g.initialize())}),r!==n?r:this},e.fn.popup.settings={name:"Popup",debug:!1,verbose:!1,performance:!1,namespace:"popup",onCreate:function(){},onRemove:function(){},onShow:function(){},onHide:function(){},variation:"",content:!1,html:!1,title:!1,on:"hover",closable:!0,context:"body",position:"top left",delay:{show:30,hide:0},target:!1,popup:!1,inline:!1,preserve:!0,hoverable:!1,duration:200,easing:"easeOutQuint",transition:"scale",distanceAway:0,offset:0,maxSearchDepth:10,error:{invalidPosition:"The position you specified is not a valid position",method:"The method you called is not defined.",recursion:"Popup attempted to reposition element to fit, but could not find an adequate position."},metadata:{content:"content",html:"html",offset:"offset",position:"position",title:"title",variation:"variation"},className:{active:"active",animating:"animating",dropdown:"dropdown",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); ->>>>>>> 238b39192a7c5ba21da361555a86c8edd26e8d22 +!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,(new Date).getTime()),c=[],u=arguments[0],d="string"==typeof u,f=[].slice.call(arguments,1);return s.each(function(){var o,s,g,h=e.isPlainObject(i)?e.extend(!0,{},e.fn.popup.settings,i):e.extend({},e.fn.popup.settings),m=h.selector,b=h.className,v=h.error,y=h.metadata,w=h.namespace,k="."+h.namespace,x="module-"+w,C=e(this),P=e(h.context),T=h.target?e(h.target):C,O=e(t),S=e("body"),A=0,E=this,z=C.data(x);g={initialize:function(){g.debug("Initializing module",C),g.refresh(),"click"==h.on?C.on("click"+k,g.toggle):g.get.startEvent()&&C.on(g.get.startEvent()+k,g.event.start).on(g.get.endEvent()+k,g.event.end),h.target&&g.debug("Target set to element",T),O.on("resize"+k,g.event.resize),g.exists()?h.hoverable&&g.bind.popup():g.create(),g.instantiate()},instantiate:function(){g.verbose("Storing instance of module",g),z=g,C.data(x,z)},refresh:function(){o=h.popup?e(h.popup):h.inline?T.next(h.selector.popup):!1,s=h.popup?o.offsetParent():h.inline?T.offsetParent():S},destroy:function(){g.debug("Destroying previous module"),o&&!h.preserve&&g.remove(),C.off(k).removeData(x)},event:{start:function(){var t=e.isPlainObject(h.delay)?h.delay.show:h.delay;clearTimeout(g.hideTimer),g.showTimer=setTimeout(function(){!g.is.hidden()||g.is.active()&&g.is.dropdown()||g.show()},t)},end:function(){var t=e.isPlainObject(h.delay)?h.delay.hide:h.delay;clearTimeout(g.showTimer),g.hideTimer=setTimeout(function(){g.is.visible()&&g.hide()},t)},resize:function(){g.is.visible()&&g.set.position()}},create:function(){var t=C.data(y.html)||h.html,n=C.data(y.variation)||h.variation,i=C.data(y.title)||h.title,r=C.data(y.content)||C.attr("title")||h.content;t||r||i?(g.debug("Creating pop-up html"),t||(t=h.templates.popup({title:i,content:r})),o=e("
").addClass(b.popup).addClass(n).html(t),n&&o.addClass(n),h.inline?(g.verbose("Inserting popup element inline",o),o.insertAfter(C)):(g.verbose("Appending popup element to body",o),o.appendTo(P)),h.hoverable&&g.bind.popup(),e.proxy(h.onCreate,o)()):0!==T.next(h.selector.popup).size()?(g.verbose("Pre-existing popup found, reverting to inline"),h.inline=!0,g.refresh(),h.hoverable&&g.bind.popup()):g.debug("No content specified skipping display",E)},toggle:function(){g.debug("Toggling pop-up"),g.is.hidden()?(g.debug("Popup is hidden, showing pop-up"),g.unbind.close(),g.hideAll(),g.show()):(g.debug("Popup is visible, hiding pop-up"),g.hide())},show:function(t){t=e.isFunction(t)?t:function(){},g.debug("Showing pop-up",h.transition),h.preserve||h.popup||g.refresh(),g.exists()||g.create(),o&&g.set.position()&&(g.save.conditions(),g.animate.show(t))},hide:function(t){t=e.isFunction(t)?t:function(){},C.removeClass(b.visible),g.unbind.close(),g.is.visible()&&(g.restore.conditions(),g.animate.hide(t))},hideAll:function(){e(m.popup).filter(":visible").popup("hide")},hideGracefully:function(t){t&&0===e(t.target).closest(m.popup).size()?(g.debug("Click occurred outside popup hiding popup"),g.hide()):g.debug("Click was inside popup, keeping popup open")},exists:function(){return o?h.inline||h.popup?0!==o.size():o.closest(P).size():!1},remove:function(){g.debug("Removing popup"),o.remove()},save:{conditions:function(){g.cache={title:C.attr("title")},g.cache.title&&C.removeAttr("title"),g.verbose("Saving original attributes",g.cache.title)}},restore:{conditions:function(){return E.blur(),g.cache&&g.cache.title&&(C.attr("title",g.cache.title),g.verbose("Restoring original attributes",g.cache.title)),!0}},animate:{show:function(t){t=e.isFunction(t)?t:function(){},h.transition&&e.fn.transition!==n&&C.transition("is supported")?o.transition({animation:h.transition+" in",queue:!1,duration:h.duration,onStart:function(){C.addClass(b.visible)},onComplete:function(){g.bind.close(),e.proxy(t,E)()}}):(C.addClass(b.visible),o.stop().fadeIn(h.duration,h.easing,function(){g.bind.close(),e.proxy(t,E)()})),e.proxy(h.onShow,E)()},hide:function(t){t=e.isFunction(t)?t:function(){},g.debug("Hiding pop-up"),h.transition&&e.fn.transition!==n&&C.transition("is supported")?o.transition({animation:h.transition+" out",queue:!1,duration:h.duration,onComplete:function(){g.reset(),t()}}):o.stop().fadeOut(h.duration,h.easing,function(){g.reset(),t()}),e.proxy(h.onHide,E)()}},get:{startEvent:function(){return"hover"==h.on?"mouseenter":"focus"==h.on?"focus":!1},endEvent:function(){return"hover"==h.on?"mouseleave":"focus"==h.on?"blur":!1},offstagePosition:function(){var n={top:e(t).scrollTop(),bottom:e(t).scrollTop()+e(t).height(),left:0,right:e(t).width()},i={width:o.width(),height:o.outerHeight(),offset:o.offset()},r={},s=[];return i.offset&&(r={top:i.offset.topn.bottom,right:i.offset.left+i.width>n.right,left:i.offset.left0?s.join(" "):!1},nextPosition:function(e){switch(e){case"top left":e="bottom left";break;case"bottom left":e="top right";break;case"top right":e="bottom right";break;case"bottom right":e="top center";break;case"top center":e="bottom center";break;case"bottom center":e="right center";break;case"right center":e="left center";break;case"left center":e="top center"}return e}},set:{position:function(i,r){var a,p,l=(e(t).width(),e(t).height(),T.outerWidth()),c=T.outerHeight(),u=o.outerWidth(),d=o.outerHeight(),f=s.outerWidth(),m=s.outerHeight(),w=h.distanceAway,k=T[0],x=h.inline?parseInt(t.getComputedStyle(k).getPropertyValue("margin-top"),10):0,P=h.inline?parseInt(t.getComputedStyle(k).getPropertyValue("margin-left"),10):0,O=h.inline||h.popup?T.position():T.offset();switch(i=i||C.data(y.position)||h.position,r=r||C.data(y.offset)||h.offset,h.inline&&(g.debug("Adding targets margin to calculation"),"left center"==i||"right center"==i?(r+=x,w+=-P):"top left"==i||"top center"==i||"top right"==i?(r+=P,w-=x):(r+=P,w+=x)),g.debug("Calculating popup positioning",i),i){case"top left":a={top:"auto",bottom:m-O.top+w,left:O.left+r,right:"auto"};break;case"top center":a={bottom:m-O.top+w,left:O.left+l/2-u/2+r,top:"auto",right:"auto"};break;case"top right":a={bottom:m-O.top+w,right:f-O.left-l-r,top:"auto",left:"auto"};break;case"left center":a={top:O.top+c/2-d/2+r,right:f-O.left+w,left:"auto",bottom:"auto"};break;case"right center":a={top:O.top+c/2-d/2+r,left:O.left+l+w,bottom:"auto",right:"auto"};break;case"bottom left":a={top:O.top+c+w,left:O.left+r,bottom:"auto",right:"auto"};break;case"bottom center":a={top:O.top+c+w,left:O.left+l/2-u/2+r,bottom:"auto",right:"auto"};break;case"bottom right":a={top:O.top+c+w,right:f-O.left-l-r,left:"auto",bottom:"auto"}}return a===n&&g.error(v.invalidPosition),o.css(a).removeClass(b.position).addClass(i).addClass(b.loading),p=g.get.offstagePosition(),p?(g.debug("Element is outside boundaries",p),A0&&(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=z;return o=o||f,i=E||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}},d?(z===n&&g.initialize(),g.invoke(u)):(z!==n&&g.destroy(),g.initialize())}),r!==n?r:this},e.fn.popup.settings={name:"Popup",debug:!1,verbose:!1,performance:!1,namespace:"popup",onCreate:function(){},onRemove:function(){},onShow:function(){},onHide:function(){},variation:"",content:!1,html:!1,title:!1,on:"hover",closable:!0,hideOnScroll:!0,context:"body",position:"top left",delay:{show:30,hide:0},target:!1,popup:!1,inline:!1,preserve:!0,hoverable:!1,duration:200,easing:"easeOutQuint",transition:"scale",distanceAway:0,offset:0,maxSearchDepth:10,error:{invalidPosition:"The position you specified is not a valid position",method:"The method you called is not defined.",recursion:"Popup attempted to reposition element to fit, but could not find an adequate position."},metadata:{content:"content",html:"html",offset:"offset",position:"position",title:"title",variation:"variation"},className:{active:"active",animating:"animating",dropdown:"dropdown",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 From 4db476befacb14b6e2f9e5fc56783dae47ffcd90 Mon Sep 17 00:00:00 2001 From: Pusher Robot Date: Fri, 21 Nov 2014 11:37:16 -0500 Subject: [PATCH 12/22] Updated component release from Semantic-UI (Automatic) --- index.js | 137 ++++++++++++++++++++++++++++++-------------------- package.json | 2 +- popup.css | 12 ++++- popup.js | 137 ++++++++++++++++++++++++++++++-------------------- popup.min.css | 2 +- popup.min.js | 2 +- 6 files changed, 179 insertions(+), 113 deletions(-) diff --git a/index.js b/index.js index 4f5f3b5..0358178 100755 --- a/index.js +++ b/index.js @@ -113,18 +113,32 @@ module.exports = function(parameters) { ? $target.next(settings.selector.popup) : false ; - $offsetParent = (settings.popup) - ? $popup.offsetParent() - : (settings.inline) - ? $target.offsetParent() - : $body - ; + if(settings.popup) { + $popup.addClass(className.loading); + $offsetParent = $popup.offsetParent(); + $popup.removeClass(className.loading); + } + else { + $offsetParent = (settings.inline) + ? $target.offsetParent() + : $body + ; + } + if( $offsetParent.is('html') ) { + module.debug('Page is popups offset parent'); + $offsetParent = $body; + } + }, + + reposition: function() { + module.refresh(); + module.set.position(); }, destroy: function() { module.debug('Destroying previous module'); if($popup && !settings.preserve) { - module.remove(); + module.removePopup(); } $module .off(eventNamespace) @@ -207,7 +221,7 @@ module.exports = function(parameters) { if(settings.hoverable) { module.bind.popup(); } - $.proxy(settings.onCreate, $popup)(); + $.proxy(settings.onCreate, $popup)(element); } else if($target.next(settings.selector.popup).size() !== 0) { module.verbose('Pre-existing popup found, reverting to inline'); @@ -255,9 +269,7 @@ module.exports = function(parameters) { hide: function(callback) { callback = $.isFunction(callback) ? callback : function(){}; - $module - .removeClass(className.visible) - ; + module.remove.visible(); module.unbind.close(); if( module.is.visible() ) { module.restore.conditions(); @@ -295,10 +307,11 @@ module.exports = function(parameters) { } }, - remove: function() { + removePopup: function() { module.debug('Removing popup'); + $.proxy(settings.onRemove, $popup)(element); $popup - .remove() + .removePopup() ; }, @@ -327,27 +340,24 @@ module.exports = function(parameters) { 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, - duration : settings.duration, - onStart : function() { - $module - .addClass(className.visible) - ; - }, - onComplete : function() { + animation : settings.transition + ' in', + queue : false, + debug : settings.debug, + verbose : settings.verbose, + duration : settings.duration, + onComplete : function() { module.bind.close(); - $.proxy(callback, element)(); + $.proxy(callback, $popup)(element); + $.proxy(settings.onVisible, $popup)(element); } }) ; } else { - $module - .addClass(className.visible) - ; + module.set.visible(); $popup .stop() .fadeIn(settings.duration, settings.easing, function() { @@ -356,7 +366,7 @@ module.exports = function(parameters) { }) ; } - $.proxy(settings.onShow, element)(); + $.proxy(settings.onShow, $popup)(element); }, hide: function(callback) { callback = $.isFunction(callback) ? callback : function(){}; @@ -367,9 +377,12 @@ module.exports = function(parameters) { animation : settings.transition + ' out', queue : false, duration : settings.duration, + debug : settings.debug, + verbose : settings.verbose, onComplete : function() { module.reset(); - callback(); + $.proxy(callback, $popup)(element); + $.proxy(settings.onHidden, $popup)(element); } }) ; @@ -383,7 +396,7 @@ module.exports = function(parameters) { }) ; } - $.proxy(settings.onHide, element)(); + $.proxy(settings.onHide, $popup)(element); } }, @@ -406,8 +419,9 @@ module.exports = function(parameters) { } return false; }, - offstagePosition: function() { + offstagePosition: function(position) { var + position = position || false, boundary = { top : $(window).scrollTop(), bottom : $(window).scrollTop() + $(window).height(), @@ -416,21 +430,21 @@ module.exports = function(parameters) { }, popup = { width : $popup.width(), - height : $popup.outerHeight(), + height : $popup.height(), offset : $popup.offset() }, offstage = {}, offstagePositions = [] ; - if(popup.offset) { + if(popup.offset && position) { + module.verbose('Checking if outside viewable area', popup.offset); 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) + left : false }; } - module.verbose('Checking if outside viewable area', popup.offset); // return only boundaries that have been surpassed $.each(offstage, function(direction, isOffstage) { if(isOffstage) { @@ -492,10 +506,10 @@ module.exports = function(parameters) { targetElement = $target[0], - marginTop = (settings.inline) + marginTop = (settings.inline) ? parseInt( window.getComputedStyle(targetElement).getPropertyValue('margin-top'), 10) : 0, - marginLeft = (settings.inline) + marginLeft = (settings.inline) ? parseInt( window.getComputedStyle(targetElement).getPropertyValue('margin-left'), 10) : 0, @@ -508,7 +522,6 @@ module.exports = function(parameters) { ; position = position || $module.data(metadata.position) || settings.position; arrowOffset = arrowOffset || $module.data(metadata.offset) || settings.offset; - if(settings.inline) { module.debug('Adding targets margin to calculation'); if(position == 'left center' || position == 'right center') { @@ -602,7 +615,8 @@ module.exports = function(parameters) { .addClass(className.loading) ; // check if is offstage - offstagePosition = module.get.offstagePosition(); + offstagePosition = module.get.offstagePosition(position); + // recursively find new positioning if(offstagePosition) { module.debug('Element is outside boundaries', offstagePosition); @@ -616,7 +630,7 @@ module.exports = function(parameters) { ; } else { - module.error(error.recursion); + module.debug('Popup could not find a position onstage', $popup); searchDepth = 0; module.reset(); $popup.removeClass(className.loading); @@ -626,11 +640,23 @@ module.exports = function(parameters) { else { module.debug('Position is on stage', position); searchDepth = 0; + if( settings.setFluidWidth && $popup.hasClass(className.fluid) ) { + $popup.css('width', $offsetParent.width()); + } $popup.removeClass(className.loading); return true; } + }, + + visible: function() { + $module.addClass(className.visible); } + }, + remove: { + visible: function() { + $module.removeClass(className.visible); + } }, bind: { @@ -642,14 +668,14 @@ module.exports = function(parameters) { ; }, close:function() { - if(settings.hideOnScroll) { + if(settings.hideOnScroll === true || settings.hideOnScroll == 'auto' && settings.on != 'click') { $document - .on('touchmove' + eventNamespace, module.hideGracefully) - .on('scroll' + eventNamespace, module.hideGracefully) + .one('touchmove' + eventNamespace, module.hideGracefully) + .one('scroll' + eventNamespace, module.hideGracefully) ; $context - .on('touchmove' + eventNamespace, module.hideGracefully) - .on('scroll' + eventNamespace, module.hideGracefully) + .one('touchmove' + eventNamespace, module.hideGracefully) + .one('scroll' + eventNamespace, module.hideGracefully) ; } if(settings.on == 'click' && settings.closable) { @@ -666,7 +692,7 @@ module.exports = function(parameters) { unbind: { close: function() { - if(settings.hideOnScroll) { + if(settings.hideOnScroll === true || settings.hideOnScroll == 'auto' && settings.on != 'click') { $document .off('scroll' + eventNamespace, module.hide) ; @@ -702,9 +728,7 @@ module.exports = function(parameters) { }, reset: function() { - $popup - .removeClass(className.visible) - ; + module.remove.visible(); if(settings.preserve || settings.popup) { if($.fn.transition !== undefined) { $popup @@ -713,7 +737,7 @@ module.exports = function(parameters) { } } else { - module.remove(); + module.removePopup(); } }, @@ -897,14 +921,17 @@ module.exports.settings = { name : 'Popup', debug : false, - verbose : false, - performance : false, + verbose : true, + performance : true, namespace : 'popup', onCreate : function(){}, onRemove : function(){}, + onShow : function(){}, + onVisible : function(){}, onHide : function(){}, + onHidden : function(){}, variation : '', content : false, @@ -913,7 +940,7 @@ module.exports.settings = { on : 'hover', closable : true, - hideOnScroll : true, + hideOnScroll : 'auto', context : 'body', position : 'top left', @@ -922,6 +949,8 @@ module.exports.settings = { hide : 0 }, + setFluidWidth : true, + target : false, popup : false, inline : false, @@ -938,8 +967,7 @@ module.exports.settings = { error: { invalidPosition : 'The position you specified is not a valid position', - method : 'The method you called is not defined.', - recursion : 'Popup attempted to reposition element to fit, but could not find an adequate position.' + method : 'The method you called is not defined.' }, metadata: { @@ -955,6 +983,7 @@ module.exports.settings = { active : 'active', animating : 'animating', dropdown : 'dropdown', + fluid : 'fluid', loading : 'loading', popup : 'ui popup', position : 'top left center bottom right', diff --git a/package.json b/package.json index a63034b..3e0d748 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "license": "MIT", "repository": { "type": "git", - "url": "git@github.com:Semantic-Org/UI-Popup.git" + "url": "https://github.com/Semantic-Org/UI-Popup.git" }, "bugs": { "url": "https://github.com/Semantic-Org/Semantic-UI/issues" diff --git a/popup.css b/popup.css index 5cb7bb6..5df0053 100755 --- a/popup.css +++ b/popup.css @@ -204,6 +204,14 @@ *******************************/ +/*-------------- + Basic +---------------*/ + +.ui.basic.popup:before { + display: none; +} + /*-------------- Wide ---------------*/ @@ -223,7 +231,7 @@ .ui.fluid.popup { width: 100%; - max-width: 99999px; + max-width: none; } /*-------------- @@ -252,7 +260,7 @@ ---------------*/ .ui.flowing.popup { - max-width: 9999px; + max-width: none; } /*-------------- diff --git a/popup.js b/popup.js index a19d1ab..de3b80f 100755 --- a/popup.js +++ b/popup.js @@ -111,18 +111,32 @@ $.fn.popup = function(parameters) { ? $target.next(settings.selector.popup) : false ; - $offsetParent = (settings.popup) - ? $popup.offsetParent() - : (settings.inline) - ? $target.offsetParent() - : $body - ; + if(settings.popup) { + $popup.addClass(className.loading); + $offsetParent = $popup.offsetParent(); + $popup.removeClass(className.loading); + } + else { + $offsetParent = (settings.inline) + ? $target.offsetParent() + : $body + ; + } + if( $offsetParent.is('html') ) { + module.debug('Page is popups offset parent'); + $offsetParent = $body; + } + }, + + reposition: function() { + module.refresh(); + module.set.position(); }, destroy: function() { module.debug('Destroying previous module'); if($popup && !settings.preserve) { - module.remove(); + module.removePopup(); } $module .off(eventNamespace) @@ -205,7 +219,7 @@ $.fn.popup = function(parameters) { if(settings.hoverable) { module.bind.popup(); } - $.proxy(settings.onCreate, $popup)(); + $.proxy(settings.onCreate, $popup)(element); } else if($target.next(settings.selector.popup).size() !== 0) { module.verbose('Pre-existing popup found, reverting to inline'); @@ -253,9 +267,7 @@ $.fn.popup = function(parameters) { hide: function(callback) { callback = $.isFunction(callback) ? callback : function(){}; - $module - .removeClass(className.visible) - ; + module.remove.visible(); module.unbind.close(); if( module.is.visible() ) { module.restore.conditions(); @@ -293,10 +305,11 @@ $.fn.popup = function(parameters) { } }, - remove: function() { + removePopup: function() { module.debug('Removing popup'); + $.proxy(settings.onRemove, $popup)(element); $popup - .remove() + .removePopup() ; }, @@ -325,27 +338,24 @@ $.fn.popup = function(parameters) { 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, - duration : settings.duration, - onStart : function() { - $module - .addClass(className.visible) - ; - }, - onComplete : function() { + animation : settings.transition + ' in', + queue : false, + debug : settings.debug, + verbose : settings.verbose, + duration : settings.duration, + onComplete : function() { module.bind.close(); - $.proxy(callback, element)(); + $.proxy(callback, $popup)(element); + $.proxy(settings.onVisible, $popup)(element); } }) ; } else { - $module - .addClass(className.visible) - ; + module.set.visible(); $popup .stop() .fadeIn(settings.duration, settings.easing, function() { @@ -354,7 +364,7 @@ $.fn.popup = function(parameters) { }) ; } - $.proxy(settings.onShow, element)(); + $.proxy(settings.onShow, $popup)(element); }, hide: function(callback) { callback = $.isFunction(callback) ? callback : function(){}; @@ -365,9 +375,12 @@ $.fn.popup = function(parameters) { animation : settings.transition + ' out', queue : false, duration : settings.duration, + debug : settings.debug, + verbose : settings.verbose, onComplete : function() { module.reset(); - callback(); + $.proxy(callback, $popup)(element); + $.proxy(settings.onHidden, $popup)(element); } }) ; @@ -381,7 +394,7 @@ $.fn.popup = function(parameters) { }) ; } - $.proxy(settings.onHide, element)(); + $.proxy(settings.onHide, $popup)(element); } }, @@ -404,8 +417,9 @@ $.fn.popup = function(parameters) { } return false; }, - offstagePosition: function() { + offstagePosition: function(position) { var + position = position || false, boundary = { top : $(window).scrollTop(), bottom : $(window).scrollTop() + $(window).height(), @@ -414,21 +428,21 @@ $.fn.popup = function(parameters) { }, popup = { width : $popup.width(), - height : $popup.outerHeight(), + height : $popup.height(), offset : $popup.offset() }, offstage = {}, offstagePositions = [] ; - if(popup.offset) { + if(popup.offset && position) { + module.verbose('Checking if outside viewable area', popup.offset); 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) + left : false }; } - module.verbose('Checking if outside viewable area', popup.offset); // return only boundaries that have been surpassed $.each(offstage, function(direction, isOffstage) { if(isOffstage) { @@ -490,10 +504,10 @@ $.fn.popup = function(parameters) { targetElement = $target[0], - marginTop = (settings.inline) + marginTop = (settings.inline) ? parseInt( window.getComputedStyle(targetElement).getPropertyValue('margin-top'), 10) : 0, - marginLeft = (settings.inline) + marginLeft = (settings.inline) ? parseInt( window.getComputedStyle(targetElement).getPropertyValue('margin-left'), 10) : 0, @@ -506,7 +520,6 @@ $.fn.popup = function(parameters) { ; position = position || $module.data(metadata.position) || settings.position; arrowOffset = arrowOffset || $module.data(metadata.offset) || settings.offset; - if(settings.inline) { module.debug('Adding targets margin to calculation'); if(position == 'left center' || position == 'right center') { @@ -600,7 +613,8 @@ $.fn.popup = function(parameters) { .addClass(className.loading) ; // check if is offstage - offstagePosition = module.get.offstagePosition(); + offstagePosition = module.get.offstagePosition(position); + // recursively find new positioning if(offstagePosition) { module.debug('Element is outside boundaries', offstagePosition); @@ -614,7 +628,7 @@ $.fn.popup = function(parameters) { ; } else { - module.error(error.recursion); + module.debug('Popup could not find a position onstage', $popup); searchDepth = 0; module.reset(); $popup.removeClass(className.loading); @@ -624,11 +638,23 @@ $.fn.popup = function(parameters) { else { module.debug('Position is on stage', position); searchDepth = 0; + if( settings.setFluidWidth && $popup.hasClass(className.fluid) ) { + $popup.css('width', $offsetParent.width()); + } $popup.removeClass(className.loading); return true; } + }, + + visible: function() { + $module.addClass(className.visible); } + }, + remove: { + visible: function() { + $module.removeClass(className.visible); + } }, bind: { @@ -640,14 +666,14 @@ $.fn.popup = function(parameters) { ; }, close:function() { - if(settings.hideOnScroll) { + if(settings.hideOnScroll === true || settings.hideOnScroll == 'auto' && settings.on != 'click') { $document - .on('touchmove' + eventNamespace, module.hideGracefully) - .on('scroll' + eventNamespace, module.hideGracefully) + .one('touchmove' + eventNamespace, module.hideGracefully) + .one('scroll' + eventNamespace, module.hideGracefully) ; $context - .on('touchmove' + eventNamespace, module.hideGracefully) - .on('scroll' + eventNamespace, module.hideGracefully) + .one('touchmove' + eventNamespace, module.hideGracefully) + .one('scroll' + eventNamespace, module.hideGracefully) ; } if(settings.on == 'click' && settings.closable) { @@ -664,7 +690,7 @@ $.fn.popup = function(parameters) { unbind: { close: function() { - if(settings.hideOnScroll) { + if(settings.hideOnScroll === true || settings.hideOnScroll == 'auto' && settings.on != 'click') { $document .off('scroll' + eventNamespace, module.hide) ; @@ -700,9 +726,7 @@ $.fn.popup = function(parameters) { }, reset: function() { - $popup - .removeClass(className.visible) - ; + module.remove.visible(); if(settings.preserve || settings.popup) { if($.fn.transition !== undefined) { $popup @@ -711,7 +735,7 @@ $.fn.popup = function(parameters) { } } else { - module.remove(); + module.removePopup(); } }, @@ -895,14 +919,17 @@ $.fn.popup.settings = { name : 'Popup', debug : false, - verbose : false, - performance : false, + verbose : true, + performance : true, namespace : 'popup', onCreate : function(){}, onRemove : function(){}, + onShow : function(){}, + onVisible : function(){}, onHide : function(){}, + onHidden : function(){}, variation : '', content : false, @@ -911,7 +938,7 @@ $.fn.popup.settings = { on : 'hover', closable : true, - hideOnScroll : true, + hideOnScroll : 'auto', context : 'body', position : 'top left', @@ -920,6 +947,8 @@ $.fn.popup.settings = { hide : 0 }, + setFluidWidth : true, + target : false, popup : false, inline : false, @@ -936,8 +965,7 @@ $.fn.popup.settings = { error: { invalidPosition : 'The position you specified is not a valid position', - method : 'The method you called is not defined.', - recursion : 'Popup attempted to reposition element to fit, but could not find an adequate position.' + method : 'The method you called is not defined.' }, metadata: { @@ -953,6 +981,7 @@ $.fn.popup.settings = { active : 'active', animating : 'animating', dropdown : 'dropdown', + fluid : 'fluid', loading : 'loading', popup : 'ui popup', position : 'top left center bottom right', diff --git a/popup.min.css b/popup.min.css index 044c446..fec7079 100755 --- a/popup.min.css +++ b/popup.min.css @@ -8,4 +8,4 @@ * http://opensource.org/licenses/MIT * */ -.ui.popup{display:none;position:absolute;top:0;right:0;z-index:900;border:1px solid #ccc;max-width:250px;background-color:#fff;padding:.8em 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)}.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{margin:0}.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.wide.popup{width:350px;max-width:350px}.ui[class*="very wide"].popup{width:550px;max-width:550px}.ui.fluid.popup{width:100%;max-width:99999px}.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:9999px}.ui.small.popup{font-size:.8rem}.ui.popup{font-size:.875rem}.ui.large.popup{font-size:1rem}.ui.huge.popup{font-size:1.1rem} \ No newline at end of file +.ui.popup{display:none;position:absolute;top:0;right:0;z-index:900;border:1px solid #ccc;max-width:250px;background-color:#fff;padding:.8em 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)}.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{margin:0}.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{width:350px;max-width:350px}.ui[class*="very wide"].popup{width:550px;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:.8rem}.ui.popup{font-size:.875rem}.ui.large.popup{font-size:1rem}.ui.huge.popup{font-size:1.1rem} \ No newline at end of file diff --git a/popup.min.js b/popup.min.js index f649bfd..cb6efa7 100755 --- a/popup.min.js +++ b/popup.min.js @@ -8,4 +8,4 @@ * 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,(new Date).getTime()),c=[],u=arguments[0],d="string"==typeof u,f=[].slice.call(arguments,1);return s.each(function(){var o,s,g,h=e.isPlainObject(i)?e.extend(!0,{},e.fn.popup.settings,i):e.extend({},e.fn.popup.settings),m=h.selector,b=h.className,v=h.error,y=h.metadata,w=h.namespace,k="."+h.namespace,x="module-"+w,C=e(this),P=e(h.context),T=h.target?e(h.target):C,O=e(t),S=e("body"),A=0,E=this,z=C.data(x);g={initialize:function(){g.debug("Initializing module",C),g.refresh(),"click"==h.on?C.on("click"+k,g.toggle):g.get.startEvent()&&C.on(g.get.startEvent()+k,g.event.start).on(g.get.endEvent()+k,g.event.end),h.target&&g.debug("Target set to element",T),O.on("resize"+k,g.event.resize),g.exists()?h.hoverable&&g.bind.popup():g.create(),g.instantiate()},instantiate:function(){g.verbose("Storing instance of module",g),z=g,C.data(x,z)},refresh:function(){o=h.popup?e(h.popup):h.inline?T.next(h.selector.popup):!1,s=h.popup?o.offsetParent():h.inline?T.offsetParent():S},destroy:function(){g.debug("Destroying previous module"),o&&!h.preserve&&g.remove(),C.off(k).removeData(x)},event:{start:function(){var t=e.isPlainObject(h.delay)?h.delay.show:h.delay;clearTimeout(g.hideTimer),g.showTimer=setTimeout(function(){!g.is.hidden()||g.is.active()&&g.is.dropdown()||g.show()},t)},end:function(){var t=e.isPlainObject(h.delay)?h.delay.hide:h.delay;clearTimeout(g.showTimer),g.hideTimer=setTimeout(function(){g.is.visible()&&g.hide()},t)},resize:function(){g.is.visible()&&g.set.position()}},create:function(){var t=C.data(y.html)||h.html,n=C.data(y.variation)||h.variation,i=C.data(y.title)||h.title,r=C.data(y.content)||C.attr("title")||h.content;t||r||i?(g.debug("Creating pop-up html"),t||(t=h.templates.popup({title:i,content:r})),o=e("
").addClass(b.popup).addClass(n).html(t),n&&o.addClass(n),h.inline?(g.verbose("Inserting popup element inline",o),o.insertAfter(C)):(g.verbose("Appending popup element to body",o),o.appendTo(P)),h.hoverable&&g.bind.popup(),e.proxy(h.onCreate,o)()):0!==T.next(h.selector.popup).size()?(g.verbose("Pre-existing popup found, reverting to inline"),h.inline=!0,g.refresh(),h.hoverable&&g.bind.popup()):g.debug("No content specified skipping display",E)},toggle:function(){g.debug("Toggling pop-up"),g.is.hidden()?(g.debug("Popup is hidden, showing pop-up"),g.unbind.close(),g.hideAll(),g.show()):(g.debug("Popup is visible, hiding pop-up"),g.hide())},show:function(t){t=e.isFunction(t)?t:function(){},g.debug("Showing pop-up",h.transition),h.preserve||h.popup||g.refresh(),g.exists()||g.create(),o&&g.set.position()&&(g.save.conditions(),g.animate.show(t))},hide:function(t){t=e.isFunction(t)?t:function(){},C.removeClass(b.visible),g.unbind.close(),g.is.visible()&&(g.restore.conditions(),g.animate.hide(t))},hideAll:function(){e(m.popup).filter(":visible").popup("hide")},hideGracefully:function(t){t&&0===e(t.target).closest(m.popup).size()?(g.debug("Click occurred outside popup hiding popup"),g.hide()):g.debug("Click was inside popup, keeping popup open")},exists:function(){return o?h.inline||h.popup?0!==o.size():o.closest(P).size():!1},remove:function(){g.debug("Removing popup"),o.remove()},save:{conditions:function(){g.cache={title:C.attr("title")},g.cache.title&&C.removeAttr("title"),g.verbose("Saving original attributes",g.cache.title)}},restore:{conditions:function(){return E.blur(),g.cache&&g.cache.title&&(C.attr("title",g.cache.title),g.verbose("Restoring original attributes",g.cache.title)),!0}},animate:{show:function(t){t=e.isFunction(t)?t:function(){},h.transition&&e.fn.transition!==n&&C.transition("is supported")?o.transition({animation:h.transition+" in",queue:!1,duration:h.duration,onStart:function(){C.addClass(b.visible)},onComplete:function(){g.bind.close(),e.proxy(t,E)()}}):(C.addClass(b.visible),o.stop().fadeIn(h.duration,h.easing,function(){g.bind.close(),e.proxy(t,E)()})),e.proxy(h.onShow,E)()},hide:function(t){t=e.isFunction(t)?t:function(){},g.debug("Hiding pop-up"),h.transition&&e.fn.transition!==n&&C.transition("is supported")?o.transition({animation:h.transition+" out",queue:!1,duration:h.duration,onComplete:function(){g.reset(),t()}}):o.stop().fadeOut(h.duration,h.easing,function(){g.reset(),t()}),e.proxy(h.onHide,E)()}},get:{startEvent:function(){return"hover"==h.on?"mouseenter":"focus"==h.on?"focus":!1},endEvent:function(){return"hover"==h.on?"mouseleave":"focus"==h.on?"blur":!1},offstagePosition:function(){var n={top:e(t).scrollTop(),bottom:e(t).scrollTop()+e(t).height(),left:0,right:e(t).width()},i={width:o.width(),height:o.outerHeight(),offset:o.offset()},r={},s=[];return i.offset&&(r={top:i.offset.topn.bottom,right:i.offset.left+i.width>n.right,left:i.offset.left0?s.join(" "):!1},nextPosition:function(e){switch(e){case"top left":e="bottom left";break;case"bottom left":e="top right";break;case"top right":e="bottom right";break;case"bottom right":e="top center";break;case"top center":e="bottom center";break;case"bottom center":e="right center";break;case"right center":e="left center";break;case"left center":e="top center"}return e}},set:{position:function(i,r){var a,p,l=(e(t).width(),e(t).height(),T.outerWidth()),c=T.outerHeight(),u=o.outerWidth(),d=o.outerHeight(),f=s.outerWidth(),m=s.outerHeight(),w=h.distanceAway,k=T[0],x=h.inline?parseInt(t.getComputedStyle(k).getPropertyValue("margin-top"),10):0,P=h.inline?parseInt(t.getComputedStyle(k).getPropertyValue("margin-left"),10):0,O=h.inline||h.popup?T.position():T.offset();switch(i=i||C.data(y.position)||h.position,r=r||C.data(y.offset)||h.offset,h.inline&&(g.debug("Adding targets margin to calculation"),"left center"==i||"right center"==i?(r+=x,w+=-P):"top left"==i||"top center"==i||"top right"==i?(r+=P,w-=x):(r+=P,w+=x)),g.debug("Calculating popup positioning",i),i){case"top left":a={top:"auto",bottom:m-O.top+w,left:O.left+r,right:"auto"};break;case"top center":a={bottom:m-O.top+w,left:O.left+l/2-u/2+r,top:"auto",right:"auto"};break;case"top right":a={bottom:m-O.top+w,right:f-O.left-l-r,top:"auto",left:"auto"};break;case"left center":a={top:O.top+c/2-d/2+r,right:f-O.left+w,left:"auto",bottom:"auto"};break;case"right center":a={top:O.top+c/2-d/2+r,left:O.left+l+w,bottom:"auto",right:"auto"};break;case"bottom left":a={top:O.top+c+w,left:O.left+r,bottom:"auto",right:"auto"};break;case"bottom center":a={top:O.top+c+w,left:O.left+l/2-u/2+r,bottom:"auto",right:"auto"};break;case"bottom right":a={top:O.top+c+w,right:f-O.left-l-r,left:"auto",bottom:"auto"}}return a===n&&g.error(v.invalidPosition),o.css(a).removeClass(b.position).addClass(i).addClass(b.loading),p=g.get.offstagePosition(),p?(g.debug("Element is outside boundaries",p),A0&&(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=z;return o=o||f,i=E||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}},d?(z===n&&g.initialize(),g.invoke(u)):(z!==n&&g.destroy(),g.initialize())}),r!==n?r:this},e.fn.popup.settings={name:"Popup",debug:!1,verbose:!1,performance:!1,namespace:"popup",onCreate:function(){},onRemove:function(){},onShow:function(){},onHide:function(){},variation:"",content:!1,html:!1,title:!1,on:"hover",closable:!0,hideOnScroll:!0,context:"body",position:"top left",delay:{show:30,hide:0},target:!1,popup:!1,inline:!1,preserve:!0,hoverable:!1,duration:200,easing:"easeOutQuint",transition:"scale",distanceAway:0,offset:0,maxSearchDepth:10,error:{invalidPosition:"The position you specified is not a valid position",method:"The method you called is not defined.",recursion:"Popup attempted to reposition element to fit, but could not find an adequate position."},metadata:{content:"content",html:"html",offset:"offset",position:"position",title:"title",variation:"variation"},className:{active:"active",animating:"animating",dropdown:"dropdown",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(e,t,o,n){"use strict";e.fn.popup=function(i){var s,r=e(this),a=e(o),l=r.selector||"",p=("ontouchstart"in o.documentElement,(new Date).getTime()),u=[],c=arguments[0],d="string"==typeof c,f=[].slice.call(arguments,1);return r.each(function(){var o,r,g,h=e.isPlainObject(i)?e.extend(!0,{},e.fn.popup.settings,i):e.extend({},e.fn.popup.settings),m=h.selector,b=h.className,v=h.error,y=h.metadata,w=h.namespace,x="."+h.namespace,k="module-"+w,C=e(this),P=e(h.context),T=h.target?e(h.target):C,O=e(t),S=e("body"),A=0,E=this,z=C.data(k);g={initialize:function(){g.debug("Initializing module",C),g.refresh(),"click"==h.on?C.on("click"+x,g.toggle):g.get.startEvent()&&C.on(g.get.startEvent()+x,g.event.start).on(g.get.endEvent()+x,g.event.end),h.target&&g.debug("Target set to element",T),O.on("resize"+x,g.event.resize),g.exists()?h.hoverable&&g.bind.popup():g.create(),g.instantiate()},instantiate:function(){g.verbose("Storing instance of module",g),z=g,C.data(k,z)},refresh:function(){o=h.popup?e(h.popup):h.inline?T.next(h.selector.popup):!1,h.popup?(o.addClass(b.loading),r=o.offsetParent(),o.removeClass(b.loading)):r=h.inline?T.offsetParent():S,r.is("html")&&(g.debug("Page is popups offset parent"),r=S)},reposition:function(){g.refresh(),g.set.position()},destroy:function(){g.debug("Destroying previous module"),o&&!h.preserve&&g.removePopup(),C.off(x).removeData(k)},event:{start:function(){var t=e.isPlainObject(h.delay)?h.delay.show:h.delay;clearTimeout(g.hideTimer),g.showTimer=setTimeout(function(){!g.is.hidden()||g.is.active()&&g.is.dropdown()||g.show()},t)},end:function(){var t=e.isPlainObject(h.delay)?h.delay.hide:h.delay;clearTimeout(g.showTimer),g.hideTimer=setTimeout(function(){g.is.visible()&&g.hide()},t)},resize:function(){g.is.visible()&&g.set.position()}},create:function(){var t=C.data(y.html)||h.html,n=C.data(y.variation)||h.variation,i=C.data(y.title)||h.title,s=C.data(y.content)||C.attr("title")||h.content;t||s||i?(g.debug("Creating pop-up html"),t||(t=h.templates.popup({title:i,content:s})),o=e("
").addClass(b.popup).addClass(n).html(t),n&&o.addClass(n),h.inline?(g.verbose("Inserting popup element inline",o),o.insertAfter(C)):(g.verbose("Appending popup element to body",o),o.appendTo(P)),h.hoverable&&g.bind.popup(),e.proxy(h.onCreate,o)(E)):0!==T.next(h.selector.popup).size()?(g.verbose("Pre-existing popup found, reverting to inline"),h.inline=!0,g.refresh(),h.hoverable&&g.bind.popup()):g.debug("No content specified skipping display",E)},toggle:function(){g.debug("Toggling pop-up"),g.is.hidden()?(g.debug("Popup is hidden, showing pop-up"),g.unbind.close(),g.hideAll(),g.show()):(g.debug("Popup is visible, hiding pop-up"),g.hide())},show:function(t){t=e.isFunction(t)?t:function(){},g.debug("Showing pop-up",h.transition),h.preserve||h.popup||g.refresh(),g.exists()||g.create(),o&&g.set.position()&&(g.save.conditions(),g.animate.show(t))},hide:function(t){t=e.isFunction(t)?t:function(){},g.remove.visible(),g.unbind.close(),g.is.visible()&&(g.restore.conditions(),g.animate.hide(t))},hideAll:function(){e(m.popup).filter(":visible").popup("hide")},hideGracefully:function(t){t&&0===e(t.target).closest(m.popup).size()?(g.debug("Click occurred outside popup hiding popup"),g.hide()):g.debug("Click was inside popup, keeping popup open")},exists:function(){return o?h.inline||h.popup?0!==o.size():o.closest(P).size():!1},removePopup:function(){g.debug("Removing popup"),e.proxy(h.onRemove,o)(E),o.removePopup()},save:{conditions:function(){g.cache={title:C.attr("title")},g.cache.title&&C.removeAttr("title"),g.verbose("Saving original attributes",g.cache.title)}},restore:{conditions:function(){return E.blur(),g.cache&&g.cache.title&&(C.attr("title",g.cache.title),g.verbose("Restoring original attributes",g.cache.title)),!0}},animate:{show:function(t){t=e.isFunction(t)?t:function(){},h.transition&&e.fn.transition!==n&&C.transition("is supported")?(g.set.visible(),o.transition({animation:h.transition+" in",queue:!1,debug:h.debug,verbose:h.verbose,duration:h.duration,onComplete:function(){g.bind.close(),e.proxy(t,o)(E),e.proxy(h.onVisible,o)(E)}})):(g.set.visible(),o.stop().fadeIn(h.duration,h.easing,function(){g.bind.close(),e.proxy(t,E)()})),e.proxy(h.onShow,o)(E)},hide:function(t){t=e.isFunction(t)?t:function(){},g.debug("Hiding pop-up"),h.transition&&e.fn.transition!==n&&C.transition("is supported")?o.transition({animation:h.transition+" out",queue:!1,duration:h.duration,debug:h.debug,verbose:h.verbose,onComplete:function(){g.reset(),e.proxy(t,o)(E),e.proxy(h.onHidden,o)(E)}}):o.stop().fadeOut(h.duration,h.easing,function(){g.reset(),t()}),e.proxy(h.onHide,o)(E)}},get:{startEvent:function(){return"hover"==h.on?"mouseenter":"focus"==h.on?"focus":!1},endEvent:function(){return"hover"==h.on?"mouseleave":"focus"==h.on?"blur":!1},offstagePosition:function(n){var n=n||!1,i={top:e(t).scrollTop(),bottom:e(t).scrollTop()+e(t).height(),left:0,right:e(t).width()},s={width:o.width(),height:o.height(),offset:o.offset()},r={},a=[];return s.offset&&n&&(g.verbose("Checking if outside viewable area",s.offset),r={top:s.offset.topi.bottom,right:s.offset.left+s.width>i.right,left:!1}),e.each(r,function(e,t){t&&a.push(e)}),a.length>0?a.join(" "):!1},nextPosition:function(e){switch(e){case"top left":e="bottom left";break;case"bottom left":e="top right";break;case"top right":e="bottom right";break;case"bottom right":e="top center";break;case"top center":e="bottom center";break;case"bottom center":e="right center";break;case"right center":e="left center";break;case"left center":e="top center"}return e}},set:{position:function(i,s){var a,l,p=(e(t).width(),e(t).height(),T.outerWidth()),u=T.outerHeight(),c=o.outerWidth(),d=o.outerHeight(),f=r.outerWidth(),m=r.outerHeight(),w=h.distanceAway,x=T[0],k=h.inline?parseInt(t.getComputedStyle(x).getPropertyValue("margin-top"),10):0,P=h.inline?parseInt(t.getComputedStyle(x).getPropertyValue("margin-left"),10):0,O=h.inline||h.popup?T.position():T.offset();switch(i=i||C.data(y.position)||h.position,s=s||C.data(y.offset)||h.offset,h.inline&&(g.debug("Adding targets margin to calculation"),"left center"==i||"right center"==i?(s+=k,w+=-P):"top left"==i||"top center"==i||"top right"==i?(s+=P,w-=k):(s+=P,w+=k)),g.debug("Calculating popup positioning",i),i){case"top left":a={top:"auto",bottom:m-O.top+w,left:O.left+s,right:"auto"};break;case"top center":a={bottom:m-O.top+w,left:O.left+p/2-c/2+s,top:"auto",right:"auto"};break;case"top right":a={bottom:m-O.top+w,right:f-O.left-p-s,top:"auto",left:"auto"};break;case"left center":a={top:O.top+u/2-d/2+s,right:f-O.left+w,left:"auto",bottom:"auto"};break;case"right center":a={top:O.top+u/2-d/2+s,left:O.left+p+w,bottom:"auto",right:"auto"};break;case"bottom left":a={top:O.top+u+w,left:O.left+s,bottom:"auto",right:"auto"};break;case"bottom center":a={top:O.top+u+w,left:O.left+p/2-c/2+s,bottom:"auto",right:"auto"};break;case"bottom right":a={top:O.top+u+w,right:f-O.left-p-s,left:"auto",bottom:"auto"}}return a===n&&g.error(v.invalidPosition),o.css(a).removeClass(b.position).addClass(i).addClass(b.loading),l=g.get.offstagePosition(i),l?(g.debug("Element is outside boundaries",l),A0&&(console.groupCollapsed(t),console.table?console.table(u):e.each(u,function(e,t){console.log(t.Name+": "+t["Execution Time"]+"ms")}),console.groupEnd()),u=[]}},invoke:function(t,o,i){var r,a,l,p=z;return o=o||f,i=E||i,"string"==typeof t&&p!==n&&(t=t.split(/[\. ]/),r=t.length-1,e.each(t,function(o,i){var s=o!=r?i+t[o+1].charAt(0).toUpperCase()+t[o+1].slice(1):t;if(e.isPlainObject(p[s])&&o!=r)p=p[s];else{if(p[s]!==n)return a=p[s],!1;if(!e.isPlainObject(p[i])||o==r)return p[i]!==n?(a=p[i],!1):!1;p=p[i]}})),e.isFunction(a)?l=a.apply(i,o):a!==n&&(l=a),e.isArray(s)?s.push(l):s!==n?s=[s,l]:l!==n&&(s=l),a}},d?(z===n&&g.initialize(),g.invoke(c)):(z!==n&&g.destroy(),g.initialize())}),s!==n?s: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",context:"body",position:"top left",delay:{show:30,hide:0},setFluidWidth:!0,target:!1,popup:!1,inline:!1,preserve:!0,hoverable:!1,duration:200,easing:"easeOutQuint",transition:"scale",distanceAway:0,offset:0,maxSearchDepth:10,error:{invalidPosition:"The position you specified is not a valid position",method:"The method you called is not defined."},metadata:{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 From e2f8062acf49aa5d83f011412ab483f5d5db2445 Mon Sep 17 00:00:00 2001 From: Pusher Robot Date: Mon, 24 Nov 2014 01:16:28 -0500 Subject: [PATCH 13/22] Updated component release from Semantic-UI (Automatic) --- RELEASE-NOTES.md | 2 +- index.js | 24 ++++++++++++++---------- popup.js | 24 ++++++++++++++---------- popup.min.js | 2 +- 4 files changed, 30 insertions(+), 22 deletions(-) mode change 100644 => 100755 RELEASE-NOTES.md diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md old mode 100644 new mode 100755 index 020ae0c..68c5a92 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -1,4 +1,4 @@ -### Version 1.0.0 - XX XX, 2014 +### Version 1.0.0 - November 24, 2014 - **Popup** - Popup can now allow itself not to be closed when hovered over - **Popup** - A popup element can now be specified on initialization. diff --git a/index.js b/index.js index 0358178..e71bb3d 100755 --- a/index.js +++ b/index.js @@ -107,12 +107,14 @@ module.exports = function(parameters) { }, refresh: function() { - $popup = (settings.popup) - ? $(settings.popup) - : (settings.inline) - ? $target.next(settings.selector.popup) - : false - ; + if(settings.popup) { + $popup = $(settings.popup); + } + else { + if(settings.inline) { + $popup = $target.next(settings.selector.popup); + } + } if(settings.popup) { $popup.addClass(className.loading); $offsetParent = $popup.offsetParent(); @@ -662,10 +664,12 @@ module.exports = function(parameters) { bind: { popup: function() { module.verbose('Allowing hover events on popup to prevent closing'); - $popup - .on('mouseenter' + eventNamespace, module.event.start) - .on('mouseleave' + eventNamespace, module.event.end) - ; + if($popup && $popup.size() > 0) { + $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') { diff --git a/popup.js b/popup.js index de3b80f..383837e 100755 --- a/popup.js +++ b/popup.js @@ -105,12 +105,14 @@ $.fn.popup = function(parameters) { }, refresh: function() { - $popup = (settings.popup) - ? $(settings.popup) - : (settings.inline) - ? $target.next(settings.selector.popup) - : false - ; + if(settings.popup) { + $popup = $(settings.popup); + } + else { + if(settings.inline) { + $popup = $target.next(settings.selector.popup); + } + } if(settings.popup) { $popup.addClass(className.loading); $offsetParent = $popup.offsetParent(); @@ -660,10 +662,12 @@ $.fn.popup = function(parameters) { bind: { popup: function() { module.verbose('Allowing hover events on popup to prevent closing'); - $popup - .on('mouseenter' + eventNamespace, module.event.start) - .on('mouseleave' + eventNamespace, module.event.end) - ; + if($popup && $popup.size() > 0) { + $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') { diff --git a/popup.min.js b/popup.min.js index cb6efa7..a4134f1 100755 --- a/popup.min.js +++ b/popup.min.js @@ -8,4 +8,4 @@ * http://opensource.org/licenses/MIT * */ -!function(e,t,o,n){"use strict";e.fn.popup=function(i){var s,r=e(this),a=e(o),l=r.selector||"",p=("ontouchstart"in o.documentElement,(new Date).getTime()),u=[],c=arguments[0],d="string"==typeof c,f=[].slice.call(arguments,1);return r.each(function(){var o,r,g,h=e.isPlainObject(i)?e.extend(!0,{},e.fn.popup.settings,i):e.extend({},e.fn.popup.settings),m=h.selector,b=h.className,v=h.error,y=h.metadata,w=h.namespace,x="."+h.namespace,k="module-"+w,C=e(this),P=e(h.context),T=h.target?e(h.target):C,O=e(t),S=e("body"),A=0,E=this,z=C.data(k);g={initialize:function(){g.debug("Initializing module",C),g.refresh(),"click"==h.on?C.on("click"+x,g.toggle):g.get.startEvent()&&C.on(g.get.startEvent()+x,g.event.start).on(g.get.endEvent()+x,g.event.end),h.target&&g.debug("Target set to element",T),O.on("resize"+x,g.event.resize),g.exists()?h.hoverable&&g.bind.popup():g.create(),g.instantiate()},instantiate:function(){g.verbose("Storing instance of module",g),z=g,C.data(k,z)},refresh:function(){o=h.popup?e(h.popup):h.inline?T.next(h.selector.popup):!1,h.popup?(o.addClass(b.loading),r=o.offsetParent(),o.removeClass(b.loading)):r=h.inline?T.offsetParent():S,r.is("html")&&(g.debug("Page is popups offset parent"),r=S)},reposition:function(){g.refresh(),g.set.position()},destroy:function(){g.debug("Destroying previous module"),o&&!h.preserve&&g.removePopup(),C.off(x).removeData(k)},event:{start:function(){var t=e.isPlainObject(h.delay)?h.delay.show:h.delay;clearTimeout(g.hideTimer),g.showTimer=setTimeout(function(){!g.is.hidden()||g.is.active()&&g.is.dropdown()||g.show()},t)},end:function(){var t=e.isPlainObject(h.delay)?h.delay.hide:h.delay;clearTimeout(g.showTimer),g.hideTimer=setTimeout(function(){g.is.visible()&&g.hide()},t)},resize:function(){g.is.visible()&&g.set.position()}},create:function(){var t=C.data(y.html)||h.html,n=C.data(y.variation)||h.variation,i=C.data(y.title)||h.title,s=C.data(y.content)||C.attr("title")||h.content;t||s||i?(g.debug("Creating pop-up html"),t||(t=h.templates.popup({title:i,content:s})),o=e("
").addClass(b.popup).addClass(n).html(t),n&&o.addClass(n),h.inline?(g.verbose("Inserting popup element inline",o),o.insertAfter(C)):(g.verbose("Appending popup element to body",o),o.appendTo(P)),h.hoverable&&g.bind.popup(),e.proxy(h.onCreate,o)(E)):0!==T.next(h.selector.popup).size()?(g.verbose("Pre-existing popup found, reverting to inline"),h.inline=!0,g.refresh(),h.hoverable&&g.bind.popup()):g.debug("No content specified skipping display",E)},toggle:function(){g.debug("Toggling pop-up"),g.is.hidden()?(g.debug("Popup is hidden, showing pop-up"),g.unbind.close(),g.hideAll(),g.show()):(g.debug("Popup is visible, hiding pop-up"),g.hide())},show:function(t){t=e.isFunction(t)?t:function(){},g.debug("Showing pop-up",h.transition),h.preserve||h.popup||g.refresh(),g.exists()||g.create(),o&&g.set.position()&&(g.save.conditions(),g.animate.show(t))},hide:function(t){t=e.isFunction(t)?t:function(){},g.remove.visible(),g.unbind.close(),g.is.visible()&&(g.restore.conditions(),g.animate.hide(t))},hideAll:function(){e(m.popup).filter(":visible").popup("hide")},hideGracefully:function(t){t&&0===e(t.target).closest(m.popup).size()?(g.debug("Click occurred outside popup hiding popup"),g.hide()):g.debug("Click was inside popup, keeping popup open")},exists:function(){return o?h.inline||h.popup?0!==o.size():o.closest(P).size():!1},removePopup:function(){g.debug("Removing popup"),e.proxy(h.onRemove,o)(E),o.removePopup()},save:{conditions:function(){g.cache={title:C.attr("title")},g.cache.title&&C.removeAttr("title"),g.verbose("Saving original attributes",g.cache.title)}},restore:{conditions:function(){return E.blur(),g.cache&&g.cache.title&&(C.attr("title",g.cache.title),g.verbose("Restoring original attributes",g.cache.title)),!0}},animate:{show:function(t){t=e.isFunction(t)?t:function(){},h.transition&&e.fn.transition!==n&&C.transition("is supported")?(g.set.visible(),o.transition({animation:h.transition+" in",queue:!1,debug:h.debug,verbose:h.verbose,duration:h.duration,onComplete:function(){g.bind.close(),e.proxy(t,o)(E),e.proxy(h.onVisible,o)(E)}})):(g.set.visible(),o.stop().fadeIn(h.duration,h.easing,function(){g.bind.close(),e.proxy(t,E)()})),e.proxy(h.onShow,o)(E)},hide:function(t){t=e.isFunction(t)?t:function(){},g.debug("Hiding pop-up"),h.transition&&e.fn.transition!==n&&C.transition("is supported")?o.transition({animation:h.transition+" out",queue:!1,duration:h.duration,debug:h.debug,verbose:h.verbose,onComplete:function(){g.reset(),e.proxy(t,o)(E),e.proxy(h.onHidden,o)(E)}}):o.stop().fadeOut(h.duration,h.easing,function(){g.reset(),t()}),e.proxy(h.onHide,o)(E)}},get:{startEvent:function(){return"hover"==h.on?"mouseenter":"focus"==h.on?"focus":!1},endEvent:function(){return"hover"==h.on?"mouseleave":"focus"==h.on?"blur":!1},offstagePosition:function(n){var n=n||!1,i={top:e(t).scrollTop(),bottom:e(t).scrollTop()+e(t).height(),left:0,right:e(t).width()},s={width:o.width(),height:o.height(),offset:o.offset()},r={},a=[];return s.offset&&n&&(g.verbose("Checking if outside viewable area",s.offset),r={top:s.offset.topi.bottom,right:s.offset.left+s.width>i.right,left:!1}),e.each(r,function(e,t){t&&a.push(e)}),a.length>0?a.join(" "):!1},nextPosition:function(e){switch(e){case"top left":e="bottom left";break;case"bottom left":e="top right";break;case"top right":e="bottom right";break;case"bottom right":e="top center";break;case"top center":e="bottom center";break;case"bottom center":e="right center";break;case"right center":e="left center";break;case"left center":e="top center"}return e}},set:{position:function(i,s){var a,l,p=(e(t).width(),e(t).height(),T.outerWidth()),u=T.outerHeight(),c=o.outerWidth(),d=o.outerHeight(),f=r.outerWidth(),m=r.outerHeight(),w=h.distanceAway,x=T[0],k=h.inline?parseInt(t.getComputedStyle(x).getPropertyValue("margin-top"),10):0,P=h.inline?parseInt(t.getComputedStyle(x).getPropertyValue("margin-left"),10):0,O=h.inline||h.popup?T.position():T.offset();switch(i=i||C.data(y.position)||h.position,s=s||C.data(y.offset)||h.offset,h.inline&&(g.debug("Adding targets margin to calculation"),"left center"==i||"right center"==i?(s+=k,w+=-P):"top left"==i||"top center"==i||"top right"==i?(s+=P,w-=k):(s+=P,w+=k)),g.debug("Calculating popup positioning",i),i){case"top left":a={top:"auto",bottom:m-O.top+w,left:O.left+s,right:"auto"};break;case"top center":a={bottom:m-O.top+w,left:O.left+p/2-c/2+s,top:"auto",right:"auto"};break;case"top right":a={bottom:m-O.top+w,right:f-O.left-p-s,top:"auto",left:"auto"};break;case"left center":a={top:O.top+u/2-d/2+s,right:f-O.left+w,left:"auto",bottom:"auto"};break;case"right center":a={top:O.top+u/2-d/2+s,left:O.left+p+w,bottom:"auto",right:"auto"};break;case"bottom left":a={top:O.top+u+w,left:O.left+s,bottom:"auto",right:"auto"};break;case"bottom center":a={top:O.top+u+w,left:O.left+p/2-c/2+s,bottom:"auto",right:"auto"};break;case"bottom right":a={top:O.top+u+w,right:f-O.left-p-s,left:"auto",bottom:"auto"}}return a===n&&g.error(v.invalidPosition),o.css(a).removeClass(b.position).addClass(i).addClass(b.loading),l=g.get.offstagePosition(i),l?(g.debug("Element is outside boundaries",l),A0&&(console.groupCollapsed(t),console.table?console.table(u):e.each(u,function(e,t){console.log(t.Name+": "+t["Execution Time"]+"ms")}),console.groupEnd()),u=[]}},invoke:function(t,o,i){var r,a,l,p=z;return o=o||f,i=E||i,"string"==typeof t&&p!==n&&(t=t.split(/[\. ]/),r=t.length-1,e.each(t,function(o,i){var s=o!=r?i+t[o+1].charAt(0).toUpperCase()+t[o+1].slice(1):t;if(e.isPlainObject(p[s])&&o!=r)p=p[s];else{if(p[s]!==n)return a=p[s],!1;if(!e.isPlainObject(p[i])||o==r)return p[i]!==n?(a=p[i],!1):!1;p=p[i]}})),e.isFunction(a)?l=a.apply(i,o):a!==n&&(l=a),e.isArray(s)?s.push(l):s!==n?s=[s,l]:l!==n&&(s=l),a}},d?(z===n&&g.initialize(),g.invoke(c)):(z!==n&&g.destroy(),g.initialize())}),s!==n?s: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",context:"body",position:"top left",delay:{show:30,hide:0},setFluidWidth:!0,target:!1,popup:!1,inline:!1,preserve:!0,hoverable:!1,duration:200,easing:"easeOutQuint",transition:"scale",distanceAway:0,offset:0,maxSearchDepth:10,error:{invalidPosition:"The position you specified is not a valid position",method:"The method you called is not defined."},metadata:{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(e,t,o,n){"use strict";e.fn.popup=function(i){var s,r=e(this),a=e(o),l=r.selector||"",p=("ontouchstart"in o.documentElement,(new Date).getTime()),u=[],c=arguments[0],d="string"==typeof c,f=[].slice.call(arguments,1);return r.each(function(){var o,r,g,h=e.isPlainObject(i)?e.extend(!0,{},e.fn.popup.settings,i):e.extend({},e.fn.popup.settings),m=h.selector,b=h.className,v=h.error,y=h.metadata,w=h.namespace,x="."+h.namespace,k="module-"+w,C=e(this),P=e(h.context),T=h.target?e(h.target):C,O=e(t),S=e("body"),z=0,A=this,E=C.data(k);g={initialize:function(){g.debug("Initializing module",C),g.refresh(),"click"==h.on?C.on("click"+x,g.toggle):g.get.startEvent()&&C.on(g.get.startEvent()+x,g.event.start).on(g.get.endEvent()+x,g.event.end),h.target&&g.debug("Target set to element",T),O.on("resize"+x,g.event.resize),g.exists()?h.hoverable&&g.bind.popup():g.create(),g.instantiate()},instantiate:function(){g.verbose("Storing instance of module",g),E=g,C.data(k,E)},refresh:function(){h.popup?o=e(h.popup):h.inline&&(o=T.next(h.selector.popup)),h.popup?(o.addClass(b.loading),r=o.offsetParent(),o.removeClass(b.loading)):r=h.inline?T.offsetParent():S,r.is("html")&&(g.debug("Page is popups offset parent"),r=S)},reposition:function(){g.refresh(),g.set.position()},destroy:function(){g.debug("Destroying previous module"),o&&!h.preserve&&g.removePopup(),C.off(x).removeData(k)},event:{start:function(){var t=e.isPlainObject(h.delay)?h.delay.show:h.delay;clearTimeout(g.hideTimer),g.showTimer=setTimeout(function(){!g.is.hidden()||g.is.active()&&g.is.dropdown()||g.show()},t)},end:function(){var t=e.isPlainObject(h.delay)?h.delay.hide:h.delay;clearTimeout(g.showTimer),g.hideTimer=setTimeout(function(){g.is.visible()&&g.hide()},t)},resize:function(){g.is.visible()&&g.set.position()}},create:function(){var t=C.data(y.html)||h.html,n=C.data(y.variation)||h.variation,i=C.data(y.title)||h.title,s=C.data(y.content)||C.attr("title")||h.content;t||s||i?(g.debug("Creating pop-up html"),t||(t=h.templates.popup({title:i,content:s})),o=e("
").addClass(b.popup).addClass(n).html(t),n&&o.addClass(n),h.inline?(g.verbose("Inserting popup element inline",o),o.insertAfter(C)):(g.verbose("Appending popup element to body",o),o.appendTo(P)),h.hoverable&&g.bind.popup(),e.proxy(h.onCreate,o)(A)):0!==T.next(h.selector.popup).size()?(g.verbose("Pre-existing popup found, reverting to inline"),h.inline=!0,g.refresh(),h.hoverable&&g.bind.popup()):g.debug("No content specified skipping display",A)},toggle:function(){g.debug("Toggling pop-up"),g.is.hidden()?(g.debug("Popup is hidden, showing pop-up"),g.unbind.close(),g.hideAll(),g.show()):(g.debug("Popup is visible, hiding pop-up"),g.hide())},show:function(t){t=e.isFunction(t)?t:function(){},g.debug("Showing pop-up",h.transition),h.preserve||h.popup||g.refresh(),g.exists()||g.create(),o&&g.set.position()&&(g.save.conditions(),g.animate.show(t))},hide:function(t){t=e.isFunction(t)?t:function(){},g.remove.visible(),g.unbind.close(),g.is.visible()&&(g.restore.conditions(),g.animate.hide(t))},hideAll:function(){e(m.popup).filter(":visible").popup("hide")},hideGracefully:function(t){t&&0===e(t.target).closest(m.popup).size()?(g.debug("Click occurred outside popup hiding popup"),g.hide()):g.debug("Click was inside popup, keeping popup open")},exists:function(){return o?h.inline||h.popup?0!==o.size():o.closest(P).size():!1},removePopup:function(){g.debug("Removing popup"),e.proxy(h.onRemove,o)(A),o.removePopup()},save:{conditions:function(){g.cache={title:C.attr("title")},g.cache.title&&C.removeAttr("title"),g.verbose("Saving original attributes",g.cache.title)}},restore:{conditions:function(){return A.blur(),g.cache&&g.cache.title&&(C.attr("title",g.cache.title),g.verbose("Restoring original attributes",g.cache.title)),!0}},animate:{show:function(t){t=e.isFunction(t)?t:function(){},h.transition&&e.fn.transition!==n&&C.transition("is supported")?(g.set.visible(),o.transition({animation:h.transition+" in",queue:!1,debug:h.debug,verbose:h.verbose,duration:h.duration,onComplete:function(){g.bind.close(),e.proxy(t,o)(A),e.proxy(h.onVisible,o)(A)}})):(g.set.visible(),o.stop().fadeIn(h.duration,h.easing,function(){g.bind.close(),e.proxy(t,A)()})),e.proxy(h.onShow,o)(A)},hide:function(t){t=e.isFunction(t)?t:function(){},g.debug("Hiding pop-up"),h.transition&&e.fn.transition!==n&&C.transition("is supported")?o.transition({animation:h.transition+" out",queue:!1,duration:h.duration,debug:h.debug,verbose:h.verbose,onComplete:function(){g.reset(),e.proxy(t,o)(A),e.proxy(h.onHidden,o)(A)}}):o.stop().fadeOut(h.duration,h.easing,function(){g.reset(),t()}),e.proxy(h.onHide,o)(A)}},get:{startEvent:function(){return"hover"==h.on?"mouseenter":"focus"==h.on?"focus":!1},endEvent:function(){return"hover"==h.on?"mouseleave":"focus"==h.on?"blur":!1},offstagePosition:function(n){var n=n||!1,i={top:e(t).scrollTop(),bottom:e(t).scrollTop()+e(t).height(),left:0,right:e(t).width()},s={width:o.width(),height:o.height(),offset:o.offset()},r={},a=[];return s.offset&&n&&(g.verbose("Checking if outside viewable area",s.offset),r={top:s.offset.topi.bottom,right:s.offset.left+s.width>i.right,left:!1}),e.each(r,function(e,t){t&&a.push(e)}),a.length>0?a.join(" "):!1},nextPosition:function(e){switch(e){case"top left":e="bottom left";break;case"bottom left":e="top right";break;case"top right":e="bottom right";break;case"bottom right":e="top center";break;case"top center":e="bottom center";break;case"bottom center":e="right center";break;case"right center":e="left center";break;case"left center":e="top center"}return e}},set:{position:function(i,s){var a,l,p=(e(t).width(),e(t).height(),T.outerWidth()),u=T.outerHeight(),c=o.outerWidth(),d=o.outerHeight(),f=r.outerWidth(),m=r.outerHeight(),w=h.distanceAway,x=T[0],k=h.inline?parseInt(t.getComputedStyle(x).getPropertyValue("margin-top"),10):0,P=h.inline?parseInt(t.getComputedStyle(x).getPropertyValue("margin-left"),10):0,O=h.inline||h.popup?T.position():T.offset();switch(i=i||C.data(y.position)||h.position,s=s||C.data(y.offset)||h.offset,h.inline&&(g.debug("Adding targets margin to calculation"),"left center"==i||"right center"==i?(s+=k,w+=-P):"top left"==i||"top center"==i||"top right"==i?(s+=P,w-=k):(s+=P,w+=k)),g.debug("Calculating popup positioning",i),i){case"top left":a={top:"auto",bottom:m-O.top+w,left:O.left+s,right:"auto"};break;case"top center":a={bottom:m-O.top+w,left:O.left+p/2-c/2+s,top:"auto",right:"auto"};break;case"top right":a={bottom:m-O.top+w,right:f-O.left-p-s,top:"auto",left:"auto"};break;case"left center":a={top:O.top+u/2-d/2+s,right:f-O.left+w,left:"auto",bottom:"auto"};break;case"right center":a={top:O.top+u/2-d/2+s,left:O.left+p+w,bottom:"auto",right:"auto"};break;case"bottom left":a={top:O.top+u+w,left:O.left+s,bottom:"auto",right:"auto"};break;case"bottom center":a={top:O.top+u+w,left:O.left+p/2-c/2+s,bottom:"auto",right:"auto"};break;case"bottom right":a={top:O.top+u+w,right:f-O.left-p-s,left:"auto",bottom:"auto"}}return a===n&&g.error(v.invalidPosition),o.css(a).removeClass(b.position).addClass(i).addClass(b.loading),l=g.get.offstagePosition(i),l?(g.debug("Element is outside boundaries",l),z0&&o.on("mouseenter"+x,g.event.start).on("mouseleave"+x,g.event.end)},close:function(){(h.hideOnScroll===!0||"auto"==h.hideOnScroll&&"click"!=h.on)&&(a.one("touchmove"+x,g.hideGracefully).one("scroll"+x,g.hideGracefully),P.one("touchmove"+x,g.hideGracefully).one("scroll"+x,g.hideGracefully)),"click"==h.on&&h.closable&&(g.verbose("Binding popup close event to document"),a.on("click"+x,function(t){g.verbose("Pop-up clickaway intent detected"),e.proxy(g.hideGracefully,A)(t)}))}},unbind:{close:function(){(h.hideOnScroll===!0||"auto"==h.hideOnScroll&&"click"!=h.on)&&(a.off("scroll"+x,g.hide),P.off("scroll"+x,g.hide)),"click"==h.on&&h.closable&&(g.verbose("Removing close event from document"),a.off("click"+x))}},is:{active:function(){return C.hasClass(b.active)},animating:function(){return o&&o.is(":animated")||o.hasClass(b.animating)},visible:function(){return o&&o.is(":visible")},dropdown:function(){return C.hasClass(b.dropdown)},hidden:function(){return!g.is.visible()}},reset:function(){g.remove.visible(),h.preserve||h.popup?e.fn.transition!==n&&o.transition("remove transition"):g.removePopup()},setting:function(t,o){if(e.isPlainObject(t))e.extend(!0,h,t);else{if(o===n)return h[t];h[t]=o}},internal:function(t,o){if(e.isPlainObject(t))e.extend(!0,g,t);else{if(o===n)return g[t];g[t]=o}},debug:function(){h.debug&&(h.performance?g.performance.log(arguments):(g.debug=Function.prototype.bind.call(console.info,console,h.name+":"),g.debug.apply(console,arguments)))},verbose:function(){h.verbose&&h.debug&&(h.performance?g.performance.log(arguments):(g.verbose=Function.prototype.bind.call(console.info,console,h.name+":"),g.verbose.apply(console,arguments)))},error:function(){g.error=Function.prototype.bind.call(console.error,console,h.name+":"),g.error.apply(console,arguments)},performance:{log:function(e){var t,o,n;h.performance&&(t=(new Date).getTime(),n=p||t,o=t-n,p=t,u.push({Name:e[0],Arguments:[].slice.call(e,1)||"",Element:A,"Execution Time":o})),clearTimeout(g.performance.timer),g.performance.timer=setTimeout(g.performance.display,100)},display:function(){var t=h.name+":",o=0;p=!1,clearTimeout(g.performance.timer),e.each(u,function(e,t){o+=t["Execution Time"]}),t+=" "+o+"ms",l&&(t+=" '"+l+"'"),(console.group!==n||console.table!==n)&&u.length>0&&(console.groupCollapsed(t),console.table?console.table(u):e.each(u,function(e,t){console.log(t.Name+": "+t["Execution Time"]+"ms")}),console.groupEnd()),u=[]}},invoke:function(t,o,i){var r,a,l,p=E;return o=o||f,i=A||i,"string"==typeof t&&p!==n&&(t=t.split(/[\. ]/),r=t.length-1,e.each(t,function(o,i){var s=o!=r?i+t[o+1].charAt(0).toUpperCase()+t[o+1].slice(1):t;if(e.isPlainObject(p[s])&&o!=r)p=p[s];else{if(p[s]!==n)return a=p[s],!1;if(!e.isPlainObject(p[i])||o==r)return p[i]!==n?(a=p[i],!1):!1;p=p[i]}})),e.isFunction(a)?l=a.apply(i,o):a!==n&&(l=a),e.isArray(s)?s.push(l):s!==n?s=[s,l]:l!==n&&(s=l),a}},d?(E===n&&g.initialize(),g.invoke(c)):(E!==n&&g.destroy(),g.initialize())}),s!==n?s: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",context:"body",position:"top left",delay:{show:30,hide:0},setFluidWidth:!0,target:!1,popup:!1,inline:!1,preserve:!0,hoverable:!1,duration:200,easing:"easeOutQuint",transition:"scale",distanceAway:0,offset:0,maxSearchDepth:10,error:{invalidPosition:"The position you specified is not a valid position",method:"The method you called is not defined."},metadata:{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 From 9952b8c06475afae5d32bb02c2f9ef1b6c3c982b Mon Sep 17 00:00:00 2001 From: Pusher Robot Date: Mon, 24 Nov 2014 02:32:15 -0500 Subject: [PATCH 14/22] Updated component release from Semantic-UI (Automatic) --- README.md | 4 ++-- RELEASE-NOTES.md | 8 ++++++++ bower.json | 2 +- composer.json | 2 +- index.js | 0 package.json | 2 +- popup.css | 2 +- popup.js | 0 popup.min.css | 2 +- popup.min.js | 2 +- 10 files changed, 16 insertions(+), 8 deletions(-) mode change 100755 => 100644 index.js mode change 100755 => 100644 popup.js mode change 100755 => 100644 popup.min.js diff --git a/README.md b/README.md index fa9c0e8..89c08d4 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,6 @@ npm install semantic-ui-popup ## Addendum -This element's definitions (required class names, html structures) are available in the [Beta UI Docs](http://beta.semantic-ui.com) +This element's definitions (required class names, html structures) are available in the [UI Docs](http://www.semantic-ui.com) -Please consider checking out [all the benefits to theming](http://learnsemantic.com/guide/expert.html) before using these stand-alone releases. +Please consider checking out [all the benefits to theming](http://www.learnsemantic.com/guide/expert.html) before using these stand-alone releases. diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 68c5a92..d6ac073 100755 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -4,6 +4,14 @@ - **Popup** - A popup element can now be specified on initialization. - **Popup** - Positioned popups will now extend in the opposite direction to fit better with floated content +### Version 0.18.0 - June 6, 2014 + +- **Popup** - Fixes javascript animation of popup missing easing dependency + +### Version 0.17.0 - May 9, 2014 + +- **Popup** - Popup now has an ``onRemove`` callback after removing element from DOM + ### Version 0.12.5 - Feb 04, 2014 - **Popup** - Fixes issue where popups using ``title`` attribute to store data were losing title content instead of correctly restoring it diff --git a/bower.json b/bower.json index 4c15e08..4a42af3 100644 --- a/bower.json +++ b/bower.json @@ -1,7 +1,7 @@ { "name": "semantic-ui-popup", "description": "Popup - Semantic UI", - "homepage": "http://beta.semantic-ui.com", + "homepage": "http://www.semantic-ui.com", "author": { "name": "Jack Lukic", "web": "http://www.jacklukic.com" diff --git a/composer.json b/composer.json index a74338c..188fb22 100644 --- a/composer.json +++ b/composer.json @@ -14,5 +14,5 @@ "jquery": "x.x.x" }, "main": "popup.js", - "version": "1.0.0-beta" + "version": "1.0.0" } \ No newline at end of file diff --git a/index.js b/index.js old mode 100755 new mode 100644 diff --git a/package.json b/package.json index 3e0d748..bbfec2a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "semantic-ui-popup", - "version": "1.0.0-beta", + "version": "1.0.0", "title": "Semantic UI - Popup", "description": "Single component release of popup", "homepage": "http://www.semantic-ui.com", diff --git a/popup.css b/popup.css index 5df0053..aab7729 100755 --- a/popup.css +++ b/popup.css @@ -1,7 +1,7 @@ /* * # Semantic UI * https://github.com/Semantic-Org/Semantic-UI - * http://beta.semantic-ui.com/ + * http://www.semantic-ui.com/ * * Copyright 2014 Contributors * Released under the MIT license diff --git a/popup.js b/popup.js old mode 100755 new mode 100644 diff --git a/popup.min.css b/popup.min.css index fec7079..4025bff 100755 --- a/popup.min.css +++ b/popup.min.css @@ -1,7 +1,7 @@ /* * # Semantic UI * https://github.com/Semantic-Org/Semantic-UI - * http://beta.semantic-ui.com/ + * http://www.semantic-ui.com/ * * Copyright 2014 Contributors * Released under the MIT license diff --git a/popup.min.js b/popup.min.js old mode 100755 new mode 100644 index a4134f1..07abeb0 --- a/popup.min.js +++ b/popup.min.js @@ -1,7 +1,7 @@ /* * # Semantic UI * https://github.com/Semantic-Org/Semantic-UI - * http://beta.semantic-ui.com/ + * http://www.semantic-ui.com/ * * Copyright 2014 Contributors * Released under the MIT license From 1ed8ac11c36fa5313d9c7de0c3d882dddd66064e Mon Sep 17 00:00:00 2001 From: Pusher Robot Date: Mon, 24 Nov 2014 04:16:02 -0500 Subject: [PATCH 15/22] Updated component release from Semantic-UI (Automatic) --- bower.json | 25 +++++++++++++++++++++---- composer.json | 7 ++++++- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/bower.json b/bower.json index 4a42af3..28ec1ba 100644 --- a/bower.json +++ b/bower.json @@ -6,10 +6,27 @@ "name": "Jack Lukic", "web": "http://www.jacklukic.com" }, - "ignore": ["docs", "node", "server", "spec", "src", "test"], - "keywords": ["semantic", "ui", "css3", "framework"], - "license": ["http://semantic-ui.mit-license.org/"], - "main": ["popup.js", "popup.css"], + "ignore": [ + "docs", + "node", + "server", + "spec", + "src", + "test" + ], + "keywords": [ + "semantic", + "ui", + "css3", + "framework" + ], + "license": [ + "http://semantic-ui.mit-license.org/" + ], + "main": [ + "popup.js", + "popup.css" + ], "dependencies": { "jquery": ">=1.8" } diff --git a/composer.json b/composer.json index 188fb22..600f9ad 100644 --- a/composer.json +++ b/composer.json @@ -8,7 +8,12 @@ "web": "http://www.jacklukic.com", "role": "Creator" }], - "keywords": ["semantic", "ui", "css", "framework"], + "keywords": [ + "semantic", + "ui", + "css", + "framework" + ], "license": "MIT", "dependencies": { "jquery": "x.x.x" From 37ee60da68ef130ad18e216f4b9576f3839ef120 Mon Sep 17 00:00:00 2001 From: Pusher Robot Date: Wed, 17 Dec 2014 19:56:15 -0500 Subject: [PATCH 16/22] Updated component release from Semantic-UI (Automatic) --- RELEASE-NOTES.md | 5 + composer.json | 2 +- index.js | 231 ++++++++++++++++++++++++++++++----------------- package.json | 2 +- popup.css | 8 +- popup.js | 231 ++++++++++++++++++++++++++++++----------------- popup.min.css | 2 +- popup.min.js | 2 +- 8 files changed, 307 insertions(+), 176 deletions(-) diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index d6ac073..a2cf134 100755 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -1,3 +1,8 @@ +### Version 1.1.0 - December 02, 2014 + +- **Popup** - Popup now has a ``settings.prefer`` that defaults to ``adjacent``. This setting sets prefered next placement when a popup cannot fit on screen in the chosen placement. ``prefer`` can also be set to ``opposite`` to prefer the same position on the opposite side +- **Popup** - Popup can now use a setting ``lastResort``. When set to a position it will be used as a last resort even if popup does not entirely fit on the page. Setting this to ``false`` will produce an error when a popup cannot fit on screen. + ### Version 1.0.0 - November 24, 2014 - **Popup** - Popup can now allow itself not to be closed when hovered over diff --git a/composer.json b/composer.json index 600f9ad..e36bc75 100644 --- a/composer.json +++ b/composer.json @@ -19,5 +19,5 @@ "jquery": "x.x.x" }, "main": "popup.js", - "version": "1.0.0" + "version": "1.3.2" } \ No newline at end of file diff --git a/index.js b/index.js index e71bb3d..0bfabf1 100644 --- a/index.js +++ b/index.js @@ -39,30 +39,31 @@ module.exports = function(parameters) { ? $.extend(true, {}, _module.exports.settings, parameters) : $.extend({}, _module.exports.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), - $target = (settings.target) + 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), + $target = (settings.target) ? $(settings.target) : $module, - $window = $(window), - $body = $('body'), + $window = $(window), + $body = $('body'), $popup, $offsetParent, - searchDepth = 0, + searchDepth = 0, + triedPositions = false, - element = this, - instance = $module.data(moduleNamespace), + element = this, + instance = $module.data(moduleNamespace), module ; @@ -312,9 +313,7 @@ module.exports = function(parameters) { removePopup: function() { module.debug('Removing popup'); $.proxy(settings.onRemove, $popup)(element); - $popup - .removePopup() - ; + $popup.remove(); }, save: { @@ -444,7 +443,7 @@ module.exports = function(parameters) { top : (popup.offset.top < boundary.top), bottom : (popup.offset.top + popup.height > boundary.bottom), right : (popup.offset.left + popup.width > boundary.right), - left : false + left : (popup.offset.left < boundary.left) }; } // return only boundaries that have been surpassed @@ -458,34 +457,74 @@ module.exports = function(parameters) { : false ; }, + 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) { - switch(position) { - case 'top left': - position = 'bottom left'; - break; - case 'bottom left': - position = 'top right'; - break; - case 'top right': - position = 'bottom right'; - break; - case 'bottom right': - position = 'top center'; - break; - case 'top center': - position = 'bottom center'; - break; - case 'bottom center': - position = 'right center'; - break; - case 'right center': - position = 'left center'; - break; - case 'left center': - position = 'top center'; - break; + 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 position; + return nextPosition; } }, @@ -524,6 +563,12 @@ module.exports = function(parameters) { ; position = position || $module.data(metadata.position) || settings.position; arrowOffset = arrowOffset || $module.data(metadata.offset) || settings.offset; + + if(searchDepth == settings.maxSearchDepth && settings.lastResort) { + module.debug('Using last resort position to display', settings.lastResort); + position = settings.lastResort; + } + if(settings.inline) { module.debug('Adding targets margin to calculation'); if(position == 'left center' || position == 'right center') { @@ -607,8 +652,9 @@ module.exports = function(parameters) { break; } if(positioning === undefined) { - module.error(error.invalidPosition); + module.error(error.invalidPosition, position); } + // tentatively place on stage $popup .css(positioning) @@ -621,32 +667,36 @@ module.exports = function(parameters) { // recursively find new positioning if(offstagePosition) { - module.debug('Element is outside boundaries', offstagePosition); + module.debug('Popup cant fit into viewport', offstagePosition); if(searchDepth < settings.maxSearchDepth) { - position = module.get.nextPosition(position); searchDepth++; + position = module.get.nextPosition(position); module.debug('Trying new position', position); return ($popup) ? module.set.position(position) : false ; } - else { - module.debug('Popup could not find a position onstage', $popup); - searchDepth = 0; + else if(!settings.lastResort) { + module.debug('Popup could not find a position in view', $popup); + module.error(error.cannotPlace); + module.remove.attempts(); + module.remove.loading(); module.reset(); - $popup.removeClass(className.loading); return false; } } - else { - module.debug('Position is on stage', position); - searchDepth = 0; - if( settings.setFluidWidth && $popup.hasClass(className.fluid) ) { - $popup.css('width', $offsetParent.width()); - } - $popup.removeClass(className.loading); - return true; + + module.debug('Position is on stage', position); + module.remove.attempts(); + module.set.fluidWidth(); + module.remove.loading(); + return true; + }, + + fluidWidth: function() { + if( settings.setFluidWidth && $popup.hasClass(className.fluid) ) { + $popup.css('width', $offsetParent.width()); } }, @@ -656,8 +706,16 @@ module.exports = function(parameters) { }, remove: { + loading: function() { + $popup.removeClass(className.loading); + }, visible: function() { $module.removeClass(className.visible); + }, + attempts: function() { + module.verbose('Resetting all searched positions'); + searchDepth = 0; + triedPositions = false; } }, @@ -922,33 +980,37 @@ module.exports = function(parameters) { module.exports.settings = { - name : 'Popup', + name : 'Popup', + + debug : false, + verbose : true, + performance : true, + namespace : 'popup', + + onCreate : function(){}, + onRemove : function(){}, - debug : false, - verbose : true, - performance : true, - namespace : 'popup', + onShow : function(){}, + onVisible : function(){}, + onHide : function(){}, + onHidden : function(){}, - onCreate : function(){}, - onRemove : function(){}, + variation : '', + content : false, + html : false, + title : false, - onShow : function(){}, - onVisible : function(){}, - onHide : function(){}, - onHidden : function(){}, + on : 'hover', + closable : true, + hideOnScroll : 'auto', - variation : '', - content : false, - html : false, - title : false, + context : 'body', - on : 'hover', - closable : true, - hideOnScroll : 'auto', + position : 'top left', + prefer : 'opposite', + lastResort : false, - context : 'body', - position : 'top left', - delay : { + delay : { show : 30, hide : 0 }, @@ -967,10 +1029,11 @@ module.exports.settings = { distanceAway : 0, offset : 0, - maxSearchDepth : 10, + 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.' }, diff --git a/package.json b/package.json index bbfec2a..41b5ee1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "semantic-ui-popup", - "version": "1.0.0", + "version": "1.3.2", "title": "Semantic UI - Popup", "description": "Single component release of popup", "homepage": "http://www.semantic-ui.com", diff --git a/popup.css b/popup.css index aab7729..be2c0fd 100755 --- a/popup.css +++ b/popup.css @@ -24,7 +24,7 @@ border: 1px solid #cccccc; max-width: 250px; background-color: #ffffff; - padding: 0.8em 1em; + padding: 0.833em 1em; font-weight: normal; font-style: normal; color: rgba(0, 0, 0, 0.8); @@ -268,16 +268,16 @@ ---------------*/ .ui.small.popup { - font-size: 0.8rem; + font-size: 0.785714rem; } .ui.popup { - font-size: 0.875rem; + font-size: 0.85714rem; } .ui.large.popup { font-size: 1rem; } .ui.huge.popup { - font-size: 1.1rem; + font-size: 1.14285rem; } diff --git a/popup.js b/popup.js index 383837e..7e410e3 100644 --- a/popup.js +++ b/popup.js @@ -37,30 +37,31 @@ $.fn.popup = function(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), - $target = (settings.target) + 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), + $target = (settings.target) ? $(settings.target) : $module, - $window = $(window), - $body = $('body'), + $window = $(window), + $body = $('body'), $popup, $offsetParent, - searchDepth = 0, + searchDepth = 0, + triedPositions = false, - element = this, - instance = $module.data(moduleNamespace), + element = this, + instance = $module.data(moduleNamespace), module ; @@ -310,9 +311,7 @@ $.fn.popup = function(parameters) { removePopup: function() { module.debug('Removing popup'); $.proxy(settings.onRemove, $popup)(element); - $popup - .removePopup() - ; + $popup.remove(); }, save: { @@ -442,7 +441,7 @@ $.fn.popup = function(parameters) { top : (popup.offset.top < boundary.top), bottom : (popup.offset.top + popup.height > boundary.bottom), right : (popup.offset.left + popup.width > boundary.right), - left : false + left : (popup.offset.left < boundary.left) }; } // return only boundaries that have been surpassed @@ -456,34 +455,74 @@ $.fn.popup = function(parameters) { : false ; }, + 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) { - switch(position) { - case 'top left': - position = 'bottom left'; - break; - case 'bottom left': - position = 'top right'; - break; - case 'top right': - position = 'bottom right'; - break; - case 'bottom right': - position = 'top center'; - break; - case 'top center': - position = 'bottom center'; - break; - case 'bottom center': - position = 'right center'; - break; - case 'right center': - position = 'left center'; - break; - case 'left center': - position = 'top center'; - break; + 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 position; + return nextPosition; } }, @@ -522,6 +561,12 @@ $.fn.popup = function(parameters) { ; position = position || $module.data(metadata.position) || settings.position; arrowOffset = arrowOffset || $module.data(metadata.offset) || settings.offset; + + if(searchDepth == settings.maxSearchDepth && settings.lastResort) { + module.debug('Using last resort position to display', settings.lastResort); + position = settings.lastResort; + } + if(settings.inline) { module.debug('Adding targets margin to calculation'); if(position == 'left center' || position == 'right center') { @@ -605,8 +650,9 @@ $.fn.popup = function(parameters) { break; } if(positioning === undefined) { - module.error(error.invalidPosition); + module.error(error.invalidPosition, position); } + // tentatively place on stage $popup .css(positioning) @@ -619,32 +665,36 @@ $.fn.popup = function(parameters) { // recursively find new positioning if(offstagePosition) { - module.debug('Element is outside boundaries', offstagePosition); + module.debug('Popup cant fit into viewport', offstagePosition); if(searchDepth < settings.maxSearchDepth) { - position = module.get.nextPosition(position); searchDepth++; + position = module.get.nextPosition(position); module.debug('Trying new position', position); return ($popup) ? module.set.position(position) : false ; } - else { - module.debug('Popup could not find a position onstage', $popup); - searchDepth = 0; + else if(!settings.lastResort) { + module.debug('Popup could not find a position in view', $popup); + module.error(error.cannotPlace); + module.remove.attempts(); + module.remove.loading(); module.reset(); - $popup.removeClass(className.loading); return false; } } - else { - module.debug('Position is on stage', position); - searchDepth = 0; - if( settings.setFluidWidth && $popup.hasClass(className.fluid) ) { - $popup.css('width', $offsetParent.width()); - } - $popup.removeClass(className.loading); - return true; + + module.debug('Position is on stage', position); + module.remove.attempts(); + module.set.fluidWidth(); + module.remove.loading(); + return true; + }, + + fluidWidth: function() { + if( settings.setFluidWidth && $popup.hasClass(className.fluid) ) { + $popup.css('width', $offsetParent.width()); } }, @@ -654,8 +704,16 @@ $.fn.popup = function(parameters) { }, remove: { + loading: function() { + $popup.removeClass(className.loading); + }, visible: function() { $module.removeClass(className.visible); + }, + attempts: function() { + module.verbose('Resetting all searched positions'); + searchDepth = 0; + triedPositions = false; } }, @@ -920,33 +978,37 @@ $.fn.popup = function(parameters) { $.fn.popup.settings = { - name : 'Popup', + name : 'Popup', + + debug : false, + verbose : true, + performance : true, + namespace : 'popup', + + onCreate : function(){}, + onRemove : function(){}, - debug : false, - verbose : true, - performance : true, - namespace : 'popup', + onShow : function(){}, + onVisible : function(){}, + onHide : function(){}, + onHidden : function(){}, - onCreate : function(){}, - onRemove : function(){}, + variation : '', + content : false, + html : false, + title : false, - onShow : function(){}, - onVisible : function(){}, - onHide : function(){}, - onHidden : function(){}, + on : 'hover', + closable : true, + hideOnScroll : 'auto', - variation : '', - content : false, - html : false, - title : false, + context : 'body', - on : 'hover', - closable : true, - hideOnScroll : 'auto', + position : 'top left', + prefer : 'opposite', + lastResort : false, - context : 'body', - position : 'top left', - delay : { + delay : { show : 30, hide : 0 }, @@ -965,10 +1027,11 @@ $.fn.popup.settings = { distanceAway : 0, offset : 0, - maxSearchDepth : 10, + 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.' }, diff --git a/popup.min.css b/popup.min.css index 4025bff..8f7e66e 100755 --- a/popup.min.css +++ b/popup.min.css @@ -8,4 +8,4 @@ * http://opensource.org/licenses/MIT * */ -.ui.popup{display:none;position:absolute;top:0;right:0;z-index:900;border:1px solid #ccc;max-width:250px;background-color:#fff;padding:.8em 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)}.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{margin:0}.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{width:350px;max-width:350px}.ui[class*="very wide"].popup{width:550px;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:.8rem}.ui.popup{font-size:.875rem}.ui.large.popup{font-size:1rem}.ui.huge.popup{font-size:1.1rem} \ No newline at end of file +.ui.popup{display:none;position:absolute;top:0;right:0;z-index:900;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)}.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{margin:0}.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{width:350px;max-width:350px}.ui[class*="very wide"].popup{width:550px;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 diff --git a/popup.min.js b/popup.min.js index 07abeb0..5864e98 100644 --- a/popup.min.js +++ b/popup.min.js @@ -8,4 +8,4 @@ * http://opensource.org/licenses/MIT * */ -!function(e,t,o,n){"use strict";e.fn.popup=function(i){var s,r=e(this),a=e(o),l=r.selector||"",p=("ontouchstart"in o.documentElement,(new Date).getTime()),u=[],c=arguments[0],d="string"==typeof c,f=[].slice.call(arguments,1);return r.each(function(){var o,r,g,h=e.isPlainObject(i)?e.extend(!0,{},e.fn.popup.settings,i):e.extend({},e.fn.popup.settings),m=h.selector,b=h.className,v=h.error,y=h.metadata,w=h.namespace,x="."+h.namespace,k="module-"+w,C=e(this),P=e(h.context),T=h.target?e(h.target):C,O=e(t),S=e("body"),z=0,A=this,E=C.data(k);g={initialize:function(){g.debug("Initializing module",C),g.refresh(),"click"==h.on?C.on("click"+x,g.toggle):g.get.startEvent()&&C.on(g.get.startEvent()+x,g.event.start).on(g.get.endEvent()+x,g.event.end),h.target&&g.debug("Target set to element",T),O.on("resize"+x,g.event.resize),g.exists()?h.hoverable&&g.bind.popup():g.create(),g.instantiate()},instantiate:function(){g.verbose("Storing instance of module",g),E=g,C.data(k,E)},refresh:function(){h.popup?o=e(h.popup):h.inline&&(o=T.next(h.selector.popup)),h.popup?(o.addClass(b.loading),r=o.offsetParent(),o.removeClass(b.loading)):r=h.inline?T.offsetParent():S,r.is("html")&&(g.debug("Page is popups offset parent"),r=S)},reposition:function(){g.refresh(),g.set.position()},destroy:function(){g.debug("Destroying previous module"),o&&!h.preserve&&g.removePopup(),C.off(x).removeData(k)},event:{start:function(){var t=e.isPlainObject(h.delay)?h.delay.show:h.delay;clearTimeout(g.hideTimer),g.showTimer=setTimeout(function(){!g.is.hidden()||g.is.active()&&g.is.dropdown()||g.show()},t)},end:function(){var t=e.isPlainObject(h.delay)?h.delay.hide:h.delay;clearTimeout(g.showTimer),g.hideTimer=setTimeout(function(){g.is.visible()&&g.hide()},t)},resize:function(){g.is.visible()&&g.set.position()}},create:function(){var t=C.data(y.html)||h.html,n=C.data(y.variation)||h.variation,i=C.data(y.title)||h.title,s=C.data(y.content)||C.attr("title")||h.content;t||s||i?(g.debug("Creating pop-up html"),t||(t=h.templates.popup({title:i,content:s})),o=e("
").addClass(b.popup).addClass(n).html(t),n&&o.addClass(n),h.inline?(g.verbose("Inserting popup element inline",o),o.insertAfter(C)):(g.verbose("Appending popup element to body",o),o.appendTo(P)),h.hoverable&&g.bind.popup(),e.proxy(h.onCreate,o)(A)):0!==T.next(h.selector.popup).size()?(g.verbose("Pre-existing popup found, reverting to inline"),h.inline=!0,g.refresh(),h.hoverable&&g.bind.popup()):g.debug("No content specified skipping display",A)},toggle:function(){g.debug("Toggling pop-up"),g.is.hidden()?(g.debug("Popup is hidden, showing pop-up"),g.unbind.close(),g.hideAll(),g.show()):(g.debug("Popup is visible, hiding pop-up"),g.hide())},show:function(t){t=e.isFunction(t)?t:function(){},g.debug("Showing pop-up",h.transition),h.preserve||h.popup||g.refresh(),g.exists()||g.create(),o&&g.set.position()&&(g.save.conditions(),g.animate.show(t))},hide:function(t){t=e.isFunction(t)?t:function(){},g.remove.visible(),g.unbind.close(),g.is.visible()&&(g.restore.conditions(),g.animate.hide(t))},hideAll:function(){e(m.popup).filter(":visible").popup("hide")},hideGracefully:function(t){t&&0===e(t.target).closest(m.popup).size()?(g.debug("Click occurred outside popup hiding popup"),g.hide()):g.debug("Click was inside popup, keeping popup open")},exists:function(){return o?h.inline||h.popup?0!==o.size():o.closest(P).size():!1},removePopup:function(){g.debug("Removing popup"),e.proxy(h.onRemove,o)(A),o.removePopup()},save:{conditions:function(){g.cache={title:C.attr("title")},g.cache.title&&C.removeAttr("title"),g.verbose("Saving original attributes",g.cache.title)}},restore:{conditions:function(){return A.blur(),g.cache&&g.cache.title&&(C.attr("title",g.cache.title),g.verbose("Restoring original attributes",g.cache.title)),!0}},animate:{show:function(t){t=e.isFunction(t)?t:function(){},h.transition&&e.fn.transition!==n&&C.transition("is supported")?(g.set.visible(),o.transition({animation:h.transition+" in",queue:!1,debug:h.debug,verbose:h.verbose,duration:h.duration,onComplete:function(){g.bind.close(),e.proxy(t,o)(A),e.proxy(h.onVisible,o)(A)}})):(g.set.visible(),o.stop().fadeIn(h.duration,h.easing,function(){g.bind.close(),e.proxy(t,A)()})),e.proxy(h.onShow,o)(A)},hide:function(t){t=e.isFunction(t)?t:function(){},g.debug("Hiding pop-up"),h.transition&&e.fn.transition!==n&&C.transition("is supported")?o.transition({animation:h.transition+" out",queue:!1,duration:h.duration,debug:h.debug,verbose:h.verbose,onComplete:function(){g.reset(),e.proxy(t,o)(A),e.proxy(h.onHidden,o)(A)}}):o.stop().fadeOut(h.duration,h.easing,function(){g.reset(),t()}),e.proxy(h.onHide,o)(A)}},get:{startEvent:function(){return"hover"==h.on?"mouseenter":"focus"==h.on?"focus":!1},endEvent:function(){return"hover"==h.on?"mouseleave":"focus"==h.on?"blur":!1},offstagePosition:function(n){var n=n||!1,i={top:e(t).scrollTop(),bottom:e(t).scrollTop()+e(t).height(),left:0,right:e(t).width()},s={width:o.width(),height:o.height(),offset:o.offset()},r={},a=[];return s.offset&&n&&(g.verbose("Checking if outside viewable area",s.offset),r={top:s.offset.topi.bottom,right:s.offset.left+s.width>i.right,left:!1}),e.each(r,function(e,t){t&&a.push(e)}),a.length>0?a.join(" "):!1},nextPosition:function(e){switch(e){case"top left":e="bottom left";break;case"bottom left":e="top right";break;case"top right":e="bottom right";break;case"bottom right":e="top center";break;case"top center":e="bottom center";break;case"bottom center":e="right center";break;case"right center":e="left center";break;case"left center":e="top center"}return e}},set:{position:function(i,s){var a,l,p=(e(t).width(),e(t).height(),T.outerWidth()),u=T.outerHeight(),c=o.outerWidth(),d=o.outerHeight(),f=r.outerWidth(),m=r.outerHeight(),w=h.distanceAway,x=T[0],k=h.inline?parseInt(t.getComputedStyle(x).getPropertyValue("margin-top"),10):0,P=h.inline?parseInt(t.getComputedStyle(x).getPropertyValue("margin-left"),10):0,O=h.inline||h.popup?T.position():T.offset();switch(i=i||C.data(y.position)||h.position,s=s||C.data(y.offset)||h.offset,h.inline&&(g.debug("Adding targets margin to calculation"),"left center"==i||"right center"==i?(s+=k,w+=-P):"top left"==i||"top center"==i||"top right"==i?(s+=P,w-=k):(s+=P,w+=k)),g.debug("Calculating popup positioning",i),i){case"top left":a={top:"auto",bottom:m-O.top+w,left:O.left+s,right:"auto"};break;case"top center":a={bottom:m-O.top+w,left:O.left+p/2-c/2+s,top:"auto",right:"auto"};break;case"top right":a={bottom:m-O.top+w,right:f-O.left-p-s,top:"auto",left:"auto"};break;case"left center":a={top:O.top+u/2-d/2+s,right:f-O.left+w,left:"auto",bottom:"auto"};break;case"right center":a={top:O.top+u/2-d/2+s,left:O.left+p+w,bottom:"auto",right:"auto"};break;case"bottom left":a={top:O.top+u+w,left:O.left+s,bottom:"auto",right:"auto"};break;case"bottom center":a={top:O.top+u+w,left:O.left+p/2-c/2+s,bottom:"auto",right:"auto"};break;case"bottom right":a={top:O.top+u+w,right:f-O.left-p-s,left:"auto",bottom:"auto"}}return a===n&&g.error(v.invalidPosition),o.css(a).removeClass(b.position).addClass(i).addClass(b.loading),l=g.get.offstagePosition(i),l?(g.debug("Element is outside boundaries",l),z0&&o.on("mouseenter"+x,g.event.start).on("mouseleave"+x,g.event.end)},close:function(){(h.hideOnScroll===!0||"auto"==h.hideOnScroll&&"click"!=h.on)&&(a.one("touchmove"+x,g.hideGracefully).one("scroll"+x,g.hideGracefully),P.one("touchmove"+x,g.hideGracefully).one("scroll"+x,g.hideGracefully)),"click"==h.on&&h.closable&&(g.verbose("Binding popup close event to document"),a.on("click"+x,function(t){g.verbose("Pop-up clickaway intent detected"),e.proxy(g.hideGracefully,A)(t)}))}},unbind:{close:function(){(h.hideOnScroll===!0||"auto"==h.hideOnScroll&&"click"!=h.on)&&(a.off("scroll"+x,g.hide),P.off("scroll"+x,g.hide)),"click"==h.on&&h.closable&&(g.verbose("Removing close event from document"),a.off("click"+x))}},is:{active:function(){return C.hasClass(b.active)},animating:function(){return o&&o.is(":animated")||o.hasClass(b.animating)},visible:function(){return o&&o.is(":visible")},dropdown:function(){return C.hasClass(b.dropdown)},hidden:function(){return!g.is.visible()}},reset:function(){g.remove.visible(),h.preserve||h.popup?e.fn.transition!==n&&o.transition("remove transition"):g.removePopup()},setting:function(t,o){if(e.isPlainObject(t))e.extend(!0,h,t);else{if(o===n)return h[t];h[t]=o}},internal:function(t,o){if(e.isPlainObject(t))e.extend(!0,g,t);else{if(o===n)return g[t];g[t]=o}},debug:function(){h.debug&&(h.performance?g.performance.log(arguments):(g.debug=Function.prototype.bind.call(console.info,console,h.name+":"),g.debug.apply(console,arguments)))},verbose:function(){h.verbose&&h.debug&&(h.performance?g.performance.log(arguments):(g.verbose=Function.prototype.bind.call(console.info,console,h.name+":"),g.verbose.apply(console,arguments)))},error:function(){g.error=Function.prototype.bind.call(console.error,console,h.name+":"),g.error.apply(console,arguments)},performance:{log:function(e){var t,o,n;h.performance&&(t=(new Date).getTime(),n=p||t,o=t-n,p=t,u.push({Name:e[0],Arguments:[].slice.call(e,1)||"",Element:A,"Execution Time":o})),clearTimeout(g.performance.timer),g.performance.timer=setTimeout(g.performance.display,100)},display:function(){var t=h.name+":",o=0;p=!1,clearTimeout(g.performance.timer),e.each(u,function(e,t){o+=t["Execution Time"]}),t+=" "+o+"ms",l&&(t+=" '"+l+"'"),(console.group!==n||console.table!==n)&&u.length>0&&(console.groupCollapsed(t),console.table?console.table(u):e.each(u,function(e,t){console.log(t.Name+": "+t["Execution Time"]+"ms")}),console.groupEnd()),u=[]}},invoke:function(t,o,i){var r,a,l,p=E;return o=o||f,i=A||i,"string"==typeof t&&p!==n&&(t=t.split(/[\. ]/),r=t.length-1,e.each(t,function(o,i){var s=o!=r?i+t[o+1].charAt(0).toUpperCase()+t[o+1].slice(1):t;if(e.isPlainObject(p[s])&&o!=r)p=p[s];else{if(p[s]!==n)return a=p[s],!1;if(!e.isPlainObject(p[i])||o==r)return p[i]!==n?(a=p[i],!1):!1;p=p[i]}})),e.isFunction(a)?l=a.apply(i,o):a!==n&&(l=a),e.isArray(s)?s.push(l):s!==n?s=[s,l]:l!==n&&(s=l),a}},d?(E===n&&g.initialize(),g.invoke(c)):(E!==n&&g.destroy(),g.initialize())}),s!==n?s: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",context:"body",position:"top left",delay:{show:30,hide:0},setFluidWidth:!0,target:!1,popup:!1,inline:!1,preserve:!0,hoverable:!1,duration:200,easing:"easeOutQuint",transition:"scale",distanceAway:0,offset:0,maxSearchDepth:10,error:{invalidPosition:"The position you specified is not a valid position",method:"The method you called is not defined."},metadata:{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(e,t,o,i){"use strict";e.fn.popup=function(n){var r,s=e(this),a=e(o),p=s.selector||"",l=("ontouchstart"in o.documentElement,(new Date).getTime()),u=[],c=arguments[0],d="string"==typeof c,f=[].slice.call(arguments,1);return s.each(function(){var o,s,g,h=e.isPlainObject(n)?e.extend(!0,{},e.fn.popup.settings,n):e.extend({},e.fn.popup.settings),m=h.selector,b=h.className,v=h.error,y=h.metadata,w=h.namespace,x="."+h.namespace,P="module-"+w,C=e(this),T=e(h.context),k=h.target?e(h.target):C,O=e(t),S=e("body"),j=0,A=!1,z=this,R=C.data(P);g={initialize:function(){g.debug("Initializing module",C),g.refresh(),"click"==h.on?C.on("click"+x,g.toggle):g.get.startEvent()&&C.on(g.get.startEvent()+x,g.event.start).on(g.get.endEvent()+x,g.event.end),h.target&&g.debug("Target set to element",k),O.on("resize"+x,g.event.resize),g.exists()?h.hoverable&&g.bind.popup():g.create(),g.instantiate()},instantiate:function(){g.verbose("Storing instance of module",g),R=g,C.data(P,R)},refresh:function(){h.popup?o=e(h.popup):h.inline&&(o=k.next(h.selector.popup)),h.popup?(o.addClass(b.loading),s=o.offsetParent(),o.removeClass(b.loading)):s=h.inline?k.offsetParent():S,s.is("html")&&(g.debug("Page is popups offset parent"),s=S)},reposition:function(){g.refresh(),g.set.position()},destroy:function(){g.debug("Destroying previous module"),o&&!h.preserve&&g.removePopup(),C.off(x).removeData(P)},event:{start:function(){var t=e.isPlainObject(h.delay)?h.delay.show:h.delay;clearTimeout(g.hideTimer),g.showTimer=setTimeout(function(){!g.is.hidden()||g.is.active()&&g.is.dropdown()||g.show()},t)},end:function(){var t=e.isPlainObject(h.delay)?h.delay.hide:h.delay;clearTimeout(g.showTimer),g.hideTimer=setTimeout(function(){g.is.visible()&&g.hide()},t)},resize:function(){g.is.visible()&&g.set.position()}},create:function(){var t=C.data(y.html)||h.html,i=C.data(y.variation)||h.variation,n=C.data(y.title)||h.title,r=C.data(y.content)||C.attr("title")||h.content;t||r||n?(g.debug("Creating pop-up html"),t||(t=h.templates.popup({title:n,content:r})),o=e("
").addClass(b.popup).addClass(i).html(t),i&&o.addClass(i),h.inline?(g.verbose("Inserting popup element inline",o),o.insertAfter(C)):(g.verbose("Appending popup element to body",o),o.appendTo(T)),h.hoverable&&g.bind.popup(),e.proxy(h.onCreate,o)(z)):0!==k.next(h.selector.popup).size()?(g.verbose("Pre-existing popup found, reverting to inline"),h.inline=!0,g.refresh(),h.hoverable&&g.bind.popup()):g.debug("No content specified skipping display",z)},toggle:function(){g.debug("Toggling pop-up"),g.is.hidden()?(g.debug("Popup is hidden, showing pop-up"),g.unbind.close(),g.hideAll(),g.show()):(g.debug("Popup is visible, hiding pop-up"),g.hide())},show:function(t){t=e.isFunction(t)?t:function(){},g.debug("Showing pop-up",h.transition),h.preserve||h.popup||g.refresh(),g.exists()||g.create(),o&&g.set.position()&&(g.save.conditions(),g.animate.show(t))},hide:function(t){t=e.isFunction(t)?t:function(){},g.remove.visible(),g.unbind.close(),g.is.visible()&&(g.restore.conditions(),g.animate.hide(t))},hideAll:function(){e(m.popup).filter(":visible").popup("hide")},hideGracefully:function(t){t&&0===e(t.target).closest(m.popup).size()?(g.debug("Click occurred outside popup hiding popup"),g.hide()):g.debug("Click was inside popup, keeping popup open")},exists:function(){return o?h.inline||h.popup?0!==o.size():o.closest(T).size():!1},removePopup:function(){g.debug("Removing popup"),e.proxy(h.onRemove,o)(z),o.remove()},save:{conditions:function(){g.cache={title:C.attr("title")},g.cache.title&&C.removeAttr("title"),g.verbose("Saving original attributes",g.cache.title)}},restore:{conditions:function(){return z.blur(),g.cache&&g.cache.title&&(C.attr("title",g.cache.title),g.verbose("Restoring original attributes",g.cache.title)),!0}},animate:{show:function(t){t=e.isFunction(t)?t:function(){},h.transition&&e.fn.transition!==i&&C.transition("is supported")?(g.set.visible(),o.transition({animation:h.transition+" in",queue:!1,debug:h.debug,verbose:h.verbose,duration:h.duration,onComplete:function(){g.bind.close(),e.proxy(t,o)(z),e.proxy(h.onVisible,o)(z)}})):(g.set.visible(),o.stop().fadeIn(h.duration,h.easing,function(){g.bind.close(),e.proxy(t,z)()})),e.proxy(h.onShow,o)(z)},hide:function(t){t=e.isFunction(t)?t:function(){},g.debug("Hiding pop-up"),h.transition&&e.fn.transition!==i&&C.transition("is supported")?o.transition({animation:h.transition+" out",queue:!1,duration:h.duration,debug:h.debug,verbose:h.verbose,onComplete:function(){g.reset(),e.proxy(t,o)(z),e.proxy(h.onHidden,o)(z)}}):o.stop().fadeOut(h.duration,h.easing,function(){g.reset(),t()}),e.proxy(h.onHide,o)(z)}},get:{startEvent:function(){return"hover"==h.on?"mouseenter":"focus"==h.on?"focus":!1},endEvent:function(){return"hover"==h.on?"mouseleave":"focus"==h.on?"blur":!1},offstagePosition:function(i){var i=i||!1,n={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 r.offset&&i&&(g.verbose("Checking if outside viewable area",r.offset),s={top:r.offset.topn.bottom,right:r.offset.left+r.width>n.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],i=t[1],n={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 A||(g.verbose("All available positions available"),A=g.get.positions()),g.debug("Recording last position tried",e),A[e]=!0,"opposite"===h.prefer&&(u=[n[o],i],u=u.join(" "),p=A[u]===!0,g.debug("Trying opposite strategy",u)),"adjacent"===h.prefer&&a&&(u=[o,r[i]],u=u.join(" "),l=A[u]===!0,g.debug("Trying adjacent strategy",u)),(l||p)&&(g.debug("Using backup position",u),u=s[e]),u}},set:{position:function(n,r){var a,p,l=(e(t).width(),e(t).height(),k.outerWidth()),u=k.outerHeight(),c=o.outerWidth(),d=o.outerHeight(),f=s.outerWidth(),m=s.outerHeight(),w=h.distanceAway,x=k[0],P=h.inline?parseInt(t.getComputedStyle(x).getPropertyValue("margin-top"),10):0,T=h.inline?parseInt(t.getComputedStyle(x).getPropertyValue("margin-left"),10):0,O=h.inline||h.popup?k.position():k.offset();switch(n=n||C.data(y.position)||h.position,r=r||C.data(y.offset)||h.offset,j==h.maxSearchDepth&&h.lastResort&&(g.debug("Using last resort position to display",h.lastResort),n=h.lastResort),h.inline&&(g.debug("Adding targets margin to calculation"),"left center"==n||"right center"==n?(r+=P,w+=-T):"top left"==n||"top center"==n||"top right"==n?(r+=T,w-=P):(r+=T,w+=P)),g.debug("Calculating popup positioning",n),n){case"top left":a={top:"auto",bottom:m-O.top+w,left:O.left+r,right:"auto"};break;case"top center":a={bottom:m-O.top+w,left:O.left+l/2-c/2+r,top:"auto",right:"auto"};break;case"top right":a={bottom:m-O.top+w,right:f-O.left-l-r,top:"auto",left:"auto"};break;case"left center":a={top:O.top+u/2-d/2+r,right:f-O.left+w,left:"auto",bottom:"auto"};break;case"right center":a={top:O.top+u/2-d/2+r,left:O.left+l+w,bottom:"auto",right:"auto"};break;case"bottom left":a={top:O.top+u+w,left:O.left+r,bottom:"auto",right:"auto"};break;case"bottom center":a={top:O.top+u+w,left:O.left+l/2-c/2+r,bottom:"auto",right:"auto"};break;case"bottom right":a={top:O.top+u+w,right:f-O.left-l-r,left:"auto",bottom:"auto"}}if(a===i&&g.error(v.invalidPosition,n),o.css(a).removeClass(b.position).addClass(n).addClass(b.loading),p=g.get.offstagePosition(n)){if(g.debug("Popup cant fit into viewport",p),j0&&o.on("mouseenter"+x,g.event.start).on("mouseleave"+x,g.event.end)},close:function(){(h.hideOnScroll===!0||"auto"==h.hideOnScroll&&"click"!=h.on)&&(a.one("touchmove"+x,g.hideGracefully).one("scroll"+x,g.hideGracefully),T.one("touchmove"+x,g.hideGracefully).one("scroll"+x,g.hideGracefully)),"click"==h.on&&h.closable&&(g.verbose("Binding popup close event to document"),a.on("click"+x,function(t){g.verbose("Pop-up clickaway intent detected"),e.proxy(g.hideGracefully,z)(t)}))}},unbind:{close:function(){(h.hideOnScroll===!0||"auto"==h.hideOnScroll&&"click"!=h.on)&&(a.off("scroll"+x,g.hide),T.off("scroll"+x,g.hide)),"click"==h.on&&h.closable&&(g.verbose("Removing close event from document"),a.off("click"+x))}},is:{active:function(){return C.hasClass(b.active)},animating:function(){return o&&o.is(":animated")||o.hasClass(b.animating)},visible:function(){return o&&o.is(":visible")},dropdown:function(){return C.hasClass(b.dropdown)},hidden:function(){return!g.is.visible()}},reset:function(){g.remove.visible(),h.preserve||h.popup?e.fn.transition!==i&&o.transition("remove transition"):g.removePopup()},setting:function(t,o){if(e.isPlainObject(t))e.extend(!0,h,t);else{if(o===i)return h[t];h[t]=o}},internal:function(t,o){if(e.isPlainObject(t))e.extend(!0,g,t);else{if(o===i)return g[t];g[t]=o}},debug:function(){h.debug&&(h.performance?g.performance.log(arguments):(g.debug=Function.prototype.bind.call(console.info,console,h.name+":"),g.debug.apply(console,arguments)))},verbose:function(){h.verbose&&h.debug&&(h.performance?g.performance.log(arguments):(g.verbose=Function.prototype.bind.call(console.info,console,h.name+":"),g.verbose.apply(console,arguments)))},error:function(){g.error=Function.prototype.bind.call(console.error,console,h.name+":"),g.error.apply(console,arguments)},performance:{log:function(e){var t,o,i;h.performance&&(t=(new Date).getTime(),i=l||t,o=t-i,l=t,u.push({Name:e[0],Arguments:[].slice.call(e,1)||"",Element:z,"Execution Time":o})),clearTimeout(g.performance.timer),g.performance.timer=setTimeout(g.performance.display,100)},display:function(){var t=h.name+":",o=0;l=!1,clearTimeout(g.performance.timer),e.each(u,function(e,t){o+=t["Execution Time"]}),t+=" "+o+"ms",p&&(t+=" '"+p+"'"),(console.group!==i||console.table!==i)&&u.length>0&&(console.groupCollapsed(t),console.table?console.table(u):e.each(u,function(e,t){console.log(t.Name+": "+t["Execution Time"]+"ms")}),console.groupEnd()),u=[]}},invoke:function(t,o,n){var s,a,p,l=R;return o=o||f,n=z||n,"string"==typeof t&&l!==i&&(t=t.split(/[\. ]/),s=t.length-1,e.each(t,function(o,n){var r=o!=s?n+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]!==i)return a=l[r],!1;if(!e.isPlainObject(l[n])||o==s)return l[n]!==i?(a=l[n],!1):!1;l=l[n]}})),e.isFunction(a)?p=a.apply(n,o):a!==i&&(p=a),e.isArray(r)?r.push(p):r!==i?r=[r,p]:p!==i&&(r=p),a}},d?(R===i&&g.initialize(),g.invoke(c)):(R!==i&&g.destroy(),g.initialize())}),r!==i?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",context:"body",position:"top left",prefer:"opposite",lastResort:!1,delay:{show:30,hide:0},setFluidWidth:!0,target:!1,popup:!1,inline:!1,preserve:!0,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:{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=/[&<>"'`]/,i={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},n=function(e){return i[e]};return o.test(e)?e.replace(t,n):e},popup:function(t){var o="",n=e.fn.popup.settings.templates.escape;return typeof t!==i&&(typeof t.title!==i&&t.title&&(t.title=n(t.title),o+='
'+t.title+"
"),typeof t.content!==i&&t.content&&(t.content=n(t.content),o+='
'+t.content+"
")),o}}},e.extend(e.easing,{easeOutQuad:function(e,t,o,i,n){return-i*(t/=n)*(t-2)+o}})}(jQuery,window,document); \ No newline at end of file From 610e7285fde6762b03ef382066c6577f6ee181ac Mon Sep 17 00:00:00 2001 From: Pusher Robot Date: Mon, 29 Dec 2014 00:19:55 -0500 Subject: [PATCH 17/22] Updated component release from Semantic-UI (Automatic) --- RELEASE-NOTES.md | 0 composer.json | 2 +- index.js | 6 +++++- package.json | 2 +- popup.js | 6 +++++- popup.min.js | 2 +- 6 files changed, 13 insertions(+), 5 deletions(-) mode change 100755 => 100644 RELEASE-NOTES.md diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md old mode 100755 new mode 100644 diff --git a/composer.json b/composer.json index e36bc75..0d86b0a 100644 --- a/composer.json +++ b/composer.json @@ -19,5 +19,5 @@ "jquery": "x.x.x" }, "main": "popup.js", - "version": "1.3.2" + "version": "1.4.1" } \ No newline at end of file diff --git a/index.js b/index.js index 0bfabf1..fd15178 100644 --- a/index.js +++ b/index.js @@ -313,7 +313,9 @@ module.exports = function(parameters) { removePopup: function() { module.debug('Removing popup'); $.proxy(settings.onRemove, $popup)(element); - $popup.remove(); + if($popup.size() > 0) { + $popup.remove(); + } }, save: { @@ -655,6 +657,8 @@ module.exports = function(parameters) { module.error(error.invalidPosition, position); } + module.debug('Calculated popup positioning values', positioning); + // tentatively place on stage $popup .css(positioning) diff --git a/package.json b/package.json index 41b5ee1..9136550 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "semantic-ui-popup", - "version": "1.3.2", + "version": "1.4.1", "title": "Semantic UI - Popup", "description": "Single component release of popup", "homepage": "http://www.semantic-ui.com", diff --git a/popup.js b/popup.js index 7e410e3..a591dc4 100644 --- a/popup.js +++ b/popup.js @@ -311,7 +311,9 @@ $.fn.popup = function(parameters) { removePopup: function() { module.debug('Removing popup'); $.proxy(settings.onRemove, $popup)(element); - $popup.remove(); + if($popup.size() > 0) { + $popup.remove(); + } }, save: { @@ -653,6 +655,8 @@ $.fn.popup = function(parameters) { module.error(error.invalidPosition, position); } + module.debug('Calculated popup positioning values', positioning); + // tentatively place on stage $popup .css(positioning) diff --git a/popup.min.js b/popup.min.js index 5864e98..8c5c09c 100644 --- a/popup.min.js +++ b/popup.min.js @@ -8,4 +8,4 @@ * http://opensource.org/licenses/MIT * */ -!function(e,t,o,i){"use strict";e.fn.popup=function(n){var r,s=e(this),a=e(o),p=s.selector||"",l=("ontouchstart"in o.documentElement,(new Date).getTime()),u=[],c=arguments[0],d="string"==typeof c,f=[].slice.call(arguments,1);return s.each(function(){var o,s,g,h=e.isPlainObject(n)?e.extend(!0,{},e.fn.popup.settings,n):e.extend({},e.fn.popup.settings),m=h.selector,b=h.className,v=h.error,y=h.metadata,w=h.namespace,x="."+h.namespace,P="module-"+w,C=e(this),T=e(h.context),k=h.target?e(h.target):C,O=e(t),S=e("body"),j=0,A=!1,z=this,R=C.data(P);g={initialize:function(){g.debug("Initializing module",C),g.refresh(),"click"==h.on?C.on("click"+x,g.toggle):g.get.startEvent()&&C.on(g.get.startEvent()+x,g.event.start).on(g.get.endEvent()+x,g.event.end),h.target&&g.debug("Target set to element",k),O.on("resize"+x,g.event.resize),g.exists()?h.hoverable&&g.bind.popup():g.create(),g.instantiate()},instantiate:function(){g.verbose("Storing instance of module",g),R=g,C.data(P,R)},refresh:function(){h.popup?o=e(h.popup):h.inline&&(o=k.next(h.selector.popup)),h.popup?(o.addClass(b.loading),s=o.offsetParent(),o.removeClass(b.loading)):s=h.inline?k.offsetParent():S,s.is("html")&&(g.debug("Page is popups offset parent"),s=S)},reposition:function(){g.refresh(),g.set.position()},destroy:function(){g.debug("Destroying previous module"),o&&!h.preserve&&g.removePopup(),C.off(x).removeData(P)},event:{start:function(){var t=e.isPlainObject(h.delay)?h.delay.show:h.delay;clearTimeout(g.hideTimer),g.showTimer=setTimeout(function(){!g.is.hidden()||g.is.active()&&g.is.dropdown()||g.show()},t)},end:function(){var t=e.isPlainObject(h.delay)?h.delay.hide:h.delay;clearTimeout(g.showTimer),g.hideTimer=setTimeout(function(){g.is.visible()&&g.hide()},t)},resize:function(){g.is.visible()&&g.set.position()}},create:function(){var t=C.data(y.html)||h.html,i=C.data(y.variation)||h.variation,n=C.data(y.title)||h.title,r=C.data(y.content)||C.attr("title")||h.content;t||r||n?(g.debug("Creating pop-up html"),t||(t=h.templates.popup({title:n,content:r})),o=e("
").addClass(b.popup).addClass(i).html(t),i&&o.addClass(i),h.inline?(g.verbose("Inserting popup element inline",o),o.insertAfter(C)):(g.verbose("Appending popup element to body",o),o.appendTo(T)),h.hoverable&&g.bind.popup(),e.proxy(h.onCreate,o)(z)):0!==k.next(h.selector.popup).size()?(g.verbose("Pre-existing popup found, reverting to inline"),h.inline=!0,g.refresh(),h.hoverable&&g.bind.popup()):g.debug("No content specified skipping display",z)},toggle:function(){g.debug("Toggling pop-up"),g.is.hidden()?(g.debug("Popup is hidden, showing pop-up"),g.unbind.close(),g.hideAll(),g.show()):(g.debug("Popup is visible, hiding pop-up"),g.hide())},show:function(t){t=e.isFunction(t)?t:function(){},g.debug("Showing pop-up",h.transition),h.preserve||h.popup||g.refresh(),g.exists()||g.create(),o&&g.set.position()&&(g.save.conditions(),g.animate.show(t))},hide:function(t){t=e.isFunction(t)?t:function(){},g.remove.visible(),g.unbind.close(),g.is.visible()&&(g.restore.conditions(),g.animate.hide(t))},hideAll:function(){e(m.popup).filter(":visible").popup("hide")},hideGracefully:function(t){t&&0===e(t.target).closest(m.popup).size()?(g.debug("Click occurred outside popup hiding popup"),g.hide()):g.debug("Click was inside popup, keeping popup open")},exists:function(){return o?h.inline||h.popup?0!==o.size():o.closest(T).size():!1},removePopup:function(){g.debug("Removing popup"),e.proxy(h.onRemove,o)(z),o.remove()},save:{conditions:function(){g.cache={title:C.attr("title")},g.cache.title&&C.removeAttr("title"),g.verbose("Saving original attributes",g.cache.title)}},restore:{conditions:function(){return z.blur(),g.cache&&g.cache.title&&(C.attr("title",g.cache.title),g.verbose("Restoring original attributes",g.cache.title)),!0}},animate:{show:function(t){t=e.isFunction(t)?t:function(){},h.transition&&e.fn.transition!==i&&C.transition("is supported")?(g.set.visible(),o.transition({animation:h.transition+" in",queue:!1,debug:h.debug,verbose:h.verbose,duration:h.duration,onComplete:function(){g.bind.close(),e.proxy(t,o)(z),e.proxy(h.onVisible,o)(z)}})):(g.set.visible(),o.stop().fadeIn(h.duration,h.easing,function(){g.bind.close(),e.proxy(t,z)()})),e.proxy(h.onShow,o)(z)},hide:function(t){t=e.isFunction(t)?t:function(){},g.debug("Hiding pop-up"),h.transition&&e.fn.transition!==i&&C.transition("is supported")?o.transition({animation:h.transition+" out",queue:!1,duration:h.duration,debug:h.debug,verbose:h.verbose,onComplete:function(){g.reset(),e.proxy(t,o)(z),e.proxy(h.onHidden,o)(z)}}):o.stop().fadeOut(h.duration,h.easing,function(){g.reset(),t()}),e.proxy(h.onHide,o)(z)}},get:{startEvent:function(){return"hover"==h.on?"mouseenter":"focus"==h.on?"focus":!1},endEvent:function(){return"hover"==h.on?"mouseleave":"focus"==h.on?"blur":!1},offstagePosition:function(i){var i=i||!1,n={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 r.offset&&i&&(g.verbose("Checking if outside viewable area",r.offset),s={top:r.offset.topn.bottom,right:r.offset.left+r.width>n.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],i=t[1],n={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 A||(g.verbose("All available positions available"),A=g.get.positions()),g.debug("Recording last position tried",e),A[e]=!0,"opposite"===h.prefer&&(u=[n[o],i],u=u.join(" "),p=A[u]===!0,g.debug("Trying opposite strategy",u)),"adjacent"===h.prefer&&a&&(u=[o,r[i]],u=u.join(" "),l=A[u]===!0,g.debug("Trying adjacent strategy",u)),(l||p)&&(g.debug("Using backup position",u),u=s[e]),u}},set:{position:function(n,r){var a,p,l=(e(t).width(),e(t).height(),k.outerWidth()),u=k.outerHeight(),c=o.outerWidth(),d=o.outerHeight(),f=s.outerWidth(),m=s.outerHeight(),w=h.distanceAway,x=k[0],P=h.inline?parseInt(t.getComputedStyle(x).getPropertyValue("margin-top"),10):0,T=h.inline?parseInt(t.getComputedStyle(x).getPropertyValue("margin-left"),10):0,O=h.inline||h.popup?k.position():k.offset();switch(n=n||C.data(y.position)||h.position,r=r||C.data(y.offset)||h.offset,j==h.maxSearchDepth&&h.lastResort&&(g.debug("Using last resort position to display",h.lastResort),n=h.lastResort),h.inline&&(g.debug("Adding targets margin to calculation"),"left center"==n||"right center"==n?(r+=P,w+=-T):"top left"==n||"top center"==n||"top right"==n?(r+=T,w-=P):(r+=T,w+=P)),g.debug("Calculating popup positioning",n),n){case"top left":a={top:"auto",bottom:m-O.top+w,left:O.left+r,right:"auto"};break;case"top center":a={bottom:m-O.top+w,left:O.left+l/2-c/2+r,top:"auto",right:"auto"};break;case"top right":a={bottom:m-O.top+w,right:f-O.left-l-r,top:"auto",left:"auto"};break;case"left center":a={top:O.top+u/2-d/2+r,right:f-O.left+w,left:"auto",bottom:"auto"};break;case"right center":a={top:O.top+u/2-d/2+r,left:O.left+l+w,bottom:"auto",right:"auto"};break;case"bottom left":a={top:O.top+u+w,left:O.left+r,bottom:"auto",right:"auto"};break;case"bottom center":a={top:O.top+u+w,left:O.left+l/2-c/2+r,bottom:"auto",right:"auto"};break;case"bottom right":a={top:O.top+u+w,right:f-O.left-l-r,left:"auto",bottom:"auto"}}if(a===i&&g.error(v.invalidPosition,n),o.css(a).removeClass(b.position).addClass(n).addClass(b.loading),p=g.get.offstagePosition(n)){if(g.debug("Popup cant fit into viewport",p),j0&&o.on("mouseenter"+x,g.event.start).on("mouseleave"+x,g.event.end)},close:function(){(h.hideOnScroll===!0||"auto"==h.hideOnScroll&&"click"!=h.on)&&(a.one("touchmove"+x,g.hideGracefully).one("scroll"+x,g.hideGracefully),T.one("touchmove"+x,g.hideGracefully).one("scroll"+x,g.hideGracefully)),"click"==h.on&&h.closable&&(g.verbose("Binding popup close event to document"),a.on("click"+x,function(t){g.verbose("Pop-up clickaway intent detected"),e.proxy(g.hideGracefully,z)(t)}))}},unbind:{close:function(){(h.hideOnScroll===!0||"auto"==h.hideOnScroll&&"click"!=h.on)&&(a.off("scroll"+x,g.hide),T.off("scroll"+x,g.hide)),"click"==h.on&&h.closable&&(g.verbose("Removing close event from document"),a.off("click"+x))}},is:{active:function(){return C.hasClass(b.active)},animating:function(){return o&&o.is(":animated")||o.hasClass(b.animating)},visible:function(){return o&&o.is(":visible")},dropdown:function(){return C.hasClass(b.dropdown)},hidden:function(){return!g.is.visible()}},reset:function(){g.remove.visible(),h.preserve||h.popup?e.fn.transition!==i&&o.transition("remove transition"):g.removePopup()},setting:function(t,o){if(e.isPlainObject(t))e.extend(!0,h,t);else{if(o===i)return h[t];h[t]=o}},internal:function(t,o){if(e.isPlainObject(t))e.extend(!0,g,t);else{if(o===i)return g[t];g[t]=o}},debug:function(){h.debug&&(h.performance?g.performance.log(arguments):(g.debug=Function.prototype.bind.call(console.info,console,h.name+":"),g.debug.apply(console,arguments)))},verbose:function(){h.verbose&&h.debug&&(h.performance?g.performance.log(arguments):(g.verbose=Function.prototype.bind.call(console.info,console,h.name+":"),g.verbose.apply(console,arguments)))},error:function(){g.error=Function.prototype.bind.call(console.error,console,h.name+":"),g.error.apply(console,arguments)},performance:{log:function(e){var t,o,i;h.performance&&(t=(new Date).getTime(),i=l||t,o=t-i,l=t,u.push({Name:e[0],Arguments:[].slice.call(e,1)||"",Element:z,"Execution Time":o})),clearTimeout(g.performance.timer),g.performance.timer=setTimeout(g.performance.display,100)},display:function(){var t=h.name+":",o=0;l=!1,clearTimeout(g.performance.timer),e.each(u,function(e,t){o+=t["Execution Time"]}),t+=" "+o+"ms",p&&(t+=" '"+p+"'"),(console.group!==i||console.table!==i)&&u.length>0&&(console.groupCollapsed(t),console.table?console.table(u):e.each(u,function(e,t){console.log(t.Name+": "+t["Execution Time"]+"ms")}),console.groupEnd()),u=[]}},invoke:function(t,o,n){var s,a,p,l=R;return o=o||f,n=z||n,"string"==typeof t&&l!==i&&(t=t.split(/[\. ]/),s=t.length-1,e.each(t,function(o,n){var r=o!=s?n+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]!==i)return a=l[r],!1;if(!e.isPlainObject(l[n])||o==s)return l[n]!==i?(a=l[n],!1):!1;l=l[n]}})),e.isFunction(a)?p=a.apply(n,o):a!==i&&(p=a),e.isArray(r)?r.push(p):r!==i?r=[r,p]:p!==i&&(r=p),a}},d?(R===i&&g.initialize(),g.invoke(c)):(R!==i&&g.destroy(),g.initialize())}),r!==i?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",context:"body",position:"top left",prefer:"opposite",lastResort:!1,delay:{show:30,hide:0},setFluidWidth:!0,target:!1,popup:!1,inline:!1,preserve:!0,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:{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=/[&<>"'`]/,i={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},n=function(e){return i[e]};return o.test(e)?e.replace(t,n):e},popup:function(t){var o="",n=e.fn.popup.settings.templates.escape;return typeof t!==i&&(typeof t.title!==i&&t.title&&(t.title=n(t.title),o+='
'+t.title+"
"),typeof t.content!==i&&t.content&&(t.content=n(t.content),o+='
'+t.content+"
")),o}}},e.extend(e.easing,{easeOutQuad:function(e,t,o,i,n){return-i*(t/=n)*(t-2)+o}})}(jQuery,window,document); \ No newline at end of file +!function(e,t,o,i){"use strict";e.fn.popup=function(n){var r,s=e(this),a=e(o),p=s.selector||"",l=("ontouchstart"in o.documentElement,(new Date).getTime()),u=[],c=arguments[0],d="string"==typeof c,f=[].slice.call(arguments,1);return s.each(function(){var o,s,g,h=e.isPlainObject(n)?e.extend(!0,{},e.fn.popup.settings,n):e.extend({},e.fn.popup.settings),m=h.selector,b=h.className,v=h.error,y=h.metadata,w=h.namespace,x="."+h.namespace,P="module-"+w,C=e(this),T=e(h.context),k=h.target?e(h.target):C,O=e(t),S=e("body"),j=0,z=!1,A=this,R=C.data(P);g={initialize:function(){g.debug("Initializing module",C),g.refresh(),"click"==h.on?C.on("click"+x,g.toggle):g.get.startEvent()&&C.on(g.get.startEvent()+x,g.event.start).on(g.get.endEvent()+x,g.event.end),h.target&&g.debug("Target set to element",k),O.on("resize"+x,g.event.resize),g.exists()?h.hoverable&&g.bind.popup():g.create(),g.instantiate()},instantiate:function(){g.verbose("Storing instance of module",g),R=g,C.data(P,R)},refresh:function(){h.popup?o=e(h.popup):h.inline&&(o=k.next(h.selector.popup)),h.popup?(o.addClass(b.loading),s=o.offsetParent(),o.removeClass(b.loading)):s=h.inline?k.offsetParent():S,s.is("html")&&(g.debug("Page is popups offset parent"),s=S)},reposition:function(){g.refresh(),g.set.position()},destroy:function(){g.debug("Destroying previous module"),o&&!h.preserve&&g.removePopup(),C.off(x).removeData(P)},event:{start:function(){var t=e.isPlainObject(h.delay)?h.delay.show:h.delay;clearTimeout(g.hideTimer),g.showTimer=setTimeout(function(){!g.is.hidden()||g.is.active()&&g.is.dropdown()||g.show()},t)},end:function(){var t=e.isPlainObject(h.delay)?h.delay.hide:h.delay;clearTimeout(g.showTimer),g.hideTimer=setTimeout(function(){g.is.visible()&&g.hide()},t)},resize:function(){g.is.visible()&&g.set.position()}},create:function(){var t=C.data(y.html)||h.html,i=C.data(y.variation)||h.variation,n=C.data(y.title)||h.title,r=C.data(y.content)||C.attr("title")||h.content;t||r||n?(g.debug("Creating pop-up html"),t||(t=h.templates.popup({title:n,content:r})),o=e("
").addClass(b.popup).addClass(i).html(t),i&&o.addClass(i),h.inline?(g.verbose("Inserting popup element inline",o),o.insertAfter(C)):(g.verbose("Appending popup element to body",o),o.appendTo(T)),h.hoverable&&g.bind.popup(),e.proxy(h.onCreate,o)(A)):0!==k.next(h.selector.popup).size()?(g.verbose("Pre-existing popup found, reverting to inline"),h.inline=!0,g.refresh(),h.hoverable&&g.bind.popup()):g.debug("No content specified skipping display",A)},toggle:function(){g.debug("Toggling pop-up"),g.is.hidden()?(g.debug("Popup is hidden, showing pop-up"),g.unbind.close(),g.hideAll(),g.show()):(g.debug("Popup is visible, hiding pop-up"),g.hide())},show:function(t){t=e.isFunction(t)?t:function(){},g.debug("Showing pop-up",h.transition),h.preserve||h.popup||g.refresh(),g.exists()||g.create(),o&&g.set.position()&&(g.save.conditions(),g.animate.show(t))},hide:function(t){t=e.isFunction(t)?t:function(){},g.remove.visible(),g.unbind.close(),g.is.visible()&&(g.restore.conditions(),g.animate.hide(t))},hideAll:function(){e(m.popup).filter(":visible").popup("hide")},hideGracefully:function(t){t&&0===e(t.target).closest(m.popup).size()?(g.debug("Click occurred outside popup hiding popup"),g.hide()):g.debug("Click was inside popup, keeping popup open")},exists:function(){return o?h.inline||h.popup?0!==o.size():o.closest(T).size():!1},removePopup:function(){g.debug("Removing popup"),e.proxy(h.onRemove,o)(A),o.size()>0&&o.remove()},save:{conditions:function(){g.cache={title:C.attr("title")},g.cache.title&&C.removeAttr("title"),g.verbose("Saving original attributes",g.cache.title)}},restore:{conditions:function(){return A.blur(),g.cache&&g.cache.title&&(C.attr("title",g.cache.title),g.verbose("Restoring original attributes",g.cache.title)),!0}},animate:{show:function(t){t=e.isFunction(t)?t:function(){},h.transition&&e.fn.transition!==i&&C.transition("is supported")?(g.set.visible(),o.transition({animation:h.transition+" in",queue:!1,debug:h.debug,verbose:h.verbose,duration:h.duration,onComplete:function(){g.bind.close(),e.proxy(t,o)(A),e.proxy(h.onVisible,o)(A)}})):(g.set.visible(),o.stop().fadeIn(h.duration,h.easing,function(){g.bind.close(),e.proxy(t,A)()})),e.proxy(h.onShow,o)(A)},hide:function(t){t=e.isFunction(t)?t:function(){},g.debug("Hiding pop-up"),h.transition&&e.fn.transition!==i&&C.transition("is supported")?o.transition({animation:h.transition+" out",queue:!1,duration:h.duration,debug:h.debug,verbose:h.verbose,onComplete:function(){g.reset(),e.proxy(t,o)(A),e.proxy(h.onHidden,o)(A)}}):o.stop().fadeOut(h.duration,h.easing,function(){g.reset(),t()}),e.proxy(h.onHide,o)(A)}},get:{startEvent:function(){return"hover"==h.on?"mouseenter":"focus"==h.on?"focus":!1},endEvent:function(){return"hover"==h.on?"mouseleave":"focus"==h.on?"blur":!1},offstagePosition:function(i){var i=i||!1,n={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 r.offset&&i&&(g.verbose("Checking if outside viewable area",r.offset),s={top:r.offset.topn.bottom,right:r.offset.left+r.width>n.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],i=t[1],n={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 z||(g.verbose("All available positions available"),z=g.get.positions()),g.debug("Recording last position tried",e),z[e]=!0,"opposite"===h.prefer&&(u=[n[o],i],u=u.join(" "),p=z[u]===!0,g.debug("Trying opposite strategy",u)),"adjacent"===h.prefer&&a&&(u=[o,r[i]],u=u.join(" "),l=z[u]===!0,g.debug("Trying adjacent strategy",u)),(l||p)&&(g.debug("Using backup position",u),u=s[e]),u}},set:{position:function(n,r){var a,p,l=(e(t).width(),e(t).height(),k.outerWidth()),u=k.outerHeight(),c=o.outerWidth(),d=o.outerHeight(),f=s.outerWidth(),m=s.outerHeight(),w=h.distanceAway,x=k[0],P=h.inline?parseInt(t.getComputedStyle(x).getPropertyValue("margin-top"),10):0,T=h.inline?parseInt(t.getComputedStyle(x).getPropertyValue("margin-left"),10):0,O=h.inline||h.popup?k.position():k.offset();switch(n=n||C.data(y.position)||h.position,r=r||C.data(y.offset)||h.offset,j==h.maxSearchDepth&&h.lastResort&&(g.debug("Using last resort position to display",h.lastResort),n=h.lastResort),h.inline&&(g.debug("Adding targets margin to calculation"),"left center"==n||"right center"==n?(r+=P,w+=-T):"top left"==n||"top center"==n||"top right"==n?(r+=T,w-=P):(r+=T,w+=P)),g.debug("Calculating popup positioning",n),n){case"top left":a={top:"auto",bottom:m-O.top+w,left:O.left+r,right:"auto"};break;case"top center":a={bottom:m-O.top+w,left:O.left+l/2-c/2+r,top:"auto",right:"auto"};break;case"top right":a={bottom:m-O.top+w,right:f-O.left-l-r,top:"auto",left:"auto"};break;case"left center":a={top:O.top+u/2-d/2+r,right:f-O.left+w,left:"auto",bottom:"auto"};break;case"right center":a={top:O.top+u/2-d/2+r,left:O.left+l+w,bottom:"auto",right:"auto"};break;case"bottom left":a={top:O.top+u+w,left:O.left+r,bottom:"auto",right:"auto"};break;case"bottom center":a={top:O.top+u+w,left:O.left+l/2-c/2+r,bottom:"auto",right:"auto"};break;case"bottom right":a={top:O.top+u+w,right:f-O.left-l-r,left:"auto",bottom:"auto"}}if(a===i&&g.error(v.invalidPosition,n),g.debug("Calculated popup positioning values",a),o.css(a).removeClass(b.position).addClass(n).addClass(b.loading),p=g.get.offstagePosition(n)){if(g.debug("Popup cant fit into viewport",p),j0&&o.on("mouseenter"+x,g.event.start).on("mouseleave"+x,g.event.end)},close:function(){(h.hideOnScroll===!0||"auto"==h.hideOnScroll&&"click"!=h.on)&&(a.one("touchmove"+x,g.hideGracefully).one("scroll"+x,g.hideGracefully),T.one("touchmove"+x,g.hideGracefully).one("scroll"+x,g.hideGracefully)),"click"==h.on&&h.closable&&(g.verbose("Binding popup close event to document"),a.on("click"+x,function(t){g.verbose("Pop-up clickaway intent detected"),e.proxy(g.hideGracefully,A)(t)}))}},unbind:{close:function(){(h.hideOnScroll===!0||"auto"==h.hideOnScroll&&"click"!=h.on)&&(a.off("scroll"+x,g.hide),T.off("scroll"+x,g.hide)),"click"==h.on&&h.closable&&(g.verbose("Removing close event from document"),a.off("click"+x))}},is:{active:function(){return C.hasClass(b.active)},animating:function(){return o&&o.is(":animated")||o.hasClass(b.animating)},visible:function(){return o&&o.is(":visible")},dropdown:function(){return C.hasClass(b.dropdown)},hidden:function(){return!g.is.visible()}},reset:function(){g.remove.visible(),h.preserve||h.popup?e.fn.transition!==i&&o.transition("remove transition"):g.removePopup()},setting:function(t,o){if(e.isPlainObject(t))e.extend(!0,h,t);else{if(o===i)return h[t];h[t]=o}},internal:function(t,o){if(e.isPlainObject(t))e.extend(!0,g,t);else{if(o===i)return g[t];g[t]=o}},debug:function(){h.debug&&(h.performance?g.performance.log(arguments):(g.debug=Function.prototype.bind.call(console.info,console,h.name+":"),g.debug.apply(console,arguments)))},verbose:function(){h.verbose&&h.debug&&(h.performance?g.performance.log(arguments):(g.verbose=Function.prototype.bind.call(console.info,console,h.name+":"),g.verbose.apply(console,arguments)))},error:function(){g.error=Function.prototype.bind.call(console.error,console,h.name+":"),g.error.apply(console,arguments)},performance:{log:function(e){var t,o,i;h.performance&&(t=(new Date).getTime(),i=l||t,o=t-i,l=t,u.push({Name:e[0],Arguments:[].slice.call(e,1)||"",Element:A,"Execution Time":o})),clearTimeout(g.performance.timer),g.performance.timer=setTimeout(g.performance.display,100)},display:function(){var t=h.name+":",o=0;l=!1,clearTimeout(g.performance.timer),e.each(u,function(e,t){o+=t["Execution Time"]}),t+=" "+o+"ms",p&&(t+=" '"+p+"'"),(console.group!==i||console.table!==i)&&u.length>0&&(console.groupCollapsed(t),console.table?console.table(u):e.each(u,function(e,t){console.log(t.Name+": "+t["Execution Time"]+"ms")}),console.groupEnd()),u=[]}},invoke:function(t,o,n){var s,a,p,l=R;return o=o||f,n=A||n,"string"==typeof t&&l!==i&&(t=t.split(/[\. ]/),s=t.length-1,e.each(t,function(o,n){var r=o!=s?n+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]!==i)return a=l[r],!1;if(!e.isPlainObject(l[n])||o==s)return l[n]!==i?(a=l[n],!1):!1;l=l[n]}})),e.isFunction(a)?p=a.apply(n,o):a!==i&&(p=a),e.isArray(r)?r.push(p):r!==i?r=[r,p]:p!==i&&(r=p),a}},d?(R===i&&g.initialize(),g.invoke(c)):(R!==i&&g.destroy(),g.initialize())}),r!==i?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",context:"body",position:"top left",prefer:"opposite",lastResort:!1,delay:{show:30,hide:0},setFluidWidth:!0,target:!1,popup:!1,inline:!1,preserve:!0,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:{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=/[&<>"'`]/,i={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},n=function(e){return i[e]};return o.test(e)?e.replace(t,n):e},popup:function(t){var o="",n=e.fn.popup.settings.templates.escape;return typeof t!==i&&(typeof t.title!==i&&t.title&&(t.title=n(t.title),o+='
'+t.title+"
"),typeof t.content!==i&&t.content&&(t.content=n(t.content),o+='
'+t.content+"
")),o}}},e.extend(e.easing,{easeOutQuad:function(e,t,o,i,n){return-i*(t/=n)*(t-2)+o}})}(jQuery,window,document); \ No newline at end of file From 0603ef7cf6d73ef5006258954ceb83474d1ffedb Mon Sep 17 00:00:00 2001 From: Pusher Robot Date: Thu, 15 Jan 2015 21:52:55 -0500 Subject: [PATCH 18/22] Updated component release from Semantic-UI (Automatic) --- RELEASE-NOTES.md | 18 ++++++ composer.json | 2 +- index.js | 151 ++++++++++++++++++++++++++++++++++------------- package.json | 2 +- popup.css | 4 +- popup.js | 151 ++++++++++++++++++++++++++++++++++------------- popup.min.css | 4 +- popup.min.js | 4 +- 8 files changed, 245 insertions(+), 91 deletions(-) mode change 100755 => 100644 popup.css mode change 100755 => 100644 popup.min.css diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index a2cf134..982262e 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -1,3 +1,21 @@ +### Version 1.7.0 - January 14, 2015 + +- **Popup** - Popup now uses its own custom method for determining `offsetParent` meaning 3D contexts (like inside an animation) no longer should break positioning +- **Popup** - Popup now uses `preserve: false` by default, this is slightly less performant but will reduce page clutter caused by leaving generated elements in the DOM +- **Popup** - `wide` and `very wide` popup will now appear when screen size is below their `max-width` +- **Popup** - Popup no longer blurs element on popup hide + +### Version 1.6.0 - January 05, 2015 + +- **Popup** - Fix issue with `ui popup` receiving error ``$offsetParent is undefined`` when using a pre-defined popup +- **Popup** - Fix issue with ``ui popup` not appearing with ``ui flowing popup`` due to newly added ``min-width: max-content`` + +### Version 1.5.0 - December 30, 2014 + +- **Popup** - Popup now uses the new property ``min-width: max-content`` to allow for better display with ``inline`` in some circumstances where it escapes parent element. +- **Popup** - Popup destroy will now also destroy any unfired timers (show/hide delay) +- **Popup** - Popup now moves to the same offset context to avoid positioning errors when using a named pre-existing popup. + ### Version 1.1.0 - December 02, 2014 - **Popup** - Popup now has a ``settings.prefer`` that defaults to ``adjacent``. This setting sets prefered next placement when a popup cannot fit on screen in the chosen placement. ``prefer`` can also be set to ``opposite`` to prefer the same position on the opposite side diff --git a/composer.json b/composer.json index 0d86b0a..c09d754 100644 --- a/composer.json +++ b/composer.json @@ -19,5 +19,5 @@ "jquery": "x.x.x" }, "main": "popup.js", - "version": "1.4.1" + "version": "1.7.2" } \ No newline at end of file diff --git a/index.js b/index.js index fd15178..0421c41 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,6 @@ /* * # Semantic - Popup - * http://github.com/jlukic/semantic-ui/ + * http://github.com/semantic-org/semantic-ui/ * * * Copyright 2014 Contributor @@ -72,7 +72,6 @@ module.exports = function(parameters) { // binds events initialize: function() { module.debug('Initializing module', $module); - module.refresh(); if(settings.on == 'click') { $module .on('click' + eventNamespace, module.toggle) @@ -90,12 +89,9 @@ module.exports = function(parameters) { $window .on('resize' + eventNamespace, module.event.resize) ; - if( !module.exists() ) { + if( !module.exists() && settings.preserve) { module.create(); } - else if(settings.hoverable) { - module.bind.popup(); - } module.instantiate(); }, @@ -113,22 +109,31 @@ module.exports = function(parameters) { } else { if(settings.inline) { - $popup = $target.next(settings.selector.popup); + $popup = $target.next(selector.popup); } } if(settings.popup) { $popup.addClass(className.loading); - $offsetParent = $popup.offsetParent(); + $offsetParent = module.get.offsetParent(); $popup.removeClass(className.loading); + if(module.has.popup() && module.get.offsetParent($popup)[0] !== $offsetParent[0]) { + module.debug('Moving popup to the same offset parent as activating element'); + $popup + .detach() + .appendTo($offsetParent) + ; + } } else { $offsetParent = (settings.inline) - ? $target.offsetParent() + ? module.get.offsetParent($target) + : module.has.popup() + ? module.get.offsetParent($popup) : $body ; } if( $offsetParent.is('html') ) { - module.debug('Page is popups offset parent'); + module.debug('Setting page as offset parent'); $offsetParent = $body; } }, @@ -143,6 +148,8 @@ module.exports = function(parameters) { if($popup && !settings.preserve) { module.removePopup(); } + clearTimeout(module.hideTimer); + clearTimeout(module.showTimer); $module .off(eventNamespace) .removeData(moduleNamespace) @@ -158,7 +165,7 @@ module.exports = function(parameters) { ; clearTimeout(module.hideTimer); module.showTimer = setTimeout(function() { - if( module.is.hidden() && !( module.is.active() && module.is.dropdown()) ) { + if(module.is.hidden() && !( module.is.active() && module.is.dropdown()) ) { module.show(); } }, delay); @@ -171,7 +178,7 @@ module.exports = function(parameters) { ; clearTimeout(module.showTimer); module.hideTimer = setTimeout(function() { - if( module.is.visible() ) { + if(module.is.visible() ) { module.hide(); } }, delay); @@ -221,14 +228,23 @@ module.exports = function(parameters) { .appendTo( $context ) ; } + module.refresh(); if(settings.hoverable) { module.bind.popup(); } - $.proxy(settings.onCreate, $popup)(element); + settings.onCreate.call($popup, element); } - else if($target.next(settings.selector.popup).size() !== 0) { - module.verbose('Pre-existing popup found, reverting to inline'); + else if($target.next(selector.popup).length !== 0) { + module.verbose('Pre-existing popup found'); settings.inline = true; + settings.popup = $target.next(selector.popup); + module.refresh(); + if(settings.hoverable) { + module.bind.popup(); + } + } + else if(settings.popup) { + module.verbose('Used popup specified in settings'); module.refresh(); if(settings.hoverable) { module.bind.popup(); @@ -257,12 +273,12 @@ module.exports = function(parameters) { show: function(callback) { callback = $.isFunction(callback) ? callback : function(){}; module.debug('Showing pop-up', settings.transition); - if(!settings.preserve && !settings.popup) { - module.refresh(); - } if( !module.exists() ) { module.create(); } + else if(!settings.preserve && !settings.popup) { + module.refresh(); + } if( $popup && module.set.position() ) { module.save.conditions(); module.animate.show(callback); @@ -283,13 +299,13 @@ module.exports = function(parameters) { hideAll: function() { $(selector.popup) .filter(':visible') - .popup('hide') + .transition('hide') ; }, hideGracefully: function(event) { // don't close on clicks inside popup - if(event && $(event.target).closest(selector.popup).size() === 0) { + if(event && $(event.target).closest(selector.popup).length === 0) { module.debug('Click occurred outside popup hiding popup'); module.hide(); } @@ -303,19 +319,23 @@ module.exports = function(parameters) { return false; } if(settings.inline || settings.popup) { - return ( $popup.size() !== 0 ); + return ( module.has.popup() ); } else { - return ( $popup.closest($context).size() ); + return ( $popup.closest($context).length >= 1 ) + ? true + : false + ; } }, removePopup: function() { - module.debug('Removing popup'); - $.proxy(settings.onRemove, $popup)(element); - if($popup.size() > 0) { + module.debug('Removing popup', $popup); + if( module.has.popup() && !settings.popup) { $popup.remove(); + $popup = undefined; } + settings.onRemove.call($popup, element); }, save: { @@ -331,7 +351,6 @@ module.exports = function(parameters) { }, restore: { conditions: function() { - element.blur(); if(module.cache && module.cache.title) { $module.attr('title', module.cache.title); module.verbose('Restoring original attributes', module.cache.title); @@ -353,8 +372,8 @@ module.exports = function(parameters) { duration : settings.duration, onComplete : function() { module.bind.close(); - $.proxy(callback, $popup)(element); - $.proxy(settings.onVisible, $popup)(element); + callback.call($popup, element); + settings.onVisible.call($popup, element); } }) ; @@ -365,11 +384,12 @@ module.exports = function(parameters) { .stop() .fadeIn(settings.duration, settings.easing, function() { module.bind.close(); - $.proxy(callback, element)(); + callback.call($popup, element); + settings.onVisible.call($popup, element); }) ; } - $.proxy(settings.onShow, $popup)(element); + settings.onShow.call($popup, element); }, hide: function(callback) { callback = $.isFunction(callback) ? callback : function(){}; @@ -384,8 +404,8 @@ module.exports = function(parameters) { verbose : settings.verbose, onComplete : function() { module.reset(); - $.proxy(callback, $popup)(element); - $.proxy(settings.onHidden, $popup)(element); + callback.call($popup, element); + settings.onHidden.call($popup, element); } }) ; @@ -395,11 +415,12 @@ module.exports = function(parameters) { .stop() .fadeOut(settings.duration, settings.easing, function() { module.reset(); - callback(); + callback.call($popup, element); + settings.onHidden.call($popup, element); }) ; } - $.proxy(settings.onHide, $popup)(element); + settings.onHide.call($popup, element); } }, @@ -422,9 +443,35 @@ module.exports = function(parameters) { } return false; }, + offsetParent: function($target) { + var + element = ($target !== undefined) + ? $target[0] + : $module[0], + parentNode = element.parentNode, + $node = $(parentNode) + ; + if(parentNode) { + var + is2D = ($node.css('transform') === 'none'), + isStatic = ($node.css('position') === 'static'), + isHTML = $node.is('html') + ; + while(parentNode && !isHTML && isStatic && is2D) { + parentNode = parentNode.parentNode; + $node = $(parentNode); + is2D = ($node.css('transform') === 'none'); + isStatic = ($node.css('position') === 'static'); + isHTML = $node.is('html'); + } + } + return ($node && $node.length > 0) + ? $node + : $() + ; + }, offstagePosition: function(position) { var - position = position || false, boundary = { top : $(window).scrollTop(), bottom : $(window).scrollTop() + $(window).height(), @@ -439,6 +486,7 @@ module.exports = function(parameters) { offstage = {}, offstagePositions = [] ; + position = position || false; if(popup.offset && position) { module.verbose('Checking if outside viewable area', popup.offset); offstage = { @@ -553,13 +601,14 @@ module.exports = function(parameters) { ? parseInt( window.getComputedStyle(targetElement).getPropertyValue('margin-top'), 10) : 0, marginLeft = (settings.inline) - ? parseInt( window.getComputedStyle(targetElement).getPropertyValue('margin-left'), 10) + ? parseInt( window.getComputedStyle(targetElement).getPropertyValue(module.is.rtl() ? 'margin-right' : 'margin-left'), 10) : 0, target = (settings.inline || settings.popup) ? $target.position() : $target.offset(), + computedPosition, positioning, offstagePosition ; @@ -587,7 +636,18 @@ module.exports = function(parameters) { } } module.debug('Calculating popup positioning', position); - switch(position) { + + computedPosition = position; + if (module.is.rtl()) { + computedPosition = computedPosition.replace(/left|right/g, function (match) { + return (match == 'left') + ? 'right' + : 'left' + ; + }); + module.debug('RTL: Popup positioning updated', computedPosition); + } + switch (computedPosition) { case 'top left': positioning = { top : 'auto', @@ -726,7 +786,7 @@ module.exports = function(parameters) { bind: { popup: function() { module.verbose('Allowing hover events on popup to prevent closing'); - if($popup && $popup.size() > 0) { + if( $popup && module.has.popup() ) { $popup .on('mouseenter' + eventNamespace, module.event.start) .on('mouseleave' + eventNamespace, module.event.end) @@ -749,7 +809,7 @@ module.exports = function(parameters) { $document .on('click' + eventNamespace, function(event) { module.verbose('Pop-up clickaway intent detected'); - $.proxy(module.hideGracefully, element)(event); + module.hideGracefully.call(element, event); }) ; } @@ -775,6 +835,12 @@ module.exports = function(parameters) { } }, + has: { + popup: function() { + return ($popup && $popup.length > 0); + } + }, + is: { active: function() { return $module.hasClass(className.active); @@ -790,12 +856,15 @@ module.exports = function(parameters) { }, hidden: function() { return !module.is.visible(); + }, + rtl: function () { + return $module.css('direction') == 'rtl'; } }, reset: function() { module.remove.visible(); - if(settings.preserve || settings.popup) { + if(settings.preserve) { if($.fn.transition !== undefined) { $popup .transition('remove transition') @@ -1024,7 +1093,7 @@ module.exports.settings = { target : false, popup : false, inline : false, - preserve : true, + preserve : false, hoverable : false, duration : 200, diff --git a/package.json b/package.json index 9136550..5026923 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "semantic-ui-popup", - "version": "1.4.1", + "version": "1.7.2", "title": "Semantic UI - Popup", "description": "Single component release of popup", "homepage": "http://www.semantic-ui.com", diff --git a/popup.css b/popup.css old mode 100755 new mode 100644 index be2c0fd..ce27c10 --- a/popup.css +++ b/popup.css @@ -1,5 +1,5 @@ /* - * # Semantic UI + * # Semantic UI - 1.7.2 * https://github.com/Semantic-Org/Semantic-UI * http://www.semantic-ui.com/ * @@ -217,11 +217,9 @@ ---------------*/ .ui.wide.popup { - width: 350px; max-width: 350px; } .ui[class*="very wide"].popup { - width: 550px; max-width: 550px; } diff --git a/popup.js b/popup.js index a591dc4..8b9a7cb 100644 --- a/popup.js +++ b/popup.js @@ -1,6 +1,6 @@ /* * # Semantic - Popup - * http://github.com/jlukic/semantic-ui/ + * http://github.com/semantic-org/semantic-ui/ * * * Copyright 2014 Contributor @@ -70,7 +70,6 @@ $.fn.popup = function(parameters) { // binds events initialize: function() { module.debug('Initializing module', $module); - module.refresh(); if(settings.on == 'click') { $module .on('click' + eventNamespace, module.toggle) @@ -88,12 +87,9 @@ $.fn.popup = function(parameters) { $window .on('resize' + eventNamespace, module.event.resize) ; - if( !module.exists() ) { + if( !module.exists() && settings.preserve) { module.create(); } - else if(settings.hoverable) { - module.bind.popup(); - } module.instantiate(); }, @@ -111,22 +107,31 @@ $.fn.popup = function(parameters) { } else { if(settings.inline) { - $popup = $target.next(settings.selector.popup); + $popup = $target.next(selector.popup); } } if(settings.popup) { $popup.addClass(className.loading); - $offsetParent = $popup.offsetParent(); + $offsetParent = module.get.offsetParent(); $popup.removeClass(className.loading); + if(module.has.popup() && module.get.offsetParent($popup)[0] !== $offsetParent[0]) { + module.debug('Moving popup to the same offset parent as activating element'); + $popup + .detach() + .appendTo($offsetParent) + ; + } } else { $offsetParent = (settings.inline) - ? $target.offsetParent() + ? module.get.offsetParent($target) + : module.has.popup() + ? module.get.offsetParent($popup) : $body ; } if( $offsetParent.is('html') ) { - module.debug('Page is popups offset parent'); + module.debug('Setting page as offset parent'); $offsetParent = $body; } }, @@ -141,6 +146,8 @@ $.fn.popup = function(parameters) { if($popup && !settings.preserve) { module.removePopup(); } + clearTimeout(module.hideTimer); + clearTimeout(module.showTimer); $module .off(eventNamespace) .removeData(moduleNamespace) @@ -156,7 +163,7 @@ $.fn.popup = function(parameters) { ; clearTimeout(module.hideTimer); module.showTimer = setTimeout(function() { - if( module.is.hidden() && !( module.is.active() && module.is.dropdown()) ) { + if(module.is.hidden() && !( module.is.active() && module.is.dropdown()) ) { module.show(); } }, delay); @@ -169,7 +176,7 @@ $.fn.popup = function(parameters) { ; clearTimeout(module.showTimer); module.hideTimer = setTimeout(function() { - if( module.is.visible() ) { + if(module.is.visible() ) { module.hide(); } }, delay); @@ -219,14 +226,23 @@ $.fn.popup = function(parameters) { .appendTo( $context ) ; } + module.refresh(); if(settings.hoverable) { module.bind.popup(); } - $.proxy(settings.onCreate, $popup)(element); + settings.onCreate.call($popup, element); } - else if($target.next(settings.selector.popup).size() !== 0) { - module.verbose('Pre-existing popup found, reverting to inline'); + else if($target.next(selector.popup).length !== 0) { + module.verbose('Pre-existing popup found'); settings.inline = true; + settings.popup = $target.next(selector.popup); + module.refresh(); + if(settings.hoverable) { + module.bind.popup(); + } + } + else if(settings.popup) { + module.verbose('Used popup specified in settings'); module.refresh(); if(settings.hoverable) { module.bind.popup(); @@ -255,12 +271,12 @@ $.fn.popup = function(parameters) { show: function(callback) { callback = $.isFunction(callback) ? callback : function(){}; module.debug('Showing pop-up', settings.transition); - if(!settings.preserve && !settings.popup) { - module.refresh(); - } if( !module.exists() ) { module.create(); } + else if(!settings.preserve && !settings.popup) { + module.refresh(); + } if( $popup && module.set.position() ) { module.save.conditions(); module.animate.show(callback); @@ -281,13 +297,13 @@ $.fn.popup = function(parameters) { hideAll: function() { $(selector.popup) .filter(':visible') - .popup('hide') + .transition('hide') ; }, hideGracefully: function(event) { // don't close on clicks inside popup - if(event && $(event.target).closest(selector.popup).size() === 0) { + if(event && $(event.target).closest(selector.popup).length === 0) { module.debug('Click occurred outside popup hiding popup'); module.hide(); } @@ -301,19 +317,23 @@ $.fn.popup = function(parameters) { return false; } if(settings.inline || settings.popup) { - return ( $popup.size() !== 0 ); + return ( module.has.popup() ); } else { - return ( $popup.closest($context).size() ); + return ( $popup.closest($context).length >= 1 ) + ? true + : false + ; } }, removePopup: function() { - module.debug('Removing popup'); - $.proxy(settings.onRemove, $popup)(element); - if($popup.size() > 0) { + module.debug('Removing popup', $popup); + if( module.has.popup() && !settings.popup) { $popup.remove(); + $popup = undefined; } + settings.onRemove.call($popup, element); }, save: { @@ -329,7 +349,6 @@ $.fn.popup = function(parameters) { }, restore: { conditions: function() { - element.blur(); if(module.cache && module.cache.title) { $module.attr('title', module.cache.title); module.verbose('Restoring original attributes', module.cache.title); @@ -351,8 +370,8 @@ $.fn.popup = function(parameters) { duration : settings.duration, onComplete : function() { module.bind.close(); - $.proxy(callback, $popup)(element); - $.proxy(settings.onVisible, $popup)(element); + callback.call($popup, element); + settings.onVisible.call($popup, element); } }) ; @@ -363,11 +382,12 @@ $.fn.popup = function(parameters) { .stop() .fadeIn(settings.duration, settings.easing, function() { module.bind.close(); - $.proxy(callback, element)(); + callback.call($popup, element); + settings.onVisible.call($popup, element); }) ; } - $.proxy(settings.onShow, $popup)(element); + settings.onShow.call($popup, element); }, hide: function(callback) { callback = $.isFunction(callback) ? callback : function(){}; @@ -382,8 +402,8 @@ $.fn.popup = function(parameters) { verbose : settings.verbose, onComplete : function() { module.reset(); - $.proxy(callback, $popup)(element); - $.proxy(settings.onHidden, $popup)(element); + callback.call($popup, element); + settings.onHidden.call($popup, element); } }) ; @@ -393,11 +413,12 @@ $.fn.popup = function(parameters) { .stop() .fadeOut(settings.duration, settings.easing, function() { module.reset(); - callback(); + callback.call($popup, element); + settings.onHidden.call($popup, element); }) ; } - $.proxy(settings.onHide, $popup)(element); + settings.onHide.call($popup, element); } }, @@ -420,9 +441,35 @@ $.fn.popup = function(parameters) { } return false; }, + offsetParent: function($target) { + var + element = ($target !== undefined) + ? $target[0] + : $module[0], + parentNode = element.parentNode, + $node = $(parentNode) + ; + if(parentNode) { + var + is2D = ($node.css('transform') === 'none'), + isStatic = ($node.css('position') === 'static'), + isHTML = $node.is('html') + ; + while(parentNode && !isHTML && isStatic && is2D) { + parentNode = parentNode.parentNode; + $node = $(parentNode); + is2D = ($node.css('transform') === 'none'); + isStatic = ($node.css('position') === 'static'); + isHTML = $node.is('html'); + } + } + return ($node && $node.length > 0) + ? $node + : $() + ; + }, offstagePosition: function(position) { var - position = position || false, boundary = { top : $(window).scrollTop(), bottom : $(window).scrollTop() + $(window).height(), @@ -437,6 +484,7 @@ $.fn.popup = function(parameters) { offstage = {}, offstagePositions = [] ; + position = position || false; if(popup.offset && position) { module.verbose('Checking if outside viewable area', popup.offset); offstage = { @@ -551,13 +599,14 @@ $.fn.popup = function(parameters) { ? parseInt( window.getComputedStyle(targetElement).getPropertyValue('margin-top'), 10) : 0, marginLeft = (settings.inline) - ? parseInt( window.getComputedStyle(targetElement).getPropertyValue('margin-left'), 10) + ? parseInt( window.getComputedStyle(targetElement).getPropertyValue(module.is.rtl() ? 'margin-right' : 'margin-left'), 10) : 0, target = (settings.inline || settings.popup) ? $target.position() : $target.offset(), + computedPosition, positioning, offstagePosition ; @@ -585,7 +634,18 @@ $.fn.popup = function(parameters) { } } module.debug('Calculating popup positioning', position); - switch(position) { + + computedPosition = position; + if (module.is.rtl()) { + computedPosition = computedPosition.replace(/left|right/g, function (match) { + return (match == 'left') + ? 'right' + : 'left' + ; + }); + module.debug('RTL: Popup positioning updated', computedPosition); + } + switch (computedPosition) { case 'top left': positioning = { top : 'auto', @@ -724,7 +784,7 @@ $.fn.popup = function(parameters) { bind: { popup: function() { module.verbose('Allowing hover events on popup to prevent closing'); - if($popup && $popup.size() > 0) { + if( $popup && module.has.popup() ) { $popup .on('mouseenter' + eventNamespace, module.event.start) .on('mouseleave' + eventNamespace, module.event.end) @@ -747,7 +807,7 @@ $.fn.popup = function(parameters) { $document .on('click' + eventNamespace, function(event) { module.verbose('Pop-up clickaway intent detected'); - $.proxy(module.hideGracefully, element)(event); + module.hideGracefully.call(element, event); }) ; } @@ -773,6 +833,12 @@ $.fn.popup = function(parameters) { } }, + has: { + popup: function() { + return ($popup && $popup.length > 0); + } + }, + is: { active: function() { return $module.hasClass(className.active); @@ -788,12 +854,15 @@ $.fn.popup = function(parameters) { }, hidden: function() { return !module.is.visible(); + }, + rtl: function () { + return $module.css('direction') == 'rtl'; } }, reset: function() { module.remove.visible(); - if(settings.preserve || settings.popup) { + if(settings.preserve) { if($.fn.transition !== undefined) { $popup .transition('remove transition') @@ -1022,7 +1091,7 @@ $.fn.popup.settings = { target : false, popup : false, inline : false, - preserve : true, + preserve : false, hoverable : false, duration : 200, diff --git a/popup.min.css b/popup.min.css old mode 100755 new mode 100644 index 8f7e66e..a7a82b5 --- a/popup.min.css +++ b/popup.min.css @@ -1,5 +1,5 @@ /* - * # Semantic UI + * # Semantic UI - 1.7.2 * https://github.com/Semantic-Org/Semantic-UI * http://www.semantic-ui.com/ * @@ -8,4 +8,4 @@ * http://opensource.org/licenses/MIT * */ -.ui.popup{display:none;position:absolute;top:0;right:0;z-index:900;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)}.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{margin:0}.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{width:350px;max-width:350px}.ui[class*="very wide"].popup{width:550px;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;z-index:900;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)}.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{margin:0}.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 diff --git a/popup.min.js b/popup.min.js index 8c5c09c..cf0a36d 100644 --- a/popup.min.js +++ b/popup.min.js @@ -1,5 +1,5 @@ /* - * # Semantic UI + * # Semantic UI - 1.7.2 * https://github.com/Semantic-Org/Semantic-UI * http://www.semantic-ui.com/ * @@ -8,4 +8,4 @@ * http://opensource.org/licenses/MIT * */ -!function(e,t,o,i){"use strict";e.fn.popup=function(n){var r,s=e(this),a=e(o),p=s.selector||"",l=("ontouchstart"in o.documentElement,(new Date).getTime()),u=[],c=arguments[0],d="string"==typeof c,f=[].slice.call(arguments,1);return s.each(function(){var o,s,g,h=e.isPlainObject(n)?e.extend(!0,{},e.fn.popup.settings,n):e.extend({},e.fn.popup.settings),m=h.selector,b=h.className,v=h.error,y=h.metadata,w=h.namespace,x="."+h.namespace,P="module-"+w,C=e(this),T=e(h.context),k=h.target?e(h.target):C,O=e(t),S=e("body"),j=0,z=!1,A=this,R=C.data(P);g={initialize:function(){g.debug("Initializing module",C),g.refresh(),"click"==h.on?C.on("click"+x,g.toggle):g.get.startEvent()&&C.on(g.get.startEvent()+x,g.event.start).on(g.get.endEvent()+x,g.event.end),h.target&&g.debug("Target set to element",k),O.on("resize"+x,g.event.resize),g.exists()?h.hoverable&&g.bind.popup():g.create(),g.instantiate()},instantiate:function(){g.verbose("Storing instance of module",g),R=g,C.data(P,R)},refresh:function(){h.popup?o=e(h.popup):h.inline&&(o=k.next(h.selector.popup)),h.popup?(o.addClass(b.loading),s=o.offsetParent(),o.removeClass(b.loading)):s=h.inline?k.offsetParent():S,s.is("html")&&(g.debug("Page is popups offset parent"),s=S)},reposition:function(){g.refresh(),g.set.position()},destroy:function(){g.debug("Destroying previous module"),o&&!h.preserve&&g.removePopup(),C.off(x).removeData(P)},event:{start:function(){var t=e.isPlainObject(h.delay)?h.delay.show:h.delay;clearTimeout(g.hideTimer),g.showTimer=setTimeout(function(){!g.is.hidden()||g.is.active()&&g.is.dropdown()||g.show()},t)},end:function(){var t=e.isPlainObject(h.delay)?h.delay.hide:h.delay;clearTimeout(g.showTimer),g.hideTimer=setTimeout(function(){g.is.visible()&&g.hide()},t)},resize:function(){g.is.visible()&&g.set.position()}},create:function(){var t=C.data(y.html)||h.html,i=C.data(y.variation)||h.variation,n=C.data(y.title)||h.title,r=C.data(y.content)||C.attr("title")||h.content;t||r||n?(g.debug("Creating pop-up html"),t||(t=h.templates.popup({title:n,content:r})),o=e("
").addClass(b.popup).addClass(i).html(t),i&&o.addClass(i),h.inline?(g.verbose("Inserting popup element inline",o),o.insertAfter(C)):(g.verbose("Appending popup element to body",o),o.appendTo(T)),h.hoverable&&g.bind.popup(),e.proxy(h.onCreate,o)(A)):0!==k.next(h.selector.popup).size()?(g.verbose("Pre-existing popup found, reverting to inline"),h.inline=!0,g.refresh(),h.hoverable&&g.bind.popup()):g.debug("No content specified skipping display",A)},toggle:function(){g.debug("Toggling pop-up"),g.is.hidden()?(g.debug("Popup is hidden, showing pop-up"),g.unbind.close(),g.hideAll(),g.show()):(g.debug("Popup is visible, hiding pop-up"),g.hide())},show:function(t){t=e.isFunction(t)?t:function(){},g.debug("Showing pop-up",h.transition),h.preserve||h.popup||g.refresh(),g.exists()||g.create(),o&&g.set.position()&&(g.save.conditions(),g.animate.show(t))},hide:function(t){t=e.isFunction(t)?t:function(){},g.remove.visible(),g.unbind.close(),g.is.visible()&&(g.restore.conditions(),g.animate.hide(t))},hideAll:function(){e(m.popup).filter(":visible").popup("hide")},hideGracefully:function(t){t&&0===e(t.target).closest(m.popup).size()?(g.debug("Click occurred outside popup hiding popup"),g.hide()):g.debug("Click was inside popup, keeping popup open")},exists:function(){return o?h.inline||h.popup?0!==o.size():o.closest(T).size():!1},removePopup:function(){g.debug("Removing popup"),e.proxy(h.onRemove,o)(A),o.size()>0&&o.remove()},save:{conditions:function(){g.cache={title:C.attr("title")},g.cache.title&&C.removeAttr("title"),g.verbose("Saving original attributes",g.cache.title)}},restore:{conditions:function(){return A.blur(),g.cache&&g.cache.title&&(C.attr("title",g.cache.title),g.verbose("Restoring original attributes",g.cache.title)),!0}},animate:{show:function(t){t=e.isFunction(t)?t:function(){},h.transition&&e.fn.transition!==i&&C.transition("is supported")?(g.set.visible(),o.transition({animation:h.transition+" in",queue:!1,debug:h.debug,verbose:h.verbose,duration:h.duration,onComplete:function(){g.bind.close(),e.proxy(t,o)(A),e.proxy(h.onVisible,o)(A)}})):(g.set.visible(),o.stop().fadeIn(h.duration,h.easing,function(){g.bind.close(),e.proxy(t,A)()})),e.proxy(h.onShow,o)(A)},hide:function(t){t=e.isFunction(t)?t:function(){},g.debug("Hiding pop-up"),h.transition&&e.fn.transition!==i&&C.transition("is supported")?o.transition({animation:h.transition+" out",queue:!1,duration:h.duration,debug:h.debug,verbose:h.verbose,onComplete:function(){g.reset(),e.proxy(t,o)(A),e.proxy(h.onHidden,o)(A)}}):o.stop().fadeOut(h.duration,h.easing,function(){g.reset(),t()}),e.proxy(h.onHide,o)(A)}},get:{startEvent:function(){return"hover"==h.on?"mouseenter":"focus"==h.on?"focus":!1},endEvent:function(){return"hover"==h.on?"mouseleave":"focus"==h.on?"blur":!1},offstagePosition:function(i){var i=i||!1,n={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 r.offset&&i&&(g.verbose("Checking if outside viewable area",r.offset),s={top:r.offset.topn.bottom,right:r.offset.left+r.width>n.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],i=t[1],n={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 z||(g.verbose("All available positions available"),z=g.get.positions()),g.debug("Recording last position tried",e),z[e]=!0,"opposite"===h.prefer&&(u=[n[o],i],u=u.join(" "),p=z[u]===!0,g.debug("Trying opposite strategy",u)),"adjacent"===h.prefer&&a&&(u=[o,r[i]],u=u.join(" "),l=z[u]===!0,g.debug("Trying adjacent strategy",u)),(l||p)&&(g.debug("Using backup position",u),u=s[e]),u}},set:{position:function(n,r){var a,p,l=(e(t).width(),e(t).height(),k.outerWidth()),u=k.outerHeight(),c=o.outerWidth(),d=o.outerHeight(),f=s.outerWidth(),m=s.outerHeight(),w=h.distanceAway,x=k[0],P=h.inline?parseInt(t.getComputedStyle(x).getPropertyValue("margin-top"),10):0,T=h.inline?parseInt(t.getComputedStyle(x).getPropertyValue("margin-left"),10):0,O=h.inline||h.popup?k.position():k.offset();switch(n=n||C.data(y.position)||h.position,r=r||C.data(y.offset)||h.offset,j==h.maxSearchDepth&&h.lastResort&&(g.debug("Using last resort position to display",h.lastResort),n=h.lastResort),h.inline&&(g.debug("Adding targets margin to calculation"),"left center"==n||"right center"==n?(r+=P,w+=-T):"top left"==n||"top center"==n||"top right"==n?(r+=T,w-=P):(r+=T,w+=P)),g.debug("Calculating popup positioning",n),n){case"top left":a={top:"auto",bottom:m-O.top+w,left:O.left+r,right:"auto"};break;case"top center":a={bottom:m-O.top+w,left:O.left+l/2-c/2+r,top:"auto",right:"auto"};break;case"top right":a={bottom:m-O.top+w,right:f-O.left-l-r,top:"auto",left:"auto"};break;case"left center":a={top:O.top+u/2-d/2+r,right:f-O.left+w,left:"auto",bottom:"auto"};break;case"right center":a={top:O.top+u/2-d/2+r,left:O.left+l+w,bottom:"auto",right:"auto"};break;case"bottom left":a={top:O.top+u+w,left:O.left+r,bottom:"auto",right:"auto"};break;case"bottom center":a={top:O.top+u+w,left:O.left+l/2-c/2+r,bottom:"auto",right:"auto"};break;case"bottom right":a={top:O.top+u+w,right:f-O.left-l-r,left:"auto",bottom:"auto"}}if(a===i&&g.error(v.invalidPosition,n),g.debug("Calculated popup positioning values",a),o.css(a).removeClass(b.position).addClass(n).addClass(b.loading),p=g.get.offstagePosition(n)){if(g.debug("Popup cant fit into viewport",p),j0&&o.on("mouseenter"+x,g.event.start).on("mouseleave"+x,g.event.end)},close:function(){(h.hideOnScroll===!0||"auto"==h.hideOnScroll&&"click"!=h.on)&&(a.one("touchmove"+x,g.hideGracefully).one("scroll"+x,g.hideGracefully),T.one("touchmove"+x,g.hideGracefully).one("scroll"+x,g.hideGracefully)),"click"==h.on&&h.closable&&(g.verbose("Binding popup close event to document"),a.on("click"+x,function(t){g.verbose("Pop-up clickaway intent detected"),e.proxy(g.hideGracefully,A)(t)}))}},unbind:{close:function(){(h.hideOnScroll===!0||"auto"==h.hideOnScroll&&"click"!=h.on)&&(a.off("scroll"+x,g.hide),T.off("scroll"+x,g.hide)),"click"==h.on&&h.closable&&(g.verbose("Removing close event from document"),a.off("click"+x))}},is:{active:function(){return C.hasClass(b.active)},animating:function(){return o&&o.is(":animated")||o.hasClass(b.animating)},visible:function(){return o&&o.is(":visible")},dropdown:function(){return C.hasClass(b.dropdown)},hidden:function(){return!g.is.visible()}},reset:function(){g.remove.visible(),h.preserve||h.popup?e.fn.transition!==i&&o.transition("remove transition"):g.removePopup()},setting:function(t,o){if(e.isPlainObject(t))e.extend(!0,h,t);else{if(o===i)return h[t];h[t]=o}},internal:function(t,o){if(e.isPlainObject(t))e.extend(!0,g,t);else{if(o===i)return g[t];g[t]=o}},debug:function(){h.debug&&(h.performance?g.performance.log(arguments):(g.debug=Function.prototype.bind.call(console.info,console,h.name+":"),g.debug.apply(console,arguments)))},verbose:function(){h.verbose&&h.debug&&(h.performance?g.performance.log(arguments):(g.verbose=Function.prototype.bind.call(console.info,console,h.name+":"),g.verbose.apply(console,arguments)))},error:function(){g.error=Function.prototype.bind.call(console.error,console,h.name+":"),g.error.apply(console,arguments)},performance:{log:function(e){var t,o,i;h.performance&&(t=(new Date).getTime(),i=l||t,o=t-i,l=t,u.push({Name:e[0],Arguments:[].slice.call(e,1)||"",Element:A,"Execution Time":o})),clearTimeout(g.performance.timer),g.performance.timer=setTimeout(g.performance.display,100)},display:function(){var t=h.name+":",o=0;l=!1,clearTimeout(g.performance.timer),e.each(u,function(e,t){o+=t["Execution Time"]}),t+=" "+o+"ms",p&&(t+=" '"+p+"'"),(console.group!==i||console.table!==i)&&u.length>0&&(console.groupCollapsed(t),console.table?console.table(u):e.each(u,function(e,t){console.log(t.Name+": "+t["Execution Time"]+"ms")}),console.groupEnd()),u=[]}},invoke:function(t,o,n){var s,a,p,l=R;return o=o||f,n=A||n,"string"==typeof t&&l!==i&&(t=t.split(/[\. ]/),s=t.length-1,e.each(t,function(o,n){var r=o!=s?n+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]!==i)return a=l[r],!1;if(!e.isPlainObject(l[n])||o==s)return l[n]!==i?(a=l[n],!1):!1;l=l[n]}})),e.isFunction(a)?p=a.apply(n,o):a!==i&&(p=a),e.isArray(r)?r.push(p):r!==i?r=[r,p]:p!==i&&(r=p),a}},d?(R===i&&g.initialize(),g.invoke(c)):(R!==i&&g.destroy(),g.initialize())}),r!==i?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",context:"body",position:"top left",prefer:"opposite",lastResort:!1,delay:{show:30,hide:0},setFluidWidth:!0,target:!1,popup:!1,inline:!1,preserve:!0,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:{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=/[&<>"'`]/,i={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},n=function(e){return i[e]};return o.test(e)?e.replace(t,n):e},popup:function(t){var o="",n=e.fn.popup.settings.templates.escape;return typeof t!==i&&(typeof t.title!==i&&t.title&&(t.title=n(t.title),o+='
'+t.title+"
"),typeof t.content!==i&&t.content&&(t.content=n(t.content),o+='
'+t.content+"
")),o}}},e.extend(e.easing,{easeOutQuad:function(e,t,o,i,n){return-i*(t/=n)*(t-2)+o}})}(jQuery,window,document); \ No newline at end of file +!function(e,t,o,n){"use strict";e.fn.popup=function(i){var s,r=e(this),a=e(o),l=r.selector||"",p=("ontouchstart"in o.documentElement,(new Date).getTime()),u=[],c=arguments[0],d="string"==typeof c,f=[].slice.call(arguments,1);return r.each(function(){var o,r,g,h=e.isPlainObject(i)?e.extend(!0,{},e.fn.popup.settings,i):e.extend({},e.fn.popup.settings),m=h.selector,b=h.className,v=h.error,y=h.metadata,w=h.namespace,P="."+h.namespace,T="module-"+w,C=e(this),k=e(h.context),x=h.target?e(h.target):C,S=e(t),O=e("body"),j=0,A=!1,R=this,E=C.data(T);g={initialize:function(){g.debug("Initializing module",C),"click"==h.on?C.on("click"+P,g.toggle):g.get.startEvent()&&C.on(g.get.startEvent()+P,g.event.start).on(g.get.endEvent()+P,g.event.end),h.target&&g.debug("Target set to element",x),S.on("resize"+P,g.event.resize),!g.exists()&&h.preserve&&g.create(),g.instantiate()},instantiate:function(){g.verbose("Storing instance of module",g),E=g,C.data(T,E)},refresh:function(){h.popup?o=e(h.popup):h.inline&&(o=x.next(m.popup)),h.popup?(o.addClass(b.loading),r=g.get.offsetParent(),o.removeClass(b.loading),g.has.popup()&&g.get.offsetParent(o)[0]!==r[0]&&(g.debug("Moving popup to the same offset parent as activating element"),o.detach().appendTo(r))):r=h.inline?g.get.offsetParent(x):g.has.popup()?g.get.offsetParent(o):O,r.is("html")&&(g.debug("Setting page as offset parent"),r=O)},reposition:function(){g.refresh(),g.set.position()},destroy:function(){g.debug("Destroying previous module"),o&&!h.preserve&&g.removePopup(),clearTimeout(g.hideTimer),clearTimeout(g.showTimer),C.off(P).removeData(T)},event:{start:function(){var t=e.isPlainObject(h.delay)?h.delay.show:h.delay;clearTimeout(g.hideTimer),g.showTimer=setTimeout(function(){!g.is.hidden()||g.is.active()&&g.is.dropdown()||g.show()},t)},end:function(){var t=e.isPlainObject(h.delay)?h.delay.hide:h.delay;clearTimeout(g.showTimer),g.hideTimer=setTimeout(function(){g.is.visible()&&g.hide()},t)},resize:function(){g.is.visible()&&g.set.position()}},create:function(){var t=C.data(y.html)||h.html,n=C.data(y.variation)||h.variation,i=C.data(y.title)||h.title,s=C.data(y.content)||C.attr("title")||h.content;t||s||i?(g.debug("Creating pop-up html"),t||(t=h.templates.popup({title:i,content:s})),o=e("
").addClass(b.popup).addClass(n).html(t),n&&o.addClass(n),h.inline?(g.verbose("Inserting popup element inline",o),o.insertAfter(C)):(g.verbose("Appending popup element to body",o),o.appendTo(k)),g.refresh(),h.hoverable&&g.bind.popup(),h.onCreate.call(o,R)):0!==x.next(m.popup).length?(g.verbose("Pre-existing popup found"),h.inline=!0,h.popup=x.next(m.popup),g.refresh(),h.hoverable&&g.bind.popup()):h.popup?(g.verbose("Used popup specified in settings"),g.refresh(),h.hoverable&&g.bind.popup()):g.debug("No content specified skipping display",R)},toggle:function(){g.debug("Toggling pop-up"),g.is.hidden()?(g.debug("Popup is hidden, showing pop-up"),g.unbind.close(),g.hideAll(),g.show()):(g.debug("Popup is visible, hiding pop-up"),g.hide())},show:function(t){t=e.isFunction(t)?t:function(){},g.debug("Showing pop-up",h.transition),g.exists()?h.preserve||h.popup||g.refresh():g.create(),o&&g.set.position()&&(g.save.conditions(),g.animate.show(t))},hide:function(t){t=e.isFunction(t)?t:function(){},g.remove.visible(),g.unbind.close(),g.is.visible()&&(g.restore.conditions(),g.animate.hide(t))},hideAll:function(){e(m.popup).filter(":visible").transition("hide")},hideGracefully:function(t){t&&0===e(t.target).closest(m.popup).length?(g.debug("Click occurred outside popup hiding popup"),g.hide()):g.debug("Click was inside popup, keeping popup open")},exists:function(){return o?h.inline||h.popup?g.has.popup():o.closest(k).length>=1?!0:!1:!1},removePopup:function(){g.debug("Removing popup",o),g.has.popup()&&!h.popup&&(o.remove(),o=n),h.onRemove.call(o,R)},save:{conditions:function(){g.cache={title:C.attr("title")},g.cache.title&&C.removeAttr("title"),g.verbose("Saving original attributes",g.cache.title)}},restore:{conditions:function(){return g.cache&&g.cache.title&&(C.attr("title",g.cache.title),g.verbose("Restoring original attributes",g.cache.title)),!0}},animate:{show:function(t){t=e.isFunction(t)?t:function(){},h.transition&&e.fn.transition!==n&&C.transition("is supported")?(g.set.visible(),o.transition({animation:h.transition+" in",queue:!1,debug:h.debug,verbose:h.verbose,duration:h.duration,onComplete:function(){g.bind.close(),t.call(o,R),h.onVisible.call(o,R)}})):(g.set.visible(),o.stop().fadeIn(h.duration,h.easing,function(){g.bind.close(),t.call(o,R),h.onVisible.call(o,R)})),h.onShow.call(o,R)},hide:function(t){t=e.isFunction(t)?t:function(){},g.debug("Hiding pop-up"),h.transition&&e.fn.transition!==n&&C.transition("is supported")?o.transition({animation:h.transition+" out",queue:!1,duration:h.duration,debug:h.debug,verbose:h.verbose,onComplete:function(){g.reset(),t.call(o,R),h.onHidden.call(o,R)}}):o.stop().fadeOut(h.duration,h.easing,function(){g.reset(),t.call(o,R),h.onHidden.call(o,R)}),h.onHide.call(o,R)}},get:{startEvent:function(){return"hover"==h.on?"mouseenter":"focus"==h.on?"focus":!1},endEvent:function(){return"hover"==h.on?"mouseleave":"focus"==h.on?"blur":!1},offsetParent:function(t){var o=t!==n?t[0]:C[0],i=o.parentNode,s=e(i);if(i)for(var r="none"===s.css("transform"),a="static"===s.css("position"),l=s.is("html");i&&!l&&a&&r;)i=i.parentNode,s=e(i),r="none"===s.css("transform"),a="static"===s.css("position"),l=s.is("html");return s&&s.length>0?s:e()},offstagePosition:function(n){var i={top:e(t).scrollTop(),bottom:e(t).scrollTop()+e(t).height(),left:0,right:e(t).width()},s={width:o.width(),height:o.height(),offset:o.offset()},r={},a=[];return n=n||!1,s.offset&&n&&(g.verbose("Checking if outside viewable area",s.offset),r={top:s.offset.topi.bottom,right:s.offset.left+s.width>i.right,left:s.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"},s={left:"center",center:"right",right:"left"},r={"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,l=!1,p=!1,u=!1;return A||(g.verbose("All available positions available"),A=g.get.positions()),g.debug("Recording last position tried",e),A[e]=!0,"opposite"===h.prefer&&(u=[i[o],n],u=u.join(" "),l=A[u]===!0,g.debug("Trying opposite strategy",u)),"adjacent"===h.prefer&&a&&(u=[o,s[n]],u=u.join(" "),p=A[u]===!0,g.debug("Trying adjacent strategy",u)),(p||l)&&(g.debug("Using backup position",u),u=r[e]),u}},set:{position:function(i,s){var a,l,p,u=(e(t).width(),e(t).height(),x.outerWidth()),c=x.outerHeight(),d=o.outerWidth(),f=o.outerHeight(),m=r.outerWidth(),w=r.outerHeight(),P=h.distanceAway,T=x[0],k=h.inline?parseInt(t.getComputedStyle(T).getPropertyValue("margin-top"),10):0,S=h.inline?parseInt(t.getComputedStyle(T).getPropertyValue(g.is.rtl()?"margin-right":"margin-left"),10):0,O=h.inline||h.popup?x.position():x.offset();switch(i=i||C.data(y.position)||h.position,s=s||C.data(y.offset)||h.offset,j==h.maxSearchDepth&&h.lastResort&&(g.debug("Using last resort position to display",h.lastResort),i=h.lastResort),h.inline&&(g.debug("Adding targets margin to calculation"),"left center"==i||"right center"==i?(s+=k,P+=-S):"top left"==i||"top center"==i||"top right"==i?(s+=S,P-=k):(s+=S,P+=k)),g.debug("Calculating popup positioning",i),a=i,g.is.rtl()&&(a=a.replace(/left|right/g,function(e){return"left"==e?"right":"left"}),g.debug("RTL: Popup positioning updated",a)),a){case"top left":l={top:"auto",bottom:w-O.top+P,left:O.left+s,right:"auto"};break;case"top center":l={bottom:w-O.top+P,left:O.left+u/2-d/2+s,top:"auto",right:"auto"};break;case"top right":l={bottom:w-O.top+P,right:m-O.left-u-s,top:"auto",left:"auto"};break;case"left center":l={top:O.top+c/2-f/2+s,right:m-O.left+P,left:"auto",bottom:"auto"};break;case"right center":l={top:O.top+c/2-f/2+s,left:O.left+u+P,bottom:"auto",right:"auto"};break;case"bottom left":l={top:O.top+c+P,left:O.left+s,bottom:"auto",right:"auto"};break;case"bottom center":l={top:O.top+c+P,left:O.left+u/2-d/2+s,bottom:"auto",right:"auto"};break;case"bottom right":l={top:O.top+c+P,right:m-O.left-u-s,left:"auto",bottom:"auto"}}if(l===n&&g.error(v.invalidPosition,i),g.debug("Calculated popup positioning values",l),o.css(l).removeClass(b.position).addClass(i).addClass(b.loading),p=g.get.offstagePosition(i)){if(g.debug("Popup cant fit into viewport",p),j0}},is:{active:function(){return C.hasClass(b.active)},animating:function(){return o&&o.is(":animated")||o.hasClass(b.animating)},visible:function(){return o&&o.is(":visible")},dropdown:function(){return C.hasClass(b.dropdown)},hidden:function(){return!g.is.visible()},rtl:function(){return"rtl"==C.css("direction")}},reset:function(){g.remove.visible(),h.preserve?e.fn.transition!==n&&o.transition("remove transition"):g.removePopup()},setting:function(t,o){if(e.isPlainObject(t))e.extend(!0,h,t);else{if(o===n)return h[t];h[t]=o}},internal:function(t,o){if(e.isPlainObject(t))e.extend(!0,g,t);else{if(o===n)return g[t];g[t]=o}},debug:function(){h.debug&&(h.performance?g.performance.log(arguments):(g.debug=Function.prototype.bind.call(console.info,console,h.name+":"),g.debug.apply(console,arguments)))},verbose:function(){h.verbose&&h.debug&&(h.performance?g.performance.log(arguments):(g.verbose=Function.prototype.bind.call(console.info,console,h.name+":"),g.verbose.apply(console,arguments)))},error:function(){g.error=Function.prototype.bind.call(console.error,console,h.name+":"),g.error.apply(console,arguments)},performance:{log:function(e){var t,o,n;h.performance&&(t=(new Date).getTime(),n=p||t,o=t-n,p=t,u.push({Name:e[0],Arguments:[].slice.call(e,1)||"",Element:R,"Execution Time":o})),clearTimeout(g.performance.timer),g.performance.timer=setTimeout(g.performance.display,100)},display:function(){var t=h.name+":",o=0;p=!1,clearTimeout(g.performance.timer),e.each(u,function(e,t){o+=t["Execution Time"]}),t+=" "+o+"ms",l&&(t+=" '"+l+"'"),(console.group!==n||console.table!==n)&&u.length>0&&(console.groupCollapsed(t),console.table?console.table(u):e.each(u,function(e,t){console.log(t.Name+": "+t["Execution Time"]+"ms")}),console.groupEnd()),u=[]}},invoke:function(t,o,i){var r,a,l,p=E;return o=o||f,i=R||i,"string"==typeof t&&p!==n&&(t=t.split(/[\. ]/),r=t.length-1,e.each(t,function(o,i){var s=o!=r?i+t[o+1].charAt(0).toUpperCase()+t[o+1].slice(1):t;if(e.isPlainObject(p[s])&&o!=r)p=p[s];else{if(p[s]!==n)return a=p[s],!1;if(!e.isPlainObject(p[i])||o==r)return p[i]!==n?(a=p[i],!1):!1;p=p[i]}})),e.isFunction(a)?l=a.apply(i,o):a!==n&&(l=a),e.isArray(s)?s.push(l):s!==n?s=[s,l]:l!==n&&(s=l),a}},d?(E===n&&g.initialize(),g.invoke(c)):(E!==n&&g.destroy(),g.initialize())}),s!==n?s: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",context:"body",position:"top left",prefer:"opposite",lastResort:!1,delay:{show:30,hide:0},setFluidWidth:!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:{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 From 6a47b4246d92ce50a8fc898921850ff0910f4e98 Mon Sep 17 00:00:00 2001 From: Jack Lukic Date: Wed, 18 Feb 2015 12:19:25 -0500 Subject: [PATCH 19/22] Updated component to version 1.9.0 --- RELEASE-NOTES.md | 59 ------ composer.json | 2 +- index.js | 510 ++++++++++++++++++++++++++++++++--------------- package.json | 4 +- popup.css | 39 ++-- popup.js | 510 ++++++++++++++++++++++++++++++++--------------- popup.min.css | 6 +- popup.min.js | 6 +- 8 files changed, 736 insertions(+), 400 deletions(-) mode change 100755 => 100644 RELEASE-NOTES.md diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md old mode 100755 new mode 100644 index 020ae0c..e69de29 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -1,59 +0,0 @@ -### Version 1.0.0 - XX XX, 2014 - -- **Popup** - Popup can now allow itself not to be closed when hovered over -- **Popup** - A popup element can now be specified on initialization. -- **Popup** - Positioned popups will now extend in the opposite direction to fit better with floated content - -### Version 0.12.5 - Feb 04, 2014 - -- **Popup** - Fixes issue where popups using ``title`` attribute to store data were losing title content instead of correctly restoring it - -### Merry Christmas! - --**Popup** - Fixes popup sometimes opening and closing when ``event:click`` is used and a user double clicks - -### Version 0.10.3 - Dec 22, 2013 - -- **Popup** - Native browser popups no longer if using ``title`` attribute - -### Version 0.9.2 - Nov 8, 2013 - -**Fixes** - Fixes popup not repositioning itself when offstage. - -### Version 0.9.1 - Nov 7, 2013 - -- **Popup** - Adds context option for popup (thanks jefmathiot) - -### Version 0.7.1 - Oct 23, 2013 - -- **Popup** - Fixes issue with popup's using setting inline: true - -### Version 0.7.0 - Oct 22, 2013 - -- **List** - Popups can now have a different target than itself -- **Popup** - Popup .toggle() now always hides/shows popup correctly -- **Popup** - Popup fixed a bug where "top right" placed popup might sometimes be too large -- **Popup** - Popup will not reshow a visible popup on hover -- **Popup** - Popup border now uses RGBA to look sexier on dark backgrounds -- **Popup** - Popup default duration is now 200ms (slighty slower) -- **Popup** - Popup metadata attribute arrowOffset is now offset for simplicities sake -- **Popup** - Popup no-longer receives class name 'visible' on show, this allows popups to be used on dropdowns and other elements with a visible state -- **Popup** - Popups are no longer inline by default - -### Version 0.5.0 - Oct 10, 2013 - -- Fixes regression where popup was overriding variation class name on positioning -- Fixes an issue where popup that was set to inline: false was being removed prematurely -- Adds an example to popup where inline is set to false -- Added onCreate to popup module - -### Version 0.3.6 - Oct 7, 2013 - -- Fixes popup position sometimes appearing off-stage on second apperance -- Fixes popup positions top left, top right, bottom left, bottom right being flipped - -### Version 0.3.3 - Oct 2, 2013 - -- Fixes issue with popup display in some edge cases Issue #128 - -### Version 0.1.0 - Sep 25, 2013 \ No newline at end of file diff --git a/composer.json b/composer.json index 188fb22..a74338c 100755 --- a/composer.json +++ b/composer.json @@ -14,5 +14,5 @@ "jquery": "x.x.x" }, "main": "popup.js", - "version": "1.0.0" + "version": "1.0.0-beta" } \ No newline at end of file diff --git a/index.js b/index.js index 5c4f160..e784765 100755 --- a/index.js +++ b/index.js @@ -1,6 +1,6 @@ /* * # Semantic - Popup - * http://github.com/jlukic/semantic-ui/ + * http://github.com/semantic-org/semantic-ui/ * * * Copyright 2014 Contributor @@ -39,30 +39,31 @@ module.exports = function(parameters) { ? $.extend(true, {}, _module.exports.settings, parameters) : $.extend({}, _module.exports.settings), - selector = settings.selector, - className = settings.className, - error = settings.error, - metadata = settings.metadata, - namespace = settings.namespace, + selector = settings.selector, + className = settings.className, + error = settings.error, + metadata = settings.metadata, + namespace = settings.namespace, - eventNamespace = '.' + settings.namespace, - moduleNamespace = 'module-' + namespace, + eventNamespace = '.' + settings.namespace, + moduleNamespace = 'module-' + namespace, - $module = $(this), - $context = $(settings.context), - $target = (settings.target) + $module = $(this), + $context = $(settings.context), + $target = (settings.target) ? $(settings.target) : $module, - $window = $(window), - $body = $('body'), + $window = $(window), + $body = $('body'), $popup, $offsetParent, - searchDepth = 0, + searchDepth = 0, + triedPositions = false, - element = this, - instance = $module.data(moduleNamespace), + element = this, + instance = $module.data(moduleNamespace), module ; @@ -71,7 +72,6 @@ module.exports = function(parameters) { // binds events initialize: function() { module.debug('Initializing module', $module); - module.refresh(); if(settings.on == 'click') { $module .on('click' + eventNamespace, module.toggle) @@ -89,12 +89,9 @@ module.exports = function(parameters) { $window .on('resize' + eventNamespace, module.event.resize) ; - if( !module.exists() ) { + if( !module.exists() && settings.preserve) { module.create(); } - else if(settings.hoverable) { - module.bind.popup(); - } module.instantiate(); }, @@ -107,25 +104,52 @@ module.exports = function(parameters) { }, refresh: function() { - $popup = (settings.popup) - ? $(settings.popup) - : (settings.inline) - ? $target.next(settings.selector.popup) - : false - ; - $offsetParent = (settings.popup) - ? $popup.offsetParent() - : (settings.inline) - ? $target.offsetParent() - : $body - ; + if(settings.popup) { + $popup = $(settings.popup).eq(0); + } + else { + if(settings.inline) { + $popup = $target.next(selector.popup).eq(0); + } + } + 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 activating element'); + $popup + .detach() + .appendTo($offsetParent) + ; + } + } + else { + $offsetParent = (settings.inline) + ? module.get.offsetParent($target) + : module.has.popup() + ? module.get.offsetParent($popup) + : $body + ; + } + if( $offsetParent.is('html') ) { + module.debug('Setting page as offset parent'); + $offsetParent = $body; + } + }, + + reposition: function() { + module.refresh(); + module.set.position(); }, destroy: function() { module.debug('Destroying previous module'); if($popup && !settings.preserve) { - module.remove(); + module.removePopup(); } + clearTimeout(module.hideTimer); + clearTimeout(module.showTimer); $module .off(eventNamespace) .removeData(moduleNamespace) @@ -141,7 +165,7 @@ module.exports = function(parameters) { ; clearTimeout(module.hideTimer); module.showTimer = setTimeout(function() { - if( module.is.hidden() && !( module.is.active() && module.is.dropdown()) ) { + if(module.is.hidden() && !( module.is.active() && module.is.dropdown()) ) { module.show(); } }, delay); @@ -154,7 +178,7 @@ module.exports = function(parameters) { ; clearTimeout(module.showTimer); module.hideTimer = setTimeout(function() { - if( module.is.visible() ) { + if(module.is.visible() ) { module.hide(); } }, delay); @@ -204,14 +228,23 @@ module.exports = function(parameters) { .appendTo( $context ) ; } + module.refresh(); if(settings.hoverable) { module.bind.popup(); } - $.proxy(settings.onCreate, $popup)(); + settings.onCreate.call($popup, element); } - else if($target.next(settings.selector.popup).size() !== 0) { - module.verbose('Pre-existing popup found, reverting to inline'); + else if($target.next(selector.popup).length !== 0) { + module.verbose('Pre-existing popup found'); settings.inline = true; + settings.popup = $target.next(selector.popup); + module.refresh(); + if(settings.hoverable) { + module.bind.popup(); + } + } + else if(settings.popup) { + module.verbose('Used popup specified in settings'); module.refresh(); if(settings.hoverable) { module.bind.popup(); @@ -238,14 +271,14 @@ module.exports = function(parameters) { }, show: function(callback) { - callback = callback || function(){}; + callback = $.isFunction(callback) ? callback : function(){}; module.debug('Showing pop-up', settings.transition); - if(!settings.preserve && !settings.popup) { - module.refresh(); - } if( !module.exists() ) { module.create(); } + else if(!settings.preserve && !settings.popup) { + module.refresh(); + } if( $popup && module.set.position() ) { module.save.conditions(); module.animate.show(callback); @@ -254,10 +287,8 @@ module.exports = function(parameters) { hide: function(callback) { - callback = callback || function(){}; - $module - .removeClass(className.visible) - ; + callback = $.isFunction(callback) ? callback : function(){}; + module.remove.visible(); module.unbind.close(); if( module.is.visible() ) { module.restore.conditions(); @@ -268,13 +299,13 @@ module.exports = function(parameters) { hideAll: function() { $(selector.popup) .filter(':visible') - .popup('hide') + .transition(settings.transition) ; }, hideGracefully: function(event) { // don't close on clicks inside popup - if(event && $(event.target).closest(selector.popup).size() === 0) { + if(event && $(event.target).closest(selector.popup).length === 0) { module.debug('Click occurred outside popup hiding popup'); module.hide(); } @@ -288,18 +319,23 @@ module.exports = function(parameters) { return false; } if(settings.inline || settings.popup) { - return ( $popup.size() !== 0 ); + return ( module.has.popup() ); } else { - return ( $popup.closest($context).size() ); + return ( $popup.closest($context).length >= 1 ) + ? true + : false + ; } }, - remove: function() { - module.debug('Removing popup'); - $popup - .remove() - ; + removePopup: function() { + module.debug('Removing popup', $popup); + if( module.has.popup() && !settings.popup) { + $popup.remove(); + $popup = undefined; + } + settings.onRemove.call($popup, element); }, save: { @@ -324,51 +360,52 @@ module.exports = function(parameters) { }, animate: { show: function(callback) { - callback = callback || function(){}; + 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, - duration : settings.duration, - start: function() { - $module - .addClass(className.visible) - ; - }, - complete : function() { + animation : settings.transition + ' in', + queue : false, + debug : settings.debug, + verbose : settings.verbose, + duration : settings.duration, + onComplete : function() { module.bind.close(); - $.proxy(callback, element)(); + callback.call($popup, element); + settings.onVisible.call($popup, element); } }) ; } else { - $module - .addClass(className.visible) - ; + module.set.visible(); $popup .stop() .fadeIn(settings.duration, settings.easing, function() { module.bind.close(); - $.proxy(callback, element)(); + callback.call($popup, element); + settings.onVisible.call($popup, element); }) ; } - $.proxy(settings.onShow, element)(); + settings.onShow.call($popup, element); }, hide: function(callback) { - callback = callback || function(){}; + callback = $.isFunction(callback) ? callback : function(){}; module.debug('Hiding pop-up'); if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) { $popup .transition({ - animation : settings.transition + ' out', - queue : false, - duration : settings.duration, - complete : function() { + animation : settings.transition + ' out', + queue : false, + duration : settings.duration, + debug : settings.debug, + verbose : settings.verbose, + onComplete : function() { module.reset(); - callback(); + callback.call($popup, element); + settings.onHidden.call($popup, element); } }) ; @@ -378,11 +415,12 @@ module.exports = function(parameters) { .stop() .fadeOut(settings.duration, settings.easing, function() { module.reset(); - callback(); + callback.call($popup, element); + settings.onHidden.call($popup, element); }) ; } - $.proxy(settings.onHide, element)(); + settings.onHide.call($popup, element); } }, @@ -405,7 +443,34 @@ module.exports = function(parameters) { } return false; }, - offstagePosition: function() { + offsetParent: function($target) { + var + element = ($target !== undefined) + ? $target[0] + : $module[0], + parentNode = element.parentNode, + $node = $(parentNode) + ; + if(parentNode) { + var + is2D = ($node.css('transform') === 'none'), + isStatic = ($node.css('position') === 'static'), + isHTML = $node.is('html') + ; + while(parentNode && !isHTML && isStatic && is2D) { + parentNode = parentNode.parentNode; + $node = $(parentNode); + is2D = ($node.css('transform') === 'none'); + isStatic = ($node.css('position') === 'static'); + isHTML = $node.is('html'); + } + } + return ($node && $node.length > 0) + ? $node + : $() + ; + }, + offstagePosition: function(position) { var boundary = { top : $(window).scrollTop(), @@ -415,13 +480,15 @@ module.exports = function(parameters) { }, popup = { width : $popup.width(), - height : $popup.outerHeight(), + height : $popup.height(), offset : $popup.offset() }, offstage = {}, offstagePositions = [] ; - if(popup.offset) { + position = position || false; + if(popup.offset && position) { + module.verbose('Checking if outside viewable area', popup.offset); offstage = { top : (popup.offset.top < boundary.top), bottom : (popup.offset.top + popup.height > boundary.bottom), @@ -429,7 +496,6 @@ module.exports = function(parameters) { left : (popup.offset.left < boundary.left) }; } - module.verbose('Checking if outside viewable area', popup.offset); // return only boundaries that have been surpassed $.each(offstage, function(direction, isOffstage) { if(isOffstage) { @@ -441,34 +507,74 @@ module.exports = function(parameters) { : false ; }, + 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) { - switch(position) { - case 'top left': - position = 'bottom left'; - break; - case 'bottom left': - position = 'top right'; - break; - case 'top right': - position = 'bottom right'; - break; - case 'bottom right': - position = 'top center'; - break; - case 'top center': - position = 'bottom center'; - break; - case 'bottom center': - position = 'right center'; - break; - case 'right center': - position = 'left center'; - break; - case 'left center': - position = 'top center'; - break; + 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(); } - return position; + + 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; } }, @@ -491,23 +597,29 @@ module.exports = function(parameters) { targetElement = $target[0], - marginTop = (settings.inline) + marginTop = (settings.inline) ? parseInt( window.getComputedStyle(targetElement).getPropertyValue('margin-top'), 10) : 0, - marginLeft = (settings.inline) - ? parseInt( window.getComputedStyle(targetElement).getPropertyValue('margin-left'), 10) + 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(), + computedPosition, positioning, offstagePosition ; position = position || $module.data(metadata.position) || settings.position; arrowOffset = arrowOffset || $module.data(metadata.offset) || settings.offset; + if(searchDepth == settings.maxSearchDepth && settings.lastResort) { + module.debug('Using last resort position to display', settings.lastResort); + position = settings.lastResort; + } + if(settings.inline) { module.debug('Adding targets margin to calculation'); if(position == 'left center' || position == 'right center') { @@ -524,7 +636,18 @@ module.exports = function(parameters) { } } module.debug('Calculating popup positioning', position); - switch(position) { + + computedPosition = position; + if (module.is.rtl()) { + computedPosition = computedPosition.replace(/left|right/g, function (match) { + return (match == 'left') + ? 'right' + : 'left' + ; + }); + module.debug('RTL: Popup positioning updated', computedPosition); + } + switch (computedPosition) { case 'top left': positioning = { top : 'auto', @@ -591,8 +714,11 @@ module.exports = function(parameters) { break; } if(positioning === undefined) { - module.error(error.invalidPosition); + module.error(error.invalidPosition, position); } + + module.debug('Calculated popup positioning values', positioning); + // tentatively place on stage $popup .css(positioning) @@ -601,52 +727,89 @@ module.exports = function(parameters) { .addClass(className.loading) ; // check if is offstage - offstagePosition = module.get.offstagePosition(); + offstagePosition = module.get.offstagePosition(position); + // recursively find new positioning if(offstagePosition) { - module.debug('Element is outside boundaries', offstagePosition); + module.debug('Popup cant fit into viewport', offstagePosition); if(searchDepth < settings.maxSearchDepth) { - position = module.get.nextPosition(position); searchDepth++; + position = module.get.nextPosition(position); module.debug('Trying new position', position); return ($popup) ? module.set.position(position) : false ; } - else { - module.error(error.recursion); - searchDepth = 0; + else if(!settings.lastResort) { + module.debug('Popup could not find a position in view', $popup); + module.error(error.cannotPlace); + module.remove.attempts(); + module.remove.loading(); module.reset(); - $popup.removeClass(className.loading); return false; } } - else { - module.debug('Position is on stage', position); - searchDepth = 0; - $popup.removeClass(className.loading); - return true; + + module.debug('Position is on stage', position); + module.remove.attempts(); + module.set.fluidWidth(); + module.remove.loading(); + return true; + }, + + fluidWidth: function() { + if( settings.setFluidWidth && $popup.hasClass(className.fluid) ) { + $popup.css('width', $offsetParent.width()); } + }, + + visible: function() { + $module.addClass(className.visible); } + }, + remove: { + loading: function() { + $popup.removeClass(className.loading); + }, + visible: function() { + $module.removeClass(className.visible); + }, + attempts: function() { + module.verbose('Resetting all searched positions'); + searchDepth = 0; + triedPositions = false; + } }, bind: { popup: function() { module.verbose('Allowing hover events on popup to prevent closing'); - $popup - .on('mouseenter', module.event.start) - .on('mouseleave', module.event.end) - ; + 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') { + $document + .one('touchmove' + eventNamespace, module.hideGracefully) + .one('scroll' + eventNamespace, module.hideGracefully) + ; + $context + .one('touchmove' + eventNamespace, module.hideGracefully) + .one('scroll' + eventNamespace, module.hideGracefully) + ; + } if(settings.on == 'click' && settings.closable) { module.verbose('Binding popup close event to document'); $document .on('click' + eventNamespace, function(event) { module.verbose('Pop-up clickaway intent detected'); - $.proxy(module.hideGracefully, element)(event); + module.hideGracefully.call(element, event); }) ; } @@ -655,6 +818,14 @@ module.exports = function(parameters) { unbind: { close: function() { + if(settings.hideOnScroll === true || settings.hideOnScroll == 'auto' && settings.on != 'click') { + $document + .off('scroll' + eventNamespace, module.hide) + ; + $context + .off('scroll' + eventNamespace, module.hide) + ; + } if(settings.on == 'click' && settings.closable) { module.verbose('Removing close event from document'); $document @@ -664,6 +835,12 @@ module.exports = function(parameters) { } }, + has: { + popup: function() { + return ($popup && $popup.length > 0); + } + }, + is: { active: function() { return $module.hasClass(className.active); @@ -679,14 +856,15 @@ module.exports = function(parameters) { }, hidden: function() { return !module.is.visible(); + }, + rtl: function () { + return $module.css('direction') == 'rtl'; } }, reset: function() { - $popup - .removeClass(className.visible) - ; - if(settings.preserve || settings.popup) { + module.remove.visible(); + if(settings.preserve) { if($.fn.transition !== undefined) { $popup .transition('remove transition') @@ -694,7 +872,7 @@ module.exports = function(parameters) { } } else { - module.remove(); + module.removePopup(); } }, @@ -860,7 +1038,7 @@ module.exports = function(parameters) { } else { if(instance !== undefined) { - module.destroy(); + instance.invoke('destroy'); } module.initialize(); } @@ -875,37 +1053,48 @@ module.exports = function(parameters) { module.exports.settings = { - name : 'Popup', + name : 'Popup', + + debug : false, + verbose : true, + performance : true, + namespace : 'popup', - debug : false, - verbose : false, - performance : false, - namespace : 'popup', + onCreate : function(){}, + onRemove : function(){}, - onCreate : function(){}, - onRemove : function(){}, - onShow : function(){}, - onHide : function(){}, + onShow : function(){}, + onVisible : function(){}, + onHide : function(){}, + onHidden : function(){}, - variation : '', - content : false, - html : false, - title : false, + variation : '', + content : false, + html : false, + title : false, - on : 'hover', - closable : true, + on : 'hover', + closable : true, + hideOnScroll : 'auto', - context : 'body', - position : 'top left', - delay : { + context : 'body', + + position : 'top left', + prefer : 'opposite', + lastResort : false, + + delay : { show : 30, hide : 0 }, + setFluidWidth : true, + movePopup : true, + target : false, popup : false, inline : false, - preserve : true, + preserve : false, hoverable : false, duration : 200, @@ -914,12 +1103,12 @@ module.exports.settings = { distanceAway : 0, offset : 0, - maxSearchDepth : 10, + maxSearchDepth : 20, error: { invalidPosition : 'The position you specified is not a valid position', - method : 'The method you called is not defined.', - recursion : 'Popup attempted to reposition element to fit, but could not find an adequate position.' + cannotPlace : 'No visible position could be found for the popup', + method : 'The method you called is not defined.' }, metadata: { @@ -935,6 +1124,7 @@ module.exports.settings = { active : 'active', animating : 'animating', dropdown : 'dropdown', + fluid : 'fluid', loading : 'loading', popup : 'ui popup', position : 'top left center bottom right', diff --git a/package.json b/package.json index bbf17d0..a63034b 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "semantic-ui-popup", - "version": "1.0.0", + "version": "1.0.0-beta", "title": "Semantic UI - Popup", "description": "Single component release of popup", "homepage": "http://www.semantic-ui.com", @@ -13,9 +13,9 @@ "bugs": { "url": "https://github.com/Semantic-Org/Semantic-UI/issues" }, + "devDependencies": {}, "dependencies": { "jquery": "x.x.x" }, - "devDependencies": {}, "main": "index.js" } \ No newline at end of file diff --git a/popup.css b/popup.css index bfcfa4c..6fb3251 100755 --- a/popup.css +++ b/popup.css @@ -1,7 +1,7 @@ /* - * # Semantic UI + * # Semantic UI - 1.9.0 * https://github.com/Semantic-Org/Semantic-UI - * http://beta.semantic-ui.com/ + * http://www.semantic-ui.com/ * * Copyright 2014 Contributors * Released under the MIT license @@ -20,11 +20,14 @@ position: absolute; top: 0px; right: 0px; - z-index: 900; + +/* Fixes content being squished when inline (moz only) */ + min-width: -moz-max-content; + z-index: 1900; border: 1px solid #cccccc; max-width: 250px; background-color: #ffffff; - padding: 0.8em 1em; + padding: 0.833em 1em; font-weight: normal; font-style: normal; color: rgba(0, 0, 0, 0.8); @@ -204,16 +207,22 @@ *******************************/ +/*-------------- + Basic +---------------*/ + +.ui.basic.popup:before { + display: none; +} + /*-------------- Wide ---------------*/ .ui.wide.popup { - width: 350px; max-width: 350px; } .ui[class*="very wide"].popup { - width: 550px; max-width: 550px; } @@ -223,7 +232,7 @@ .ui.fluid.popup { width: 100%; - max-width: 99999px; + max-width: none; } /*-------------- @@ -244,7 +253,7 @@ } .ui.inverted.popup:before { background-color: #1b1c1d; - box-shadow: none; + box-shadow: none !important; } /*-------------- @@ -252,7 +261,7 @@ ---------------*/ .ui.flowing.popup { - max-width: 9999px; + max-width: none; } /*-------------- @@ -260,16 +269,16 @@ ---------------*/ .ui.small.popup { - font-size: 0.8rem; + font-size: 0.785714rem; } .ui.popup { - font-size: 0.875rem; + font-size: 0.85714rem; } .ui.large.popup { font-size: 1rem; } .ui.huge.popup { - font-size: 1.1rem; + font-size: 1.14285rem; } @@ -277,3 +286,9 @@ Theme Overrides *******************************/ + + +/******************************* + User Overrides +*******************************/ + diff --git a/popup.js b/popup.js index 3dae337..4360408 100755 --- a/popup.js +++ b/popup.js @@ -1,6 +1,6 @@ /* * # Semantic - Popup - * http://github.com/jlukic/semantic-ui/ + * http://github.com/semantic-org/semantic-ui/ * * * Copyright 2014 Contributor @@ -37,30 +37,31 @@ $.fn.popup = function(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, + selector = settings.selector, + className = settings.className, + error = settings.error, + metadata = settings.metadata, + namespace = settings.namespace, - eventNamespace = '.' + settings.namespace, - moduleNamespace = 'module-' + namespace, + eventNamespace = '.' + settings.namespace, + moduleNamespace = 'module-' + namespace, - $module = $(this), - $context = $(settings.context), - $target = (settings.target) + $module = $(this), + $context = $(settings.context), + $target = (settings.target) ? $(settings.target) : $module, - $window = $(window), - $body = $('body'), + $window = $(window), + $body = $('body'), $popup, $offsetParent, - searchDepth = 0, + searchDepth = 0, + triedPositions = false, - element = this, - instance = $module.data(moduleNamespace), + element = this, + instance = $module.data(moduleNamespace), module ; @@ -69,7 +70,6 @@ $.fn.popup = function(parameters) { // binds events initialize: function() { module.debug('Initializing module', $module); - module.refresh(); if(settings.on == 'click') { $module .on('click' + eventNamespace, module.toggle) @@ -87,12 +87,9 @@ $.fn.popup = function(parameters) { $window .on('resize' + eventNamespace, module.event.resize) ; - if( !module.exists() ) { + if( !module.exists() && settings.preserve) { module.create(); } - else if(settings.hoverable) { - module.bind.popup(); - } module.instantiate(); }, @@ -105,25 +102,52 @@ $.fn.popup = function(parameters) { }, refresh: function() { - $popup = (settings.popup) - ? $(settings.popup) - : (settings.inline) - ? $target.next(settings.selector.popup) - : false - ; - $offsetParent = (settings.popup) - ? $popup.offsetParent() - : (settings.inline) - ? $target.offsetParent() - : $body - ; + if(settings.popup) { + $popup = $(settings.popup).eq(0); + } + else { + if(settings.inline) { + $popup = $target.next(selector.popup).eq(0); + } + } + 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 activating element'); + $popup + .detach() + .appendTo($offsetParent) + ; + } + } + else { + $offsetParent = (settings.inline) + ? module.get.offsetParent($target) + : module.has.popup() + ? module.get.offsetParent($popup) + : $body + ; + } + if( $offsetParent.is('html') ) { + module.debug('Setting page as offset parent'); + $offsetParent = $body; + } + }, + + reposition: function() { + module.refresh(); + module.set.position(); }, destroy: function() { module.debug('Destroying previous module'); if($popup && !settings.preserve) { - module.remove(); + module.removePopup(); } + clearTimeout(module.hideTimer); + clearTimeout(module.showTimer); $module .off(eventNamespace) .removeData(moduleNamespace) @@ -139,7 +163,7 @@ $.fn.popup = function(parameters) { ; clearTimeout(module.hideTimer); module.showTimer = setTimeout(function() { - if( module.is.hidden() && !( module.is.active() && module.is.dropdown()) ) { + if(module.is.hidden() && !( module.is.active() && module.is.dropdown()) ) { module.show(); } }, delay); @@ -152,7 +176,7 @@ $.fn.popup = function(parameters) { ; clearTimeout(module.showTimer); module.hideTimer = setTimeout(function() { - if( module.is.visible() ) { + if(module.is.visible() ) { module.hide(); } }, delay); @@ -202,14 +226,23 @@ $.fn.popup = function(parameters) { .appendTo( $context ) ; } + module.refresh(); if(settings.hoverable) { module.bind.popup(); } - $.proxy(settings.onCreate, $popup)(); + settings.onCreate.call($popup, element); } - else if($target.next(settings.selector.popup).size() !== 0) { - module.verbose('Pre-existing popup found, reverting to inline'); + else if($target.next(selector.popup).length !== 0) { + module.verbose('Pre-existing popup found'); settings.inline = true; + settings.popup = $target.next(selector.popup); + module.refresh(); + if(settings.hoverable) { + module.bind.popup(); + } + } + else if(settings.popup) { + module.verbose('Used popup specified in settings'); module.refresh(); if(settings.hoverable) { module.bind.popup(); @@ -236,14 +269,14 @@ $.fn.popup = function(parameters) { }, show: function(callback) { - callback = callback || function(){}; + callback = $.isFunction(callback) ? callback : function(){}; module.debug('Showing pop-up', settings.transition); - if(!settings.preserve && !settings.popup) { - module.refresh(); - } if( !module.exists() ) { module.create(); } + else if(!settings.preserve && !settings.popup) { + module.refresh(); + } if( $popup && module.set.position() ) { module.save.conditions(); module.animate.show(callback); @@ -252,10 +285,8 @@ $.fn.popup = function(parameters) { hide: function(callback) { - callback = callback || function(){}; - $module - .removeClass(className.visible) - ; + callback = $.isFunction(callback) ? callback : function(){}; + module.remove.visible(); module.unbind.close(); if( module.is.visible() ) { module.restore.conditions(); @@ -266,13 +297,13 @@ $.fn.popup = function(parameters) { hideAll: function() { $(selector.popup) .filter(':visible') - .popup('hide') + .transition(settings.transition) ; }, hideGracefully: function(event) { // don't close on clicks inside popup - if(event && $(event.target).closest(selector.popup).size() === 0) { + if(event && $(event.target).closest(selector.popup).length === 0) { module.debug('Click occurred outside popup hiding popup'); module.hide(); } @@ -286,18 +317,23 @@ $.fn.popup = function(parameters) { return false; } if(settings.inline || settings.popup) { - return ( $popup.size() !== 0 ); + return ( module.has.popup() ); } else { - return ( $popup.closest($context).size() ); + return ( $popup.closest($context).length >= 1 ) + ? true + : false + ; } }, - remove: function() { - module.debug('Removing popup'); - $popup - .remove() - ; + removePopup: function() { + module.debug('Removing popup', $popup); + if( module.has.popup() && !settings.popup) { + $popup.remove(); + $popup = undefined; + } + settings.onRemove.call($popup, element); }, save: { @@ -322,51 +358,52 @@ $.fn.popup = function(parameters) { }, animate: { show: function(callback) { - callback = callback || function(){}; + 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, - duration : settings.duration, - start: function() { - $module - .addClass(className.visible) - ; - }, - complete : function() { + animation : settings.transition + ' in', + queue : false, + debug : settings.debug, + verbose : settings.verbose, + duration : settings.duration, + onComplete : function() { module.bind.close(); - $.proxy(callback, element)(); + callback.call($popup, element); + settings.onVisible.call($popup, element); } }) ; } else { - $module - .addClass(className.visible) - ; + module.set.visible(); $popup .stop() .fadeIn(settings.duration, settings.easing, function() { module.bind.close(); - $.proxy(callback, element)(); + callback.call($popup, element); + settings.onVisible.call($popup, element); }) ; } - $.proxy(settings.onShow, element)(); + settings.onShow.call($popup, element); }, hide: function(callback) { - callback = callback || function(){}; + callback = $.isFunction(callback) ? callback : function(){}; module.debug('Hiding pop-up'); if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) { $popup .transition({ - animation : settings.transition + ' out', - queue : false, - duration : settings.duration, - complete : function() { + animation : settings.transition + ' out', + queue : false, + duration : settings.duration, + debug : settings.debug, + verbose : settings.verbose, + onComplete : function() { module.reset(); - callback(); + callback.call($popup, element); + settings.onHidden.call($popup, element); } }) ; @@ -376,11 +413,12 @@ $.fn.popup = function(parameters) { .stop() .fadeOut(settings.duration, settings.easing, function() { module.reset(); - callback(); + callback.call($popup, element); + settings.onHidden.call($popup, element); }) ; } - $.proxy(settings.onHide, element)(); + settings.onHide.call($popup, element); } }, @@ -403,7 +441,34 @@ $.fn.popup = function(parameters) { } return false; }, - offstagePosition: function() { + offsetParent: function($target) { + var + element = ($target !== undefined) + ? $target[0] + : $module[0], + parentNode = element.parentNode, + $node = $(parentNode) + ; + if(parentNode) { + var + is2D = ($node.css('transform') === 'none'), + isStatic = ($node.css('position') === 'static'), + isHTML = $node.is('html') + ; + while(parentNode && !isHTML && isStatic && is2D) { + parentNode = parentNode.parentNode; + $node = $(parentNode); + is2D = ($node.css('transform') === 'none'); + isStatic = ($node.css('position') === 'static'); + isHTML = $node.is('html'); + } + } + return ($node && $node.length > 0) + ? $node + : $() + ; + }, + offstagePosition: function(position) { var boundary = { top : $(window).scrollTop(), @@ -413,13 +478,15 @@ $.fn.popup = function(parameters) { }, popup = { width : $popup.width(), - height : $popup.outerHeight(), + height : $popup.height(), offset : $popup.offset() }, offstage = {}, offstagePositions = [] ; - if(popup.offset) { + position = position || false; + if(popup.offset && position) { + module.verbose('Checking if outside viewable area', popup.offset); offstage = { top : (popup.offset.top < boundary.top), bottom : (popup.offset.top + popup.height > boundary.bottom), @@ -427,7 +494,6 @@ $.fn.popup = function(parameters) { left : (popup.offset.left < boundary.left) }; } - module.verbose('Checking if outside viewable area', popup.offset); // return only boundaries that have been surpassed $.each(offstage, function(direction, isOffstage) { if(isOffstage) { @@ -439,34 +505,74 @@ $.fn.popup = function(parameters) { : false ; }, + 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) { - switch(position) { - case 'top left': - position = 'bottom left'; - break; - case 'bottom left': - position = 'top right'; - break; - case 'top right': - position = 'bottom right'; - break; - case 'bottom right': - position = 'top center'; - break; - case 'top center': - position = 'bottom center'; - break; - case 'bottom center': - position = 'right center'; - break; - case 'right center': - position = 'left center'; - break; - case 'left center': - position = 'top center'; - break; + 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(); } - return position; + + 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; } }, @@ -489,23 +595,29 @@ $.fn.popup = function(parameters) { targetElement = $target[0], - marginTop = (settings.inline) + marginTop = (settings.inline) ? parseInt( window.getComputedStyle(targetElement).getPropertyValue('margin-top'), 10) : 0, - marginLeft = (settings.inline) - ? parseInt( window.getComputedStyle(targetElement).getPropertyValue('margin-left'), 10) + 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(), + computedPosition, positioning, offstagePosition ; position = position || $module.data(metadata.position) || settings.position; arrowOffset = arrowOffset || $module.data(metadata.offset) || settings.offset; + if(searchDepth == settings.maxSearchDepth && settings.lastResort) { + module.debug('Using last resort position to display', settings.lastResort); + position = settings.lastResort; + } + if(settings.inline) { module.debug('Adding targets margin to calculation'); if(position == 'left center' || position == 'right center') { @@ -522,7 +634,18 @@ $.fn.popup = function(parameters) { } } module.debug('Calculating popup positioning', position); - switch(position) { + + computedPosition = position; + if (module.is.rtl()) { + computedPosition = computedPosition.replace(/left|right/g, function (match) { + return (match == 'left') + ? 'right' + : 'left' + ; + }); + module.debug('RTL: Popup positioning updated', computedPosition); + } + switch (computedPosition) { case 'top left': positioning = { top : 'auto', @@ -589,8 +712,11 @@ $.fn.popup = function(parameters) { break; } if(positioning === undefined) { - module.error(error.invalidPosition); + module.error(error.invalidPosition, position); } + + module.debug('Calculated popup positioning values', positioning); + // tentatively place on stage $popup .css(positioning) @@ -599,52 +725,89 @@ $.fn.popup = function(parameters) { .addClass(className.loading) ; // check if is offstage - offstagePosition = module.get.offstagePosition(); + offstagePosition = module.get.offstagePosition(position); + // recursively find new positioning if(offstagePosition) { - module.debug('Element is outside boundaries', offstagePosition); + module.debug('Popup cant fit into viewport', offstagePosition); if(searchDepth < settings.maxSearchDepth) { - position = module.get.nextPosition(position); searchDepth++; + position = module.get.nextPosition(position); module.debug('Trying new position', position); return ($popup) ? module.set.position(position) : false ; } - else { - module.error(error.recursion); - searchDepth = 0; + else if(!settings.lastResort) { + module.debug('Popup could not find a position in view', $popup); + module.error(error.cannotPlace); + module.remove.attempts(); + module.remove.loading(); module.reset(); - $popup.removeClass(className.loading); return false; } } - else { - module.debug('Position is on stage', position); - searchDepth = 0; - $popup.removeClass(className.loading); - return true; + + module.debug('Position is on stage', position); + module.remove.attempts(); + module.set.fluidWidth(); + module.remove.loading(); + return true; + }, + + fluidWidth: function() { + if( settings.setFluidWidth && $popup.hasClass(className.fluid) ) { + $popup.css('width', $offsetParent.width()); } + }, + + visible: function() { + $module.addClass(className.visible); } + }, + remove: { + loading: function() { + $popup.removeClass(className.loading); + }, + visible: function() { + $module.removeClass(className.visible); + }, + attempts: function() { + module.verbose('Resetting all searched positions'); + searchDepth = 0; + triedPositions = false; + } }, bind: { popup: function() { module.verbose('Allowing hover events on popup to prevent closing'); - $popup - .on('mouseenter', module.event.start) - .on('mouseleave', module.event.end) - ; + 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') { + $document + .one('touchmove' + eventNamespace, module.hideGracefully) + .one('scroll' + eventNamespace, module.hideGracefully) + ; + $context + .one('touchmove' + eventNamespace, module.hideGracefully) + .one('scroll' + eventNamespace, module.hideGracefully) + ; + } if(settings.on == 'click' && settings.closable) { module.verbose('Binding popup close event to document'); $document .on('click' + eventNamespace, function(event) { module.verbose('Pop-up clickaway intent detected'); - $.proxy(module.hideGracefully, element)(event); + module.hideGracefully.call(element, event); }) ; } @@ -653,6 +816,14 @@ $.fn.popup = function(parameters) { unbind: { close: function() { + if(settings.hideOnScroll === true || settings.hideOnScroll == 'auto' && settings.on != 'click') { + $document + .off('scroll' + eventNamespace, module.hide) + ; + $context + .off('scroll' + eventNamespace, module.hide) + ; + } if(settings.on == 'click' && settings.closable) { module.verbose('Removing close event from document'); $document @@ -662,6 +833,12 @@ $.fn.popup = function(parameters) { } }, + has: { + popup: function() { + return ($popup && $popup.length > 0); + } + }, + is: { active: function() { return $module.hasClass(className.active); @@ -677,14 +854,15 @@ $.fn.popup = function(parameters) { }, hidden: function() { return !module.is.visible(); + }, + rtl: function () { + return $module.css('direction') == 'rtl'; } }, reset: function() { - $popup - .removeClass(className.visible) - ; - if(settings.preserve || settings.popup) { + module.remove.visible(); + if(settings.preserve) { if($.fn.transition !== undefined) { $popup .transition('remove transition') @@ -692,7 +870,7 @@ $.fn.popup = function(parameters) { } } else { - module.remove(); + module.removePopup(); } }, @@ -858,7 +1036,7 @@ $.fn.popup = function(parameters) { } else { if(instance !== undefined) { - module.destroy(); + instance.invoke('destroy'); } module.initialize(); } @@ -873,37 +1051,48 @@ $.fn.popup = function(parameters) { $.fn.popup.settings = { - name : 'Popup', + name : 'Popup', + + debug : false, + verbose : true, + performance : true, + namespace : 'popup', - debug : false, - verbose : false, - performance : false, - namespace : 'popup', + onCreate : function(){}, + onRemove : function(){}, - onCreate : function(){}, - onRemove : function(){}, - onShow : function(){}, - onHide : function(){}, + onShow : function(){}, + onVisible : function(){}, + onHide : function(){}, + onHidden : function(){}, - variation : '', - content : false, - html : false, - title : false, + variation : '', + content : false, + html : false, + title : false, - on : 'hover', - closable : true, + on : 'hover', + closable : true, + hideOnScroll : 'auto', - context : 'body', - position : 'top left', - delay : { + context : 'body', + + position : 'top left', + prefer : 'opposite', + lastResort : false, + + delay : { show : 30, hide : 0 }, + setFluidWidth : true, + movePopup : true, + target : false, popup : false, inline : false, - preserve : true, + preserve : false, hoverable : false, duration : 200, @@ -912,12 +1101,12 @@ $.fn.popup.settings = { distanceAway : 0, offset : 0, - maxSearchDepth : 10, + maxSearchDepth : 20, error: { invalidPosition : 'The position you specified is not a valid position', - method : 'The method you called is not defined.', - recursion : 'Popup attempted to reposition element to fit, but could not find an adequate position.' + cannotPlace : 'No visible position could be found for the popup', + method : 'The method you called is not defined.' }, metadata: { @@ -933,6 +1122,7 @@ $.fn.popup.settings = { active : 'active', animating : 'animating', dropdown : 'dropdown', + fluid : 'fluid', loading : 'loading', popup : 'ui popup', position : 'top left center bottom right', diff --git a/popup.min.css b/popup.min.css index f36dd2f..1544988 100755 --- a/popup.min.css +++ b/popup.min.css @@ -1,11 +1,11 @@ /* - * # Semantic UI + * # Semantic UI - 1.9.0 * https://github.com/Semantic-Org/Semantic-UI - * http://beta.semantic-ui.com/ + * http://www.semantic-ui.com/ * * Copyright 2014 Contributors * Released under the MIT license * http://opensource.org/licenses/MIT * */ -.ui.popup{display:none;position:absolute;top:0;right:0;z-index:900;border:1px solid #ccc;max-width:250px;background-color:#fff;padding:.8em 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)}.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{margin:0}.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.wide.popup{width:350px;max-width:350px}.ui[class*="very wide"].popup{width:550px;max-width:550px}.ui.fluid.popup{width:100%;max-width:99999px}.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}.ui.flowing.popup{max-width:9999px}.ui.small.popup{font-size:.8rem}.ui.popup{font-size:.875rem}.ui.large.popup{font-size:1rem}.ui.huge.popup{font-size:1.1rem} \ No newline at end of file +.ui.popup{display:none;position:absolute;top:0;right:0;min-width:-moz-max-content;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)}.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{margin:0}.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 diff --git a/popup.min.js b/popup.min.js index c9b288e..a1c0092 100755 --- a/popup.min.js +++ b/popup.min.js @@ -1,11 +1,11 @@ /* - * # Semantic UI + * # Semantic UI - 1.9.0 * https://github.com/Semantic-Org/Semantic-UI - * http://beta.semantic-ui.com/ + * http://www.semantic-ui.com/ * * Copyright 2014 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||"",u=("ontouchstart"in o.documentElement,(new Date).getTime()),c=[],l=arguments[0],d="string"==typeof l,f=[].slice.call(arguments,1);return s.each(function(){var o,s,g,m=e.isPlainObject(i)?e.extend(!0,{},e.fn.popup.settings,i):e.extend({},e.fn.popup.settings),h=m.selector,b=m.className,v=m.error,y=m.metadata,w=m.namespace,k="."+m.namespace,x="module-"+w,C=e(this),P=e(m.context),T=m.target?e(m.target):C,A=e(t),E=e("body"),z=0,O=this,j=C.data(x);g={initialize:function(){g.debug("Initializing module",C),g.refresh(),"click"==m.on?C.on("click"+k,g.toggle):g.get.startEvent()&&C.on(g.get.startEvent()+k,g.event.start).on(g.get.endEvent()+k,g.event.end),m.target&&g.debug("Target set to element",T),A.on("resize"+k,g.event.resize),g.exists()?m.hoverable&&g.bind.popup():g.create(),g.instantiate()},instantiate:function(){g.verbose("Storing instance of module",g),j=g,C.data(x,j)},refresh:function(){o=m.popup?e(m.popup):m.inline?T.next(m.selector.popup):!1,s=m.popup?o.offsetParent():m.inline?T.offsetParent():E},destroy:function(){g.debug("Destroying previous module"),o&&!m.preserve&&g.remove(),C.off(k).removeData(x)},event:{start:function(){var t=e.isPlainObject(m.delay)?m.delay.show:m.delay;clearTimeout(g.hideTimer),g.showTimer=setTimeout(function(){!g.is.hidden()||g.is.active()&&g.is.dropdown()||g.show()},t)},end:function(){var t=e.isPlainObject(m.delay)?m.delay.hide:m.delay;clearTimeout(g.showTimer),g.hideTimer=setTimeout(function(){g.is.visible()&&g.hide()},t)},resize:function(){g.is.visible()&&g.set.position()}},create:function(){var t=C.data(y.html)||m.html,n=C.data(y.variation)||m.variation,i=C.data(y.title)||m.title,r=C.data(y.content)||C.attr("title")||m.content;t||r||i?(g.debug("Creating pop-up html"),t||(t=m.templates.popup({title:i,content:r})),o=e("
").addClass(b.popup).addClass(n).html(t),n&&o.addClass(n),m.inline?(g.verbose("Inserting popup element inline",o),o.insertAfter(C)):(g.verbose("Appending popup element to body",o),o.appendTo(P)),m.hoverable&&g.bind.popup(),e.proxy(m.onCreate,o)()):0!==T.next(m.selector.popup).size()?(g.verbose("Pre-existing popup found, reverting to inline"),m.inline=!0,g.refresh(),m.hoverable&&g.bind.popup()):g.debug("No content specified skipping display",O)},toggle:function(){g.debug("Toggling pop-up"),g.is.hidden()?(g.debug("Popup is hidden, showing pop-up"),g.unbind.close(),g.hideAll(),g.show()):(g.debug("Popup is visible, hiding pop-up"),g.hide())},show:function(e){e=e||function(){},g.debug("Showing pop-up",m.transition),m.preserve||m.popup||g.refresh(),g.exists()||g.create(),o&&g.set.position()&&(g.save.conditions(),g.animate.show(e))},hide:function(e){e=e||function(){},C.removeClass(b.visible),g.unbind.close(),g.is.visible()&&(g.restore.conditions(),g.animate.hide(e))},hideAll:function(){e(h.popup).filter(":visible").popup("hide")},hideGracefully:function(t){t&&0===e(t.target).closest(h.popup).size()?(g.debug("Click occurred outside popup hiding popup"),g.hide()):g.debug("Click was inside popup, keeping popup open")},exists:function(){return o?m.inline||m.popup?0!==o.size():o.closest(P).size():!1},remove:function(){g.debug("Removing popup"),o.remove()},save:{conditions:function(){g.cache={title:C.attr("title")},g.cache.title&&C.removeAttr("title"),g.verbose("Saving original attributes",g.cache.title)}},restore:{conditions:function(){return g.cache&&g.cache.title&&(C.attr("title",g.cache.title),g.verbose("Restoring original attributes",g.cache.title)),!0}},animate:{show:function(t){t=t||function(){},m.transition&&e.fn.transition!==n&&C.transition("is supported")?o.transition({animation:m.transition+" in",queue:!1,duration:m.duration,start:function(){C.addClass(b.visible)},complete:function(){g.bind.close(),e.proxy(t,O)()}}):(C.addClass(b.visible),o.stop().fadeIn(m.duration,m.easing,function(){g.bind.close(),e.proxy(t,O)()})),e.proxy(m.onShow,O)()},hide:function(t){t=t||function(){},g.debug("Hiding pop-up"),m.transition&&e.fn.transition!==n&&C.transition("is supported")?o.transition({animation:m.transition+" out",queue:!1,duration:m.duration,complete:function(){g.reset(),t()}}):o.stop().fadeOut(m.duration,m.easing,function(){g.reset(),t()}),e.proxy(m.onHide,O)()}},get:{startEvent:function(){return"hover"==m.on?"mouseenter":"focus"==m.on?"focus":!1},endEvent:function(){return"hover"==m.on?"mouseleave":"focus"==m.on?"blur":!1},offstagePosition:function(){var n={top:e(t).scrollTop(),bottom:e(t).scrollTop()+e(t).height(),left:0,right:e(t).width()},i={width:o.width(),height:o.outerHeight(),offset:o.offset()},r={},s=[];return i.offset&&(r={top:i.offset.topn.bottom,right:i.offset.left+i.width>n.right,left:i.offset.left0?s.join(" "):!1},nextPosition:function(e){switch(e){case"top left":e="bottom left";break;case"bottom left":e="top right";break;case"top right":e="bottom right";break;case"bottom right":e="top center";break;case"top center":e="bottom center";break;case"bottom center":e="right center";break;case"right center":e="left center";break;case"left center":e="top center"}return e}},set:{position:function(i,r){var a,p,u=(e(t).width(),e(t).height(),T.outerWidth()),c=T.outerHeight(),l=o.outerWidth(),d=o.outerHeight(),f=s.outerWidth(),h=s.outerHeight(),w=m.distanceAway,k=T[0],x=m.inline?parseInt(t.getComputedStyle(k).getPropertyValue("margin-top"),10):0,P=m.inline?parseInt(t.getComputedStyle(k).getPropertyValue("margin-left"),10):0,A=m.inline||m.popup?T.position():T.offset();switch(i=i||C.data(y.position)||m.position,r=r||C.data(y.offset)||m.offset,m.inline&&(g.debug("Adding targets margin to calculation"),"left center"==i||"right center"==i?(r+=x,w+=-P):"top left"==i||"top center"==i||"top right"==i?(r+=P,w-=x):(r+=P,w+=x)),g.debug("Calculating popup positioning",i),i){case"top left":a={top:"auto",bottom:h-A.top+w,left:A.left+r,right:"auto"};break;case"top center":a={bottom:h-A.top+w,left:A.left+u/2-l/2+r,top:"auto",right:"auto"};break;case"top right":a={bottom:h-A.top+w,right:f-A.left-u-r,top:"auto",left:"auto"};break;case"left center":a={top:A.top+c/2-d/2+r,right:f-A.left+w,left:"auto",bottom:"auto"};break;case"right center":a={top:A.top+c/2-d/2+r,left:A.left+u+w,bottom:"auto",right:"auto"};break;case"bottom left":a={top:A.top+c+w,left:A.left+r,bottom:"auto",right:"auto"};break;case"bottom center":a={top:A.top+c+w,left:A.left+u/2-l/2+r,bottom:"auto",right:"auto"};break;case"bottom right":a={top:A.top+c+w,right:f-A.left-u-r,left:"auto",bottom:"auto"}}return a===n&&g.error(v.invalidPosition),o.css(a).removeClass(b.position).addClass(i).addClass(b.loading),p=g.get.offstagePosition(),p?(g.debug("Element is outside boundaries",p),z0&&(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,u=j;return o=o||f,i=O||i,"string"==typeof t&&u!==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(u[r])&&o!=s)u=u[r];else{if(u[r]!==n)return a=u[r],!1;if(!e.isPlainObject(u[i])||o==s)return u[i]!==n?(a=u[i],!1):!1;u=u[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}},d?(j===n&&g.initialize(),g.invoke(l)):(j!==n&&g.destroy(),g.initialize())}),r!==n?r:this},e.fn.popup.settings={name:"Popup",debug:!1,verbose:!1,performance:!1,namespace:"popup",onCreate:function(){},onRemove:function(){},onShow:function(){},onHide:function(){},variation:"",content:!1,html:!1,title:!1,on:"hover",closable:!0,context:"body",position:"top left",delay:{show:30,hide:0},target:!1,popup:!1,inline:!1,preserve:!0,hoverable:!1,duration:200,easing:"easeOutQuint",transition:"scale",distanceAway:0,offset:0,maxSearchDepth:10,error:{invalidPosition:"The position you specified is not a valid position",method:"The method you called is not defined.",recursion:"Popup attempted to reposition element to fit, but could not find an adequate position."},metadata:{content:"content",html:"html",offset:"offset",position:"position",title:"title",variation:"variation"},className:{active:"active",animating:"animating",dropdown:"dropdown",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(e,t,o,n){"use strict";e.fn.popup=function(i){var s,r=e(this),a=e(o),l=r.selector||"",p=("ontouchstart"in o.documentElement,(new Date).getTime()),u=[],c=arguments[0],d="string"==typeof c,f=[].slice.call(arguments,1);return r.each(function(){var o,r,g,h=e.isPlainObject(i)?e.extend(!0,{},e.fn.popup.settings,i):e.extend({},e.fn.popup.settings),m=h.selector,b=h.className,v=h.error,y=h.metadata,w=h.namespace,P="."+h.namespace,T="module-"+w,C=e(this),k=e(h.context),x=h.target?e(h.target):C,S=e(t),O=e("body"),j=0,A=!1,R=this,E=C.data(T);g={initialize:function(){g.debug("Initializing module",C),"click"==h.on?C.on("click"+P,g.toggle):g.get.startEvent()&&C.on(g.get.startEvent()+P,g.event.start).on(g.get.endEvent()+P,g.event.end),h.target&&g.debug("Target set to element",x),S.on("resize"+P,g.event.resize),!g.exists()&&h.preserve&&g.create(),g.instantiate()},instantiate:function(){g.verbose("Storing instance of module",g),E=g,C.data(T,E)},refresh:function(){h.popup?o=e(h.popup).eq(0):h.inline&&(o=x.next(m.popup).eq(0)),h.popup?(o.addClass(b.loading),r=g.get.offsetParent(),o.removeClass(b.loading),h.movePopup&&g.has.popup()&&g.get.offsetParent(o)[0]!==r[0]&&(g.debug("Moving popup to the same offset parent as activating element"),o.detach().appendTo(r))):r=h.inline?g.get.offsetParent(x):g.has.popup()?g.get.offsetParent(o):O,r.is("html")&&(g.debug("Setting page as offset parent"),r=O)},reposition:function(){g.refresh(),g.set.position()},destroy:function(){g.debug("Destroying previous module"),o&&!h.preserve&&g.removePopup(),clearTimeout(g.hideTimer),clearTimeout(g.showTimer),C.off(P).removeData(T)},event:{start:function(){var t=e.isPlainObject(h.delay)?h.delay.show:h.delay;clearTimeout(g.hideTimer),g.showTimer=setTimeout(function(){!g.is.hidden()||g.is.active()&&g.is.dropdown()||g.show()},t)},end:function(){var t=e.isPlainObject(h.delay)?h.delay.hide:h.delay;clearTimeout(g.showTimer),g.hideTimer=setTimeout(function(){g.is.visible()&&g.hide()},t)},resize:function(){g.is.visible()&&g.set.position()}},create:function(){var t=C.data(y.html)||h.html,n=C.data(y.variation)||h.variation,i=C.data(y.title)||h.title,s=C.data(y.content)||C.attr("title")||h.content;t||s||i?(g.debug("Creating pop-up html"),t||(t=h.templates.popup({title:i,content:s})),o=e("
").addClass(b.popup).addClass(n).html(t),n&&o.addClass(n),h.inline?(g.verbose("Inserting popup element inline",o),o.insertAfter(C)):(g.verbose("Appending popup element to body",o),o.appendTo(k)),g.refresh(),h.hoverable&&g.bind.popup(),h.onCreate.call(o,R)):0!==x.next(m.popup).length?(g.verbose("Pre-existing popup found"),h.inline=!0,h.popup=x.next(m.popup),g.refresh(),h.hoverable&&g.bind.popup()):h.popup?(g.verbose("Used popup specified in settings"),g.refresh(),h.hoverable&&g.bind.popup()):g.debug("No content specified skipping display",R)},toggle:function(){g.debug("Toggling pop-up"),g.is.hidden()?(g.debug("Popup is hidden, showing pop-up"),g.unbind.close(),g.hideAll(),g.show()):(g.debug("Popup is visible, hiding pop-up"),g.hide())},show:function(t){t=e.isFunction(t)?t:function(){},g.debug("Showing pop-up",h.transition),g.exists()?h.preserve||h.popup||g.refresh():g.create(),o&&g.set.position()&&(g.save.conditions(),g.animate.show(t))},hide:function(t){t=e.isFunction(t)?t:function(){},g.remove.visible(),g.unbind.close(),g.is.visible()&&(g.restore.conditions(),g.animate.hide(t))},hideAll:function(){e(m.popup).filter(":visible").transition(h.transition)},hideGracefully:function(t){t&&0===e(t.target).closest(m.popup).length?(g.debug("Click occurred outside popup hiding popup"),g.hide()):g.debug("Click was inside popup, keeping popup open")},exists:function(){return o?h.inline||h.popup?g.has.popup():o.closest(k).length>=1?!0:!1:!1},removePopup:function(){g.debug("Removing popup",o),g.has.popup()&&!h.popup&&(o.remove(),o=n),h.onRemove.call(o,R)},save:{conditions:function(){g.cache={title:C.attr("title")},g.cache.title&&C.removeAttr("title"),g.verbose("Saving original attributes",g.cache.title)}},restore:{conditions:function(){return g.cache&&g.cache.title&&(C.attr("title",g.cache.title),g.verbose("Restoring original attributes",g.cache.title)),!0}},animate:{show:function(t){t=e.isFunction(t)?t:function(){},h.transition&&e.fn.transition!==n&&C.transition("is supported")?(g.set.visible(),o.transition({animation:h.transition+" in",queue:!1,debug:h.debug,verbose:h.verbose,duration:h.duration,onComplete:function(){g.bind.close(),t.call(o,R),h.onVisible.call(o,R)}})):(g.set.visible(),o.stop().fadeIn(h.duration,h.easing,function(){g.bind.close(),t.call(o,R),h.onVisible.call(o,R)})),h.onShow.call(o,R)},hide:function(t){t=e.isFunction(t)?t:function(){},g.debug("Hiding pop-up"),h.transition&&e.fn.transition!==n&&C.transition("is supported")?o.transition({animation:h.transition+" out",queue:!1,duration:h.duration,debug:h.debug,verbose:h.verbose,onComplete:function(){g.reset(),t.call(o,R),h.onHidden.call(o,R)}}):o.stop().fadeOut(h.duration,h.easing,function(){g.reset(),t.call(o,R),h.onHidden.call(o,R)}),h.onHide.call(o,R)}},get:{startEvent:function(){return"hover"==h.on?"mouseenter":"focus"==h.on?"focus":!1},endEvent:function(){return"hover"==h.on?"mouseleave":"focus"==h.on?"blur":!1},offsetParent:function(t){var o=t!==n?t[0]:C[0],i=o.parentNode,s=e(i);if(i)for(var r="none"===s.css("transform"),a="static"===s.css("position"),l=s.is("html");i&&!l&&a&&r;)i=i.parentNode,s=e(i),r="none"===s.css("transform"),a="static"===s.css("position"),l=s.is("html");return s&&s.length>0?s:e()},offstagePosition:function(n){var i={top:e(t).scrollTop(),bottom:e(t).scrollTop()+e(t).height(),left:0,right:e(t).width()},s={width:o.width(),height:o.height(),offset:o.offset()},r={},a=[];return n=n||!1,s.offset&&n&&(g.verbose("Checking if outside viewable area",s.offset),r={top:s.offset.topi.bottom,right:s.offset.left+s.width>i.right,left:s.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"},s={left:"center",center:"right",right:"left"},r={"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,l=!1,p=!1,u=!1;return A||(g.verbose("All available positions available"),A=g.get.positions()),g.debug("Recording last position tried",e),A[e]=!0,"opposite"===h.prefer&&(u=[i[o],n],u=u.join(" "),l=A[u]===!0,g.debug("Trying opposite strategy",u)),"adjacent"===h.prefer&&a&&(u=[o,s[n]],u=u.join(" "),p=A[u]===!0,g.debug("Trying adjacent strategy",u)),(p||l)&&(g.debug("Using backup position",u),u=r[e]),u}},set:{position:function(i,s){var a,l,p,u=(e(t).width(),e(t).height(),x.outerWidth()),c=x.outerHeight(),d=o.outerWidth(),f=o.outerHeight(),m=r.outerWidth(),w=r.outerHeight(),P=h.distanceAway,T=x[0],k=h.inline?parseInt(t.getComputedStyle(T).getPropertyValue("margin-top"),10):0,S=h.inline?parseInt(t.getComputedStyle(T).getPropertyValue(g.is.rtl()?"margin-right":"margin-left"),10):0,O=h.inline||h.popup?x.position():x.offset();switch(i=i||C.data(y.position)||h.position,s=s||C.data(y.offset)||h.offset,j==h.maxSearchDepth&&h.lastResort&&(g.debug("Using last resort position to display",h.lastResort),i=h.lastResort),h.inline&&(g.debug("Adding targets margin to calculation"),"left center"==i||"right center"==i?(s+=k,P+=-S):"top left"==i||"top center"==i||"top right"==i?(s+=S,P-=k):(s+=S,P+=k)),g.debug("Calculating popup positioning",i),a=i,g.is.rtl()&&(a=a.replace(/left|right/g,function(e){return"left"==e?"right":"left"}),g.debug("RTL: Popup positioning updated",a)),a){case"top left":l={top:"auto",bottom:w-O.top+P,left:O.left+s,right:"auto"};break;case"top center":l={bottom:w-O.top+P,left:O.left+u/2-d/2+s,top:"auto",right:"auto"};break;case"top right":l={bottom:w-O.top+P,right:m-O.left-u-s,top:"auto",left:"auto"};break;case"left center":l={top:O.top+c/2-f/2+s,right:m-O.left+P,left:"auto",bottom:"auto"};break;case"right center":l={top:O.top+c/2-f/2+s,left:O.left+u+P,bottom:"auto",right:"auto"};break;case"bottom left":l={top:O.top+c+P,left:O.left+s,bottom:"auto",right:"auto"};break;case"bottom center":l={top:O.top+c+P,left:O.left+u/2-d/2+s,bottom:"auto",right:"auto"};break;case"bottom right":l={top:O.top+c+P,right:m-O.left-u-s,left:"auto",bottom:"auto"}}if(l===n&&g.error(v.invalidPosition,i),g.debug("Calculated popup positioning values",l),o.css(l).removeClass(b.position).addClass(i).addClass(b.loading),p=g.get.offstagePosition(i)){if(g.debug("Popup cant fit into viewport",p),j0}},is:{active:function(){return C.hasClass(b.active)},animating:function(){return o&&o.is(":animated")||o.hasClass(b.animating)},visible:function(){return o&&o.is(":visible")},dropdown:function(){return C.hasClass(b.dropdown)},hidden:function(){return!g.is.visible()},rtl:function(){return"rtl"==C.css("direction")}},reset:function(){g.remove.visible(),h.preserve?e.fn.transition!==n&&o.transition("remove transition"):g.removePopup()},setting:function(t,o){if(e.isPlainObject(t))e.extend(!0,h,t);else{if(o===n)return h[t];h[t]=o}},internal:function(t,o){if(e.isPlainObject(t))e.extend(!0,g,t);else{if(o===n)return g[t];g[t]=o}},debug:function(){h.debug&&(h.performance?g.performance.log(arguments):(g.debug=Function.prototype.bind.call(console.info,console,h.name+":"),g.debug.apply(console,arguments)))},verbose:function(){h.verbose&&h.debug&&(h.performance?g.performance.log(arguments):(g.verbose=Function.prototype.bind.call(console.info,console,h.name+":"),g.verbose.apply(console,arguments)))},error:function(){g.error=Function.prototype.bind.call(console.error,console,h.name+":"),g.error.apply(console,arguments)},performance:{log:function(e){var t,o,n;h.performance&&(t=(new Date).getTime(),n=p||t,o=t-n,p=t,u.push({Name:e[0],Arguments:[].slice.call(e,1)||"",Element:R,"Execution Time":o})),clearTimeout(g.performance.timer),g.performance.timer=setTimeout(g.performance.display,100)},display:function(){var t=h.name+":",o=0;p=!1,clearTimeout(g.performance.timer),e.each(u,function(e,t){o+=t["Execution Time"]}),t+=" "+o+"ms",l&&(t+=" '"+l+"'"),(console.group!==n||console.table!==n)&&u.length>0&&(console.groupCollapsed(t),console.table?console.table(u):e.each(u,function(e,t){console.log(t.Name+": "+t["Execution Time"]+"ms")}),console.groupEnd()),u=[]}},invoke:function(t,o,i){var r,a,l,p=E;return o=o||f,i=R||i,"string"==typeof t&&p!==n&&(t=t.split(/[\. ]/),r=t.length-1,e.each(t,function(o,i){var s=o!=r?i+t[o+1].charAt(0).toUpperCase()+t[o+1].slice(1):t;if(e.isPlainObject(p[s])&&o!=r)p=p[s];else{if(p[s]!==n)return a=p[s],!1;if(!e.isPlainObject(p[i])||o==r)return p[i]!==n?(a=p[i],!1):!1;p=p[i]}})),e.isFunction(a)?l=a.apply(i,o):a!==n&&(l=a),e.isArray(s)?s.push(l):s!==n?s=[s,l]:l!==n&&(s=l),a}},d?(E===n&&g.initialize(),g.invoke(c)):(E!==n&&E.invoke("destroy"),g.initialize())}),s!==n?s: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",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:{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 From 369a80790517a585541ccc0de06f2e0dbd09f703 Mon Sep 17 00:00:00 2001 From: Jack Lukic Date: Wed, 18 Feb 2015 12:28:15 -0500 Subject: [PATCH 20/22] Updated component to version 1.9.0 --- RELEASE-NOTES.md | 103 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) mode change 100644 => 100755 RELEASE-NOTES.md diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md old mode 100644 new mode 100755 index e69de29..2084199 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -0,0 +1,103 @@ +### UI Changes + +- **Transition** - Transitions with direction now use word order dependency to prevent conflict with component directions, for example `bottom left popup slide down in transition + +### Version 1.8.1 - January 26, 2015 + +- **Popup** - Popup `hide all` will now use transition set in `settings.transition` when closing other popups + +### Version 1.8.0 - January 23, 2015 + +- **Popup** - Popup will now only use a max of one element when `settings.popup` mistakingly passes multiple DOM elements +- **Popup** - Popups will now by default appear over all UI content, even dimmers. + +### Version 1.7.0 - January 14, 2015 + +- **Popup** - Popup now uses its own custom method for determining `offsetParent` meaning 3D contexts (like inside an animation) no longer should break positioning +- **Popup** - Popup now uses `preserve: false` by default, this is slightly less performant but will reduce page clutter caused by leaving generated elements in the DOM +- **Popup** - `wide` and `very wide` popup will now appear when screen size is below their `max-width` +- **Popup** - Popup no longer blurs element on popup hide + +### Version 1.6.0 - January 05, 2015 + +- **Popup** - Fix issue with `ui popup` receiving error ``$offsetParent is undefined`` when using a pre-defined popup +- **Popup** - Fix issue with ``ui popup` not appearing with ``ui flowing popup`` due to newly added ``min-width: max-content`` + +### Version 1.5.0 - December 30, 2014 + +- **Popup** - Popup now uses the new property ``min-width: max-content`` to allow for better display with ``inline`` in some circumstances where it escapes parent element. +- **Popup** - Popup destroy will now also destroy any unfired timers (show/hide delay) +- **Popup** - Popup now moves to the same offset context to avoid positioning errors when using a named pre-existing popup. + +### Version 1.1.0 - December 02, 2014 + +- **Popup** - Popup now has a ``settings.prefer`` that defaults to ``adjacent``. This setting sets prefered next placement when a popup cannot fit on screen in the chosen placement. ``prefer`` can also be set to ``opposite`` to prefer the same position on the opposite side +- **Popup** - Popup can now use a setting ``lastResort``. When set to a position it will be used as a last resort even if popup does not entirely fit on the page. Setting this to ``false`` will produce an error when a popup cannot fit on screen. + +### Version 1.0.0 - November 24, 2014 + +- **Popup** - Popup can now allow itself not to be closed when hovered over +- **Popup** - A popup element can now be specified on initialization. +- **Popup** - Positioned popups will now extend in the opposite direction to fit better with floated content + +### Version 0.18.0 - June 6, 2014 + +- **Popup** - Fixes javascript animation of popup missing easing dependency + +### Version 0.17.0 - May 9, 2014 + +- **Popup** - Popup now has an ``onRemove`` callback after removing element from DOM + +### Version 0.12.5 - Feb 04, 2014 + +- **Popup** - Fixes issue where popups using ``title`` attribute to store data were losing title content instead of correctly restoring it + +### Merry Christmas! + +-**Popup** - Fixes popup sometimes opening and closing when ``event:click`` is used and a user double clicks + +### Version 0.10.3 - Dec 22, 2013 + +- **Popup** - Native browser popups no longer if using ``title`` attribute + +### Version 0.9.2 - Nov 8, 2013 + +**Fixes** - Fixes popup not repositioning itself when offstage. + +### Version 0.9.1 - Nov 7, 2013 + +- **Popup** - Adds context option for popup (thanks jefmathiot) + +### Version 0.7.1 - Oct 23, 2013 + +- **Popup** - Fixes issue with popup's using setting inline: true + +### Version 0.7.0 - Oct 22, 2013 + +- **List** - Popups can now have a different target than itself +- **Popup** - Popup .toggle() now always hides/shows popup correctly +- **Popup** - Popup fixed a bug where "top right" placed popup might sometimes be too large +- **Popup** - Popup will not reshow a visible popup on hover +- **Popup** - Popup border now uses RGBA to look sexier on dark backgrounds +- **Popup** - Popup default duration is now 200ms (slighty slower) +- **Popup** - Popup metadata attribute arrowOffset is now offset for simplicities sake +- **Popup** - Popup no-longer receives class name 'visible' on show, this allows popups to be used on dropdowns and other elements with a visible state +- **Popup** - Popups are no longer inline by default + +### Version 0.5.0 - Oct 10, 2013 + +- Fixes regression where popup was overriding variation class name on positioning +- Fixes an issue where popup that was set to inline: false was being removed prematurely +- Adds an example to popup where inline is set to false +- Added onCreate to popup module + +### Version 0.3.6 - Oct 7, 2013 + +- Fixes popup position sometimes appearing off-stage on second apperance +- Fixes popup positions top left, top right, bottom left, bottom right being flipped + +### Version 0.3.3 - Oct 2, 2013 + +- Fixes issue with popup display in some edge cases Issue #128 + +### Version 0.1.0 - Sep 25, 2013 \ No newline at end of file From 5f2cb2d39eae1816241036b999027e801256cca7 Mon Sep 17 00:00:00 2001 From: Jack Lukic Date: Wed, 18 Feb 2015 12:42:57 -0500 Subject: [PATCH 21/22] Merged from upstream --- RELEASE-NOTES.md | 103 ++++ index.js | 1189 ++++++++++++++++++++++++++++++++++++++++++++++ popup.css | 294 ++++++++++++ popup.js | 1187 +++++++++++++++++++++++++++++++++++++++++++++ popup.min.css | 11 + popup.min.js | 11 + 6 files changed, 2795 insertions(+) create mode 100755 RELEASE-NOTES.md create mode 100755 index.js create mode 100755 popup.css create mode 100755 popup.js create mode 100755 popup.min.css create mode 100755 popup.min.js diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md new file mode 100755 index 0000000..2084199 --- /dev/null +++ b/RELEASE-NOTES.md @@ -0,0 +1,103 @@ +### UI Changes + +- **Transition** - Transitions with direction now use word order dependency to prevent conflict with component directions, for example `bottom left popup slide down in transition + +### Version 1.8.1 - January 26, 2015 + +- **Popup** - Popup `hide all` will now use transition set in `settings.transition` when closing other popups + +### Version 1.8.0 - January 23, 2015 + +- **Popup** - Popup will now only use a max of one element when `settings.popup` mistakingly passes multiple DOM elements +- **Popup** - Popups will now by default appear over all UI content, even dimmers. + +### Version 1.7.0 - January 14, 2015 + +- **Popup** - Popup now uses its own custom method for determining `offsetParent` meaning 3D contexts (like inside an animation) no longer should break positioning +- **Popup** - Popup now uses `preserve: false` by default, this is slightly less performant but will reduce page clutter caused by leaving generated elements in the DOM +- **Popup** - `wide` and `very wide` popup will now appear when screen size is below their `max-width` +- **Popup** - Popup no longer blurs element on popup hide + +### Version 1.6.0 - January 05, 2015 + +- **Popup** - Fix issue with `ui popup` receiving error ``$offsetParent is undefined`` when using a pre-defined popup +- **Popup** - Fix issue with ``ui popup` not appearing with ``ui flowing popup`` due to newly added ``min-width: max-content`` + +### Version 1.5.0 - December 30, 2014 + +- **Popup** - Popup now uses the new property ``min-width: max-content`` to allow for better display with ``inline`` in some circumstances where it escapes parent element. +- **Popup** - Popup destroy will now also destroy any unfired timers (show/hide delay) +- **Popup** - Popup now moves to the same offset context to avoid positioning errors when using a named pre-existing popup. + +### Version 1.1.0 - December 02, 2014 + +- **Popup** - Popup now has a ``settings.prefer`` that defaults to ``adjacent``. This setting sets prefered next placement when a popup cannot fit on screen in the chosen placement. ``prefer`` can also be set to ``opposite`` to prefer the same position on the opposite side +- **Popup** - Popup can now use a setting ``lastResort``. When set to a position it will be used as a last resort even if popup does not entirely fit on the page. Setting this to ``false`` will produce an error when a popup cannot fit on screen. + +### Version 1.0.0 - November 24, 2014 + +- **Popup** - Popup can now allow itself not to be closed when hovered over +- **Popup** - A popup element can now be specified on initialization. +- **Popup** - Positioned popups will now extend in the opposite direction to fit better with floated content + +### Version 0.18.0 - June 6, 2014 + +- **Popup** - Fixes javascript animation of popup missing easing dependency + +### Version 0.17.0 - May 9, 2014 + +- **Popup** - Popup now has an ``onRemove`` callback after removing element from DOM + +### Version 0.12.5 - Feb 04, 2014 + +- **Popup** - Fixes issue where popups using ``title`` attribute to store data were losing title content instead of correctly restoring it + +### Merry Christmas! + +-**Popup** - Fixes popup sometimes opening and closing when ``event:click`` is used and a user double clicks + +### Version 0.10.3 - Dec 22, 2013 + +- **Popup** - Native browser popups no longer if using ``title`` attribute + +### Version 0.9.2 - Nov 8, 2013 + +**Fixes** - Fixes popup not repositioning itself when offstage. + +### Version 0.9.1 - Nov 7, 2013 + +- **Popup** - Adds context option for popup (thanks jefmathiot) + +### Version 0.7.1 - Oct 23, 2013 + +- **Popup** - Fixes issue with popup's using setting inline: true + +### Version 0.7.0 - Oct 22, 2013 + +- **List** - Popups can now have a different target than itself +- **Popup** - Popup .toggle() now always hides/shows popup correctly +- **Popup** - Popup fixed a bug where "top right" placed popup might sometimes be too large +- **Popup** - Popup will not reshow a visible popup on hover +- **Popup** - Popup border now uses RGBA to look sexier on dark backgrounds +- **Popup** - Popup default duration is now 200ms (slighty slower) +- **Popup** - Popup metadata attribute arrowOffset is now offset for simplicities sake +- **Popup** - Popup no-longer receives class name 'visible' on show, this allows popups to be used on dropdowns and other elements with a visible state +- **Popup** - Popups are no longer inline by default + +### Version 0.5.0 - Oct 10, 2013 + +- Fixes regression where popup was overriding variation class name on positioning +- Fixes an issue where popup that was set to inline: false was being removed prematurely +- Adds an example to popup where inline is set to false +- Added onCreate to popup module + +### Version 0.3.6 - Oct 7, 2013 + +- Fixes popup position sometimes appearing off-stage on second apperance +- Fixes popup positions top left, top right, bottom left, bottom right being flipped + +### Version 0.3.3 - Oct 2, 2013 + +- Fixes issue with popup display in some edge cases Issue #128 + +### Version 0.1.0 - Sep 25, 2013 \ No newline at end of file diff --git a/index.js b/index.js new file mode 100755 index 0000000..e784765 --- /dev/null +++ b/index.js @@ -0,0 +1,1189 @@ +/* + * # Semantic - Popup + * http://github.com/semantic-org/semantic-ui/ + * + * + * Copyright 2014 Contributor + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +;(function ($, window, document, undefined) { + +"use strict"; + +module.exports = function(parameters) { + var _module = module; + + var + $allModules = $(this), + $document = $(document), + + moduleSelector = $allModules.selector || '', + + hasTouch = ('ontouchstart' in document.documentElement), + 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, {}, _module.exports.settings, parameters) + : $.extend({}, _module.exports.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), + $target = (settings.target) + ? $(settings.target) + : $module, + + $window = $(window), + $body = $('body'), + $popup, + $offsetParent, + + searchDepth = 0, + triedPositions = false, + + element = this, + instance = $module.data(moduleNamespace), + module + ; + + module = { + + // binds events + initialize: function() { + module.debug('Initializing module', $module); + if(settings.on == 'click') { + $module + .on('click' + eventNamespace, module.toggle) + ; + } + else 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' + eventNamespace, module.event.resize) + ; + if( !module.exists() && settings.preserve) { + module.create(); + } + module.instantiate(); + }, + + instantiate: function() { + module.verbose('Storing instance of module', module); + instance = module; + $module + .data(moduleNamespace, instance) + ; + }, + + refresh: function() { + if(settings.popup) { + $popup = $(settings.popup).eq(0); + } + else { + if(settings.inline) { + $popup = $target.next(selector.popup).eq(0); + } + } + 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 activating element'); + $popup + .detach() + .appendTo($offsetParent) + ; + } + } + else { + $offsetParent = (settings.inline) + ? module.get.offsetParent($target) + : module.has.popup() + ? module.get.offsetParent($popup) + : $body + ; + } + if( $offsetParent.is('html') ) { + module.debug('Setting page as offset parent'); + $offsetParent = $body; + } + }, + + reposition: function() { + module.refresh(); + module.set.position(); + }, + + destroy: function() { + module.debug('Destroying previous module'); + if($popup && !settings.preserve) { + module.removePopup(); + } + clearTimeout(module.hideTimer); + clearTimeout(module.showTimer); + $module + .off(eventNamespace) + .removeData(moduleNamespace) + ; + }, + + event: { + start: function(event) { + var + delay = ($.isPlainObject(settings.delay)) + ? settings.delay.show + : settings.delay + ; + clearTimeout(module.hideTimer); + module.showTimer = setTimeout(function() { + if(module.is.hidden() && !( module.is.active() && module.is.dropdown()) ) { + module.show(); + } + }, delay); + }, + end: function() { + var + delay = ($.isPlainObject(settings.delay)) + ? settings.delay.hide + : settings.delay + ; + clearTimeout(module.showTimer); + module.hideTimer = setTimeout(function() { + if(module.is.visible() ) { + module.hide(); + } + }, delay); + }, + resize: function() { + if( module.is.visible() ) { + module.set.position(); + } + } + }, + + // 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 + ; + if(html || content || title) { + module.debug('Creating pop-up html'); + if(!html) { + html = settings.templates.popup({ + title : title, + content : content + }); + } + $popup = $('
') + .addClass(className.popup) + .addClass(variation) + .html(html) + ; + if(variation) { + $popup + .addClass(variation) + ; + } + 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(); + 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); + module.refresh(); + if(settings.hoverable) { + module.bind.popup(); + } + } + else if(settings.popup) { + module.verbose('Used popup specified in settings'); + module.refresh(); + if(settings.hoverable) { + module.bind.popup(); + } + } + else { + module.debug('No content specified skipping display', element); + } + }, + + // 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.hideAll(); + module.show(); + } + else { + module.debug('Popup is visible, hiding pop-up'); + module.hide(); + } + }, + + show: function(callback) { + callback = $.isFunction(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(); + module.animate.show(callback); + } + }, + + + hide: function(callback) { + callback = $.isFunction(callback) ? callback : function(){}; + module.remove.visible(); + module.unbind.close(); + if( module.is.visible() ) { + module.restore.conditions(); + module.animate.hide(callback); + } + }, + + hideAll: function() { + $(selector.popup) + .filter(':visible') + .transition(settings.transition) + ; + }, + + 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; + } + if(settings.inline || settings.popup) { + return ( module.has.popup() ); + } + else { + return ( $popup.closest($context).length >= 1 ) + ? true + : false + ; + } + }, + + removePopup: function() { + module.debug('Removing popup', $popup); + if( module.has.popup() && !settings.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; + } + }, + 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.set.visible(); + $popup + .stop() + .fadeIn(settings.duration, settings.easing, function() { + module.bind.close(); + callback.call($popup, element); + settings.onVisible.call($popup, element); + }) + ; + } + settings.onShow.call($popup, element); + }, + hide: function(callback) { + callback = $.isFunction(callback) ? callback : function(){}; + module.debug('Hiding pop-up'); + 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 { + $popup + .stop() + .fadeOut(settings.duration, settings.easing, function() { + module.reset(); + callback.call($popup, element); + settings.onHidden.call($popup, element); + }) + ; + } + settings.onHide.call($popup, element); + } + }, + + get: { + startEvent: function() { + if(settings.on == 'hover') { + return 'mouseenter'; + } + else if(settings.on == 'focus') { + return 'focus'; + } + return false; + }, + endEvent: function() { + if(settings.on == 'hover') { + return 'mouseleave'; + } + else if(settings.on == 'focus') { + return 'blur'; + } + return false; + }, + offsetParent: function($target) { + var + element = ($target !== undefined) + ? $target[0] + : $module[0], + parentNode = element.parentNode, + $node = $(parentNode) + ; + if(parentNode) { + var + is2D = ($node.css('transform') === 'none'), + isStatic = ($node.css('position') === 'static'), + isHTML = $node.is('html') + ; + while(parentNode && !isHTML && isStatic && is2D) { + parentNode = parentNode.parentNode; + $node = $(parentNode); + is2D = ($node.css('transform') === 'none'); + isStatic = ($node.css('position') === 'static'); + isHTML = $node.is('html'); + } + } + return ($node && $node.length > 0) + ? $node + : $() + ; + }, + offstagePosition: function(position) { + 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 = [] + ; + position = position || false; + if(popup.offset && position) { + module.verbose('Checking if outside viewable area', popup.offset); + 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) + }; + } + // return only boundaries that have been surpassed + $.each(offstage, function(direction, isOffstage) { + if(isOffstage) { + offstagePositions.push(direction); + } + }); + return (offstagePositions.length > 0) + ? offstagePositions.join(' ') + : false + ; + }, + 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, 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(), + + computedPosition, + positioning, + offstagePosition + ; + position = position || $module.data(metadata.position) || settings.position; + arrowOffset = arrowOffset || $module.data(metadata.offset) || settings.offset; + + if(searchDepth == settings.maxSearchDepth && settings.lastResort) { + module.debug('Using last resort position to display', settings.lastResort); + position = settings.lastResort; + } + + if(settings.inline) { + module.debug('Adding targets margin to calculation'); + if(position == 'left center' || position == 'right center') { + arrowOffset += marginTop; + distanceAway += -marginLeft; + } + else if (position == 'top left' || position == 'top center' || position == 'top right') { + arrowOffset += marginLeft; + distanceAway -= marginTop; + } + else { + arrowOffset += marginLeft; + distanceAway += marginTop; + } + } + module.debug('Calculating popup positioning', position); + + computedPosition = position; + if (module.is.rtl()) { + computedPosition = computedPosition.replace(/left|right/g, function (match) { + return (match == 'left') + ? 'right' + : 'left' + ; + }); + module.debug('RTL: Popup positioning updated', computedPosition); + } + switch (computedPosition) { + case 'top left': + positioning = { + top : 'auto', + bottom : parentHeight - target.top + distanceAway, + left : target.left + arrowOffset, + right : 'auto' + }; + break; + case 'top center': + positioning = { + bottom : parentHeight - target.top + distanceAway, + left : target.left + (targetWidth / 2) - (popupWidth / 2) + arrowOffset, + top : 'auto', + right : 'auto' + }; + break; + case 'top right': + positioning = { + bottom : parentHeight - target.top + distanceAway, + right : parentWidth - target.left - targetWidth - arrowOffset, + top : 'auto', + left : 'auto' + }; + break; + case 'left center': + positioning = { + top : target.top + (targetHeight / 2) - (popupHeight / 2) + arrowOffset, + right : parentWidth - 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, + bottom : 'auto', + right : 'auto' + }; + break; + case 'bottom left': + positioning = { + top : target.top + targetHeight + distanceAway, + left : target.left + arrowOffset, + bottom : 'auto', + right : 'auto' + }; + break; + case 'bottom center': + positioning = { + top : target.top + targetHeight + distanceAway, + left : target.left + (targetWidth / 2) - (popupWidth / 2) + arrowOffset, + bottom : 'auto', + right : 'auto' + }; + break; + case 'bottom right': + positioning = { + top : target.top + targetHeight + distanceAway, + right : parentWidth - target.left - targetWidth - arrowOffset, + 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) + ; + // check if is offstage + offstagePosition = module.get.offstagePosition(position); + + // recursively find new positioning + if(offstagePosition) { + module.debug('Popup cant fit into viewport', offstagePosition); + if(searchDepth < settings.maxSearchDepth) { + searchDepth++; + position = module.get.nextPosition(position); + module.debug('Trying new position', position); + return ($popup) + ? module.set.position(position) + : false + ; + } + else if(!settings.lastResort) { + module.debug('Popup could not find a position in view', $popup); + module.error(error.cannotPlace); + module.remove.attempts(); + module.remove.loading(); + module.reset(); + return false; + } + } + + module.debug('Position is on stage', position); + module.remove.attempts(); + module.set.fluidWidth(); + module.remove.loading(); + return true; + }, + + fluidWidth: function() { + if( settings.setFluidWidth && $popup.hasClass(className.fluid) ) { + $popup.css('width', $offsetParent.width()); + } + }, + + visible: function() { + $module.addClass(className.visible); + } + }, + + remove: { + loading: function() { + $popup.removeClass(className.loading); + }, + visible: function() { + $module.removeClass(className.visible); + }, + attempts: function() { + module.verbose('Resetting all searched positions'); + searchDepth = 0; + triedPositions = false; + } + }, + + bind: { + 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') { + $document + .one('touchmove' + eventNamespace, module.hideGracefully) + .one('scroll' + eventNamespace, module.hideGracefully) + ; + $context + .one('touchmove' + eventNamespace, module.hideGracefully) + .one('scroll' + eventNamespace, module.hideGracefully) + ; + } + if(settings.on == 'click' && settings.closable) { + module.verbose('Binding popup close event to document'); + $document + .on('click' + eventNamespace, function(event) { + module.verbose('Pop-up clickaway intent detected'); + module.hideGracefully.call(element, event); + }) + ; + } + } + }, + + unbind: { + close: function() { + if(settings.hideOnScroll === true || settings.hideOnScroll == 'auto' && settings.on != 'click') { + $document + .off('scroll' + eventNamespace, module.hide) + ; + $context + .off('scroll' + eventNamespace, module.hide) + ; + } + if(settings.on == 'click' && settings.closable) { + module.verbose('Removing close event from document'); + $document + .off('click' + eventNamespace) + ; + } + } + }, + + has: { + popup: function() { + return ($popup && $popup.length > 0); + } + }, + + is: { + active: function() { + return $module.hasClass(className.active); + }, + animating: function() { + return ( $popup && $popup.is(':animated') || $popup.hasClass(className.animating) ); + }, + visible: function() { + return $popup && $popup.is(':visible'); + }, + 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.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.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() { + 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, 100); + }, + 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 + ; +}; + +module.exports.settings = { + + name : 'Popup', + + debug : false, + verbose : true, + performance : true, + namespace : 'popup', + + onCreate : function(){}, + onRemove : function(){}, + + onShow : function(){}, + onVisible : function(){}, + onHide : function(){}, + onHidden : function(){}, + + variation : '', + content : false, + html : false, + title : false, + + on : 'hover', + closable : true, + hideOnScroll : 'auto', + + context : 'body', + + position : 'top left', + prefer : 'opposite', + lastResort : false, + + delay : { + show : 30, + hide : 0 + }, + + setFluidWidth : true, + movePopup : true, + + target : false, + popup : false, + inline : false, + preserve : false, + hoverable : false, + + 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: { + 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(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 = _module.exports.settings.templates.escape + ; + if(typeof text !== undefined) { + if(typeof text.title !== undefined && text.title) { + text.title = escape(text.title); + html += '
' + text.title + '
'; + } + if(typeof text.content !== undefined && text.content) { + text.content = escape(text.content); + html += '
' + text.content + '
'; + } + } + return html; + } + } + +}; + +// 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/popup.css b/popup.css new file mode 100755 index 0000000..6fb3251 --- /dev/null +++ b/popup.css @@ -0,0 +1,294 @@ + /* + * # Semantic UI - 1.9.0 + * https://github.com/Semantic-Org/Semantic-UI + * http://www.semantic-ui.com/ + * + * Copyright 2014 Contributors + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + + + +/******************************* + Popup +*******************************/ + +.ui.popup { + display: none; + position: absolute; + top: 0px; + right: 0px; + +/* Fixes content being squished when inline (moz only) */ + min-width: -moz-max-content; + z-index: 1900; + border: 1px solid #cccccc; + 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); +} +.ui.popup > .header { + padding: 0em; + font-family: 'Lato', 'Helvetica Neue', Arial, Helvetica, sans-serif; + font-size: 1.125em; + line-height: 1.2; + font-weight: bold; +} +.ui.popup > .header + .content { + padding-top: 0.5em; +} +.ui.popup:before { + position: absolute; + content: ''; + width: 0.75em; + height: 0.75em; + background: #ffffff; + -webkit-transform: rotate(45deg); + -ms-transform: rotate(45deg); + transform: rotate(45deg); + z-index: 2; + box-shadow: 1px 1px 0px 0px #b3b3b3; +} + + +/******************************* + Types +*******************************/ + + +/*-------------- + Spacing +---------------*/ + +.ui.popup { + margin: 0em; +} +.ui.popup.bottom { + margin: 0.75em 0em 0em; +} +.ui.popup.top { + margin: 0em 0em 0.75em; +} +.ui.popup.left.center { + margin: 0em 0.75em 0em 0em; +} +.ui.popup.right.center { + margin: 0em 0em 0em 0.75em; +} + +/*-------------- + Pointer +---------------*/ + + +/*--- Below ---*/ + +.ui.bottom.center.popup:before { + margin-left: -0.325em; + top: -0.325em; + left: 50%; + right: auto; + bottom: auto; + box-shadow: -1px -1px 0px 0px #b3b3b3; +} +.ui.bottom.left.popup { + margin-left: 0em; +} +.ui.bottom.left.popup:before { + top: -0.325em; + left: 1em; + right: auto; + bottom: auto; + margin-left: 0em; + box-shadow: -1px -1px 0px 0px #b3b3b3; +} +.ui.bottom.right.popup { + margin-right: 0em; +} +.ui.bottom.right.popup:before { + top: -0.325em; + right: 1em; + bottom: auto; + left: auto; + margin-left: 0em; + box-shadow: -1px -1px 0px 0px #b3b3b3; +} + +/*--- Above ---*/ + +.ui.top.center.popup:before { + top: auto; + right: auto; + bottom: -0.325em; + left: 50%; + margin-left: -0.325em; +} +.ui.top.left.popup { + margin-left: 0em; +} +.ui.top.left.popup:before { + bottom: -0.325em; + left: 1em; + top: auto; + right: auto; + margin-left: 0em; +} +.ui.top.right.popup { + margin-right: 0em; +} +.ui.top.right.popup:before { + bottom: -0.325em; + right: 1em; + top: auto; + left: auto; + margin-left: 0em; +} + +/*--- Left Center ---*/ + +.ui.left.center.popup:before { + top: 50%; + right: -0.325em; + bottom: auto; + left: auto; + margin-top: -0.325em; + box-shadow: 1px -1px 0px 0px #b3b3b3; +} + +/*--- Right Center ---*/ + +.ui.right.center.popup:before { + top: 50%; + left: -0.325em; + bottom: auto; + right: auto; + margin-top: -0.325em; + box-shadow: -1px 1px 0px 0px #b3b3b3; +} + + +/******************************* + Coupling +*******************************/ + + +/* 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; +} + + +/******************************* + States +*******************************/ + +.ui.loading.popup { + display: block; + visibility: hidden; + z-index: -1; +} +.ui.animating.popup, +.ui.visible.popup { + display: block; +} + + +/******************************* + Variations +*******************************/ + + +/*-------------- + Basic +---------------*/ + +.ui.basic.popup:before { + display: none; +} + +/*-------------- + Wide +---------------*/ + +.ui.wide.popup { + max-width: 350px; +} +.ui[class*="very wide"].popup { + max-width: 550px; +} + +/*-------------- + Fluid +---------------*/ + +.ui.fluid.popup { + width: 100%; + max-width: none; +} + +/*-------------- + Colors +---------------*/ + + +/* Inverted colors */ +.ui.inverted.popup { + background: #1b1c1d; + color: #ffffff; + border: none; + box-shadow: none; +} +.ui.inverted.popup .header { + background-color: none; + color: #ffffff; +} +.ui.inverted.popup:before { + background-color: #1b1c1d; + box-shadow: none !important; +} + +/*-------------- + Flowing +---------------*/ + +.ui.flowing.popup { + max-width: none; +} + +/*-------------- + Sizes +---------------*/ + +.ui.small.popup { + font-size: 0.785714rem; +} +.ui.popup { + font-size: 0.85714rem; +} +.ui.large.popup { + font-size: 1rem; +} +.ui.huge.popup { + font-size: 1.14285rem; +} + + +/******************************* + Theme Overrides +*******************************/ + + + +/******************************* + User Overrides +*******************************/ + diff --git a/popup.js b/popup.js new file mode 100755 index 0000000..4360408 --- /dev/null +++ b/popup.js @@ -0,0 +1,1187 @@ +/* + * # Semantic - Popup + * http://github.com/semantic-org/semantic-ui/ + * + * + * Copyright 2014 Contributor + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +;(function ($, window, document, undefined) { + +"use strict"; + +$.fn.popup = function(parameters) { + var + $allModules = $(this), + $document = $(document), + + moduleSelector = $allModules.selector || '', + + hasTouch = ('ontouchstart' in document.documentElement), + 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), + $target = (settings.target) + ? $(settings.target) + : $module, + + $window = $(window), + $body = $('body'), + $popup, + $offsetParent, + + searchDepth = 0, + triedPositions = false, + + element = this, + instance = $module.data(moduleNamespace), + module + ; + + module = { + + // binds events + initialize: function() { + module.debug('Initializing module', $module); + if(settings.on == 'click') { + $module + .on('click' + eventNamespace, module.toggle) + ; + } + else 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' + eventNamespace, module.event.resize) + ; + if( !module.exists() && settings.preserve) { + module.create(); + } + module.instantiate(); + }, + + instantiate: function() { + module.verbose('Storing instance of module', module); + instance = module; + $module + .data(moduleNamespace, instance) + ; + }, + + refresh: function() { + if(settings.popup) { + $popup = $(settings.popup).eq(0); + } + else { + if(settings.inline) { + $popup = $target.next(selector.popup).eq(0); + } + } + 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 activating element'); + $popup + .detach() + .appendTo($offsetParent) + ; + } + } + else { + $offsetParent = (settings.inline) + ? module.get.offsetParent($target) + : module.has.popup() + ? module.get.offsetParent($popup) + : $body + ; + } + if( $offsetParent.is('html') ) { + module.debug('Setting page as offset parent'); + $offsetParent = $body; + } + }, + + reposition: function() { + module.refresh(); + module.set.position(); + }, + + destroy: function() { + module.debug('Destroying previous module'); + if($popup && !settings.preserve) { + module.removePopup(); + } + clearTimeout(module.hideTimer); + clearTimeout(module.showTimer); + $module + .off(eventNamespace) + .removeData(moduleNamespace) + ; + }, + + event: { + start: function(event) { + var + delay = ($.isPlainObject(settings.delay)) + ? settings.delay.show + : settings.delay + ; + clearTimeout(module.hideTimer); + module.showTimer = setTimeout(function() { + if(module.is.hidden() && !( module.is.active() && module.is.dropdown()) ) { + module.show(); + } + }, delay); + }, + end: function() { + var + delay = ($.isPlainObject(settings.delay)) + ? settings.delay.hide + : settings.delay + ; + clearTimeout(module.showTimer); + module.hideTimer = setTimeout(function() { + if(module.is.visible() ) { + module.hide(); + } + }, delay); + }, + resize: function() { + if( module.is.visible() ) { + module.set.position(); + } + } + }, + + // 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 + ; + if(html || content || title) { + module.debug('Creating pop-up html'); + if(!html) { + html = settings.templates.popup({ + title : title, + content : content + }); + } + $popup = $('
') + .addClass(className.popup) + .addClass(variation) + .html(html) + ; + if(variation) { + $popup + .addClass(variation) + ; + } + 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(); + 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); + module.refresh(); + if(settings.hoverable) { + module.bind.popup(); + } + } + else if(settings.popup) { + module.verbose('Used popup specified in settings'); + module.refresh(); + if(settings.hoverable) { + module.bind.popup(); + } + } + else { + module.debug('No content specified skipping display', element); + } + }, + + // 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.hideAll(); + module.show(); + } + else { + module.debug('Popup is visible, hiding pop-up'); + module.hide(); + } + }, + + show: function(callback) { + callback = $.isFunction(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(); + module.animate.show(callback); + } + }, + + + hide: function(callback) { + callback = $.isFunction(callback) ? callback : function(){}; + module.remove.visible(); + module.unbind.close(); + if( module.is.visible() ) { + module.restore.conditions(); + module.animate.hide(callback); + } + }, + + hideAll: function() { + $(selector.popup) + .filter(':visible') + .transition(settings.transition) + ; + }, + + 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; + } + if(settings.inline || settings.popup) { + return ( module.has.popup() ); + } + else { + return ( $popup.closest($context).length >= 1 ) + ? true + : false + ; + } + }, + + removePopup: function() { + module.debug('Removing popup', $popup); + if( module.has.popup() && !settings.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; + } + }, + 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.set.visible(); + $popup + .stop() + .fadeIn(settings.duration, settings.easing, function() { + module.bind.close(); + callback.call($popup, element); + settings.onVisible.call($popup, element); + }) + ; + } + settings.onShow.call($popup, element); + }, + hide: function(callback) { + callback = $.isFunction(callback) ? callback : function(){}; + module.debug('Hiding pop-up'); + 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 { + $popup + .stop() + .fadeOut(settings.duration, settings.easing, function() { + module.reset(); + callback.call($popup, element); + settings.onHidden.call($popup, element); + }) + ; + } + settings.onHide.call($popup, element); + } + }, + + get: { + startEvent: function() { + if(settings.on == 'hover') { + return 'mouseenter'; + } + else if(settings.on == 'focus') { + return 'focus'; + } + return false; + }, + endEvent: function() { + if(settings.on == 'hover') { + return 'mouseleave'; + } + else if(settings.on == 'focus') { + return 'blur'; + } + return false; + }, + offsetParent: function($target) { + var + element = ($target !== undefined) + ? $target[0] + : $module[0], + parentNode = element.parentNode, + $node = $(parentNode) + ; + if(parentNode) { + var + is2D = ($node.css('transform') === 'none'), + isStatic = ($node.css('position') === 'static'), + isHTML = $node.is('html') + ; + while(parentNode && !isHTML && isStatic && is2D) { + parentNode = parentNode.parentNode; + $node = $(parentNode); + is2D = ($node.css('transform') === 'none'); + isStatic = ($node.css('position') === 'static'); + isHTML = $node.is('html'); + } + } + return ($node && $node.length > 0) + ? $node + : $() + ; + }, + offstagePosition: function(position) { + 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 = [] + ; + position = position || false; + if(popup.offset && position) { + module.verbose('Checking if outside viewable area', popup.offset); + 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) + }; + } + // return only boundaries that have been surpassed + $.each(offstage, function(direction, isOffstage) { + if(isOffstage) { + offstagePositions.push(direction); + } + }); + return (offstagePositions.length > 0) + ? offstagePositions.join(' ') + : false + ; + }, + 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, 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(), + + computedPosition, + positioning, + offstagePosition + ; + position = position || $module.data(metadata.position) || settings.position; + arrowOffset = arrowOffset || $module.data(metadata.offset) || settings.offset; + + if(searchDepth == settings.maxSearchDepth && settings.lastResort) { + module.debug('Using last resort position to display', settings.lastResort); + position = settings.lastResort; + } + + if(settings.inline) { + module.debug('Adding targets margin to calculation'); + if(position == 'left center' || position == 'right center') { + arrowOffset += marginTop; + distanceAway += -marginLeft; + } + else if (position == 'top left' || position == 'top center' || position == 'top right') { + arrowOffset += marginLeft; + distanceAway -= marginTop; + } + else { + arrowOffset += marginLeft; + distanceAway += marginTop; + } + } + module.debug('Calculating popup positioning', position); + + computedPosition = position; + if (module.is.rtl()) { + computedPosition = computedPosition.replace(/left|right/g, function (match) { + return (match == 'left') + ? 'right' + : 'left' + ; + }); + module.debug('RTL: Popup positioning updated', computedPosition); + } + switch (computedPosition) { + case 'top left': + positioning = { + top : 'auto', + bottom : parentHeight - target.top + distanceAway, + left : target.left + arrowOffset, + right : 'auto' + }; + break; + case 'top center': + positioning = { + bottom : parentHeight - target.top + distanceAway, + left : target.left + (targetWidth / 2) - (popupWidth / 2) + arrowOffset, + top : 'auto', + right : 'auto' + }; + break; + case 'top right': + positioning = { + bottom : parentHeight - target.top + distanceAway, + right : parentWidth - target.left - targetWidth - arrowOffset, + top : 'auto', + left : 'auto' + }; + break; + case 'left center': + positioning = { + top : target.top + (targetHeight / 2) - (popupHeight / 2) + arrowOffset, + right : parentWidth - 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, + bottom : 'auto', + right : 'auto' + }; + break; + case 'bottom left': + positioning = { + top : target.top + targetHeight + distanceAway, + left : target.left + arrowOffset, + bottom : 'auto', + right : 'auto' + }; + break; + case 'bottom center': + positioning = { + top : target.top + targetHeight + distanceAway, + left : target.left + (targetWidth / 2) - (popupWidth / 2) + arrowOffset, + bottom : 'auto', + right : 'auto' + }; + break; + case 'bottom right': + positioning = { + top : target.top + targetHeight + distanceAway, + right : parentWidth - target.left - targetWidth - arrowOffset, + 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) + ; + // check if is offstage + offstagePosition = module.get.offstagePosition(position); + + // recursively find new positioning + if(offstagePosition) { + module.debug('Popup cant fit into viewport', offstagePosition); + if(searchDepth < settings.maxSearchDepth) { + searchDepth++; + position = module.get.nextPosition(position); + module.debug('Trying new position', position); + return ($popup) + ? module.set.position(position) + : false + ; + } + else if(!settings.lastResort) { + module.debug('Popup could not find a position in view', $popup); + module.error(error.cannotPlace); + module.remove.attempts(); + module.remove.loading(); + module.reset(); + return false; + } + } + + module.debug('Position is on stage', position); + module.remove.attempts(); + module.set.fluidWidth(); + module.remove.loading(); + return true; + }, + + fluidWidth: function() { + if( settings.setFluidWidth && $popup.hasClass(className.fluid) ) { + $popup.css('width', $offsetParent.width()); + } + }, + + visible: function() { + $module.addClass(className.visible); + } + }, + + remove: { + loading: function() { + $popup.removeClass(className.loading); + }, + visible: function() { + $module.removeClass(className.visible); + }, + attempts: function() { + module.verbose('Resetting all searched positions'); + searchDepth = 0; + triedPositions = false; + } + }, + + bind: { + 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') { + $document + .one('touchmove' + eventNamespace, module.hideGracefully) + .one('scroll' + eventNamespace, module.hideGracefully) + ; + $context + .one('touchmove' + eventNamespace, module.hideGracefully) + .one('scroll' + eventNamespace, module.hideGracefully) + ; + } + if(settings.on == 'click' && settings.closable) { + module.verbose('Binding popup close event to document'); + $document + .on('click' + eventNamespace, function(event) { + module.verbose('Pop-up clickaway intent detected'); + module.hideGracefully.call(element, event); + }) + ; + } + } + }, + + unbind: { + close: function() { + if(settings.hideOnScroll === true || settings.hideOnScroll == 'auto' && settings.on != 'click') { + $document + .off('scroll' + eventNamespace, module.hide) + ; + $context + .off('scroll' + eventNamespace, module.hide) + ; + } + if(settings.on == 'click' && settings.closable) { + module.verbose('Removing close event from document'); + $document + .off('click' + eventNamespace) + ; + } + } + }, + + has: { + popup: function() { + return ($popup && $popup.length > 0); + } + }, + + is: { + active: function() { + return $module.hasClass(className.active); + }, + animating: function() { + return ( $popup && $popup.is(':animated') || $popup.hasClass(className.animating) ); + }, + visible: function() { + return $popup && $popup.is(':visible'); + }, + 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.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.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() { + 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, 100); + }, + 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', + + debug : false, + verbose : true, + performance : true, + namespace : 'popup', + + onCreate : function(){}, + onRemove : function(){}, + + onShow : function(){}, + onVisible : function(){}, + onHide : function(){}, + onHidden : function(){}, + + variation : '', + content : false, + html : false, + title : false, + + on : 'hover', + closable : true, + hideOnScroll : 'auto', + + context : 'body', + + position : 'top left', + prefer : 'opposite', + lastResort : false, + + delay : { + show : 30, + hide : 0 + }, + + setFluidWidth : true, + movePopup : true, + + target : false, + popup : false, + inline : false, + preserve : false, + hoverable : false, + + 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: { + 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(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 += '
' + text.title + '
'; + } + if(typeof text.content !== undefined && text.content) { + text.content = escape(text.content); + html += '
' + text.content + '
'; + } + } + return html; + } + } + +}; + +// 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 new file mode 100755 index 0000000..1544988 --- /dev/null +++ b/popup.min.css @@ -0,0 +1,11 @@ + /* + * # Semantic UI - 1.9.0 + * https://github.com/Semantic-Org/Semantic-UI + * http://www.semantic-ui.com/ + * + * Copyright 2014 Contributors + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ +.ui.popup{display:none;position:absolute;top:0;right:0;min-width:-moz-max-content;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)}.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{margin:0}.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 diff --git a/popup.min.js b/popup.min.js new file mode 100755 index 0000000..a1c0092 --- /dev/null +++ b/popup.min.js @@ -0,0 +1,11 @@ + /* + * # Semantic UI - 1.9.0 + * https://github.com/Semantic-Org/Semantic-UI + * http://www.semantic-ui.com/ + * + * Copyright 2014 Contributors + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ +!function(e,t,o,n){"use strict";e.fn.popup=function(i){var s,r=e(this),a=e(o),l=r.selector||"",p=("ontouchstart"in o.documentElement,(new Date).getTime()),u=[],c=arguments[0],d="string"==typeof c,f=[].slice.call(arguments,1);return r.each(function(){var o,r,g,h=e.isPlainObject(i)?e.extend(!0,{},e.fn.popup.settings,i):e.extend({},e.fn.popup.settings),m=h.selector,b=h.className,v=h.error,y=h.metadata,w=h.namespace,P="."+h.namespace,T="module-"+w,C=e(this),k=e(h.context),x=h.target?e(h.target):C,S=e(t),O=e("body"),j=0,A=!1,R=this,E=C.data(T);g={initialize:function(){g.debug("Initializing module",C),"click"==h.on?C.on("click"+P,g.toggle):g.get.startEvent()&&C.on(g.get.startEvent()+P,g.event.start).on(g.get.endEvent()+P,g.event.end),h.target&&g.debug("Target set to element",x),S.on("resize"+P,g.event.resize),!g.exists()&&h.preserve&&g.create(),g.instantiate()},instantiate:function(){g.verbose("Storing instance of module",g),E=g,C.data(T,E)},refresh:function(){h.popup?o=e(h.popup).eq(0):h.inline&&(o=x.next(m.popup).eq(0)),h.popup?(o.addClass(b.loading),r=g.get.offsetParent(),o.removeClass(b.loading),h.movePopup&&g.has.popup()&&g.get.offsetParent(o)[0]!==r[0]&&(g.debug("Moving popup to the same offset parent as activating element"),o.detach().appendTo(r))):r=h.inline?g.get.offsetParent(x):g.has.popup()?g.get.offsetParent(o):O,r.is("html")&&(g.debug("Setting page as offset parent"),r=O)},reposition:function(){g.refresh(),g.set.position()},destroy:function(){g.debug("Destroying previous module"),o&&!h.preserve&&g.removePopup(),clearTimeout(g.hideTimer),clearTimeout(g.showTimer),C.off(P).removeData(T)},event:{start:function(){var t=e.isPlainObject(h.delay)?h.delay.show:h.delay;clearTimeout(g.hideTimer),g.showTimer=setTimeout(function(){!g.is.hidden()||g.is.active()&&g.is.dropdown()||g.show()},t)},end:function(){var t=e.isPlainObject(h.delay)?h.delay.hide:h.delay;clearTimeout(g.showTimer),g.hideTimer=setTimeout(function(){g.is.visible()&&g.hide()},t)},resize:function(){g.is.visible()&&g.set.position()}},create:function(){var t=C.data(y.html)||h.html,n=C.data(y.variation)||h.variation,i=C.data(y.title)||h.title,s=C.data(y.content)||C.attr("title")||h.content;t||s||i?(g.debug("Creating pop-up html"),t||(t=h.templates.popup({title:i,content:s})),o=e("
").addClass(b.popup).addClass(n).html(t),n&&o.addClass(n),h.inline?(g.verbose("Inserting popup element inline",o),o.insertAfter(C)):(g.verbose("Appending popup element to body",o),o.appendTo(k)),g.refresh(),h.hoverable&&g.bind.popup(),h.onCreate.call(o,R)):0!==x.next(m.popup).length?(g.verbose("Pre-existing popup found"),h.inline=!0,h.popup=x.next(m.popup),g.refresh(),h.hoverable&&g.bind.popup()):h.popup?(g.verbose("Used popup specified in settings"),g.refresh(),h.hoverable&&g.bind.popup()):g.debug("No content specified skipping display",R)},toggle:function(){g.debug("Toggling pop-up"),g.is.hidden()?(g.debug("Popup is hidden, showing pop-up"),g.unbind.close(),g.hideAll(),g.show()):(g.debug("Popup is visible, hiding pop-up"),g.hide())},show:function(t){t=e.isFunction(t)?t:function(){},g.debug("Showing pop-up",h.transition),g.exists()?h.preserve||h.popup||g.refresh():g.create(),o&&g.set.position()&&(g.save.conditions(),g.animate.show(t))},hide:function(t){t=e.isFunction(t)?t:function(){},g.remove.visible(),g.unbind.close(),g.is.visible()&&(g.restore.conditions(),g.animate.hide(t))},hideAll:function(){e(m.popup).filter(":visible").transition(h.transition)},hideGracefully:function(t){t&&0===e(t.target).closest(m.popup).length?(g.debug("Click occurred outside popup hiding popup"),g.hide()):g.debug("Click was inside popup, keeping popup open")},exists:function(){return o?h.inline||h.popup?g.has.popup():o.closest(k).length>=1?!0:!1:!1},removePopup:function(){g.debug("Removing popup",o),g.has.popup()&&!h.popup&&(o.remove(),o=n),h.onRemove.call(o,R)},save:{conditions:function(){g.cache={title:C.attr("title")},g.cache.title&&C.removeAttr("title"),g.verbose("Saving original attributes",g.cache.title)}},restore:{conditions:function(){return g.cache&&g.cache.title&&(C.attr("title",g.cache.title),g.verbose("Restoring original attributes",g.cache.title)),!0}},animate:{show:function(t){t=e.isFunction(t)?t:function(){},h.transition&&e.fn.transition!==n&&C.transition("is supported")?(g.set.visible(),o.transition({animation:h.transition+" in",queue:!1,debug:h.debug,verbose:h.verbose,duration:h.duration,onComplete:function(){g.bind.close(),t.call(o,R),h.onVisible.call(o,R)}})):(g.set.visible(),o.stop().fadeIn(h.duration,h.easing,function(){g.bind.close(),t.call(o,R),h.onVisible.call(o,R)})),h.onShow.call(o,R)},hide:function(t){t=e.isFunction(t)?t:function(){},g.debug("Hiding pop-up"),h.transition&&e.fn.transition!==n&&C.transition("is supported")?o.transition({animation:h.transition+" out",queue:!1,duration:h.duration,debug:h.debug,verbose:h.verbose,onComplete:function(){g.reset(),t.call(o,R),h.onHidden.call(o,R)}}):o.stop().fadeOut(h.duration,h.easing,function(){g.reset(),t.call(o,R),h.onHidden.call(o,R)}),h.onHide.call(o,R)}},get:{startEvent:function(){return"hover"==h.on?"mouseenter":"focus"==h.on?"focus":!1},endEvent:function(){return"hover"==h.on?"mouseleave":"focus"==h.on?"blur":!1},offsetParent:function(t){var o=t!==n?t[0]:C[0],i=o.parentNode,s=e(i);if(i)for(var r="none"===s.css("transform"),a="static"===s.css("position"),l=s.is("html");i&&!l&&a&&r;)i=i.parentNode,s=e(i),r="none"===s.css("transform"),a="static"===s.css("position"),l=s.is("html");return s&&s.length>0?s:e()},offstagePosition:function(n){var i={top:e(t).scrollTop(),bottom:e(t).scrollTop()+e(t).height(),left:0,right:e(t).width()},s={width:o.width(),height:o.height(),offset:o.offset()},r={},a=[];return n=n||!1,s.offset&&n&&(g.verbose("Checking if outside viewable area",s.offset),r={top:s.offset.topi.bottom,right:s.offset.left+s.width>i.right,left:s.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"},s={left:"center",center:"right",right:"left"},r={"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,l=!1,p=!1,u=!1;return A||(g.verbose("All available positions available"),A=g.get.positions()),g.debug("Recording last position tried",e),A[e]=!0,"opposite"===h.prefer&&(u=[i[o],n],u=u.join(" "),l=A[u]===!0,g.debug("Trying opposite strategy",u)),"adjacent"===h.prefer&&a&&(u=[o,s[n]],u=u.join(" "),p=A[u]===!0,g.debug("Trying adjacent strategy",u)),(p||l)&&(g.debug("Using backup position",u),u=r[e]),u}},set:{position:function(i,s){var a,l,p,u=(e(t).width(),e(t).height(),x.outerWidth()),c=x.outerHeight(),d=o.outerWidth(),f=o.outerHeight(),m=r.outerWidth(),w=r.outerHeight(),P=h.distanceAway,T=x[0],k=h.inline?parseInt(t.getComputedStyle(T).getPropertyValue("margin-top"),10):0,S=h.inline?parseInt(t.getComputedStyle(T).getPropertyValue(g.is.rtl()?"margin-right":"margin-left"),10):0,O=h.inline||h.popup?x.position():x.offset();switch(i=i||C.data(y.position)||h.position,s=s||C.data(y.offset)||h.offset,j==h.maxSearchDepth&&h.lastResort&&(g.debug("Using last resort position to display",h.lastResort),i=h.lastResort),h.inline&&(g.debug("Adding targets margin to calculation"),"left center"==i||"right center"==i?(s+=k,P+=-S):"top left"==i||"top center"==i||"top right"==i?(s+=S,P-=k):(s+=S,P+=k)),g.debug("Calculating popup positioning",i),a=i,g.is.rtl()&&(a=a.replace(/left|right/g,function(e){return"left"==e?"right":"left"}),g.debug("RTL: Popup positioning updated",a)),a){case"top left":l={top:"auto",bottom:w-O.top+P,left:O.left+s,right:"auto"};break;case"top center":l={bottom:w-O.top+P,left:O.left+u/2-d/2+s,top:"auto",right:"auto"};break;case"top right":l={bottom:w-O.top+P,right:m-O.left-u-s,top:"auto",left:"auto"};break;case"left center":l={top:O.top+c/2-f/2+s,right:m-O.left+P,left:"auto",bottom:"auto"};break;case"right center":l={top:O.top+c/2-f/2+s,left:O.left+u+P,bottom:"auto",right:"auto"};break;case"bottom left":l={top:O.top+c+P,left:O.left+s,bottom:"auto",right:"auto"};break;case"bottom center":l={top:O.top+c+P,left:O.left+u/2-d/2+s,bottom:"auto",right:"auto"};break;case"bottom right":l={top:O.top+c+P,right:m-O.left-u-s,left:"auto",bottom:"auto"}}if(l===n&&g.error(v.invalidPosition,i),g.debug("Calculated popup positioning values",l),o.css(l).removeClass(b.position).addClass(i).addClass(b.loading),p=g.get.offstagePosition(i)){if(g.debug("Popup cant fit into viewport",p),j0}},is:{active:function(){return C.hasClass(b.active)},animating:function(){return o&&o.is(":animated")||o.hasClass(b.animating)},visible:function(){return o&&o.is(":visible")},dropdown:function(){return C.hasClass(b.dropdown)},hidden:function(){return!g.is.visible()},rtl:function(){return"rtl"==C.css("direction")}},reset:function(){g.remove.visible(),h.preserve?e.fn.transition!==n&&o.transition("remove transition"):g.removePopup()},setting:function(t,o){if(e.isPlainObject(t))e.extend(!0,h,t);else{if(o===n)return h[t];h[t]=o}},internal:function(t,o){if(e.isPlainObject(t))e.extend(!0,g,t);else{if(o===n)return g[t];g[t]=o}},debug:function(){h.debug&&(h.performance?g.performance.log(arguments):(g.debug=Function.prototype.bind.call(console.info,console,h.name+":"),g.debug.apply(console,arguments)))},verbose:function(){h.verbose&&h.debug&&(h.performance?g.performance.log(arguments):(g.verbose=Function.prototype.bind.call(console.info,console,h.name+":"),g.verbose.apply(console,arguments)))},error:function(){g.error=Function.prototype.bind.call(console.error,console,h.name+":"),g.error.apply(console,arguments)},performance:{log:function(e){var t,o,n;h.performance&&(t=(new Date).getTime(),n=p||t,o=t-n,p=t,u.push({Name:e[0],Arguments:[].slice.call(e,1)||"",Element:R,"Execution Time":o})),clearTimeout(g.performance.timer),g.performance.timer=setTimeout(g.performance.display,100)},display:function(){var t=h.name+":",o=0;p=!1,clearTimeout(g.performance.timer),e.each(u,function(e,t){o+=t["Execution Time"]}),t+=" "+o+"ms",l&&(t+=" '"+l+"'"),(console.group!==n||console.table!==n)&&u.length>0&&(console.groupCollapsed(t),console.table?console.table(u):e.each(u,function(e,t){console.log(t.Name+": "+t["Execution Time"]+"ms")}),console.groupEnd()),u=[]}},invoke:function(t,o,i){var r,a,l,p=E;return o=o||f,i=R||i,"string"==typeof t&&p!==n&&(t=t.split(/[\. ]/),r=t.length-1,e.each(t,function(o,i){var s=o!=r?i+t[o+1].charAt(0).toUpperCase()+t[o+1].slice(1):t;if(e.isPlainObject(p[s])&&o!=r)p=p[s];else{if(p[s]!==n)return a=p[s],!1;if(!e.isPlainObject(p[i])||o==r)return p[i]!==n?(a=p[i],!1):!1;p=p[i]}})),e.isFunction(a)?l=a.apply(i,o):a!==n&&(l=a),e.isArray(s)?s.push(l):s!==n?s=[s,l]:l!==n&&(s=l),a}},d?(E===n&&g.initialize(),g.invoke(c)):(E!==n&&E.invoke("destroy"),g.initialize())}),s!==n?s: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",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:{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 From 6efe65285274d8a2e64c6500e8dc349a3b6b6151 Mon Sep 17 00:00:00 2001 From: Jack Lukic Date: Wed, 18 Feb 2015 14:14:25 -0500 Subject: [PATCH 22/22] Updated component to version 1.9.0 --- README.md | 29 ++ RELEASE-NOTES.md | 103 ++++ bower.json | 29 ++ composer.json | 19 + index.js | 1189 ++++++++++++++++++++++++++++++++++++++++++++++ package.js | 17 + package.json | 17 + popup.css | 294 ++++++++++++ popup.js | 1187 +++++++++++++++++++++++++++++++++++++++++++++ popup.min.css | 11 + popup.min.js | 11 + 11 files changed, 2906 insertions(+) create mode 100755 README.md create mode 100755 RELEASE-NOTES.md create mode 100755 bower.json create mode 100755 composer.json create mode 100755 index.js create mode 100755 package.js create mode 100755 package.json create mode 100755 popup.css create mode 100755 popup.js create mode 100755 popup.min.css create mode 100755 popup.min.js diff --git a/README.md b/README.md new file mode 100755 index 0000000..0931be1 --- /dev/null +++ b/README.md @@ -0,0 +1,29 @@ +# Semantic Popup + +This repository contains pre-compiled popup files using the default themes. This is intended for use in projects that do not need all the bells and whistles of Semantic UI, and want to keep file size to a minimum. + +For the latest changes please see the [Release Notes](https://github.com/Semantic-Org/UI-Popup/blob/master/RELEASE-NOTES.md) + +If you're looking for the full version of Semantic including all components and build tools [check out the main project repository](https://github.com/Semantic-Org/Semantic-UI/tree/1.0) + +#### To install with Bower +``` +bower install semantic-ui-popup +``` + +#### To install with NPM +``` +npm install semantic-ui-popup +``` + +#### To install with Meteor +``` +meteor add semantic:ui-popup +``` + + +## Addendum + +This element's definitions (required class names, html structures) are available in the [UI Docs](http://www.semantic-ui.com) + +Please consider checking out [all the benefits to theming](http://www.learnsemantic.com/guide/expert.html) before using these stand-alone releases. diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md new file mode 100755 index 0000000..2084199 --- /dev/null +++ b/RELEASE-NOTES.md @@ -0,0 +1,103 @@ +### UI Changes + +- **Transition** - Transitions with direction now use word order dependency to prevent conflict with component directions, for example `bottom left popup slide down in transition + +### Version 1.8.1 - January 26, 2015 + +- **Popup** - Popup `hide all` will now use transition set in `settings.transition` when closing other popups + +### Version 1.8.0 - January 23, 2015 + +- **Popup** - Popup will now only use a max of one element when `settings.popup` mistakingly passes multiple DOM elements +- **Popup** - Popups will now by default appear over all UI content, even dimmers. + +### Version 1.7.0 - January 14, 2015 + +- **Popup** - Popup now uses its own custom method for determining `offsetParent` meaning 3D contexts (like inside an animation) no longer should break positioning +- **Popup** - Popup now uses `preserve: false` by default, this is slightly less performant but will reduce page clutter caused by leaving generated elements in the DOM +- **Popup** - `wide` and `very wide` popup will now appear when screen size is below their `max-width` +- **Popup** - Popup no longer blurs element on popup hide + +### Version 1.6.0 - January 05, 2015 + +- **Popup** - Fix issue with `ui popup` receiving error ``$offsetParent is undefined`` when using a pre-defined popup +- **Popup** - Fix issue with ``ui popup` not appearing with ``ui flowing popup`` due to newly added ``min-width: max-content`` + +### Version 1.5.0 - December 30, 2014 + +- **Popup** - Popup now uses the new property ``min-width: max-content`` to allow for better display with ``inline`` in some circumstances where it escapes parent element. +- **Popup** - Popup destroy will now also destroy any unfired timers (show/hide delay) +- **Popup** - Popup now moves to the same offset context to avoid positioning errors when using a named pre-existing popup. + +### Version 1.1.0 - December 02, 2014 + +- **Popup** - Popup now has a ``settings.prefer`` that defaults to ``adjacent``. This setting sets prefered next placement when a popup cannot fit on screen in the chosen placement. ``prefer`` can also be set to ``opposite`` to prefer the same position on the opposite side +- **Popup** - Popup can now use a setting ``lastResort``. When set to a position it will be used as a last resort even if popup does not entirely fit on the page. Setting this to ``false`` will produce an error when a popup cannot fit on screen. + +### Version 1.0.0 - November 24, 2014 + +- **Popup** - Popup can now allow itself not to be closed when hovered over +- **Popup** - A popup element can now be specified on initialization. +- **Popup** - Positioned popups will now extend in the opposite direction to fit better with floated content + +### Version 0.18.0 - June 6, 2014 + +- **Popup** - Fixes javascript animation of popup missing easing dependency + +### Version 0.17.0 - May 9, 2014 + +- **Popup** - Popup now has an ``onRemove`` callback after removing element from DOM + +### Version 0.12.5 - Feb 04, 2014 + +- **Popup** - Fixes issue where popups using ``title`` attribute to store data were losing title content instead of correctly restoring it + +### Merry Christmas! + +-**Popup** - Fixes popup sometimes opening and closing when ``event:click`` is used and a user double clicks + +### Version 0.10.3 - Dec 22, 2013 + +- **Popup** - Native browser popups no longer if using ``title`` attribute + +### Version 0.9.2 - Nov 8, 2013 + +**Fixes** - Fixes popup not repositioning itself when offstage. + +### Version 0.9.1 - Nov 7, 2013 + +- **Popup** - Adds context option for popup (thanks jefmathiot) + +### Version 0.7.1 - Oct 23, 2013 + +- **Popup** - Fixes issue with popup's using setting inline: true + +### Version 0.7.0 - Oct 22, 2013 + +- **List** - Popups can now have a different target than itself +- **Popup** - Popup .toggle() now always hides/shows popup correctly +- **Popup** - Popup fixed a bug where "top right" placed popup might sometimes be too large +- **Popup** - Popup will not reshow a visible popup on hover +- **Popup** - Popup border now uses RGBA to look sexier on dark backgrounds +- **Popup** - Popup default duration is now 200ms (slighty slower) +- **Popup** - Popup metadata attribute arrowOffset is now offset for simplicities sake +- **Popup** - Popup no-longer receives class name 'visible' on show, this allows popups to be used on dropdowns and other elements with a visible state +- **Popup** - Popups are no longer inline by default + +### Version 0.5.0 - Oct 10, 2013 + +- Fixes regression where popup was overriding variation class name on positioning +- Fixes an issue where popup that was set to inline: false was being removed prematurely +- Adds an example to popup where inline is set to false +- Added onCreate to popup module + +### Version 0.3.6 - Oct 7, 2013 + +- Fixes popup position sometimes appearing off-stage on second apperance +- Fixes popup positions top left, top right, bottom left, bottom right being flipped + +### Version 0.3.3 - Oct 2, 2013 + +- Fixes issue with popup display in some edge cases Issue #128 + +### Version 0.1.0 - Sep 25, 2013 \ No newline at end of file diff --git a/bower.json b/bower.json new file mode 100755 index 0000000..8f77800 --- /dev/null +++ b/bower.json @@ -0,0 +1,29 @@ +{ + "name": "semantic-ui-popup", + "description": "Popup - Semantic UI", + "homepage": "http://www.semantic-ui.com", + "author": { + "name": "Jack Lukic", + "web": "http://www.jacklukic.com" + }, + "ignore": [ + "docs", + "node", + "server", + "spec", + "src", + "test" + ], + "keywords": [ + "semantic", + "ui", + "css3", + "framework" + ], + "license": [ + "http://semantic-ui.mit-license.org/" + ], + "main": [ + "popup.css" + ] +} \ No newline at end of file diff --git a/composer.json b/composer.json new file mode 100755 index 0000000..3f44efa --- /dev/null +++ b/composer.json @@ -0,0 +1,19 @@ +{ + "name": "semantic/popup", + "description": "Single component release of popup", + "homepage": "http://www.semantic-ui.com", + "authors": [{ + "name": "Jack Lukic", + "email": "jacklukic@gmail.com", + "web": "http://www.jacklukic.com", + "role": "Creator" + }], + "keywords": [ + "semantic", + "ui", + "css", + "framework" + ], + "license": "MIT", + "version": "1.9.0" +} \ No newline at end of file diff --git a/index.js b/index.js new file mode 100755 index 0000000..e784765 --- /dev/null +++ b/index.js @@ -0,0 +1,1189 @@ +/* + * # Semantic - Popup + * http://github.com/semantic-org/semantic-ui/ + * + * + * Copyright 2014 Contributor + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +;(function ($, window, document, undefined) { + +"use strict"; + +module.exports = function(parameters) { + var _module = module; + + var + $allModules = $(this), + $document = $(document), + + moduleSelector = $allModules.selector || '', + + hasTouch = ('ontouchstart' in document.documentElement), + 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, {}, _module.exports.settings, parameters) + : $.extend({}, _module.exports.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), + $target = (settings.target) + ? $(settings.target) + : $module, + + $window = $(window), + $body = $('body'), + $popup, + $offsetParent, + + searchDepth = 0, + triedPositions = false, + + element = this, + instance = $module.data(moduleNamespace), + module + ; + + module = { + + // binds events + initialize: function() { + module.debug('Initializing module', $module); + if(settings.on == 'click') { + $module + .on('click' + eventNamespace, module.toggle) + ; + } + else 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' + eventNamespace, module.event.resize) + ; + if( !module.exists() && settings.preserve) { + module.create(); + } + module.instantiate(); + }, + + instantiate: function() { + module.verbose('Storing instance of module', module); + instance = module; + $module + .data(moduleNamespace, instance) + ; + }, + + refresh: function() { + if(settings.popup) { + $popup = $(settings.popup).eq(0); + } + else { + if(settings.inline) { + $popup = $target.next(selector.popup).eq(0); + } + } + 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 activating element'); + $popup + .detach() + .appendTo($offsetParent) + ; + } + } + else { + $offsetParent = (settings.inline) + ? module.get.offsetParent($target) + : module.has.popup() + ? module.get.offsetParent($popup) + : $body + ; + } + if( $offsetParent.is('html') ) { + module.debug('Setting page as offset parent'); + $offsetParent = $body; + } + }, + + reposition: function() { + module.refresh(); + module.set.position(); + }, + + destroy: function() { + module.debug('Destroying previous module'); + if($popup && !settings.preserve) { + module.removePopup(); + } + clearTimeout(module.hideTimer); + clearTimeout(module.showTimer); + $module + .off(eventNamespace) + .removeData(moduleNamespace) + ; + }, + + event: { + start: function(event) { + var + delay = ($.isPlainObject(settings.delay)) + ? settings.delay.show + : settings.delay + ; + clearTimeout(module.hideTimer); + module.showTimer = setTimeout(function() { + if(module.is.hidden() && !( module.is.active() && module.is.dropdown()) ) { + module.show(); + } + }, delay); + }, + end: function() { + var + delay = ($.isPlainObject(settings.delay)) + ? settings.delay.hide + : settings.delay + ; + clearTimeout(module.showTimer); + module.hideTimer = setTimeout(function() { + if(module.is.visible() ) { + module.hide(); + } + }, delay); + }, + resize: function() { + if( module.is.visible() ) { + module.set.position(); + } + } + }, + + // 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 + ; + if(html || content || title) { + module.debug('Creating pop-up html'); + if(!html) { + html = settings.templates.popup({ + title : title, + content : content + }); + } + $popup = $('
') + .addClass(className.popup) + .addClass(variation) + .html(html) + ; + if(variation) { + $popup + .addClass(variation) + ; + } + 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(); + 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); + module.refresh(); + if(settings.hoverable) { + module.bind.popup(); + } + } + else if(settings.popup) { + module.verbose('Used popup specified in settings'); + module.refresh(); + if(settings.hoverable) { + module.bind.popup(); + } + } + else { + module.debug('No content specified skipping display', element); + } + }, + + // 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.hideAll(); + module.show(); + } + else { + module.debug('Popup is visible, hiding pop-up'); + module.hide(); + } + }, + + show: function(callback) { + callback = $.isFunction(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(); + module.animate.show(callback); + } + }, + + + hide: function(callback) { + callback = $.isFunction(callback) ? callback : function(){}; + module.remove.visible(); + module.unbind.close(); + if( module.is.visible() ) { + module.restore.conditions(); + module.animate.hide(callback); + } + }, + + hideAll: function() { + $(selector.popup) + .filter(':visible') + .transition(settings.transition) + ; + }, + + 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; + } + if(settings.inline || settings.popup) { + return ( module.has.popup() ); + } + else { + return ( $popup.closest($context).length >= 1 ) + ? true + : false + ; + } + }, + + removePopup: function() { + module.debug('Removing popup', $popup); + if( module.has.popup() && !settings.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; + } + }, + 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.set.visible(); + $popup + .stop() + .fadeIn(settings.duration, settings.easing, function() { + module.bind.close(); + callback.call($popup, element); + settings.onVisible.call($popup, element); + }) + ; + } + settings.onShow.call($popup, element); + }, + hide: function(callback) { + callback = $.isFunction(callback) ? callback : function(){}; + module.debug('Hiding pop-up'); + 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 { + $popup + .stop() + .fadeOut(settings.duration, settings.easing, function() { + module.reset(); + callback.call($popup, element); + settings.onHidden.call($popup, element); + }) + ; + } + settings.onHide.call($popup, element); + } + }, + + get: { + startEvent: function() { + if(settings.on == 'hover') { + return 'mouseenter'; + } + else if(settings.on == 'focus') { + return 'focus'; + } + return false; + }, + endEvent: function() { + if(settings.on == 'hover') { + return 'mouseleave'; + } + else if(settings.on == 'focus') { + return 'blur'; + } + return false; + }, + offsetParent: function($target) { + var + element = ($target !== undefined) + ? $target[0] + : $module[0], + parentNode = element.parentNode, + $node = $(parentNode) + ; + if(parentNode) { + var + is2D = ($node.css('transform') === 'none'), + isStatic = ($node.css('position') === 'static'), + isHTML = $node.is('html') + ; + while(parentNode && !isHTML && isStatic && is2D) { + parentNode = parentNode.parentNode; + $node = $(parentNode); + is2D = ($node.css('transform') === 'none'); + isStatic = ($node.css('position') === 'static'); + isHTML = $node.is('html'); + } + } + return ($node && $node.length > 0) + ? $node + : $() + ; + }, + offstagePosition: function(position) { + 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 = [] + ; + position = position || false; + if(popup.offset && position) { + module.verbose('Checking if outside viewable area', popup.offset); + 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) + }; + } + // return only boundaries that have been surpassed + $.each(offstage, function(direction, isOffstage) { + if(isOffstage) { + offstagePositions.push(direction); + } + }); + return (offstagePositions.length > 0) + ? offstagePositions.join(' ') + : false + ; + }, + 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, 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(), + + computedPosition, + positioning, + offstagePosition + ; + position = position || $module.data(metadata.position) || settings.position; + arrowOffset = arrowOffset || $module.data(metadata.offset) || settings.offset; + + if(searchDepth == settings.maxSearchDepth && settings.lastResort) { + module.debug('Using last resort position to display', settings.lastResort); + position = settings.lastResort; + } + + if(settings.inline) { + module.debug('Adding targets margin to calculation'); + if(position == 'left center' || position == 'right center') { + arrowOffset += marginTop; + distanceAway += -marginLeft; + } + else if (position == 'top left' || position == 'top center' || position == 'top right') { + arrowOffset += marginLeft; + distanceAway -= marginTop; + } + else { + arrowOffset += marginLeft; + distanceAway += marginTop; + } + } + module.debug('Calculating popup positioning', position); + + computedPosition = position; + if (module.is.rtl()) { + computedPosition = computedPosition.replace(/left|right/g, function (match) { + return (match == 'left') + ? 'right' + : 'left' + ; + }); + module.debug('RTL: Popup positioning updated', computedPosition); + } + switch (computedPosition) { + case 'top left': + positioning = { + top : 'auto', + bottom : parentHeight - target.top + distanceAway, + left : target.left + arrowOffset, + right : 'auto' + }; + break; + case 'top center': + positioning = { + bottom : parentHeight - target.top + distanceAway, + left : target.left + (targetWidth / 2) - (popupWidth / 2) + arrowOffset, + top : 'auto', + right : 'auto' + }; + break; + case 'top right': + positioning = { + bottom : parentHeight - target.top + distanceAway, + right : parentWidth - target.left - targetWidth - arrowOffset, + top : 'auto', + left : 'auto' + }; + break; + case 'left center': + positioning = { + top : target.top + (targetHeight / 2) - (popupHeight / 2) + arrowOffset, + right : parentWidth - 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, + bottom : 'auto', + right : 'auto' + }; + break; + case 'bottom left': + positioning = { + top : target.top + targetHeight + distanceAway, + left : target.left + arrowOffset, + bottom : 'auto', + right : 'auto' + }; + break; + case 'bottom center': + positioning = { + top : target.top + targetHeight + distanceAway, + left : target.left + (targetWidth / 2) - (popupWidth / 2) + arrowOffset, + bottom : 'auto', + right : 'auto' + }; + break; + case 'bottom right': + positioning = { + top : target.top + targetHeight + distanceAway, + right : parentWidth - target.left - targetWidth - arrowOffset, + 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) + ; + // check if is offstage + offstagePosition = module.get.offstagePosition(position); + + // recursively find new positioning + if(offstagePosition) { + module.debug('Popup cant fit into viewport', offstagePosition); + if(searchDepth < settings.maxSearchDepth) { + searchDepth++; + position = module.get.nextPosition(position); + module.debug('Trying new position', position); + return ($popup) + ? module.set.position(position) + : false + ; + } + else if(!settings.lastResort) { + module.debug('Popup could not find a position in view', $popup); + module.error(error.cannotPlace); + module.remove.attempts(); + module.remove.loading(); + module.reset(); + return false; + } + } + + module.debug('Position is on stage', position); + module.remove.attempts(); + module.set.fluidWidth(); + module.remove.loading(); + return true; + }, + + fluidWidth: function() { + if( settings.setFluidWidth && $popup.hasClass(className.fluid) ) { + $popup.css('width', $offsetParent.width()); + } + }, + + visible: function() { + $module.addClass(className.visible); + } + }, + + remove: { + loading: function() { + $popup.removeClass(className.loading); + }, + visible: function() { + $module.removeClass(className.visible); + }, + attempts: function() { + module.verbose('Resetting all searched positions'); + searchDepth = 0; + triedPositions = false; + } + }, + + bind: { + 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') { + $document + .one('touchmove' + eventNamespace, module.hideGracefully) + .one('scroll' + eventNamespace, module.hideGracefully) + ; + $context + .one('touchmove' + eventNamespace, module.hideGracefully) + .one('scroll' + eventNamespace, module.hideGracefully) + ; + } + if(settings.on == 'click' && settings.closable) { + module.verbose('Binding popup close event to document'); + $document + .on('click' + eventNamespace, function(event) { + module.verbose('Pop-up clickaway intent detected'); + module.hideGracefully.call(element, event); + }) + ; + } + } + }, + + unbind: { + close: function() { + if(settings.hideOnScroll === true || settings.hideOnScroll == 'auto' && settings.on != 'click') { + $document + .off('scroll' + eventNamespace, module.hide) + ; + $context + .off('scroll' + eventNamespace, module.hide) + ; + } + if(settings.on == 'click' && settings.closable) { + module.verbose('Removing close event from document'); + $document + .off('click' + eventNamespace) + ; + } + } + }, + + has: { + popup: function() { + return ($popup && $popup.length > 0); + } + }, + + is: { + active: function() { + return $module.hasClass(className.active); + }, + animating: function() { + return ( $popup && $popup.is(':animated') || $popup.hasClass(className.animating) ); + }, + visible: function() { + return $popup && $popup.is(':visible'); + }, + 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.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.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() { + 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, 100); + }, + 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 + ; +}; + +module.exports.settings = { + + name : 'Popup', + + debug : false, + verbose : true, + performance : true, + namespace : 'popup', + + onCreate : function(){}, + onRemove : function(){}, + + onShow : function(){}, + onVisible : function(){}, + onHide : function(){}, + onHidden : function(){}, + + variation : '', + content : false, + html : false, + title : false, + + on : 'hover', + closable : true, + hideOnScroll : 'auto', + + context : 'body', + + position : 'top left', + prefer : 'opposite', + lastResort : false, + + delay : { + show : 30, + hide : 0 + }, + + setFluidWidth : true, + movePopup : true, + + target : false, + popup : false, + inline : false, + preserve : false, + hoverable : false, + + 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: { + 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(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 = _module.exports.settings.templates.escape + ; + if(typeof text !== undefined) { + if(typeof text.title !== undefined && text.title) { + text.title = escape(text.title); + html += '
' + text.title + '
'; + } + if(typeof text.content !== undefined && text.content) { + text.content = escape(text.content); + html += '
' + text.content + '
'; + } + } + return html; + } + } + +}; + +// 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 new file mode 100755 index 0000000..776a292 --- /dev/null +++ b/package.js @@ -0,0 +1,17 @@ +var + where = 'client' // Adds files only to the client +; + +Package.describe({ + name : 'semantic:ui-popup', + summary : 'Semantic UI - Popup (official): Single component release of popup', + version : '1.9.0', + git : 'git://github.com/Semantic-Org/UI-Popup.git', +}); + +Package.onUse(function(api) { + api.versionsFrom('1.0'); + api.addFiles([ + + ], where); +}); diff --git a/package.json b/package.json new file mode 100755 index 0000000..356a43a --- /dev/null +++ b/package.json @@ -0,0 +1,17 @@ +{ + "name": "semantic-ui-popup", + "version": "1.9.0", + "title": "Semantic UI - Popup", + "description": "Single component release of popup", + "homepage": "http://www.semantic-ui.com", + "author": "Jack Lukic ", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/Semantic-Org/UI-Popup.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 new file mode 100755 index 0000000..6fb3251 --- /dev/null +++ b/popup.css @@ -0,0 +1,294 @@ + /* + * # Semantic UI - 1.9.0 + * https://github.com/Semantic-Org/Semantic-UI + * http://www.semantic-ui.com/ + * + * Copyright 2014 Contributors + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + + + +/******************************* + Popup +*******************************/ + +.ui.popup { + display: none; + position: absolute; + top: 0px; + right: 0px; + +/* Fixes content being squished when inline (moz only) */ + min-width: -moz-max-content; + z-index: 1900; + border: 1px solid #cccccc; + 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); +} +.ui.popup > .header { + padding: 0em; + font-family: 'Lato', 'Helvetica Neue', Arial, Helvetica, sans-serif; + font-size: 1.125em; + line-height: 1.2; + font-weight: bold; +} +.ui.popup > .header + .content { + padding-top: 0.5em; +} +.ui.popup:before { + position: absolute; + content: ''; + width: 0.75em; + height: 0.75em; + background: #ffffff; + -webkit-transform: rotate(45deg); + -ms-transform: rotate(45deg); + transform: rotate(45deg); + z-index: 2; + box-shadow: 1px 1px 0px 0px #b3b3b3; +} + + +/******************************* + Types +*******************************/ + + +/*-------------- + Spacing +---------------*/ + +.ui.popup { + margin: 0em; +} +.ui.popup.bottom { + margin: 0.75em 0em 0em; +} +.ui.popup.top { + margin: 0em 0em 0.75em; +} +.ui.popup.left.center { + margin: 0em 0.75em 0em 0em; +} +.ui.popup.right.center { + margin: 0em 0em 0em 0.75em; +} + +/*-------------- + Pointer +---------------*/ + + +/*--- Below ---*/ + +.ui.bottom.center.popup:before { + margin-left: -0.325em; + top: -0.325em; + left: 50%; + right: auto; + bottom: auto; + box-shadow: -1px -1px 0px 0px #b3b3b3; +} +.ui.bottom.left.popup { + margin-left: 0em; +} +.ui.bottom.left.popup:before { + top: -0.325em; + left: 1em; + right: auto; + bottom: auto; + margin-left: 0em; + box-shadow: -1px -1px 0px 0px #b3b3b3; +} +.ui.bottom.right.popup { + margin-right: 0em; +} +.ui.bottom.right.popup:before { + top: -0.325em; + right: 1em; + bottom: auto; + left: auto; + margin-left: 0em; + box-shadow: -1px -1px 0px 0px #b3b3b3; +} + +/*--- Above ---*/ + +.ui.top.center.popup:before { + top: auto; + right: auto; + bottom: -0.325em; + left: 50%; + margin-left: -0.325em; +} +.ui.top.left.popup { + margin-left: 0em; +} +.ui.top.left.popup:before { + bottom: -0.325em; + left: 1em; + top: auto; + right: auto; + margin-left: 0em; +} +.ui.top.right.popup { + margin-right: 0em; +} +.ui.top.right.popup:before { + bottom: -0.325em; + right: 1em; + top: auto; + left: auto; + margin-left: 0em; +} + +/*--- Left Center ---*/ + +.ui.left.center.popup:before { + top: 50%; + right: -0.325em; + bottom: auto; + left: auto; + margin-top: -0.325em; + box-shadow: 1px -1px 0px 0px #b3b3b3; +} + +/*--- Right Center ---*/ + +.ui.right.center.popup:before { + top: 50%; + left: -0.325em; + bottom: auto; + right: auto; + margin-top: -0.325em; + box-shadow: -1px 1px 0px 0px #b3b3b3; +} + + +/******************************* + Coupling +*******************************/ + + +/* 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; +} + + +/******************************* + States +*******************************/ + +.ui.loading.popup { + display: block; + visibility: hidden; + z-index: -1; +} +.ui.animating.popup, +.ui.visible.popup { + display: block; +} + + +/******************************* + Variations +*******************************/ + + +/*-------------- + Basic +---------------*/ + +.ui.basic.popup:before { + display: none; +} + +/*-------------- + Wide +---------------*/ + +.ui.wide.popup { + max-width: 350px; +} +.ui[class*="very wide"].popup { + max-width: 550px; +} + +/*-------------- + Fluid +---------------*/ + +.ui.fluid.popup { + width: 100%; + max-width: none; +} + +/*-------------- + Colors +---------------*/ + + +/* Inverted colors */ +.ui.inverted.popup { + background: #1b1c1d; + color: #ffffff; + border: none; + box-shadow: none; +} +.ui.inverted.popup .header { + background-color: none; + color: #ffffff; +} +.ui.inverted.popup:before { + background-color: #1b1c1d; + box-shadow: none !important; +} + +/*-------------- + Flowing +---------------*/ + +.ui.flowing.popup { + max-width: none; +} + +/*-------------- + Sizes +---------------*/ + +.ui.small.popup { + font-size: 0.785714rem; +} +.ui.popup { + font-size: 0.85714rem; +} +.ui.large.popup { + font-size: 1rem; +} +.ui.huge.popup { + font-size: 1.14285rem; +} + + +/******************************* + Theme Overrides +*******************************/ + + + +/******************************* + User Overrides +*******************************/ + diff --git a/popup.js b/popup.js new file mode 100755 index 0000000..4360408 --- /dev/null +++ b/popup.js @@ -0,0 +1,1187 @@ +/* + * # Semantic - Popup + * http://github.com/semantic-org/semantic-ui/ + * + * + * Copyright 2014 Contributor + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +;(function ($, window, document, undefined) { + +"use strict"; + +$.fn.popup = function(parameters) { + var + $allModules = $(this), + $document = $(document), + + moduleSelector = $allModules.selector || '', + + hasTouch = ('ontouchstart' in document.documentElement), + 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), + $target = (settings.target) + ? $(settings.target) + : $module, + + $window = $(window), + $body = $('body'), + $popup, + $offsetParent, + + searchDepth = 0, + triedPositions = false, + + element = this, + instance = $module.data(moduleNamespace), + module + ; + + module = { + + // binds events + initialize: function() { + module.debug('Initializing module', $module); + if(settings.on == 'click') { + $module + .on('click' + eventNamespace, module.toggle) + ; + } + else 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' + eventNamespace, module.event.resize) + ; + if( !module.exists() && settings.preserve) { + module.create(); + } + module.instantiate(); + }, + + instantiate: function() { + module.verbose('Storing instance of module', module); + instance = module; + $module + .data(moduleNamespace, instance) + ; + }, + + refresh: function() { + if(settings.popup) { + $popup = $(settings.popup).eq(0); + } + else { + if(settings.inline) { + $popup = $target.next(selector.popup).eq(0); + } + } + 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 activating element'); + $popup + .detach() + .appendTo($offsetParent) + ; + } + } + else { + $offsetParent = (settings.inline) + ? module.get.offsetParent($target) + : module.has.popup() + ? module.get.offsetParent($popup) + : $body + ; + } + if( $offsetParent.is('html') ) { + module.debug('Setting page as offset parent'); + $offsetParent = $body; + } + }, + + reposition: function() { + module.refresh(); + module.set.position(); + }, + + destroy: function() { + module.debug('Destroying previous module'); + if($popup && !settings.preserve) { + module.removePopup(); + } + clearTimeout(module.hideTimer); + clearTimeout(module.showTimer); + $module + .off(eventNamespace) + .removeData(moduleNamespace) + ; + }, + + event: { + start: function(event) { + var + delay = ($.isPlainObject(settings.delay)) + ? settings.delay.show + : settings.delay + ; + clearTimeout(module.hideTimer); + module.showTimer = setTimeout(function() { + if(module.is.hidden() && !( module.is.active() && module.is.dropdown()) ) { + module.show(); + } + }, delay); + }, + end: function() { + var + delay = ($.isPlainObject(settings.delay)) + ? settings.delay.hide + : settings.delay + ; + clearTimeout(module.showTimer); + module.hideTimer = setTimeout(function() { + if(module.is.visible() ) { + module.hide(); + } + }, delay); + }, + resize: function() { + if( module.is.visible() ) { + module.set.position(); + } + } + }, + + // 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 + ; + if(html || content || title) { + module.debug('Creating pop-up html'); + if(!html) { + html = settings.templates.popup({ + title : title, + content : content + }); + } + $popup = $('
') + .addClass(className.popup) + .addClass(variation) + .html(html) + ; + if(variation) { + $popup + .addClass(variation) + ; + } + 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(); + 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); + module.refresh(); + if(settings.hoverable) { + module.bind.popup(); + } + } + else if(settings.popup) { + module.verbose('Used popup specified in settings'); + module.refresh(); + if(settings.hoverable) { + module.bind.popup(); + } + } + else { + module.debug('No content specified skipping display', element); + } + }, + + // 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.hideAll(); + module.show(); + } + else { + module.debug('Popup is visible, hiding pop-up'); + module.hide(); + } + }, + + show: function(callback) { + callback = $.isFunction(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(); + module.animate.show(callback); + } + }, + + + hide: function(callback) { + callback = $.isFunction(callback) ? callback : function(){}; + module.remove.visible(); + module.unbind.close(); + if( module.is.visible() ) { + module.restore.conditions(); + module.animate.hide(callback); + } + }, + + hideAll: function() { + $(selector.popup) + .filter(':visible') + .transition(settings.transition) + ; + }, + + 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; + } + if(settings.inline || settings.popup) { + return ( module.has.popup() ); + } + else { + return ( $popup.closest($context).length >= 1 ) + ? true + : false + ; + } + }, + + removePopup: function() { + module.debug('Removing popup', $popup); + if( module.has.popup() && !settings.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; + } + }, + 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.set.visible(); + $popup + .stop() + .fadeIn(settings.duration, settings.easing, function() { + module.bind.close(); + callback.call($popup, element); + settings.onVisible.call($popup, element); + }) + ; + } + settings.onShow.call($popup, element); + }, + hide: function(callback) { + callback = $.isFunction(callback) ? callback : function(){}; + module.debug('Hiding pop-up'); + 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 { + $popup + .stop() + .fadeOut(settings.duration, settings.easing, function() { + module.reset(); + callback.call($popup, element); + settings.onHidden.call($popup, element); + }) + ; + } + settings.onHide.call($popup, element); + } + }, + + get: { + startEvent: function() { + if(settings.on == 'hover') { + return 'mouseenter'; + } + else if(settings.on == 'focus') { + return 'focus'; + } + return false; + }, + endEvent: function() { + if(settings.on == 'hover') { + return 'mouseleave'; + } + else if(settings.on == 'focus') { + return 'blur'; + } + return false; + }, + offsetParent: function($target) { + var + element = ($target !== undefined) + ? $target[0] + : $module[0], + parentNode = element.parentNode, + $node = $(parentNode) + ; + if(parentNode) { + var + is2D = ($node.css('transform') === 'none'), + isStatic = ($node.css('position') === 'static'), + isHTML = $node.is('html') + ; + while(parentNode && !isHTML && isStatic && is2D) { + parentNode = parentNode.parentNode; + $node = $(parentNode); + is2D = ($node.css('transform') === 'none'); + isStatic = ($node.css('position') === 'static'); + isHTML = $node.is('html'); + } + } + return ($node && $node.length > 0) + ? $node + : $() + ; + }, + offstagePosition: function(position) { + 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 = [] + ; + position = position || false; + if(popup.offset && position) { + module.verbose('Checking if outside viewable area', popup.offset); + 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) + }; + } + // return only boundaries that have been surpassed + $.each(offstage, function(direction, isOffstage) { + if(isOffstage) { + offstagePositions.push(direction); + } + }); + return (offstagePositions.length > 0) + ? offstagePositions.join(' ') + : false + ; + }, + 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, 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(), + + computedPosition, + positioning, + offstagePosition + ; + position = position || $module.data(metadata.position) || settings.position; + arrowOffset = arrowOffset || $module.data(metadata.offset) || settings.offset; + + if(searchDepth == settings.maxSearchDepth && settings.lastResort) { + module.debug('Using last resort position to display', settings.lastResort); + position = settings.lastResort; + } + + if(settings.inline) { + module.debug('Adding targets margin to calculation'); + if(position == 'left center' || position == 'right center') { + arrowOffset += marginTop; + distanceAway += -marginLeft; + } + else if (position == 'top left' || position == 'top center' || position == 'top right') { + arrowOffset += marginLeft; + distanceAway -= marginTop; + } + else { + arrowOffset += marginLeft; + distanceAway += marginTop; + } + } + module.debug('Calculating popup positioning', position); + + computedPosition = position; + if (module.is.rtl()) { + computedPosition = computedPosition.replace(/left|right/g, function (match) { + return (match == 'left') + ? 'right' + : 'left' + ; + }); + module.debug('RTL: Popup positioning updated', computedPosition); + } + switch (computedPosition) { + case 'top left': + positioning = { + top : 'auto', + bottom : parentHeight - target.top + distanceAway, + left : target.left + arrowOffset, + right : 'auto' + }; + break; + case 'top center': + positioning = { + bottom : parentHeight - target.top + distanceAway, + left : target.left + (targetWidth / 2) - (popupWidth / 2) + arrowOffset, + top : 'auto', + right : 'auto' + }; + break; + case 'top right': + positioning = { + bottom : parentHeight - target.top + distanceAway, + right : parentWidth - target.left - targetWidth - arrowOffset, + top : 'auto', + left : 'auto' + }; + break; + case 'left center': + positioning = { + top : target.top + (targetHeight / 2) - (popupHeight / 2) + arrowOffset, + right : parentWidth - 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, + bottom : 'auto', + right : 'auto' + }; + break; + case 'bottom left': + positioning = { + top : target.top + targetHeight + distanceAway, + left : target.left + arrowOffset, + bottom : 'auto', + right : 'auto' + }; + break; + case 'bottom center': + positioning = { + top : target.top + targetHeight + distanceAway, + left : target.left + (targetWidth / 2) - (popupWidth / 2) + arrowOffset, + bottom : 'auto', + right : 'auto' + }; + break; + case 'bottom right': + positioning = { + top : target.top + targetHeight + distanceAway, + right : parentWidth - target.left - targetWidth - arrowOffset, + 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) + ; + // check if is offstage + offstagePosition = module.get.offstagePosition(position); + + // recursively find new positioning + if(offstagePosition) { + module.debug('Popup cant fit into viewport', offstagePosition); + if(searchDepth < settings.maxSearchDepth) { + searchDepth++; + position = module.get.nextPosition(position); + module.debug('Trying new position', position); + return ($popup) + ? module.set.position(position) + : false + ; + } + else if(!settings.lastResort) { + module.debug('Popup could not find a position in view', $popup); + module.error(error.cannotPlace); + module.remove.attempts(); + module.remove.loading(); + module.reset(); + return false; + } + } + + module.debug('Position is on stage', position); + module.remove.attempts(); + module.set.fluidWidth(); + module.remove.loading(); + return true; + }, + + fluidWidth: function() { + if( settings.setFluidWidth && $popup.hasClass(className.fluid) ) { + $popup.css('width', $offsetParent.width()); + } + }, + + visible: function() { + $module.addClass(className.visible); + } + }, + + remove: { + loading: function() { + $popup.removeClass(className.loading); + }, + visible: function() { + $module.removeClass(className.visible); + }, + attempts: function() { + module.verbose('Resetting all searched positions'); + searchDepth = 0; + triedPositions = false; + } + }, + + bind: { + 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') { + $document + .one('touchmove' + eventNamespace, module.hideGracefully) + .one('scroll' + eventNamespace, module.hideGracefully) + ; + $context + .one('touchmove' + eventNamespace, module.hideGracefully) + .one('scroll' + eventNamespace, module.hideGracefully) + ; + } + if(settings.on == 'click' && settings.closable) { + module.verbose('Binding popup close event to document'); + $document + .on('click' + eventNamespace, function(event) { + module.verbose('Pop-up clickaway intent detected'); + module.hideGracefully.call(element, event); + }) + ; + } + } + }, + + unbind: { + close: function() { + if(settings.hideOnScroll === true || settings.hideOnScroll == 'auto' && settings.on != 'click') { + $document + .off('scroll' + eventNamespace, module.hide) + ; + $context + .off('scroll' + eventNamespace, module.hide) + ; + } + if(settings.on == 'click' && settings.closable) { + module.verbose('Removing close event from document'); + $document + .off('click' + eventNamespace) + ; + } + } + }, + + has: { + popup: function() { + return ($popup && $popup.length > 0); + } + }, + + is: { + active: function() { + return $module.hasClass(className.active); + }, + animating: function() { + return ( $popup && $popup.is(':animated') || $popup.hasClass(className.animating) ); + }, + visible: function() { + return $popup && $popup.is(':visible'); + }, + 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.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.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() { + 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, 100); + }, + 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', + + debug : false, + verbose : true, + performance : true, + namespace : 'popup', + + onCreate : function(){}, + onRemove : function(){}, + + onShow : function(){}, + onVisible : function(){}, + onHide : function(){}, + onHidden : function(){}, + + variation : '', + content : false, + html : false, + title : false, + + on : 'hover', + closable : true, + hideOnScroll : 'auto', + + context : 'body', + + position : 'top left', + prefer : 'opposite', + lastResort : false, + + delay : { + show : 30, + hide : 0 + }, + + setFluidWidth : true, + movePopup : true, + + target : false, + popup : false, + inline : false, + preserve : false, + hoverable : false, + + 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: { + 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(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 += '
' + text.title + '
'; + } + if(typeof text.content !== undefined && text.content) { + text.content = escape(text.content); + html += '
' + text.content + '
'; + } + } + return html; + } + } + +}; + +// 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 new file mode 100755 index 0000000..1544988 --- /dev/null +++ b/popup.min.css @@ -0,0 +1,11 @@ + /* + * # Semantic UI - 1.9.0 + * https://github.com/Semantic-Org/Semantic-UI + * http://www.semantic-ui.com/ + * + * Copyright 2014 Contributors + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ +.ui.popup{display:none;position:absolute;top:0;right:0;min-width:-moz-max-content;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)}.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{margin:0}.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 diff --git a/popup.min.js b/popup.min.js new file mode 100755 index 0000000..a1c0092 --- /dev/null +++ b/popup.min.js @@ -0,0 +1,11 @@ + /* + * # Semantic UI - 1.9.0 + * https://github.com/Semantic-Org/Semantic-UI + * http://www.semantic-ui.com/ + * + * Copyright 2014 Contributors + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ +!function(e,t,o,n){"use strict";e.fn.popup=function(i){var s,r=e(this),a=e(o),l=r.selector||"",p=("ontouchstart"in o.documentElement,(new Date).getTime()),u=[],c=arguments[0],d="string"==typeof c,f=[].slice.call(arguments,1);return r.each(function(){var o,r,g,h=e.isPlainObject(i)?e.extend(!0,{},e.fn.popup.settings,i):e.extend({},e.fn.popup.settings),m=h.selector,b=h.className,v=h.error,y=h.metadata,w=h.namespace,P="."+h.namespace,T="module-"+w,C=e(this),k=e(h.context),x=h.target?e(h.target):C,S=e(t),O=e("body"),j=0,A=!1,R=this,E=C.data(T);g={initialize:function(){g.debug("Initializing module",C),"click"==h.on?C.on("click"+P,g.toggle):g.get.startEvent()&&C.on(g.get.startEvent()+P,g.event.start).on(g.get.endEvent()+P,g.event.end),h.target&&g.debug("Target set to element",x),S.on("resize"+P,g.event.resize),!g.exists()&&h.preserve&&g.create(),g.instantiate()},instantiate:function(){g.verbose("Storing instance of module",g),E=g,C.data(T,E)},refresh:function(){h.popup?o=e(h.popup).eq(0):h.inline&&(o=x.next(m.popup).eq(0)),h.popup?(o.addClass(b.loading),r=g.get.offsetParent(),o.removeClass(b.loading),h.movePopup&&g.has.popup()&&g.get.offsetParent(o)[0]!==r[0]&&(g.debug("Moving popup to the same offset parent as activating element"),o.detach().appendTo(r))):r=h.inline?g.get.offsetParent(x):g.has.popup()?g.get.offsetParent(o):O,r.is("html")&&(g.debug("Setting page as offset parent"),r=O)},reposition:function(){g.refresh(),g.set.position()},destroy:function(){g.debug("Destroying previous module"),o&&!h.preserve&&g.removePopup(),clearTimeout(g.hideTimer),clearTimeout(g.showTimer),C.off(P).removeData(T)},event:{start:function(){var t=e.isPlainObject(h.delay)?h.delay.show:h.delay;clearTimeout(g.hideTimer),g.showTimer=setTimeout(function(){!g.is.hidden()||g.is.active()&&g.is.dropdown()||g.show()},t)},end:function(){var t=e.isPlainObject(h.delay)?h.delay.hide:h.delay;clearTimeout(g.showTimer),g.hideTimer=setTimeout(function(){g.is.visible()&&g.hide()},t)},resize:function(){g.is.visible()&&g.set.position()}},create:function(){var t=C.data(y.html)||h.html,n=C.data(y.variation)||h.variation,i=C.data(y.title)||h.title,s=C.data(y.content)||C.attr("title")||h.content;t||s||i?(g.debug("Creating pop-up html"),t||(t=h.templates.popup({title:i,content:s})),o=e("
").addClass(b.popup).addClass(n).html(t),n&&o.addClass(n),h.inline?(g.verbose("Inserting popup element inline",o),o.insertAfter(C)):(g.verbose("Appending popup element to body",o),o.appendTo(k)),g.refresh(),h.hoverable&&g.bind.popup(),h.onCreate.call(o,R)):0!==x.next(m.popup).length?(g.verbose("Pre-existing popup found"),h.inline=!0,h.popup=x.next(m.popup),g.refresh(),h.hoverable&&g.bind.popup()):h.popup?(g.verbose("Used popup specified in settings"),g.refresh(),h.hoverable&&g.bind.popup()):g.debug("No content specified skipping display",R)},toggle:function(){g.debug("Toggling pop-up"),g.is.hidden()?(g.debug("Popup is hidden, showing pop-up"),g.unbind.close(),g.hideAll(),g.show()):(g.debug("Popup is visible, hiding pop-up"),g.hide())},show:function(t){t=e.isFunction(t)?t:function(){},g.debug("Showing pop-up",h.transition),g.exists()?h.preserve||h.popup||g.refresh():g.create(),o&&g.set.position()&&(g.save.conditions(),g.animate.show(t))},hide:function(t){t=e.isFunction(t)?t:function(){},g.remove.visible(),g.unbind.close(),g.is.visible()&&(g.restore.conditions(),g.animate.hide(t))},hideAll:function(){e(m.popup).filter(":visible").transition(h.transition)},hideGracefully:function(t){t&&0===e(t.target).closest(m.popup).length?(g.debug("Click occurred outside popup hiding popup"),g.hide()):g.debug("Click was inside popup, keeping popup open")},exists:function(){return o?h.inline||h.popup?g.has.popup():o.closest(k).length>=1?!0:!1:!1},removePopup:function(){g.debug("Removing popup",o),g.has.popup()&&!h.popup&&(o.remove(),o=n),h.onRemove.call(o,R)},save:{conditions:function(){g.cache={title:C.attr("title")},g.cache.title&&C.removeAttr("title"),g.verbose("Saving original attributes",g.cache.title)}},restore:{conditions:function(){return g.cache&&g.cache.title&&(C.attr("title",g.cache.title),g.verbose("Restoring original attributes",g.cache.title)),!0}},animate:{show:function(t){t=e.isFunction(t)?t:function(){},h.transition&&e.fn.transition!==n&&C.transition("is supported")?(g.set.visible(),o.transition({animation:h.transition+" in",queue:!1,debug:h.debug,verbose:h.verbose,duration:h.duration,onComplete:function(){g.bind.close(),t.call(o,R),h.onVisible.call(o,R)}})):(g.set.visible(),o.stop().fadeIn(h.duration,h.easing,function(){g.bind.close(),t.call(o,R),h.onVisible.call(o,R)})),h.onShow.call(o,R)},hide:function(t){t=e.isFunction(t)?t:function(){},g.debug("Hiding pop-up"),h.transition&&e.fn.transition!==n&&C.transition("is supported")?o.transition({animation:h.transition+" out",queue:!1,duration:h.duration,debug:h.debug,verbose:h.verbose,onComplete:function(){g.reset(),t.call(o,R),h.onHidden.call(o,R)}}):o.stop().fadeOut(h.duration,h.easing,function(){g.reset(),t.call(o,R),h.onHidden.call(o,R)}),h.onHide.call(o,R)}},get:{startEvent:function(){return"hover"==h.on?"mouseenter":"focus"==h.on?"focus":!1},endEvent:function(){return"hover"==h.on?"mouseleave":"focus"==h.on?"blur":!1},offsetParent:function(t){var o=t!==n?t[0]:C[0],i=o.parentNode,s=e(i);if(i)for(var r="none"===s.css("transform"),a="static"===s.css("position"),l=s.is("html");i&&!l&&a&&r;)i=i.parentNode,s=e(i),r="none"===s.css("transform"),a="static"===s.css("position"),l=s.is("html");return s&&s.length>0?s:e()},offstagePosition:function(n){var i={top:e(t).scrollTop(),bottom:e(t).scrollTop()+e(t).height(),left:0,right:e(t).width()},s={width:o.width(),height:o.height(),offset:o.offset()},r={},a=[];return n=n||!1,s.offset&&n&&(g.verbose("Checking if outside viewable area",s.offset),r={top:s.offset.topi.bottom,right:s.offset.left+s.width>i.right,left:s.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"},s={left:"center",center:"right",right:"left"},r={"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,l=!1,p=!1,u=!1;return A||(g.verbose("All available positions available"),A=g.get.positions()),g.debug("Recording last position tried",e),A[e]=!0,"opposite"===h.prefer&&(u=[i[o],n],u=u.join(" "),l=A[u]===!0,g.debug("Trying opposite strategy",u)),"adjacent"===h.prefer&&a&&(u=[o,s[n]],u=u.join(" "),p=A[u]===!0,g.debug("Trying adjacent strategy",u)),(p||l)&&(g.debug("Using backup position",u),u=r[e]),u}},set:{position:function(i,s){var a,l,p,u=(e(t).width(),e(t).height(),x.outerWidth()),c=x.outerHeight(),d=o.outerWidth(),f=o.outerHeight(),m=r.outerWidth(),w=r.outerHeight(),P=h.distanceAway,T=x[0],k=h.inline?parseInt(t.getComputedStyle(T).getPropertyValue("margin-top"),10):0,S=h.inline?parseInt(t.getComputedStyle(T).getPropertyValue(g.is.rtl()?"margin-right":"margin-left"),10):0,O=h.inline||h.popup?x.position():x.offset();switch(i=i||C.data(y.position)||h.position,s=s||C.data(y.offset)||h.offset,j==h.maxSearchDepth&&h.lastResort&&(g.debug("Using last resort position to display",h.lastResort),i=h.lastResort),h.inline&&(g.debug("Adding targets margin to calculation"),"left center"==i||"right center"==i?(s+=k,P+=-S):"top left"==i||"top center"==i||"top right"==i?(s+=S,P-=k):(s+=S,P+=k)),g.debug("Calculating popup positioning",i),a=i,g.is.rtl()&&(a=a.replace(/left|right/g,function(e){return"left"==e?"right":"left"}),g.debug("RTL: Popup positioning updated",a)),a){case"top left":l={top:"auto",bottom:w-O.top+P,left:O.left+s,right:"auto"};break;case"top center":l={bottom:w-O.top+P,left:O.left+u/2-d/2+s,top:"auto",right:"auto"};break;case"top right":l={bottom:w-O.top+P,right:m-O.left-u-s,top:"auto",left:"auto"};break;case"left center":l={top:O.top+c/2-f/2+s,right:m-O.left+P,left:"auto",bottom:"auto"};break;case"right center":l={top:O.top+c/2-f/2+s,left:O.left+u+P,bottom:"auto",right:"auto"};break;case"bottom left":l={top:O.top+c+P,left:O.left+s,bottom:"auto",right:"auto"};break;case"bottom center":l={top:O.top+c+P,left:O.left+u/2-d/2+s,bottom:"auto",right:"auto"};break;case"bottom right":l={top:O.top+c+P,right:m-O.left-u-s,left:"auto",bottom:"auto"}}if(l===n&&g.error(v.invalidPosition,i),g.debug("Calculated popup positioning values",l),o.css(l).removeClass(b.position).addClass(i).addClass(b.loading),p=g.get.offstagePosition(i)){if(g.debug("Popup cant fit into viewport",p),j0}},is:{active:function(){return C.hasClass(b.active)},animating:function(){return o&&o.is(":animated")||o.hasClass(b.animating)},visible:function(){return o&&o.is(":visible")},dropdown:function(){return C.hasClass(b.dropdown)},hidden:function(){return!g.is.visible()},rtl:function(){return"rtl"==C.css("direction")}},reset:function(){g.remove.visible(),h.preserve?e.fn.transition!==n&&o.transition("remove transition"):g.removePopup()},setting:function(t,o){if(e.isPlainObject(t))e.extend(!0,h,t);else{if(o===n)return h[t];h[t]=o}},internal:function(t,o){if(e.isPlainObject(t))e.extend(!0,g,t);else{if(o===n)return g[t];g[t]=o}},debug:function(){h.debug&&(h.performance?g.performance.log(arguments):(g.debug=Function.prototype.bind.call(console.info,console,h.name+":"),g.debug.apply(console,arguments)))},verbose:function(){h.verbose&&h.debug&&(h.performance?g.performance.log(arguments):(g.verbose=Function.prototype.bind.call(console.info,console,h.name+":"),g.verbose.apply(console,arguments)))},error:function(){g.error=Function.prototype.bind.call(console.error,console,h.name+":"),g.error.apply(console,arguments)},performance:{log:function(e){var t,o,n;h.performance&&(t=(new Date).getTime(),n=p||t,o=t-n,p=t,u.push({Name:e[0],Arguments:[].slice.call(e,1)||"",Element:R,"Execution Time":o})),clearTimeout(g.performance.timer),g.performance.timer=setTimeout(g.performance.display,100)},display:function(){var t=h.name+":",o=0;p=!1,clearTimeout(g.performance.timer),e.each(u,function(e,t){o+=t["Execution Time"]}),t+=" "+o+"ms",l&&(t+=" '"+l+"'"),(console.group!==n||console.table!==n)&&u.length>0&&(console.groupCollapsed(t),console.table?console.table(u):e.each(u,function(e,t){console.log(t.Name+": "+t["Execution Time"]+"ms")}),console.groupEnd()),u=[]}},invoke:function(t,o,i){var r,a,l,p=E;return o=o||f,i=R||i,"string"==typeof t&&p!==n&&(t=t.split(/[\. ]/),r=t.length-1,e.each(t,function(o,i){var s=o!=r?i+t[o+1].charAt(0).toUpperCase()+t[o+1].slice(1):t;if(e.isPlainObject(p[s])&&o!=r)p=p[s];else{if(p[s]!==n)return a=p[s],!1;if(!e.isPlainObject(p[i])||o==r)return p[i]!==n?(a=p[i],!1):!1;p=p[i]}})),e.isFunction(a)?l=a.apply(i,o):a!==n&&(l=a),e.isArray(s)?s.push(l):s!==n?s=[s,l]:l!==n&&(s=l),a}},d?(E===n&&g.initialize(),g.invoke(c)):(E!==n&&E.invoke("destroy"),g.initialize())}),s!==n?s: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",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:{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