/*
* # Fomantic UI - 2.8.8
* https://github.com/fomantic/Fomantic-UI
* http://fomantic-ui.com/
*
* Copyright 2022 Contributors
* Released under the MIT license
* http://opensource.org/licenses/MIT
*
*/
/*!
* # Fomantic-UI 2.8.8 - Site
* http://github.com/fomantic/Fomantic-UI/
*
*
* Released under the MIT license
* http://opensource.org/licenses/MIT
*
*/
;(function ($, window, document, undefined) {
$.isFunction = $.isFunction || function(obj) {
return typeof obj === "function" && typeof obj.nodeType !== "number";
};
$.site = $.fn.site = function(parameters) {
var
time = new Date().getTime(),
performance = [],
query = arguments[0],
methodInvoked = (typeof query == 'string'),
queryArguments = [].slice.call(arguments, 1),
settings = ( $.isPlainObject(parameters) )
? $.extend(true, {}, $.site.settings, parameters)
: $.extend({}, $.site.settings),
namespace = settings.namespace,
error = settings.error,
moduleNamespace = 'module-' + namespace,
$document = $(document),
$module = $document,
element = this,
instance = $module.data(moduleNamespace),
module,
returnedValue
;
module = {
initialize: function() {
module.instantiate();
},
instantiate: function() {
module.verbose('Storing instance of site', module);
instance = module;
$module
.data(moduleNamespace, module)
;
},
normalize: function() {
module.fix.console();
module.fix.requestAnimationFrame();
},
fix: {
console: function() {
module.debug('Normalizing window.console');
if (console === undefined || console.log === undefined) {
module.verbose('Console not available, normalizing events');
module.disable.console();
}
if (typeof console.group == 'undefined' || typeof console.groupEnd == 'undefined' || typeof console.groupCollapsed == 'undefined') {
module.verbose('Console group not available, normalizing events');
window.console.group = function() {};
window.console.groupEnd = function() {};
window.console.groupCollapsed = function() {};
}
if (typeof console.markTimeline == 'undefined') {
module.verbose('Mark timeline not available, normalizing events');
window.console.markTimeline = function() {};
}
},
consoleClear: function() {
module.debug('Disabling programmatic console clearing');
window.console.clear = function() {};
},
requestAnimationFrame: function() {
module.debug('Normalizing requestAnimationFrame');
if(window.requestAnimationFrame === undefined) {
module.debug('RequestAnimationFrame not available, normalizing event');
window.requestAnimationFrame = window.requestAnimationFrame
|| window.mozRequestAnimationFrame
|| window.webkitRequestAnimationFrame
|| window.msRequestAnimationFrame
|| function(callback) { setTimeout(callback, 0); }
;
}
}
},
moduleExists: function(name) {
return ($.fn[name] !== undefined && $.fn[name].settings !== undefined);
},
enabled: {
modules: function(modules) {
var
enabledModules = []
;
modules = modules || settings.modules;
$.each(modules, function(index, name) {
if(module.moduleExists(name)) {
enabledModules.push(name);
}
});
return enabledModules;
}
},
disabled: {
modules: function(modules) {
var
disabledModules = []
;
modules = modules || settings.modules;
$.each(modules, function(index, name) {
if(!module.moduleExists(name)) {
disabledModules.push(name);
}
});
return disabledModules;
}
},
change: {
setting: function(setting, value, modules, modifyExisting) {
modules = (typeof modules === 'string')
? (modules === 'all')
? settings.modules
: [modules]
: modules || settings.modules
;
modifyExisting = (modifyExisting !== undefined)
? modifyExisting
: true
;
$.each(modules, function(index, name) {
var
namespace = (module.moduleExists(name))
? $.fn[name].settings.namespace || false
: true,
$existingModules
;
if(module.moduleExists(name)) {
module.verbose('Changing default setting', setting, value, name);
$.fn[name].settings[setting] = value;
if(modifyExisting && namespace) {
$existingModules = $(':data(module-' + namespace + ')');
if($existingModules.length > 0) {
module.verbose('Modifying existing settings', $existingModules);
$existingModules[name]('setting', setting, value);
}
}
}
});
},
settings: function(newSettings, modules, modifyExisting) {
modules = (typeof modules === 'string')
? [modules]
: modules || settings.modules
;
modifyExisting = (modifyExisting !== undefined)
? modifyExisting
: true
;
$.each(modules, function(index, name) {
var
$existingModules
;
if(module.moduleExists(name)) {
module.verbose('Changing default setting', newSettings, name);
$.extend(true, $.fn[name].settings, newSettings);
if(modifyExisting && namespace) {
$existingModules = $(':data(module-' + namespace + ')');
if($existingModules.length > 0) {
module.verbose('Modifying existing settings', $existingModules);
$existingModules[name]('setting', newSettings);
}
}
}
});
}
},
enable: {
console: function() {
module.console(true);
},
debug: function(modules, modifyExisting) {
modules = modules || settings.modules;
module.debug('Enabling debug for modules', modules);
module.change.setting('debug', true, modules, modifyExisting);
},
verbose: function(modules, modifyExisting) {
modules = modules || settings.modules;
module.debug('Enabling verbose debug for modules', modules);
module.change.setting('verbose', true, modules, modifyExisting);
}
},
disable: {
console: function() {
module.console(false);
},
debug: function(modules, modifyExisting) {
modules = modules || settings.modules;
module.debug('Disabling debug for modules', modules);
module.change.setting('debug', false, modules, modifyExisting);
},
verbose: function(modules, modifyExisting) {
modules = modules || settings.modules;
module.debug('Disabling verbose debug for modules', modules);
module.change.setting('verbose', false, modules, modifyExisting);
}
},
console: function(enable) {
if(enable) {
if(instance.cache.console === undefined) {
module.error(error.console);
return;
}
module.debug('Restoring console function');
window.console = instance.cache.console;
}
else {
module.debug('Disabling console function');
instance.cache.console = window.console;
window.console = {
clear : function(){},
error : function(){},
group : function(){},
groupCollapsed : function(){},
groupEnd : function(){},
info : function(){},
log : function(){},
markTimeline : function(){},
warn : function(){}
};
}
},
destroy: function() {
module.verbose('Destroying previous site for', $module);
$module
.removeData(moduleNamespace)
;
},
cache: {},
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({
'Element' : element,
'Name' : message[0],
'Arguments' : [].slice.call(message, 1) || '',
'Execution Time' : executionTime
});
}
clearTimeout(module.performance.timer);
module.performance.timer = setTimeout(module.performance.display, 500);
},
display: function() {
var
title = settings.name + ':',
totalTime = 0
;
time = false;
clearTimeout(module.performance.timer);
$.each(performance, function(index, data) {
totalTime += data['Execution Time'];
});
title += ' ' + totalTime + 'ms';
if( (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 {
module.error(error.method, query);
return false;
}
});
}
if ( $.isFunction( found ) ) {
response = found.apply(context, passedArguments);
}
else if(found !== undefined) {
response = found;
}
if(Array.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
;
};
$.site.settings = {
name : 'Site',
namespace : 'site',
error : {
console : 'Console cannot be restored, most likely it was overwritten outside of module',
method : 'The method you called is not defined.'
},
debug : false,
verbose : false,
performance : true,
modules: [
'accordion',
'api',
'calendar',
'checkbox',
'dimmer',
'dropdown',
'embed',
'form',
'modal',
'nag',
'popup',
'slider',
'rating',
'shape',
'sidebar',
'state',
'sticky',
'tab',
'toast',
'transition',
'visibility',
'visit'
],
siteNamespace : 'site',
namespaceStub : {
cache : {},
config : {},
sections : {},
section : {},
utilities : {}
}
};
// allows for selection of elements with data attributes
$.extend($.expr[ ":" ], {
data: ($.expr.createPseudo)
? $.expr.createPseudo(function(dataName) {
return function(elem) {
return !!$.data(elem, dataName);
};
})
: function(elem, i, match) {
// support: jQuery < 1.8
return !!$.data(elem, match[ 3 ]);
}
});
})( jQuery, window, document );
/*!
* # Fomantic-UI 2.8.8 - Checkbox
* http://github.com/fomantic/Fomantic-UI/
*
*
* Released under the MIT license
* http://opensource.org/licenses/MIT
*
*/
;(function ($, window, document, undefined) {
'use strict';
$.isFunction = $.isFunction || function(obj) {
return typeof obj === "function" && typeof obj.nodeType !== "number";
};
window = (typeof window != 'undefined' && window.Math == Math)
? window
: (typeof self != 'undefined' && self.Math == Math)
? self
: Function('return this')()
;
$.fn.checkbox = function(parameters) {
var
$allModules = $(this),
moduleSelector = $allModules.selector || '',
time = new Date().getTime(),
performance = [],
query = arguments[0],
methodInvoked = (typeof query == 'string'),
queryArguments = [].slice.call(arguments, 1),
returnedValue
;
$allModules
.each(function() {
var
settings = $.extend(true, {}, $.fn.checkbox.settings, parameters),
className = settings.className,
namespace = settings.namespace,
selector = settings.selector,
error = settings.error,
eventNamespace = '.' + namespace,
moduleNamespace = 'module-' + namespace,
$module = $(this),
$label = $(this).children(selector.label),
$input = $(this).children(selector.input),
input = $input[0],
initialLoad = false,
shortcutPressed = false,
instance = $module.data(moduleNamespace),
observer,
element = this,
module
;
module = {
initialize: function() {
module.verbose('Initializing checkbox', settings);
module.create.label();
module.bind.events();
module.set.tabbable();
module.hide.input();
module.observeChanges();
module.instantiate();
module.setup();
},
instantiate: function() {
module.verbose('Storing instance of module', module);
instance = module;
$module
.data(moduleNamespace, module)
;
},
destroy: function() {
module.verbose('Destroying module');
module.unbind.events();
module.show.input();
$module.removeData(moduleNamespace);
},
fix: {
reference: function() {
if( $module.is(selector.input) ) {
module.debug('Behavior called on adjusting invoked element');
$module = $module.closest(selector.checkbox);
module.refresh();
}
}
},
setup: function() {
module.set.initialLoad();
if( module.is.indeterminate() ) {
module.debug('Initial value is indeterminate');
module.indeterminate();
}
else if( module.is.checked() ) {
module.debug('Initial value is checked');
module.check();
}
else {
module.debug('Initial value is unchecked');
module.uncheck();
}
module.remove.initialLoad();
},
refresh: function() {
$label = $module.children(selector.label);
$input = $module.children(selector.input);
input = $input[0];
},
hide: {
input: function() {
module.verbose('Modifying z-index to be unselectable');
$input.addClass(className.hidden);
}
},
show: {
input: function() {
module.verbose('Modifying z-index to be selectable');
$input.removeClass(className.hidden);
}
},
observeChanges: function() {
if('MutationObserver' in window) {
observer = new MutationObserver(function(mutations) {
module.debug('DOM tree modified, updating selector cache');
module.refresh();
});
observer.observe(element, {
childList : true,
subtree : true
});
module.debug('Setting up mutation observer', observer);
}
},
attachEvents: function(selector, event) {
var
$element = $(selector)
;
event = $.isFunction(module[event])
? module[event]
: module.toggle
;
if($element.length > 0) {
module.debug('Attaching checkbox events to element', selector, event);
$element
.on('click' + eventNamespace, event)
;
}
else {
module.error(error.notFound);
}
},
preventDefaultOnInputTarget: function() {
if(typeof event !== 'undefined' && event !== null && $(event.target).is(selector.input)) {
module.verbose('Preventing default check action after manual check action');
event.preventDefault();
}
},
event: {
change: function(event) {
if( !module.should.ignoreCallbacks() ) {
settings.onChange.call(input);
}
},
click: function(event) {
var
$target = $(event.target)
;
if( $target.is(selector.input) ) {
module.verbose('Using default check action on initialized checkbox');
return;
}
if( $target.is(selector.link) ) {
module.debug('Clicking link inside checkbox, skipping toggle');
return;
}
module.toggle();
$input.focus();
event.preventDefault();
},
keydown: function(event) {
var
key = event.which,
keyCode = {
enter : 13,
space : 32,
escape : 27,
left : 37,
up : 38,
right : 39,
down : 40
}
;
var r = module.get.radios(),
rIndex = r.index($module),
rLen = r.length,
checkIndex = false;
if(key == keyCode.left || key == keyCode.up) {
checkIndex = (rIndex === 0 ? rLen : rIndex) - 1;
} else if(key == keyCode.right || key == keyCode.down) {
checkIndex = rIndex === rLen-1 ? 0 : rIndex+1;
}
if (!module.should.ignoreCallbacks() && checkIndex !== false) {
if(settings.beforeUnchecked.apply(input)===false) {
module.verbose('Option not allowed to be unchecked, cancelling key navigation');
return false;
}
if (settings.beforeChecked.apply($(r[checkIndex]).children(selector.input)[0])===false) {
module.verbose('Next option should not allow check, cancelling key navigation');
return false;
}
}
if(key == keyCode.escape) {
module.verbose('Escape key pressed blurring field');
$input.blur();
shortcutPressed = true;
}
else if(!event.ctrlKey && ( key == keyCode.space || (key == keyCode.enter && settings.enableEnterKey)) ) {
module.verbose('Enter/space key pressed, toggling checkbox');
module.toggle();
shortcutPressed = true;
}
else {
shortcutPressed = false;
}
},
keyup: function(event) {
if(shortcutPressed) {
event.preventDefault();
}
}
},
check: function() {
if( !module.should.allowCheck() ) {
return;
}
module.debug('Checking checkbox', $input);
module.set.checked();
if( !module.should.ignoreCallbacks() ) {
settings.onChecked.call(input);
module.trigger.change();
}
module.preventDefaultOnInputTarget();
},
uncheck: function() {
if( !module.should.allowUncheck() ) {
return;
}
module.debug('Unchecking checkbox');
module.set.unchecked();
if( !module.should.ignoreCallbacks() ) {
settings.onUnchecked.call(input);
module.trigger.change();
}
module.preventDefaultOnInputTarget();
},
indeterminate: function() {
if( module.should.allowIndeterminate() ) {
module.debug('Checkbox is already indeterminate');
return;
}
module.debug('Making checkbox indeterminate');
module.set.indeterminate();
if( !module.should.ignoreCallbacks() ) {
settings.onIndeterminate.call(input);
module.trigger.change();
}
},
determinate: function() {
if( module.should.allowDeterminate() ) {
module.debug('Checkbox is already determinate');
return;
}
module.debug('Making checkbox determinate');
module.set.determinate();
if( !module.should.ignoreCallbacks() ) {
settings.onDeterminate.call(input);
module.trigger.change();
}
},
enable: function() {
if( module.is.enabled() ) {
module.debug('Checkbox is already enabled');
return;
}
module.debug('Enabling checkbox');
module.set.enabled();
if( !module.should.ignoreCallbacks() ) {
settings.onEnable.call(input);
// preserve legacy callbacks
settings.onEnabled.call(input);
module.trigger.change();
}
},
disable: function() {
if( module.is.disabled() ) {
module.debug('Checkbox is already disabled');
return;
}
module.debug('Disabling checkbox');
module.set.disabled();
if( !module.should.ignoreCallbacks() ) {
settings.onDisable.call(input);
// preserve legacy callbacks
settings.onDisabled.call(input);
module.trigger.change();
}
},
get: {
radios: function() {
var
name = module.get.name()
;
return $('input[name="' + name + '"]').closest(selector.checkbox);
},
otherRadios: function() {
return module.get.radios().not($module);
},
name: function() {
return $input.attr('name');
}
},
is: {
initialLoad: function() {
return initialLoad;
},
radio: function() {
return ($input.hasClass(className.radio) || $input.attr('type') == 'radio');
},
indeterminate: function() {
return $input.prop('indeterminate') !== undefined && $input.prop('indeterminate');
},
checked: function() {
return $input.prop('checked') !== undefined && $input.prop('checked');
},
disabled: function() {
return $input.prop('disabled') !== undefined && $input.prop('disabled');
},
enabled: function() {
return !module.is.disabled();
},
determinate: function() {
return !module.is.indeterminate();
},
unchecked: function() {
return !module.is.checked();
}
},
should: {
allowCheck: function() {
if(module.is.determinate() && module.is.checked() && !module.is.initialLoad() ) {
module.debug('Should not allow check, checkbox is already checked');
return false;
}
if(!module.should.ignoreCallbacks() && settings.beforeChecked.apply(input) === false) {
module.debug('Should not allow check, beforeChecked cancelled');
return false;
}
return true;
},
allowUncheck: function() {
if(module.is.determinate() && module.is.unchecked() && !module.is.initialLoad() ) {
module.debug('Should not allow uncheck, checkbox is already unchecked');
return false;
}
if(!module.should.ignoreCallbacks() && settings.beforeUnchecked.apply(input) === false) {
module.debug('Should not allow uncheck, beforeUnchecked cancelled');
return false;
}
return true;
},
allowIndeterminate: function() {
if(module.is.indeterminate() && !module.is.initialLoad() ) {
module.debug('Should not allow indeterminate, checkbox is already indeterminate');
return false;
}
if(!module.should.ignoreCallbacks() && settings.beforeIndeterminate.apply(input) === false) {
module.debug('Should not allow indeterminate, beforeIndeterminate cancelled');
return false;
}
return true;
},
allowDeterminate: function() {
if(module.is.determinate() && !module.is.initialLoad() ) {
module.debug('Should not allow determinate, checkbox is already determinate');
return false;
}
if(!module.should.ignoreCallbacks() && settings.beforeDeterminate.apply(input) === false) {
module.debug('Should not allow determinate, beforeDeterminate cancelled');
return false;
}
return true;
},
ignoreCallbacks: function() {
return (initialLoad && !settings.fireOnInit);
}
},
can: {
change: function() {
return !( $module.hasClass(className.disabled) || $module.hasClass(className.readOnly) || $input.prop('disabled') || $input.prop('readonly') );
},
uncheck: function() {
return (typeof settings.uncheckable === 'boolean')
? settings.uncheckable
: !module.is.radio()
;
}
},
set: {
initialLoad: function() {
initialLoad = true;
},
checked: function() {
module.verbose('Setting class to checked');
$module
.removeClass(className.indeterminate)
.addClass(className.checked)
;
if( module.is.radio() ) {
module.uncheckOthers();
}
if(!module.is.indeterminate() && module.is.checked()) {
module.debug('Input is already checked, skipping input property change');
return;
}
module.verbose('Setting state to checked', input);
$input
.prop('indeterminate', false)
.prop('checked', true)
;
},
unchecked: function() {
module.verbose('Removing checked class');
$module
.removeClass(className.indeterminate)
.removeClass(className.checked)
;
if(!module.is.indeterminate() && module.is.unchecked() ) {
module.debug('Input is already unchecked');
return;
}
module.debug('Setting state to unchecked');
$input
.prop('indeterminate', false)
.prop('checked', false)
;
},
indeterminate: function() {
module.verbose('Setting class to indeterminate');
$module
.addClass(className.indeterminate)
;
if( module.is.indeterminate() ) {
module.debug('Input is already indeterminate, skipping input property change');
return;
}
module.debug('Setting state to indeterminate');
$input
.prop('indeterminate', true)
;
},
determinate: function() {
module.verbose('Removing indeterminate class');
$module
.removeClass(className.indeterminate)
;
if( module.is.determinate() ) {
module.debug('Input is already determinate, skipping input property change');
return;
}
module.debug('Setting state to determinate');
$input
.prop('indeterminate', false)
;
},
disabled: function() {
module.verbose('Setting class to disabled');
$module
.addClass(className.disabled)
;
if( module.is.disabled() ) {
module.debug('Input is already disabled, skipping input property change');
return;
}
module.debug('Setting state to disabled');
$input
.prop('disabled', 'disabled')
;
},
enabled: function() {
module.verbose('Removing disabled class');
$module.removeClass(className.disabled);
if( module.is.enabled() ) {
module.debug('Input is already enabled, skipping input property change');
return;
}
module.debug('Setting state to enabled');
$input
.prop('disabled', false)
;
},
tabbable: function() {
module.verbose('Adding tabindex to checkbox');
if( $input.attr('tabindex') === undefined) {
$input.attr('tabindex', 0);
}
}
},
remove: {
initialLoad: function() {
initialLoad = false;
}
},
trigger: {
change: function() {
var
inputElement = $input[0]
;
if(inputElement) {
var events = document.createEvent('HTMLEvents');
module.verbose('Triggering native change event');
events.initEvent('change', true, false);
inputElement.dispatchEvent(events);
}
}
},
create: {
label: function() {
if($input.prevAll(selector.label).length > 0) {
$input.prev(selector.label).detach().insertAfter($input);
module.debug('Moving existing label', $label);
}
else if( !module.has.label() ) {
$label = $('
';
}
return {
title : args.title,
content: args.content,
actions: [{
text: settings.text.ok,
class: settings.className.ok,
click: function(){
var settings = $this.get.settings(),
inputField = $this.get.element().find(settings.selector.prompt)[0]
;
args.handler($(inputField).val());
}
},{
text: settings.text.cancel,
class: settings.className.cancel,
click: function(){args.handler(null)}
}]
}
}
}
})( jQuery, window, document );
/*!
* # Fomantic-UI 2.8.8 - Popup
* http://github.com/fomantic/Fomantic-UI/
*
*
* Released under the MIT license
* http://opensource.org/licenses/MIT
*
*/
;(function ($, window, document, undefined) {
'use strict';
$.isFunction = $.isFunction || function(obj) {
return typeof obj === "function" && typeof obj.nodeType !== "number";
};
window = (typeof window != 'undefined' && window.Math == Math)
? window
: (typeof self != 'undefined' && self.Math == Math)
? self
: Function('return this')()
;
$.fn.popup = function(parameters) {
var
$allModules = $(this),
$document = $(document),
$window = $(window),
$body = $('body'),
moduleSelector = $allModules.selector || '',
clickEvent = ('ontouchstart' in document.documentElement)
? 'touchstart'
: 'click',
time = new Date().getTime(),
performance = [],
query = arguments[0],
methodInvoked = (typeof query == 'string'),
queryArguments = [].slice.call(arguments, 1),
returnedValue
;
$allModules
.each(function() {
var
settings = ( $.isPlainObject(parameters) )
? $.extend(true, {}, $.fn.popup.settings, parameters)
: $.extend({}, $.fn.popup.settings),
selector = settings.selector,
className = settings.className,
error = settings.error,
metadata = settings.metadata,
namespace = settings.namespace,
eventNamespace = '.' + settings.namespace,
moduleNamespace = 'module-' + namespace,
$module = $(this),
$context = $(settings.context),
$scrollContext = $(settings.scrollContext),
$boundary = $(settings.boundary),
$target = (settings.target)
? $(settings.target)
: $module,
$popup,
$offsetParent,
searchDepth = 0,
triedPositions = false,
openedWithTouch = false,
element = this,
instance = $module.data(moduleNamespace),
documentObserver,
elementNamespace,
id,
module
;
module = {
// binds events
initialize: function() {
module.debug('Initializing', $module);
module.createID();
module.bind.events();
if(!module.exists() && settings.preserve) {
module.create();
}
if(settings.observeChanges) {
module.observeChanges();
}
module.instantiate();
},
instantiate: function() {
module.verbose('Storing instance', module);
instance = module;
$module
.data(moduleNamespace, instance)
;
},
observeChanges: function() {
if('MutationObserver' in window) {
documentObserver = new MutationObserver(module.event.documentChanged);
documentObserver.observe(document, {
childList : true,
subtree : true
});
module.debug('Setting up mutation observer', documentObserver);
}
},
refresh: function() {
if(settings.popup) {
$popup = $(settings.popup).eq(0);
}
else {
if(settings.inline) {
$popup = $target.nextAll(selector.popup).eq(0);
settings.popup = $popup;
}
}
if(settings.popup) {
$popup.addClass(className.loading);
$offsetParent = module.get.offsetParent();
$popup.removeClass(className.loading);
if(settings.movePopup && module.has.popup() && module.get.offsetParent($popup)[0] !== $offsetParent[0]) {
module.debug('Moving popup to the same offset parent as target');
$popup
.detach()
.appendTo($offsetParent)
;
}
}
else {
$offsetParent = (settings.inline)
? module.get.offsetParent($target)
: module.has.popup()
? module.get.offsetParent($popup)
: $body
;
}
if( $offsetParent.is('html') && $offsetParent[0] !== $body[0] ) {
module.debug('Setting page as offset parent');
$offsetParent = $body;
}
if( module.get.variation() ) {
module.set.variation();
}
},
reposition: function() {
module.refresh();
module.set.position();
},
destroy: function() {
module.debug('Destroying previous module');
if(documentObserver) {
documentObserver.disconnect();
}
// remove element only if was created dynamically
if($popup && !settings.preserve) {
module.removePopup();
}
// clear all timeouts
clearTimeout(module.hideTimer);
clearTimeout(module.showTimer);
// remove events
module.unbind.close();
module.unbind.events();
$module
.removeData(moduleNamespace)
;
},
event: {
start: function(event) {
var
delay = ($.isPlainObject(settings.delay))
? settings.delay.show
: settings.delay
;
clearTimeout(module.hideTimer);
if(!openedWithTouch || (openedWithTouch && settings.addTouchEvents) ) {
module.showTimer = setTimeout(module.show, delay);
}
},
end: function() {
var
delay = ($.isPlainObject(settings.delay))
? settings.delay.hide
: settings.delay
;
clearTimeout(module.showTimer);
module.hideTimer = setTimeout(module.hide, delay);
},
touchstart: function(event) {
openedWithTouch = true;
if(settings.addTouchEvents) {
module.show();
}
},
resize: function() {
if( module.is.visible() ) {
module.set.position();
}
},
documentChanged: function(mutations) {
[].forEach.call(mutations, function(mutation) {
if(mutation.removedNodes) {
[].forEach.call(mutation.removedNodes, function(node) {
if(node == element || $(node).find(element).length > 0) {
module.debug('Element removed from DOM, tearing down events');
module.destroy();
}
});
}
});
},
hideGracefully: function(event) {
var
$target = $(event.target),
isInDOM = $.contains(document.documentElement, event.target),
inPopup = ($target.closest(selector.popup).length > 0)
;
// don't close on clicks inside popup
if(event && !inPopup && isInDOM) {
module.debug('Click occurred outside popup hiding popup');
module.hide();
}
else {
module.debug('Click was inside popup, keeping popup open');
}
}
},
// generates popup html from metadata
create: function() {
var
html = module.get.html(),
title = module.get.title(),
content = module.get.content()
;
if(html || content || title) {
module.debug('Creating pop-up html');
if(!html) {
html = settings.templates.popup({
title : title,
content : content
});
}
$popup = $('')
.addClass(className.popup)
.data(metadata.activator, $module)
.html(html)
;
if(settings.inline) {
module.verbose('Inserting popup element inline', $popup);
$popup
.insertAfter($module)
;
}
else {
module.verbose('Appending popup element to body', $popup);
$popup
.appendTo( $context )
;
}
module.refresh();
module.set.variation();
if(settings.hoverable) {
module.bind.popup();
}
settings.onCreate.call($popup, element);
}
else if(settings.popup) {
$(settings.popup).data(metadata.activator, $module);
module.verbose('Used popup specified in settings');
module.refresh();
if(settings.hoverable) {
module.bind.popup();
}
}
else if($target.next(selector.popup).length !== 0) {
module.verbose('Pre-existing popup found');
settings.inline = true;
settings.popup = $target.next(selector.popup).data(metadata.activator, $module);
module.refresh();
if(settings.hoverable) {
module.bind.popup();
}
}
else {
module.debug('No content specified skipping display', element);
}
},
createID: function() {
id = (Math.random().toString(16) + '000000000').substr(2, 8);
elementNamespace = '.' + id;
module.verbose('Creating unique id for element', id);
},
// determines popup state
toggle: function() {
module.debug('Toggling pop-up');
if( module.is.hidden() ) {
module.debug('Popup is hidden, showing pop-up');
module.unbind.close();
module.show();
}
else {
module.debug('Popup is visible, hiding pop-up');
module.hide();
}
},
show: function(callback) {
callback = callback || function(){};
module.debug('Showing pop-up', settings.transition);
if(module.is.hidden() && !( module.is.active() && module.is.dropdown()) ) {
if( !module.exists() ) {
module.create();
}
if(settings.onShow.call($popup, element) === false) {
module.debug('onShow callback returned false, cancelling popup animation');
return;
}
else if(!settings.preserve && !settings.popup) {
module.refresh();
}
if( $popup && module.set.position() ) {
module.save.conditions();
if(settings.exclusive) {
module.hideAll();
}
module.animate.show(callback);
}
}
},
hide: function(callback) {
callback = callback || function(){};
if( module.is.visible() || module.is.animating() ) {
if(settings.onHide.call($popup, element) === false) {
module.debug('onHide callback returned false, cancelling popup animation');
return;
}
module.remove.visible();
module.unbind.close();
module.restore.conditions();
module.animate.hide(callback);
}
},
hideAll: function() {
$(selector.popup)
.filter('.' + className.popupVisible)
.each(function() {
$(this)
.data(metadata.activator)
.popup('hide')
;
})
;
},
exists: function() {
if(!$popup) {
return false;
}
if(settings.inline || settings.popup) {
return ( module.has.popup() );
}
else {
return ( $popup.closest($context).length >= 1 )
? true
: false
;
}
},
removePopup: function() {
if( module.has.popup() && !settings.popup) {
module.debug('Removing popup', $popup);
$popup.remove();
$popup = undefined;
settings.onRemove.call($popup, element);
}
},
save: {
conditions: function() {
module.cache = {
title: $module.attr('title')
};
if (module.cache.title) {
$module.removeAttr('title');
}
module.verbose('Saving original attributes', module.cache.title);
}
},
restore: {
conditions: function() {
if(module.cache && module.cache.title) {
$module.attr('title', module.cache.title);
module.verbose('Restoring original attributes', module.cache.title);
}
return true;
}
},
supports: {
svg: function() {
return (typeof SVGGraphicsElement !== 'undefined');
}
},
animate: {
show: function(callback) {
callback = $.isFunction(callback) ? callback : function(){};
if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
module.set.visible();
$popup
.transition({
animation : (settings.transition.showMethod || settings.transition) + ' in',
queue : false,
debug : settings.debug,
verbose : settings.verbose,
duration : settings.transition.showDuration || settings.duration,
onComplete : function() {
module.bind.close();
callback.call($popup, element);
settings.onVisible.call($popup, element);
}
})
;
}
else {
module.error(error.noTransition);
}
},
hide: function(callback) {
callback = $.isFunction(callback) ? callback : function(){};
module.debug('Hiding pop-up');
if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
$popup
.transition({
animation : (settings.transition.hideMethod || settings.transition) + ' out',
queue : false,
duration : settings.transition.hideDuration || settings.duration,
debug : settings.debug,
verbose : settings.verbose,
onComplete : function() {
module.reset();
callback.call($popup, element);
settings.onHidden.call($popup, element);
}
})
;
}
else {
module.error(error.noTransition);
}
}
},
change: {
content: function(html) {
$popup.html(html);
}
},
get: {
html: function() {
$module.removeData(metadata.html);
return $module.data(metadata.html) || settings.html;
},
title: function() {
$module.removeData(metadata.title);
return $module.data(metadata.title) || settings.title;
},
content: function() {
$module.removeData(metadata.content);
return $module.data(metadata.content) || settings.content || $module.attr('title');
},
variation: function() {
$module.removeData(metadata.variation);
return $module.data(metadata.variation) || settings.variation;
},
popup: function() {
return $popup;
},
popupOffset: function() {
return $popup.offset();
},
calculations: function() {
var
$popupOffsetParent = module.get.offsetParent($popup),
targetElement = $target[0],
isWindow = ($boundary[0] == window),
targetOffset = $target.offset(),
parentOffset = settings.inline || (settings.popup && settings.movePopup)
? $target.offsetParent().offset()
: { top: 0, left: 0 },
screenPosition = (isWindow)
? { top: 0, left: 0 }
: $boundary.offset(),
calculations = {},
scroll = (isWindow)
? { top: $window.scrollTop(), left: $window.scrollLeft() }
: { top: 0, left: 0},
screen
;
calculations = {
// element which is launching popup
target : {
element : $target[0],
width : $target.outerWidth(),
height : $target.outerHeight(),
top : targetOffset.top - parentOffset.top,
left : targetOffset.left - parentOffset.left,
margin : {}
},
// popup itself
popup : {
width : $popup.outerWidth(),
height : $popup.outerHeight()
},
// offset container (or 3d context)
parent : {
width : $offsetParent.outerWidth(),
height : $offsetParent.outerHeight()
},
// screen boundaries
screen : {
top : screenPosition.top,
left : screenPosition.left,
scroll: {
top : scroll.top,
left : scroll.left
},
width : $boundary.width(),
height : $boundary.height()
}
};
// if popup offset context is not same as target, then adjust calculations
if($popupOffsetParent.get(0) !== $offsetParent.get(0)) {
var
popupOffset = $popupOffsetParent.offset()
;
calculations.target.top -= popupOffset.top;
calculations.target.left -= popupOffset.left;
calculations.parent.width = $popupOffsetParent.outerWidth();
calculations.parent.height = $popupOffsetParent.outerHeight();
}
// add in container calcs if fluid
if( settings.setFluidWidth && module.is.fluid() ) {
calculations.container = {
width: $popup.parent().outerWidth()
};
calculations.popup.width = calculations.container.width;
}
// add in margins if inline
calculations.target.margin.top = (settings.inline)
? parseInt( window.getComputedStyle(targetElement).getPropertyValue('margin-top'), 10)
: 0
;
calculations.target.margin.left = (settings.inline)
? module.is.rtl()
? parseInt( window.getComputedStyle(targetElement).getPropertyValue('margin-right'), 10)
: parseInt( window.getComputedStyle(targetElement).getPropertyValue('margin-left'), 10)
: 0
;
// calculate screen boundaries
screen = calculations.screen;
calculations.boundary = {
top : screen.top + screen.scroll.top,
bottom : screen.top + screen.scroll.top + screen.height,
left : screen.left + screen.scroll.left,
right : screen.left + screen.scroll.left + screen.width
};
return calculations;
},
id: function() {
return id;
},
startEvent: function() {
if(settings.on == 'hover') {
return 'mouseenter';
}
else if(settings.on == 'focus') {
return 'focus';
}
return false;
},
scrollEvent: function() {
return 'scroll';
},
endEvent: function() {
if(settings.on == 'hover') {
return 'mouseleave';
}
else if(settings.on == 'focus') {
return 'blur';
}
return false;
},
distanceFromBoundary: function(offset, calculations) {
var
distanceFromBoundary = {},
popup,
boundary
;
calculations = calculations || module.get.calculations();
// shorthand
popup = calculations.popup;
boundary = calculations.boundary;
if(offset) {
distanceFromBoundary = {
top : (offset.top - boundary.top),
left : (offset.left - boundary.left),
right : (boundary.right - (offset.left + popup.width) ),
bottom : (boundary.bottom - (offset.top + popup.height) )
};
module.verbose('Distance from boundaries determined', offset, distanceFromBoundary);
}
return distanceFromBoundary;
},
offsetParent: function($element) {
var
element = ($element !== undefined)
? $element[0]
: $target[0],
parentNode = element.parentNode,
$node = $(parentNode)
;
if(parentNode) {
var
is2D = ($node.css('transform') === 'none'),
isStatic = ($node.css('position') === 'static'),
isBody = $node.is('body')
;
while(parentNode && !isBody && isStatic && is2D) {
parentNode = parentNode.parentNode;
$node = $(parentNode);
is2D = ($node.css('transform') === 'none');
isStatic = ($node.css('position') === 'static');
isBody = $node.is('body');
}
}
return ($node && $node.length > 0)
? $node
: $()
;
},
positions: function() {
return {
'top left' : false,
'top center' : false,
'top right' : false,
'bottom left' : false,
'bottom center' : false,
'bottom right' : false,
'left center' : false,
'right center' : false
};
},
nextPosition: function(position) {
var
positions = position.split(' '),
verticalPosition = positions[0],
horizontalPosition = positions[1],
opposite = {
top : 'bottom',
bottom : 'top',
left : 'right',
right : 'left'
},
adjacent = {
left : 'center',
center : 'right',
right : 'left'
},
backup = {
'top left' : 'top center',
'top center' : 'top right',
'top right' : 'right center',
'right center' : 'bottom right',
'bottom right' : 'bottom center',
'bottom center' : 'bottom left',
'bottom left' : 'left center',
'left center' : 'top left'
},
adjacentsAvailable = (verticalPosition == 'top' || verticalPosition == 'bottom'),
oppositeTried = false,
adjacentTried = false,
nextPosition = false
;
if(!triedPositions) {
module.verbose('All available positions available');
triedPositions = module.get.positions();
}
module.debug('Recording last position tried', position);
triedPositions[position] = true;
if(settings.prefer === 'opposite') {
nextPosition = [opposite[verticalPosition], horizontalPosition];
nextPosition = nextPosition.join(' ');
oppositeTried = (triedPositions[nextPosition] === true);
module.debug('Trying opposite strategy', nextPosition);
}
if((settings.prefer === 'adjacent') && adjacentsAvailable ) {
nextPosition = [verticalPosition, adjacent[horizontalPosition]];
nextPosition = nextPosition.join(' ');
adjacentTried = (triedPositions[nextPosition] === true);
module.debug('Trying adjacent strategy', nextPosition);
}
if(adjacentTried || oppositeTried) {
module.debug('Using backup position', nextPosition);
nextPosition = backup[position];
}
return nextPosition;
}
},
set: {
position: function(position, calculations) {
// exit conditions
if($target.length === 0 || $popup.length === 0) {
module.error(error.notFound);
return;
}
var
offset,
distanceAway,
target,
popup,
parent,
positioning,
popupOffset,
distanceFromBoundary
;
calculations = calculations || module.get.calculations();
position = position || $module.data(metadata.position) || settings.position;
offset = $module.data(metadata.offset) || settings.offset;
distanceAway = settings.distanceAway;
// shorthand
target = calculations.target;
popup = calculations.popup;
parent = calculations.parent;
if(module.should.centerArrow(calculations)) {
module.verbose('Adjusting offset to center arrow on small target element');
if(position == 'top left' || position == 'bottom left') {
offset += (target.width / 2);
offset -= settings.arrowPixelsFromEdge;
}
if(position == 'top right' || position == 'bottom right') {
offset -= (target.width / 2);
offset += settings.arrowPixelsFromEdge;
}
}
if(target.width === 0 && target.height === 0 && !module.is.svg(target.element)) {
module.debug('Popup target is hidden, no action taken');
return false;
}
if(settings.inline) {
module.debug('Adding margin to calculation', target.margin);
if(position == 'left center' || position == 'right center') {
offset += target.margin.top;
distanceAway += -target.margin.left;
}
else if (position == 'top left' || position == 'top center' || position == 'top right') {
offset += target.margin.left;
distanceAway -= target.margin.top;
}
else {
offset += target.margin.left;
distanceAway += target.margin.top;
}
}
module.debug('Determining popup position from calculations', position, calculations);
if (module.is.rtl()) {
position = position.replace(/left|right/g, function (match) {
return (match == 'left')
? 'right'
: 'left'
;
});
module.debug('RTL: Popup position updated', position);
}
// if last attempt use specified last resort position
if(searchDepth == settings.maxSearchDepth && typeof settings.lastResort === 'string') {
position = settings.lastResort;
}
switch (position) {
case 'top left':
positioning = {
top : 'auto',
bottom : parent.height - target.top + distanceAway,
left : target.left + offset,
right : 'auto'
};
break;
case 'top center':
positioning = {
bottom : parent.height - target.top + distanceAway,
left : target.left + (target.width / 2) - (popup.width / 2) + offset,
top : 'auto',
right : 'auto'
};
break;
case 'top right':
positioning = {
bottom : parent.height - target.top + distanceAway,
right : parent.width - target.left - target.width - offset,
top : 'auto',
left : 'auto'
};
break;
case 'left center':
positioning = {
top : target.top + (target.height / 2) - (popup.height / 2) + offset,
right : parent.width - target.left + distanceAway,
left : 'auto',
bottom : 'auto'
};
break;
case 'right center':
positioning = {
top : target.top + (target.height / 2) - (popup.height / 2) + offset,
left : target.left + target.width + distanceAway,
bottom : 'auto',
right : 'auto'
};
break;
case 'bottom left':
positioning = {
top : target.top + target.height + distanceAway,
left : target.left + offset,
bottom : 'auto',
right : 'auto'
};
break;
case 'bottom center':
positioning = {
top : target.top + target.height + distanceAway,
left : target.left + (target.width / 2) - (popup.width / 2) + offset,
bottom : 'auto',
right : 'auto'
};
break;
case 'bottom right':
positioning = {
top : target.top + target.height + distanceAway,
right : parent.width - target.left - target.width - offset,
left : 'auto',
bottom : 'auto'
};
break;
}
if(positioning === undefined) {
module.error(error.invalidPosition, position);
}
module.debug('Calculated popup positioning values', positioning);
// tentatively place on stage
$popup
.css(positioning)
.removeClass(className.position)
.addClass(position)
.addClass(className.loading)
;
popupOffset = module.get.popupOffset();
// see if any boundaries are surpassed with this tentative position
distanceFromBoundary = module.get.distanceFromBoundary(popupOffset, calculations);
if(!settings.forcePosition && module.is.offstage(distanceFromBoundary, position) ) {
module.debug('Position is outside viewport', position);
if(searchDepth < settings.maxSearchDepth) {
searchDepth++;
position = module.get.nextPosition(position);
module.debug('Trying new position', position);
return ($popup)
? module.set.position(position, calculations)
: false
;
}
else {
if(settings.lastResort) {
module.debug('No position found, showing with last position');
}
else {
module.debug('Popup could not find a position to display', $popup);
module.error(error.cannotPlace, element);
module.remove.attempts();
module.remove.loading();
module.reset();
settings.onUnplaceable.call($popup, element);
return false;
}
}
}
module.debug('Position is on stage', position);
module.remove.attempts();
module.remove.loading();
if( settings.setFluidWidth && module.is.fluid() ) {
module.set.fluidWidth(calculations);
}
return true;
},
fluidWidth: function(calculations) {
calculations = calculations || module.get.calculations();
module.debug('Automatically setting element width to parent width', calculations.parent.width);
$popup.css('width', calculations.container.width);
},
variation: function(variation) {
variation = variation || module.get.variation();
if(variation && module.has.popup() ) {
module.verbose('Adding variation to popup', variation);
$popup.addClass(variation);
}
},
visible: function() {
$module.addClass(className.visible);
}
},
remove: {
loading: function() {
$popup.removeClass(className.loading);
},
variation: function(variation) {
variation = variation || module.get.variation();
if(variation) {
module.verbose('Removing variation', variation);
$popup.removeClass(variation);
}
},
visible: function() {
$module.removeClass(className.visible);
},
attempts: function() {
module.verbose('Resetting all searched positions');
searchDepth = 0;
triedPositions = false;
}
},
bind: {
events: function() {
module.debug('Binding popup events to module');
if(settings.on == 'click') {
$module
.on(clickEvent + eventNamespace, module.toggle)
;
}
if(settings.on == 'hover') {
$module
.on('touchstart' + eventNamespace, module.event.touchstart)
;
}
if( module.get.startEvent() ) {
$module
.on(module.get.startEvent() + eventNamespace, module.event.start)
.on(module.get.endEvent() + eventNamespace, module.event.end)
;
}
if(settings.target) {
module.debug('Target set to element', $target);
}
$window.on('resize' + elementNamespace, module.event.resize);
},
popup: function() {
module.verbose('Allowing hover events on popup to prevent closing');
if( $popup && module.has.popup() ) {
$popup
.on('mouseenter' + eventNamespace, module.event.start)
.on('mouseleave' + eventNamespace, module.event.end)
;
}
},
close: function() {
if(settings.hideOnScroll === true || (settings.hideOnScroll == 'auto' && settings.on != 'click')) {
module.bind.closeOnScroll();
}
if(module.is.closable()) {
module.bind.clickaway();
}
else if(settings.on == 'hover' && openedWithTouch) {
module.bind.touchClose();
}
},
closeOnScroll: function() {
module.verbose('Binding scroll close event to document');
$scrollContext
.one(module.get.scrollEvent() + elementNamespace, module.event.hideGracefully)
;
},
touchClose: function() {
module.verbose('Binding popup touchclose event to document');
$document
.on('touchstart' + elementNamespace, function(event) {
module.verbose('Touched away from popup');
module.event.hideGracefully.call(element, event);
})
;
},
clickaway: function() {
module.verbose('Binding popup close event to document');
$document
.on(clickEvent + elementNamespace, function(event) {
module.verbose('Clicked away from popup');
module.event.hideGracefully.call(element, event);
})
;
}
},
unbind: {
events: function() {
$window
.off(elementNamespace)
;
$module
.off(eventNamespace)
;
},
close: function() {
$document
.off(elementNamespace)
;
$scrollContext
.off(elementNamespace)
;
},
},
has: {
popup: function() {
return ($popup && $popup.length > 0);
}
},
should: {
centerArrow: function(calculations) {
return !module.is.basic() && calculations.target.width <= (settings.arrowPixelsFromEdge * 2);
},
},
is: {
closable: function() {
if(settings.closable == 'auto') {
if(settings.on == 'hover') {
return false;
}
return true;
}
return settings.closable;
},
offstage: function(distanceFromBoundary, position) {
var
offstage = []
;
// return boundaries that have been surpassed
$.each(distanceFromBoundary, function(direction, distance) {
if(distance < -settings.jitter) {
module.debug('Position exceeds allowable distance from edge', direction, distance, position);
offstage.push(direction);
}
});
if(offstage.length > 0) {
return true;
}
else {
return false;
}
},
svg: function(element) {
return module.supports.svg() && (element instanceof SVGGraphicsElement);
},
basic: function() {
return $module.hasClass(className.basic);
},
active: function() {
return $module.hasClass(className.active);
},
animating: function() {
return ($popup !== undefined && $popup.hasClass(className.animating) );
},
fluid: function() {
return ($popup !== undefined && $popup.hasClass(className.fluid));
},
visible: function() {
return ($popup !== undefined && $popup.hasClass(className.popupVisible));
},
dropdown: function() {
return $module.hasClass(className.dropdown);
},
hidden: function() {
return !module.is.visible();
},
rtl: function () {
return $module.attr('dir') === 'rtl' || $module.css('direction') === 'rtl';
}
},
reset: function() {
module.remove.visible();
if(settings.preserve) {
if($.fn.transition !== undefined) {
$popup
.transition('remove transition')
;
}
}
else {
module.removePopup();
}
},
setting: function(name, value) {
if( $.isPlainObject(name) ) {
$.extend(true, settings, name);
}
else if(value !== undefined) {
settings[name] = value;
}
else {
return settings[name];
}
},
internal: function(name, value) {
if( $.isPlainObject(name) ) {
$.extend(true, module, name);
}
else if(value !== undefined) {
module[name] = value;
}
else {
return module[name];
}
},
debug: function() {
if(!settings.silent && settings.debug) {
if(settings.performance) {
module.performance.log(arguments);
}
else {
module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
module.debug.apply(console, arguments);
}
}
},
verbose: function() {
if(!settings.silent && settings.verbose && settings.debug) {
if(settings.performance) {
module.performance.log(arguments);
}
else {
module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
module.verbose.apply(console, arguments);
}
}
},
error: function() {
if(!settings.silent) {
module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
module.error.apply(console, arguments);
}
},
performance: {
log: function(message) {
var
currentTime,
executionTime,
previousTime
;
if(settings.performance) {
currentTime = new Date().getTime();
previousTime = time || currentTime;
executionTime = currentTime - previousTime;
time = currentTime;
performance.push({
'Name' : message[0],
'Arguments' : [].slice.call(message, 1) || '',
'Element' : element,
'Execution Time' : executionTime
});
}
clearTimeout(module.performance.timer);
module.performance.timer = setTimeout(module.performance.display, 500);
},
display: function() {
var
title = settings.name + ':',
totalTime = 0
;
time = false;
clearTimeout(module.performance.timer);
$.each(performance, function(index, data) {
totalTime += data['Execution Time'];
});
title += ' ' + totalTime + 'ms';
if(moduleSelector) {
title += ' \'' + moduleSelector + '\'';
}
if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
console.groupCollapsed(title);
if(console.table) {
console.table(performance);
}
else {
$.each(performance, function(index, data) {
console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
});
}
console.groupEnd();
}
performance = [];
}
},
invoke: function(query, passedArguments, context) {
var
object = instance,
maxDepth,
found,
response
;
passedArguments = passedArguments || queryArguments;
context = element || context;
if(typeof query == 'string' && object !== undefined) {
query = query.split(/[\. ]/);
maxDepth = query.length - 1;
$.each(query, function(depth, value) {
var camelCaseValue = (depth != maxDepth)
? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
: query
;
if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
object = object[camelCaseValue];
}
else if( object[camelCaseValue] !== undefined ) {
found = object[camelCaseValue];
return false;
}
else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
object = object[value];
}
else if( object[value] !== undefined ) {
found = object[value];
return false;
}
else {
return false;
}
});
}
if ( $.isFunction( found ) ) {
response = found.apply(context, passedArguments);
}
else if(found !== undefined) {
response = found;
}
if(Array.isArray(returnedValue)) {
returnedValue.push(response);
}
else if(returnedValue !== undefined) {
returnedValue = [returnedValue, response];
}
else if(response !== undefined) {
returnedValue = response;
}
return found;
}
};
if(methodInvoked) {
if(instance === undefined) {
module.initialize();
}
module.invoke(query);
}
else {
if(instance !== undefined) {
instance.invoke('destroy');
}
module.initialize();
}
})
;
return (returnedValue !== undefined)
? returnedValue
: this
;
};
$.fn.popup.settings = {
name : 'Popup',
// module settings
silent : false,
debug : false,
verbose : false,
performance : true,
namespace : 'popup',
// whether it should use dom mutation observers
observeChanges : true,
// callback only when element added to dom
onCreate : function(){},
// callback before element removed from dom
onRemove : function(){},
// callback before show animation
onShow : function(){},
// callback after show animation
onVisible : function(){},
// callback before hide animation
onHide : function(){},
// callback when popup cannot be positioned in visible screen
onUnplaceable : function(){},
// callback after hide animation
onHidden : function(){},
// when to show popup
on : 'hover',
// element to use to determine if popup is out of boundary
boundary : window,
// whether to add touchstart events when using hover
addTouchEvents : true,
// default position relative to element
position : 'top left',
// if given position should be used regardless if popup fits
forcePosition : false,
// name of variation to use
variation : '',
// whether popup should be moved to context
movePopup : true,
// element which popup should be relative to
target : false,
// jq selector or element that should be used as popup
popup : false,
// popup should remain inline next to activator
inline : false,
// popup should be removed from page on hide
preserve : false,
// popup should not close when being hovered on
hoverable : false,
// explicitly set content
content : false,
// explicitly set html
html : false,
// explicitly set title
title : false,
// whether automatically close on clickaway when on click
closable : true,
// automatically hide on scroll
hideOnScroll : 'auto',
// hide other popups on show
exclusive : false,
// context to attach popups
context : 'body',
// context for binding scroll events
scrollContext : window,
// position to prefer when calculating new position
prefer : 'opposite',
// specify position to appear even if it doesn't fit
lastResort : false,
// number of pixels from edge of popup to pointing arrow center (used from centering)
arrowPixelsFromEdge: 20,
// delay used to prevent accidental refiring of animations due to user error
delay : {
show : 50,
hide : 70
},
// whether fluid variation should assign width explicitly
setFluidWidth : true,
// transition settings
duration : 200,
transition : 'scale',
// distance away from activating element in px
distanceAway : 0,
// number of pixels an element is allowed to be "offstage" for a position to be chosen (allows for rounding)
jitter : 2,
// offset on aligning axis from calculated position
offset : 0,
// maximum times to look for a position before failing (9 positions total)
maxSearchDepth : 15,
error: {
invalidPosition : 'The position you specified is not a valid position',
cannotPlace : 'Popup does not fit within the boundaries of the viewport',
method : 'The method you called is not defined.',
noTransition : 'This module requires ui transitions ',
notFound : 'The target or popup you specified does not exist on the page'
},
metadata: {
activator : 'activator',
content : 'content',
html : 'html',
offset : 'offset',
position : 'position',
title : 'title',
variation : 'variation'
},
className : {
active : 'active',
basic : 'basic',
animating : 'animating',
dropdown : 'dropdown',
fluid : 'fluid',
loading : 'loading',
popup : 'ui popup',
position : 'top left center bottom right',
visible : 'visible',
popupVisible : 'visible'
},
selector : {
popup : '.ui.popup'
},
templates: {
escape: function(string) {
var
badChars = /[<>"'`]/g,
shouldEscape = /[&<>"'`]/,
escape = {
"<": "<",
">": ">",
'"': """,
"'": "'",
"`": "`"
},
escapedChar = function(chr) {
return escape[chr];
}
;
if(shouldEscape.test(string)) {
string = string.replace(/&(?![a-z0-9#]{1,6};)/, "&");
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 += '';
}
if(typeof text.content !== undefined && text.content) {
text.content = escape(text.content);
html += '' + text.content + '
';
}
}
return html;
}
}
};
})( jQuery, window, document );
/*!
* # Fomantic-UI 2.8.8 - Progress
* http://github.com/fomantic/Fomantic-UI/
*
*
* Released under the MIT license
* http://opensource.org/licenses/MIT
*
*/
;(function ($, window, document, undefined) {
'use strict';
$.isFunction = $.isFunction || function(obj) {
return typeof obj === "function" && typeof obj.nodeType !== "number";
};
window = (typeof window != 'undefined' && window.Math == Math)
? window
: (typeof self != 'undefined' && self.Math == Math)
? self
: Function('return this')()
;
$.fn.progress = function(parameters) {
var
$allModules = $(this),
moduleSelector = $allModules.selector || '',
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.progress.settings, parameters)
: $.extend({}, $.fn.progress.settings),
className = settings.className,
metadata = settings.metadata,
namespace = settings.namespace,
selector = settings.selector,
error = settings.error,
eventNamespace = '.' + namespace,
moduleNamespace = 'module-' + namespace,
$module = $(this),
$bars = $(this).find(selector.bar),
$progresses = $(this).find(selector.progress),
$label = $(this).find(selector.label),
element = this,
instance = $module.data(moduleNamespace),
animating = false,
transitionEnd,
module
;
module = {
helper: {
sum: function (nums) {
return Array.isArray(nums) ? nums.reduce(function (left, right) {
return left + Number(right);
}, 0) : 0;
},
/**
* Derive precision for multiple progress with total and values.
*
* This helper dervices a precision that is sufficiently large to show minimum value of multiple progress.
*
* Example1
* - total: 1122
* - values: [325, 111, 74, 612]
* - min ratio: 74/1122 = 0.0659...
* - required precision: 100
*
* Example2
* - total: 10541
* - values: [3235, 1111, 74, 6121]
* - min ratio: 74/10541 = 0.0070...
* - required precision: 1000
*
* @param min A minimum value within multiple values
* @param total A total amount of multiple values
* @returns {number} A precison. Could be 1, 10, 100, ... 1e+10.
*/
derivePrecision: function(min, total) {
var precisionPower = 0
var precision = 1;
var ratio = min / total;
while (precisionPower < 10) {
ratio = ratio * precision;
if (ratio > 1) {
break;
}
precision = Math.pow(10, precisionPower++);
}
return precision;
},
forceArray: function (element) {
return Array.isArray(element)
? element
: !isNaN(element)
? [element]
: typeof element == 'string'
? element.split(',')
: []
;
}
},
initialize: function() {
module.set.duration();
module.set.transitionEvent();
module.debug(element);
module.read.metadata();
module.read.settings();
module.instantiate();
},
instantiate: function() {
module.verbose('Storing instance of progress', module);
instance = module;
$module
.data(moduleNamespace, module)
;
},
destroy: function() {
module.verbose('Destroying previous progress for', $module);
clearInterval(instance.interval);
module.remove.state();
$module.removeData(moduleNamespace);
instance = undefined;
},
reset: function() {
module.remove.nextValue();
module.update.progress(0);
},
complete: function(keepState) {
if(module.percent === undefined || module.percent < 100) {
module.remove.progressPoll();
if(keepState !== true){
module.set.percent(100);
}
}
},
read: {
metadata: function() {
var
data = {
percent : module.helper.forceArray($module.data(metadata.percent)),
total : $module.data(metadata.total),
value : module.helper.forceArray($module.data(metadata.value))
}
;
if(data.total !== undefined) {
module.debug('Total value set from metadata', data.total);
module.set.total(data.total);
}
if(data.value.length > 0) {
module.debug('Current value set from metadata', data.value);
module.set.value(data.value);
module.set.progress(data.value);
}
if(data.percent.length > 0) {
module.debug('Current percent value set from metadata', data.percent);
module.set.percent(data.percent);
}
},
settings: function() {
if(settings.total !== false) {
module.debug('Current total set in settings', settings.total);
module.set.total(settings.total);
}
if(settings.value !== false) {
module.debug('Current value set in settings', settings.value);
module.set.value(settings.value);
module.set.progress(module.value);
}
if(settings.percent !== false) {
module.debug('Current percent set in settings', settings.percent);
module.set.percent(settings.percent);
}
}
},
bind: {
transitionEnd: function(callback) {
var
transitionEnd = module.get.transitionEnd()
;
$bars
.one(transitionEnd + eventNamespace, function(event) {
clearTimeout(module.failSafeTimer);
callback.call(this, event);
})
;
module.failSafeTimer = setTimeout(function() {
$bars.triggerHandler(transitionEnd);
}, settings.duration + settings.failSafeDelay);
module.verbose('Adding fail safe timer', module.timer);
}
},
increment: function(incrementValue) {
var
startValue,
newValue
;
if( module.has.total() ) {
startValue = module.get.value();
incrementValue = incrementValue || 1;
}
else {
startValue = module.get.percent();
incrementValue = incrementValue || module.get.randomValue();
}
newValue = startValue + incrementValue;
module.debug('Incrementing percentage by', startValue, newValue, incrementValue);
newValue = module.get.normalizedValue(newValue);
module.set.progress(newValue);
},
decrement: function(decrementValue) {
var
total = module.get.total(),
startValue,
newValue
;
if(total) {
startValue = module.get.value();
decrementValue = decrementValue || 1;
newValue = startValue - decrementValue;
module.debug('Decrementing value by', decrementValue, startValue);
}
else {
startValue = module.get.percent();
decrementValue = decrementValue || module.get.randomValue();
newValue = startValue - decrementValue;
module.debug('Decrementing percentage by', decrementValue, startValue);
}
newValue = module.get.normalizedValue(newValue);
module.set.progress(newValue);
},
has: {
progressPoll: function() {
return module.progressPoll;
},
total: function() {
return (module.get.total() !== false);
}
},
get: {
text: function(templateText, index) {
var
index_ = index || 0,
value = module.get.value(index_),
total = module.get.total(),
percent = (animating)
? module.get.displayPercent(index_)
: module.get.percent(index_),
left = (total !== false)
? Math.max(0,total - value)
: (100 - percent)
;
templateText = templateText || '';
templateText = templateText
.replace('{value}', value)
.replace('{total}', total || 0)
.replace('{left}', left)
.replace('{percent}', percent)
.replace('{bar}', settings.text.bars[index_] || '')
;
module.verbose('Adding variables to progress bar text', templateText);
return templateText;
},
normalizedValue: function(value) {
if(value < 0) {
module.debug('Value cannot decrement below 0');
return 0;
}
if(module.has.total()) {
if(value > module.total) {
module.debug('Value cannot increment above total', module.total);
return module.total;
}
}
else if(value > 100 ) {
module.debug('Value cannot increment above 100 percent');
return 100;
}
return value;
},
updateInterval: function() {
if(settings.updateInterval == 'auto') {
return settings.duration;
}
return settings.updateInterval;
},
randomValue: function() {
module.debug('Generating random increment percentage');
return Math.floor((Math.random() * settings.random.max) + settings.random.min);
},
numericValue: function(value) {
return (typeof value === 'string')
? (value.replace(/[^\d.]/g, '') !== '')
? +(value.replace(/[^\d.]/g, ''))
: false
: value
;
},
transitionEnd: function() {
var
element = document.createElement('element'),
transitions = {
'transition' :'transitionend',
'OTransition' :'oTransitionEnd',
'MozTransition' :'transitionend',
'WebkitTransition' :'webkitTransitionEnd'
},
transition
;
for(transition in transitions){
if( element.style[transition] !== undefined ){
return transitions[transition];
}
}
},
// gets current displayed percentage (if animating values this is the intermediary value)
displayPercent: function(index) {
var
$bar = $($bars[index]),
barWidth = $bar.width(),
totalWidth = $module.width(),
minDisplay = parseInt($bar.css('min-width'), 10),
displayPercent = (barWidth > minDisplay)
? (barWidth / totalWidth * 100)
: module.percent
;
return (settings.precision > 0)
? Math.round(displayPercent * (10 * settings.precision)) / (10 * settings.precision)
: Math.round(displayPercent)
;
},
percent: function(index) {
return module.percent && module.percent[index || 0] || 0;
},
value: function(index) {
return module.nextValue || module.value && module.value[index || 0] || 0;
},
total: function() {
return module.total !== undefined ? module.total : false;
}
},
create: {
progressPoll: function() {
module.progressPoll = setTimeout(function() {
module.update.toNextValue();
module.remove.progressPoll();
}, module.get.updateInterval());
},
},
is: {
complete: function() {
return module.is.success() || module.is.warning() || module.is.error();
},
success: function() {
return $module.hasClass(className.success);
},
warning: function() {
return $module.hasClass(className.warning);
},
error: function() {
return $module.hasClass(className.error);
},
active: function() {
return $module.hasClass(className.active);
},
visible: function() {
return $module.is(':visible');
}
},
remove: {
progressPoll: function() {
module.verbose('Removing progress poll timer');
if(module.progressPoll) {
clearTimeout(module.progressPoll);
delete module.progressPoll;
}
},
nextValue: function() {
module.verbose('Removing progress value stored for next update');
delete module.nextValue;
},
state: function() {
module.verbose('Removing stored state');
delete module.total;
delete module.percent;
delete module.value;
},
active: function() {
module.verbose('Removing active state');
$module.removeClass(className.active);
},
success: function() {
module.verbose('Removing success state');
$module.removeClass(className.success);
},
warning: function() {
module.verbose('Removing warning state');
$module.removeClass(className.warning);
},
error: function() {
module.verbose('Removing error state');
$module.removeClass(className.error);
}
},
set: {
barWidth: function(values) {
module.debug("set bar width with ", values);
values = module.helper.forceArray(values);
var firstNonZeroIndex = -1;
var lastNonZeroIndex = -1;
var valuesSum = module.helper.sum(values);
var barCounts = $bars.length;
var isMultiple = barCounts > 1;
var percents = values.map(function(value, index) {
var allZero = (index === barCounts - 1 && valuesSum === 0);
var $bar = $($bars[index]);
if (value === 0 && isMultiple && !allZero) {
$bar.css('display', 'none');
} else {
if (isMultiple && allZero) {
$bar.css('background', 'transparent');
}
if (firstNonZeroIndex == -1) {
firstNonZeroIndex = index;
}
lastNonZeroIndex = index;
$bar.css({
display: 'block',
width: value + '%'
});
}
return parseFloat(value);
});
values.forEach(function(_, index) {
var $bar = $($bars[index]);
$bar.css({
borderTopLeftRadius: index == firstNonZeroIndex ? '' : 0,
borderBottomLeftRadius: index == firstNonZeroIndex ? '' : 0,
borderTopRightRadius: index == lastNonZeroIndex ? '' : 0,
borderBottomRightRadius: index == lastNonZeroIndex ? '' : 0
});
});
$module
.attr('data-percent', percents)
;
},
duration: function(duration) {
duration = duration || settings.duration;
duration = (typeof duration == 'number')
? duration + 'ms'
: duration
;
module.verbose('Setting progress bar transition duration', duration);
$bars
.css({
'transition-duration': duration
})
;
},
percent: function(percents) {
percents = module.helper.forceArray(percents).map(function(percent) {
percent = (typeof percent == 'string')
? +(percent.replace('%', ''))
: percent
;
return (settings.limitValues)
? Math.max(0, Math.min(100, percent))
: percent
;
});
var hasTotal = module.has.total();
var totalPercent = module.helper.sum(percents);
var isMultipleValues = percents.length > 1 && hasTotal;
var sumTotal = module.helper.sum(module.helper.forceArray(module.value));
if (isMultipleValues && sumTotal > module.total) {
// Sum values instead of pecents to avoid precision issues when summing floats
module.error(error.sumExceedsTotal, sumTotal, module.total);
} else if (!isMultipleValues && totalPercent > 100) {
// Sum before rounding since sum of rounded may have error though sum of actual is fine
module.error(error.tooHigh, totalPercent);
} else if (totalPercent < 0) {
module.error(error.tooLow, totalPercent);
} else {
var autoPrecision = settings.precision > 0
? settings.precision
: isMultipleValues
? module.helper.derivePrecision(Math.min.apply(null, module.value), module.total)
: 0;
// round display percentage
var roundedPercents = percents.map(function (percent) {
return (autoPrecision > 0)
? Math.round(percent * (10 * autoPrecision)) / (10 * autoPrecision)
: Math.round(percent)
;
});
module.percent = roundedPercents;
if (hasTotal) {
module.value = percents.map(function (percent) {
return (autoPrecision > 0)
? Math.round((percent / 100) * module.total * (10 * autoPrecision)) / (10 * autoPrecision)
: Math.round((percent / 100) * module.total * 10) / 10
;
});
}
module.set.barWidth(percents);
module.set.labelInterval();
}
settings.onChange.call(element, percents, module.value, module.total);
},
labelInterval: function() {
var
animationCallback = function() {
module.verbose('Bar finished animating, removing continuous label updates');
clearInterval(module.interval);
animating = false;
module.set.labels();
}
;
clearInterval(module.interval);
module.bind.transitionEnd(animationCallback);
animating = true;
module.interval = setInterval(function() {
var
isInDOM = $.contains(document.documentElement, element)
;
if(!isInDOM) {
clearInterval(module.interval);
animating = false;
}
module.set.labels();
}, settings.framerate);
},
labels: function() {
module.verbose('Setting both bar progress and outer label text');
module.set.barLabel();
module.set.state();
},
label: function(text) {
text = text || '';
if(text) {
text = module.get.text(text);
module.verbose('Setting label to text', text);
$label.text(text);
}
},
state: function(percent) {
percent = (percent !== undefined)
? percent
: module.helper.sum(module.percent)
;
if(percent === 100) {
if(settings.autoSuccess && $bars.length === 1 && !(module.is.warning() || module.is.error() || module.is.success())) {
module.set.success();
module.debug('Automatically triggering success at 100%');
}
else {
module.verbose('Reached 100% removing active state');
module.remove.active();
module.remove.progressPoll();
}
}
else if(percent > 0) {
module.verbose('Adjusting active progress bar label', percent);
module.set.active();
}
else {
module.remove.active();
module.set.label(settings.text.active);
}
},
barLabel: function(text) {
$progresses.map(function(index, element){
var $progress = $(element);
if (text !== undefined) {
$progress.text( module.get.text(text, index) );
}
else if (settings.label == 'ratio' && module.has.total()) {
module.verbose('Adding ratio to bar label');
$progress.text( module.get.text(settings.text.ratio, index) );
}
else if (settings.label == 'percent') {
module.verbose('Adding percentage to bar label');
$progress.text( module.get.text(settings.text.percent, index) );
}
});
},
active: function(text) {
text = text || settings.text.active;
module.debug('Setting active state');
if(settings.showActivity && !module.is.active() ) {
$module.addClass(className.active);
}
module.remove.warning();
module.remove.error();
module.remove.success();
text = settings.onLabelUpdate('active', text, module.value, module.total);
if(text) {
module.set.label(text);
}
module.bind.transitionEnd(function() {
settings.onActive.call(element, module.value, module.total);
});
},
success : function(text, keepState) {
text = text || settings.text.success || settings.text.active;
module.debug('Setting success state');
$module.addClass(className.success);
module.remove.active();
module.remove.warning();
module.remove.error();
module.complete(keepState);
if(settings.text.success) {
text = settings.onLabelUpdate('success', text, module.value, module.total);
module.set.label(text);
}
else {
text = settings.onLabelUpdate('active', text, module.value, module.total);
module.set.label(text);
}
module.bind.transitionEnd(function() {
settings.onSuccess.call(element, module.total);
});
},
warning : function(text, keepState) {
text = text || settings.text.warning;
module.debug('Setting warning state');
$module.addClass(className.warning);
module.remove.active();
module.remove.success();
module.remove.error();
module.complete(keepState);
text = settings.onLabelUpdate('warning', text, module.value, module.total);
if(text) {
module.set.label(text);
}
module.bind.transitionEnd(function() {
settings.onWarning.call(element, module.value, module.total);
});
},
error : function(text, keepState) {
text = text || settings.text.error;
module.debug('Setting error state');
$module.addClass(className.error);
module.remove.active();
module.remove.success();
module.remove.warning();
module.complete(keepState);
text = settings.onLabelUpdate('error', text, module.value, module.total);
if(text) {
module.set.label(text);
}
module.bind.transitionEnd(function() {
settings.onError.call(element, module.value, module.total);
});
},
transitionEvent: function() {
transitionEnd = module.get.transitionEnd();
},
total: function(totalValue) {
module.total = totalValue;
},
value: function(value) {
module.value = module.helper.forceArray(value);
},
progress: function(value) {
if(!module.has.progressPoll()) {
module.debug('First update in progress update interval, immediately updating', value);
module.update.progress(value);
module.create.progressPoll();
}
else {
module.debug('Updated within interval, setting next update to use new value', value);
module.set.nextValue(value);
}
},
nextValue: function(value) {
module.nextValue = value;
}
},
update: {
toNextValue: function() {
var
nextValue = module.nextValue
;
if(nextValue) {
module.debug('Update interval complete using last updated value', nextValue);
module.update.progress(nextValue);
module.remove.nextValue();
}
},
progress: function(values) {
var hasTotal = module.has.total();
if (hasTotal) {
module.set.value(values);
}
var percentCompletes = module.helper.forceArray(values).map(function(value) {
var
percentComplete
;
value = module.get.numericValue(value);
if (value === false) {
module.error(error.nonNumeric, value);
}
value = module.get.normalizedValue(value);
if (hasTotal) {
percentComplete = module.total > 0 ? (value / module.total) * 100 : 100;
module.debug('Calculating percent complete from total', percentComplete);
}
else {
percentComplete = value;
module.debug('Setting value to exact percentage value', percentComplete);
}
return percentComplete;
});
module.set.percent( percentCompletes );
}
},
setting: function(name, value) {
module.debug('Changing setting', name, value);
if( $.isPlainObject(name) ) {
$.extend(true, settings, name);
}
else if(value !== undefined) {
if($.isPlainObject(settings[name])) {
$.extend(true, settings[name], value);
}
else {
settings[name] = value;
}
}
else {
return settings[name];
}
},
internal: function(name, value) {
if( $.isPlainObject(name) ) {
$.extend(true, module, name);
}
else if(value !== undefined) {
module[name] = value;
}
else {
return module[name];
}
},
debug: function() {
if(!settings.silent && settings.debug) {
if(settings.performance) {
module.performance.log(arguments);
}
else {
module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
module.debug.apply(console, arguments);
}
}
},
verbose: function() {
if(!settings.silent && settings.verbose && settings.debug) {
if(settings.performance) {
module.performance.log(arguments);
}
else {
module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
module.verbose.apply(console, arguments);
}
}
},
error: function() {
if(!settings.silent) {
module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
module.error.apply(console, arguments);
}
},
performance: {
log: function(message) {
var
currentTime,
executionTime,
previousTime
;
if(settings.performance) {
currentTime = new Date().getTime();
previousTime = time || currentTime;
executionTime = currentTime - previousTime;
time = currentTime;
performance.push({
'Name' : message[0],
'Arguments' : [].slice.call(message, 1) || '',
'Element' : element,
'Execution Time' : executionTime
});
}
clearTimeout(module.performance.timer);
module.performance.timer = setTimeout(module.performance.display, 500);
},
display: function() {
var
title = settings.name + ':',
totalTime = 0
;
time = false;
clearTimeout(module.performance.timer);
$.each(performance, function(index, data) {
totalTime += data['Execution Time'];
});
title += ' ' + totalTime + 'ms';
if(moduleSelector) {
title += ' \'' + moduleSelector + '\'';
}
if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
console.groupCollapsed(title);
if(console.table) {
console.table(performance);
}
else {
$.each(performance, function(index, data) {
console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
});
}
console.groupEnd();
}
performance = [];
}
},
invoke: function(query, passedArguments, context) {
var
object = instance,
maxDepth,
found,
response
;
passedArguments = passedArguments || queryArguments;
context = element || context;
if(typeof query == 'string' && object !== undefined) {
query = query.split(/[\. ]/);
maxDepth = query.length - 1;
$.each(query, function(depth, value) {
var camelCaseValue = (depth != maxDepth)
? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
: query
;
if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
object = object[camelCaseValue];
}
else if( object[camelCaseValue] !== undefined ) {
found = object[camelCaseValue];
return false;
}
else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
object = object[value];
}
else if( object[value] !== undefined ) {
found = object[value];
return false;
}
else {
module.error(error.method, query);
return false;
}
});
}
if ( $.isFunction( found ) ) {
response = found.apply(context, passedArguments);
}
else if(found !== undefined) {
response = found;
}
if(Array.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.progress.settings = {
name : 'Progress',
namespace : 'progress',
silent : false,
debug : false,
verbose : false,
performance : true,
random : {
min : 2,
max : 5
},
duration : 300,
updateInterval : 'auto',
autoSuccess : true,
showActivity : true,
limitValues : true,
label : 'percent',
precision : 0,
framerate : (1000 / 30), /// 30 fps
percent : false,
total : false,
value : false,
// delay in ms for fail safe animation callback
failSafeDelay : 100,
onLabelUpdate : function(state, text, value, total){
return text;
},
onChange : function(percent, value, total){},
onSuccess : function(total){},
onActive : function(value, total){},
onError : function(value, total){},
onWarning : function(value, total){},
error : {
method : 'The method you called is not defined.',
nonNumeric : 'Progress value is non numeric',
tooHigh : 'Value specified is above 100%',
tooLow : 'Value specified is below 0%',
sumExceedsTotal : 'Sum of multple values exceed total',
},
regExp: {
variable: /\{\$*[A-z0-9]+\}/g
},
metadata: {
percent : 'percent',
total : 'total',
value : 'value'
},
selector : {
bar : '> .bar',
label : '> .label',
progress : '.bar > .progress'
},
text : {
active : false,
error : false,
success : false,
warning : false,
percent : '{percent}%',
ratio : '{value} of {total}',
bars : ['']
},
className : {
active : 'active',
error : 'error',
success : 'success',
warning : 'warning'
}
};
})( jQuery, window, document );
/*!
* # Fomantic-UI 2.8.8 - Sidebar
* http://github.com/fomantic/Fomantic-UI/
*
*
* Released under the MIT license
* http://opensource.org/licenses/MIT
*
*/
;(function ($, window, document, undefined) {
'use strict';
$.isFunction = $.isFunction || function(obj) {
return typeof obj === "function" && typeof obj.nodeType !== "number";
};
window = (typeof window != 'undefined' && window.Math == Math)
? window
: (typeof self != 'undefined' && self.Math == Math)
? self
: Function('return this')()
;
$.fn.sidebar = function(parameters) {
var
$allModules = $(this),
$window = $(window),
$document = $(document),
$html = $('html'),
$head = $('head'),
moduleSelector = $allModules.selector || '',
time = new Date().getTime(),
performance = [],
query = arguments[0],
methodInvoked = (typeof query == 'string'),
queryArguments = [].slice.call(arguments, 1),
requestAnimationFrame = window.requestAnimationFrame
|| window.mozRequestAnimationFrame
|| window.webkitRequestAnimationFrame
|| window.msRequestAnimationFrame
|| function(callback) { setTimeout(callback, 0); },
returnedValue
;
$allModules
.each(function() {
var
settings = ( $.isPlainObject(parameters) )
? $.extend(true, {}, $.fn.sidebar.settings, parameters)
: $.extend({}, $.fn.sidebar.settings),
selector = settings.selector,
className = settings.className,
namespace = settings.namespace,
regExp = settings.regExp,
error = settings.error,
eventNamespace = '.' + namespace,
moduleNamespace = 'module-' + namespace,
$module = $(this),
$context = $(settings.context),
$sidebars = $module.children(selector.sidebar),
$fixed = $context.children(selector.fixed),
$pusher = $context.children(selector.pusher),
$style,
element = this,
instance = $module.data(moduleNamespace),
elementNamespace,
id,
currentScroll,
transitionEvent,
module
;
module = {
initialize: function() {
module.debug('Initializing sidebar', parameters);
module.create.id();
transitionEvent = module.get.transitionEvent();
// avoids locking rendering if initialized in onReady
if(settings.delaySetup) {
requestAnimationFrame(module.setup.layout);
}
else {
module.setup.layout();
}
requestAnimationFrame(function() {
module.setup.cache();
});
module.instantiate();
},
instantiate: function() {
module.verbose('Storing instance of module', module);
instance = module;
$module
.data(moduleNamespace, module)
;
},
create: {
id: function() {
id = (Math.random().toString(16) + '000000000').substr(2,8);
elementNamespace = '.' + id;
module.verbose('Creating unique id for element', id);
}
},
destroy: function() {
module.verbose('Destroying previous module for', $module);
$module
.off(eventNamespace)
.removeData(moduleNamespace)
;
if(module.is.ios()) {
module.remove.ios();
}
// bound by uuid
$context.off(elementNamespace);
$window.off(elementNamespace);
$document.off(elementNamespace);
},
event: {
clickaway: function(event) {
if(settings.closable){
var
clickedInPusher = ($pusher.find(event.target).length > 0 || $pusher.is(event.target)),
clickedContext = ($context.is(event.target))
;
if(clickedInPusher) {
module.verbose('User clicked on dimmed page');
module.hide();
}
if(clickedContext) {
module.verbose('User clicked on dimmable context (scaled out page)');
module.hide();
}
}
},
touch: function(event) {
//event.stopPropagation();
},
containScroll: function(event) {
if(element.scrollTop <= 0) {
element.scrollTop = 1;
}
if((element.scrollTop + element.offsetHeight) >= element.scrollHeight) {
element.scrollTop = element.scrollHeight - element.offsetHeight - 1;
}
},
scroll: function(event) {
if( $(event.target).closest(selector.sidebar).length === 0 ) {
event.preventDefault();
}
}
},
bind: {
clickaway: function() {
module.verbose('Adding clickaway events to context', $context);
$context
.on('click' + elementNamespace, module.event.clickaway)
.on('touchend' + elementNamespace, module.event.clickaway)
;
},
scrollLock: function() {
if(settings.scrollLock) {
module.debug('Disabling page scroll');
$window
.on('DOMMouseScroll' + elementNamespace, module.event.scroll)
;
}
module.verbose('Adding events to contain sidebar scroll');
$document
.on('touchmove' + elementNamespace, module.event.touch)
;
$module
.on('scroll' + eventNamespace, module.event.containScroll)
;
}
},
unbind: {
clickaway: function() {
module.verbose('Removing clickaway events from context', $context);
$context.off(elementNamespace);
},
scrollLock: function() {
module.verbose('Removing scroll lock from page');
$document.off(elementNamespace);
$window.off(elementNamespace);
$module.off('scroll' + eventNamespace);
}
},
add: {
inlineCSS: function() {
var
width = module.cache.width || $module.outerWidth(),
height = module.cache.height || $module.outerHeight(),
isRTL = module.is.rtl(),
direction = module.get.direction(),
distance = {
left : width,
right : -width,
top : height,
bottom : -height
},
style
;
if(isRTL){
module.verbose('RTL detected, flipping widths');
distance.left = -width;
distance.right = width;
}
style = '';
$style = $(style)
.appendTo($head)
;
module.debug('Adding sizing css to head', $style);
}
},
refresh: function() {
module.verbose('Refreshing selector cache');
$context = $(settings.context);
$sidebars = $context.children(selector.sidebar);
$pusher = $context.children(selector.pusher);
$fixed = $context.children(selector.fixed);
module.clear.cache();
},
refreshSidebars: function() {
module.verbose('Refreshing other sidebars');
$sidebars = $context.children(selector.sidebar);
},
repaint: function() {
module.verbose('Forcing repaint event');
element.style.display = 'none';
var ignored = element.offsetHeight;
element.scrollTop = element.scrollTop;
element.style.display = '';
},
setup: {
cache: function() {
module.cache = {
width : $module.outerWidth(),
height : $module.outerHeight()
};
},
layout: function() {
if( $context.children(selector.pusher).length === 0 ) {
module.debug('Adding wrapper element for sidebar');
module.error(error.pusher);
$pusher = $('');
$context
.children()
.not(selector.omitted)
.not($sidebars)
.wrapAll($pusher)
;
module.refresh();
}
if($module.nextAll(selector.pusher).length === 0 || $module.nextAll(selector.pusher)[0] !== $pusher[0]) {
module.debug('Moved sidebar to correct parent element');
module.error(error.movedSidebar, element);
$module.detach().prependTo($context);
module.refresh();
}
module.clear.cache();
module.set.pushable();
module.set.direction();
}
},
attachEvents: function(selector, event) {
var
$toggle = $(selector)
;
event = $.isFunction(module[event])
? module[event]
: module.toggle
;
if($toggle.length > 0) {
module.debug('Attaching sidebar events to element', selector, event);
$toggle
.on('click' + eventNamespace, event)
;
}
else {
module.error(error.notFound, selector);
}
},
show: function(callback) {
callback = $.isFunction(callback)
? callback
: function(){}
;
if(module.is.hidden()) {
module.refreshSidebars();
if(settings.overlay) {
module.error(error.overlay);
settings.transition = 'overlay';
}
module.refresh();
if(module.othersActive()) {
module.debug('Other sidebars currently visible');
if(settings.exclusive) {
// if not overlay queue animation after hide
if(settings.transition != 'overlay') {
module.hideOthers(module.show);
return;
}
else {
module.hideOthers();
}
}
else {
settings.transition = 'overlay';
}
}
module.pushPage(function() {
callback.call(element);
settings.onShow.call(element);
});
settings.onChange.call(element);
settings.onVisible.call(element);
}
else {
module.debug('Sidebar is already visible');
}
},
hide: function(callback) {
callback = $.isFunction(callback)
? callback
: function(){}
;
if(module.is.visible() || module.is.animating()) {
module.debug('Hiding sidebar', callback);
module.refreshSidebars();
module.pullPage(function() {
callback.call(element);
settings.onHidden.call(element);
});
settings.onChange.call(element);
settings.onHide.call(element);
}
},
othersAnimating: function() {
return ($sidebars.not($module).filter('.' + className.animating).length > 0);
},
othersVisible: function() {
return ($sidebars.not($module).filter('.' + className.visible).length > 0);
},
othersActive: function() {
return(module.othersVisible() || module.othersAnimating());
},
hideOthers: function(callback) {
var
$otherSidebars = $sidebars.not($module).filter('.' + className.visible),
sidebarCount = $otherSidebars.length,
callbackCount = 0
;
callback = callback || function(){};
$otherSidebars
.sidebar('hide', function() {
callbackCount++;
if(callbackCount == sidebarCount) {
callback();
}
})
;
},
toggle: function() {
module.verbose('Determining toggled direction');
if(module.is.hidden()) {
module.show();
}
else {
module.hide();
}
},
pushPage: function(callback) {
var
transition = module.get.transition(),
$transition = (transition === 'overlay' || module.othersActive())
? $module
: $pusher,
animate,
dim,
transitionEnd
;
callback = $.isFunction(callback)
? callback
: function(){}
;
if(settings.transition == 'scale down') {
module.scrollToTop();
}
module.set.transition(transition);
module.repaint();
animate = function() {
module.bind.clickaway();
module.add.inlineCSS();
module.set.animating();
module.set.visible();
};
dim = function() {
module.set.dimmed();
};
transitionEnd = function(event) {
if( event.target == $transition[0] ) {
$transition.off(transitionEvent + elementNamespace, transitionEnd);
module.remove.animating();
module.bind.scrollLock();
callback.call(element);
}
};
$transition.off(transitionEvent + elementNamespace);
$transition.on(transitionEvent + elementNamespace, transitionEnd);
requestAnimationFrame(animate);
if(settings.dimPage && !module.othersVisible()) {
requestAnimationFrame(dim);
}
},
pullPage: function(callback) {
var
transition = module.get.transition(),
$transition = (transition == 'overlay' || module.othersActive())
? $module
: $pusher,
animate,
transitionEnd
;
callback = $.isFunction(callback)
? callback
: function(){}
;
module.verbose('Removing context push state', module.get.direction());
module.unbind.clickaway();
module.unbind.scrollLock();
animate = function() {
module.set.transition(transition);
module.set.animating();
module.remove.visible();
if(settings.dimPage && !module.othersVisible()) {
$pusher.removeClass(className.dimmed);
}
};
transitionEnd = function(event) {
if( event.target == $transition[0] ) {
$transition.off(transitionEvent + elementNamespace, transitionEnd);
module.remove.animating();
module.remove.transition();
module.remove.inlineCSS();
if(transition == 'scale down' || (settings.returnScroll && module.is.mobile()) ) {
module.scrollBack();
}
callback.call(element);
}
};
$transition.off(transitionEvent + elementNamespace);
$transition.on(transitionEvent + elementNamespace, transitionEnd);
requestAnimationFrame(animate);
},
scrollToTop: function() {
module.verbose('Scrolling to top of page to avoid animation issues');
currentScroll = $(window).scrollTop();
$module.scrollTop(0);
window.scrollTo(0, 0);
},
scrollBack: function() {
module.verbose('Scrolling back to original page position');
window.scrollTo(0, currentScroll);
},
clear: {
cache: function() {
module.verbose('Clearing cached dimensions');
module.cache = {};
}
},
set: {
// ios only (scroll on html not document). This prevent auto-resize canvas/scroll in ios
// (This is no longer necessary in latest iOS)
ios: function() {
$html.addClass(className.ios);
},
// container
pushed: function() {
$context.addClass(className.pushed);
},
pushable: function() {
$context.addClass(className.pushable);
},
// pusher
dimmed: function() {
$pusher.addClass(className.dimmed);
},
// sidebar
active: function() {
$module.addClass(className.active);
},
animating: function() {
$module.addClass(className.animating);
},
transition: function(transition) {
transition = transition || module.get.transition();
$module.addClass(transition);
},
direction: function(direction) {
direction = direction || module.get.direction();
$module.addClass(className[direction]);
},
visible: function() {
$module.addClass(className.visible);
},
overlay: function() {
$module.addClass(className.overlay);
}
},
remove: {
inlineCSS: function() {
module.debug('Removing inline css styles', $style);
if($style && $style.length > 0) {
$style.remove();
}
},
// ios scroll on html not document
ios: function() {
$html.removeClass(className.ios);
},
// context
pushed: function() {
$context.removeClass(className.pushed);
},
pushable: function() {
$context.removeClass(className.pushable);
},
// sidebar
active: function() {
$module.removeClass(className.active);
},
animating: function() {
$module.removeClass(className.animating);
},
transition: function(transition) {
transition = transition || module.get.transition();
$module.removeClass(transition);
},
direction: function(direction) {
direction = direction || module.get.direction();
$module.removeClass(className[direction]);
},
visible: function() {
$module.removeClass(className.visible);
},
overlay: function() {
$module.removeClass(className.overlay);
}
},
get: {
direction: function() {
if($module.hasClass(className.top)) {
return className.top;
}
else if($module.hasClass(className.right)) {
return className.right;
}
else if($module.hasClass(className.bottom)) {
return className.bottom;
}
return className.left;
},
transition: function() {
var
direction = module.get.direction(),
transition
;
transition = ( module.is.mobile() )
? (settings.mobileTransition == 'auto')
? settings.defaultTransition.mobile[direction]
: settings.mobileTransition
: (settings.transition == 'auto')
? settings.defaultTransition.computer[direction]
: settings.transition
;
module.verbose('Determined transition', transition);
return transition;
},
transitionEvent: function() {
var
element = document.createElement('element'),
transitions = {
'transition' :'transitionend',
'OTransition' :'oTransitionEnd',
'MozTransition' :'transitionend',
'WebkitTransition' :'webkitTransitionEnd'
},
transition
;
for(transition in transitions){
if( element.style[transition] !== undefined ){
return transitions[transition];
}
}
}
},
is: {
ie: function() {
var
isIE11 = (!(window.ActiveXObject) && 'ActiveXObject' in window),
isIE = ('ActiveXObject' in window)
;
return (isIE11 || isIE);
},
ios: function() {
var
userAgent = navigator.userAgent,
isIOS = userAgent.match(regExp.ios),
isMobileChrome = userAgent.match(regExp.mobileChrome)
;
if(isIOS && !isMobileChrome) {
module.verbose('Browser was found to be iOS', userAgent);
return true;
}
else {
return false;
}
},
mobile: function() {
var
userAgent = navigator.userAgent,
isMobile = userAgent.match(regExp.mobile)
;
if(isMobile) {
module.verbose('Browser was found to be mobile', userAgent);
return true;
}
else {
module.verbose('Browser is not mobile, using regular transition', userAgent);
return false;
}
},
hidden: function() {
return !module.is.visible();
},
visible: function() {
return $module.hasClass(className.visible);
},
// alias
open: function() {
return module.is.visible();
},
closed: function() {
return module.is.hidden();
},
vertical: function() {
return $module.hasClass(className.top);
},
animating: function() {
return $context.hasClass(className.animating);
},
rtl: function () {
if(module.cache.rtl === undefined) {
module.cache.rtl = $module.attr('dir') === 'rtl' || $module.css('direction') === 'rtl';
}
return module.cache.rtl;
}
},
setting: function(name, value) {
module.debug('Changing setting', name, value);
if( $.isPlainObject(name) ) {
$.extend(true, settings, name);
}
else if(value !== undefined) {
if($.isPlainObject(settings[name])) {
$.extend(true, settings[name], value);
}
else {
settings[name] = value;
}
}
else {
return settings[name];
}
},
internal: function(name, value) {
if( $.isPlainObject(name) ) {
$.extend(true, module, name);
}
else if(value !== undefined) {
module[name] = value;
}
else {
return module[name];
}
},
debug: function() {
if(!settings.silent && settings.debug) {
if(settings.performance) {
module.performance.log(arguments);
}
else {
module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
module.debug.apply(console, arguments);
}
}
},
verbose: function() {
if(!settings.silent && settings.verbose && settings.debug) {
if(settings.performance) {
module.performance.log(arguments);
}
else {
module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
module.verbose.apply(console, arguments);
}
}
},
error: function() {
if(!settings.silent) {
module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
module.error.apply(console, arguments);
}
},
performance: {
log: function(message) {
var
currentTime,
executionTime,
previousTime
;
if(settings.performance) {
currentTime = new Date().getTime();
previousTime = time || currentTime;
executionTime = currentTime - previousTime;
time = currentTime;
performance.push({
'Name' : message[0],
'Arguments' : [].slice.call(message, 1) || '',
'Element' : element,
'Execution Time' : executionTime
});
}
clearTimeout(module.performance.timer);
module.performance.timer = setTimeout(module.performance.display, 500);
},
display: function() {
var
title = settings.name + ':',
totalTime = 0
;
time = false;
clearTimeout(module.performance.timer);
$.each(performance, function(index, data) {
totalTime += data['Execution Time'];
});
title += ' ' + totalTime + 'ms';
if(moduleSelector) {
title += ' \'' + moduleSelector + '\'';
}
if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
console.groupCollapsed(title);
if(console.table) {
console.table(performance);
}
else {
$.each(performance, function(index, data) {
console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
});
}
console.groupEnd();
}
performance = [];
}
},
invoke: function(query, passedArguments, context) {
var
object = instance,
maxDepth,
found,
response
;
passedArguments = passedArguments || queryArguments;
context = element || context;
if(typeof query == 'string' && object !== undefined) {
query = query.split(/[\. ]/);
maxDepth = query.length - 1;
$.each(query, function(depth, value) {
var camelCaseValue = (depth != maxDepth)
? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
: query
;
if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
object = object[camelCaseValue];
}
else if( object[camelCaseValue] !== undefined ) {
found = object[camelCaseValue];
return false;
}
else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
object = object[value];
}
else if( object[value] !== undefined ) {
found = object[value];
return false;
}
else {
module.error(error.method, query);
return false;
}
});
}
if ( $.isFunction( found ) ) {
response = found.apply(context, passedArguments);
}
else if(found !== undefined) {
response = found;
}
if(Array.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.invoke('destroy');
}
module.initialize();
}
});
return (returnedValue !== undefined)
? returnedValue
: this
;
};
$.fn.sidebar.settings = {
name : 'Sidebar',
namespace : 'sidebar',
silent : false,
debug : false,
verbose : false,
performance : true,
transition : 'auto',
mobileTransition : 'auto',
defaultTransition : {
computer: {
left : 'uncover',
right : 'uncover',
top : 'overlay',
bottom : 'overlay'
},
mobile: {
left : 'uncover',
right : 'uncover',
top : 'overlay',
bottom : 'overlay'
}
},
context : 'body',
exclusive : false,
closable : true,
dimPage : true,
scrollLock : false,
returnScroll : false,
delaySetup : false,
duration : 500,
onChange : function(){},
onShow : function(){},
onHide : function(){},
onHidden : function(){},
onVisible : function(){},
className : {
active : 'active',
animating : 'animating',
dimmed : 'dimmed',
ios : 'ios',
pushable : 'pushable',
pushed : 'pushed',
right : 'right',
top : 'top',
left : 'left',
bottom : 'bottom',
visible : 'visible'
},
selector: {
fixed : '.fixed',
omitted : 'script, link, style, .ui.modal, .ui.dimmer, .ui.nag, .ui.fixed',
pusher : '.pusher',
sidebar : '.ui.sidebar'
},
regExp: {
ios : /(iPad|iPhone|iPod)/g,
mobileChrome : /(CriOS)/g,
mobile : /Mobile|iP(hone|od|ad)|Android|BlackBerry|IEMobile|Kindle|NetFront|Silk-Accelerated|(hpw|web)OS|Fennec|Minimo|Opera M(obi|ini)|Blazer|Dolfin|Dolphin|Skyfire|Zune/g
},
error : {
method : 'The method you called is not defined.',
pusher : 'Had to add pusher element. For optimal performance make sure body content is inside a pusher element',
movedSidebar : 'Had to move sidebar. For optimal performance make sure sidebar and pusher are direct children of your body tag',
overlay : 'The overlay setting is no longer supported, use animation: overlay',
notFound : 'There were no elements that matched the specified selector'
}
};
})( jQuery, window, document );
/*!
* # Fomantic-UI 2.8.8 - Tab
* http://github.com/fomantic/Fomantic-UI/
*
*
* Released under the MIT license
* http://opensource.org/licenses/MIT
*
*/
;(function ($, window, document, undefined) {
'use strict';
$.isWindow = $.isWindow || function(obj) {
return obj != null && obj === obj.window;
};
$.isFunction = $.isFunction || function(obj) {
return typeof obj === "function" && typeof obj.nodeType !== "number";
};
window = (typeof window != 'undefined' && window.Math == Math)
? window
: (typeof self != 'undefined' && self.Math == Math)
? self
: Function('return this')()
;
$.fn.tab = function(parameters) {
var
// use window context if none specified
$allModules = $.isFunction(this)
? $(window)
: $(this),
moduleSelector = $allModules.selector || '',
time = new Date().getTime(),
performance = [],
query = arguments[0],
methodInvoked = (typeof query == 'string'),
queryArguments = [].slice.call(arguments, 1),
initializedHistory = false,
returnedValue
;
$allModules
.each(function() {
var
settings = ( $.isPlainObject(parameters) )
? $.extend(true, {}, $.fn.tab.settings, parameters)
: $.extend({}, $.fn.tab.settings),
className = settings.className,
metadata = settings.metadata,
selector = settings.selector,
error = settings.error,
regExp = settings.regExp,
eventNamespace = '.' + settings.namespace,
moduleNamespace = 'module-' + settings.namespace,
$module = $(this),
$context,
$tabs,
cache = {},
firstLoad = true,
recursionDepth = 0,
element = this,
instance = $module.data(moduleNamespace),
activeTabPath,
parameterArray,
module,
historyEvent
;
module = {
initialize: function() {
module.debug('Initializing tab menu item', $module);
module.fix.callbacks();
module.determineTabs();
module.debug('Determining tabs', settings.context, $tabs);
// set up automatic routing
if(settings.auto) {
module.set.auto();
}
module.bind.events();
if(settings.history && !initializedHistory) {
module.initializeHistory();
initializedHistory = true;
}
if(settings.autoTabActivation && instance === undefined && module.determine.activeTab() == null) {
module.debug('No active tab detected, setting first tab active', module.get.initialPath());
module.changeTab(settings.autoTabActivation === true ? module.get.initialPath() : settings.autoTabActivation);
};
module.instantiate();
},
instantiate: function () {
module.verbose('Storing instance of module', module);
instance = module;
$module
.data(moduleNamespace, module)
;
},
destroy: function() {
module.debug('Destroying tabs', $module);
$module
.removeData(moduleNamespace)
.off(eventNamespace)
;
},
bind: {
events: function() {
// if using $.tab don't add events
if( !$.isWindow( element ) ) {
module.debug('Attaching tab activation events to element', $module);
$module
.on('click' + eventNamespace, module.event.click)
;
}
}
},
determineTabs: function() {
var
$reference
;
// determine tab context
if(settings.context === 'parent') {
if($module.closest(selector.ui).length > 0) {
$reference = $module.closest(selector.ui);
module.verbose('Using closest UI element as parent', $reference);
}
else {
$reference = $module;
}
$context = $reference.parent();
module.verbose('Determined parent element for creating context', $context);
}
else if(settings.context) {
$context = $(settings.context);
module.verbose('Using selector for tab context', settings.context, $context);
}
else {
$context = $('body');
}
// find tabs
if(settings.childrenOnly) {
$tabs = $context.children(selector.tabs);
module.debug('Searching tab context children for tabs', $context, $tabs);
}
else {
$tabs = $context.find(selector.tabs);
module.debug('Searching tab context for tabs', $context, $tabs);
}
},
fix: {
callbacks: function() {
if( $.isPlainObject(parameters) && (parameters.onTabLoad || parameters.onTabInit) ) {
if(parameters.onTabLoad) {
parameters.onLoad = parameters.onTabLoad;
delete parameters.onTabLoad;
module.error(error.legacyLoad, parameters.onLoad);
}
if(parameters.onTabInit) {
parameters.onFirstLoad = parameters.onTabInit;
delete parameters.onTabInit;
module.error(error.legacyInit, parameters.onFirstLoad);
}
settings = $.extend(true, {}, $.fn.tab.settings, parameters);
}
}
},
initializeHistory: function() {
module.debug('Initializing page state');
if( $.address === undefined ) {
module.error(error.state);
return false;
}
else {
if(settings.historyType == 'state') {
module.debug('Using HTML5 to manage state');
if(settings.path !== false) {
$.address
.history(true)
.state(settings.path)
;
}
else {
module.error(error.path);
return false;
}
}
$.address
.bind('change', module.event.history.change)
;
}
},
event: {
click: function(event) {
var
tabPath = $(this).data(metadata.tab)
;
if(tabPath !== undefined) {
if(settings.history) {
module.verbose('Updating page state', event);
$.address.value(tabPath);
}
else {
module.verbose('Changing tab', event);
module.changeTab(tabPath);
}
event.preventDefault();
}
else {
module.debug('No tab specified');
}
},
history: {
change: function(event) {
var
tabPath = event.pathNames.join('/') || module.get.initialPath(),
pageTitle = settings.templates.determineTitle(tabPath) || false
;
module.performance.display();
module.debug('History change event', tabPath, event);
historyEvent = event;
if(tabPath !== undefined) {
module.changeTab(tabPath);
}
if(pageTitle) {
$.address.title(pageTitle);
}
}
}
},
refresh: function() {
if(activeTabPath) {
module.debug('Refreshing tab', activeTabPath);
module.changeTab(activeTabPath);
}
},
cache: {
read: function(cacheKey) {
return (cacheKey !== undefined)
? cache[cacheKey]
: false
;
},
add: function(cacheKey, content) {
cacheKey = cacheKey || activeTabPath;
module.debug('Adding cached content for', cacheKey);
cache[cacheKey] = content;
},
remove: function(cacheKey) {
cacheKey = cacheKey || activeTabPath;
module.debug('Removing cached content for', cacheKey);
delete cache[cacheKey];
}
},
escape: {
string: function(text) {
text = String(text);
return text.replace(regExp.escape, '\\$&');
}
},
set: {
auto: function() {
var
url = (typeof settings.path == 'string')
? settings.path.replace(/\/$/, '') + '/{$tab}'
: '/{$tab}'
;
module.verbose('Setting up automatic tab retrieval from server', url);
if($.isPlainObject(settings.apiSettings)) {
settings.apiSettings.url = url;
}
else {
settings.apiSettings = {
url: url
};
}
},
loading: function(tabPath) {
var
$tab = module.get.tabElement(tabPath),
isLoading = $tab.hasClass(className.loading)
;
if(!isLoading) {
module.verbose('Setting loading state for', $tab);
$tab
.addClass(className.loading)
.siblings($tabs)
.removeClass(className.active + ' ' + className.loading)
;
if($tab.length > 0) {
settings.onRequest.call($tab[0], tabPath);
}
}
},
state: function(state) {
$.address.value(state);
}
},
changeTab: function(tabPath) {
var
pushStateAvailable = (window.history && window.history.pushState),
shouldIgnoreLoad = (pushStateAvailable && settings.ignoreFirstLoad && firstLoad),
remoteContent = (settings.auto || $.isPlainObject(settings.apiSettings) ),
// only add default path if not remote content
pathArray = (remoteContent && !shouldIgnoreLoad)
? module.utilities.pathToArray(tabPath)
: module.get.defaultPathArray(tabPath)
;
tabPath = module.utilities.arrayToPath(pathArray);
$.each(pathArray, function(index, tab) {
var
currentPathArray = pathArray.slice(0, index + 1),
currentPath = module.utilities.arrayToPath(currentPathArray),
isTab = module.is.tab(currentPath),
isLastIndex = (index + 1 == pathArray.length),
$tab = module.get.tabElement(currentPath),
$anchor,
nextPathArray,
nextPath,
isLastTab
;
module.verbose('Looking for tab', tab);
if(isTab) {
module.verbose('Tab was found', tab);
// scope up
activeTabPath = currentPath;
parameterArray = module.utilities.filterArray(pathArray, currentPathArray);
if(isLastIndex) {
isLastTab = true;
}
else {
nextPathArray = pathArray.slice(0, index + 2);
nextPath = module.utilities.arrayToPath(nextPathArray);
isLastTab = ( !module.is.tab(nextPath) );
if(isLastTab) {
module.verbose('Tab parameters found', nextPathArray);
}
}
if(isLastTab && remoteContent) {
if(!shouldIgnoreLoad) {
module.activate.navigation(currentPath);
module.fetch.content(currentPath, tabPath);
}
else {
module.debug('Ignoring remote content on first tab load', currentPath);
firstLoad = false;
module.cache.add(tabPath, $tab.html());
module.activate.all(currentPath);
settings.onFirstLoad.call($tab[0], currentPath, parameterArray, historyEvent);
settings.onLoad.call($tab[0], currentPath, parameterArray, historyEvent);
}
return false;
}
else {
module.debug('Opened local tab', currentPath);
module.activate.all(currentPath);
if( !module.cache.read(currentPath) ) {
module.cache.add(currentPath, true);
module.debug('First time tab loaded calling tab init');
settings.onFirstLoad.call($tab[0], currentPath, parameterArray, historyEvent);
}
settings.onLoad.call($tab[0], currentPath, parameterArray, historyEvent);
}
}
else if(tabPath.search('/') == -1 && tabPath !== '') {
// look for in page anchor
tabPath = module.escape.string(tabPath);
$anchor = $('#' + tabPath + ', a[name="' + tabPath + '"]');
currentPath = $anchor.closest('[data-tab]').data(metadata.tab);
$tab = module.get.tabElement(currentPath);
// if anchor exists use parent tab
if($anchor && $anchor.length > 0 && currentPath) {
module.debug('Anchor link used, opening parent tab', $tab, $anchor);
if( !$tab.hasClass(className.active) ) {
setTimeout(function() {
module.scrollTo($anchor);
}, 0);
}
module.activate.all(currentPath);
if( !module.cache.read(currentPath) ) {
module.cache.add(currentPath, true);
module.debug('First time tab loaded calling tab init');
settings.onFirstLoad.call($tab[0], currentPath, parameterArray, historyEvent);
}
settings.onLoad.call($tab[0], currentPath, parameterArray, historyEvent);
return false;
}
}
else {
module.error(error.missingTab, $module, $context, currentPath);
return false;
}
});
},
scrollTo: function($element) {
var
scrollOffset = ($element && $element.length > 0)
? $element.offset().top
: false
;
if(scrollOffset !== false) {
module.debug('Forcing scroll to an in-page link in a hidden tab', scrollOffset, $element);
$(document).scrollTop(scrollOffset);
}
},
update: {
content: function(tabPath, html, evaluateScripts) {
var
$tab = module.get.tabElement(tabPath),
tab = $tab[0]
;
evaluateScripts = (evaluateScripts !== undefined)
? evaluateScripts
: settings.evaluateScripts
;
if(typeof settings.cacheType == 'string' && settings.cacheType.toLowerCase() == 'dom' && typeof html !== 'string') {
$tab
.empty()
.append($(html).clone(true))
;
}
else {
if(evaluateScripts) {
module.debug('Updating HTML and evaluating inline scripts', tabPath, html);
$tab.html(html);
}
else {
module.debug('Updating HTML', tabPath, html);
tab.innerHTML = html;
}
}
}
},
fetch: {
content: function(tabPath, fullTabPath) {
var
$tab = module.get.tabElement(tabPath),
apiSettings = {
dataType : 'html',
encodeParameters : false,
on : 'now',
cache : settings.alwaysRefresh,
headers : {
'X-Remote': true
},
onSuccess : function(response) {
if(settings.cacheType == 'response') {
module.cache.add(fullTabPath, response);
}
module.update.content(tabPath, response);
if(tabPath == activeTabPath) {
module.debug('Content loaded', tabPath);
module.activate.tab(tabPath);
}
else {
module.debug('Content loaded in background', tabPath);
}
settings.onFirstLoad.call($tab[0], tabPath, parameterArray, historyEvent);
settings.onLoad.call($tab[0], tabPath, parameterArray, historyEvent);
if(settings.loadOnce) {
module.cache.add(fullTabPath, true);
}
else if(typeof settings.cacheType == 'string' && settings.cacheType.toLowerCase() == 'dom' && $tab.children().length > 0) {
setTimeout(function() {
var
$clone = $tab.children().clone(true)
;
$clone = $clone.not('script');
module.cache.add(fullTabPath, $clone);
}, 0);
}
else {
module.cache.add(fullTabPath, $tab.html());
}
},
urlData: {
tab: fullTabPath
}
},
request = $tab.api('get request') || false,
existingRequest = ( request && request.state() === 'pending' ),
requestSettings,
cachedContent
;
fullTabPath = fullTabPath || tabPath;
cachedContent = module.cache.read(fullTabPath);
if(settings.cache && cachedContent) {
module.activate.tab(tabPath);
module.debug('Adding cached content', fullTabPath);
if(!settings.loadOnce) {
if(settings.evaluateScripts == 'once') {
module.update.content(tabPath, cachedContent, false);
}
else {
module.update.content(tabPath, cachedContent);
}
}
settings.onLoad.call($tab[0], tabPath, parameterArray, historyEvent);
}
else if(existingRequest) {
module.set.loading(tabPath);
module.debug('Content is already loading', fullTabPath);
}
else if($.api !== undefined) {
requestSettings = $.extend(true, {}, settings.apiSettings, apiSettings);
module.debug('Retrieving remote content', fullTabPath, requestSettings);
module.set.loading(tabPath);
$tab.api(requestSettings);
}
else {
module.error(error.api);
}
}
},
activate: {
all: function(tabPath) {
module.activate.tab(tabPath);
module.activate.navigation(tabPath);
},
tab: function(tabPath) {
var
$tab = module.get.tabElement(tabPath),
$deactiveTabs = (settings.deactivate == 'siblings')
? $tab.siblings($tabs)
: $tabs.not($tab),
isActive = $tab.hasClass(className.active)
;
module.verbose('Showing tab content for', $tab);
if(!isActive) {
$tab
.addClass(className.active)
;
$deactiveTabs
.removeClass(className.active + ' ' + className.loading)
;
if($tab.length > 0) {
settings.onVisible.call($tab[0], tabPath);
}
}
},
navigation: function(tabPath) {
var
$navigation = module.get.navElement(tabPath),
$deactiveNavigation = (settings.deactivate == 'siblings')
? $navigation.siblings($allModules)
: $allModules.not($navigation),
isActive = $navigation.hasClass(className.active)
;
module.verbose('Activating tab navigation for', $navigation, tabPath);
if(!isActive) {
$navigation
.addClass(className.active)
;
$deactiveNavigation
.removeClass(className.active + ' ' + className.loading)
;
}
}
},
deactivate: {
all: function() {
module.deactivate.navigation();
module.deactivate.tabs();
},
navigation: function() {
$allModules
.removeClass(className.active)
;
},
tabs: function() {
$tabs
.removeClass(className.active + ' ' + className.loading)
;
}
},
is: {
tab: function(tabName) {
return (tabName !== undefined)
? ( module.get.tabElement(tabName).length > 0 )
: false
;
}
},
get: {
initialPath: function() {
return $allModules.eq(0).data(metadata.tab) || $tabs.eq(0).data(metadata.tab);
},
path: function() {
return $.address.value();
},
// adds default tabs to tab path
defaultPathArray: function(tabPath) {
return module.utilities.pathToArray( module.get.defaultPath(tabPath) );
},
defaultPath: function(tabPath) {
var
$defaultNav = $allModules.filter('[data-' + metadata.tab + '^="' + module.escape.string(tabPath) + '/"]').eq(0),
defaultTab = $defaultNav.data(metadata.tab) || false
;
if( defaultTab ) {
module.debug('Found default tab', defaultTab);
if(recursionDepth < settings.maxDepth) {
recursionDepth++;
return module.get.defaultPath(defaultTab);
}
module.error(error.recursion);
}
else {
module.debug('No default tabs found for', tabPath, $tabs);
}
recursionDepth = 0;
return tabPath;
},
navElement: function(tabPath) {
tabPath = tabPath || activeTabPath;
return $allModules.filter('[data-' + metadata.tab + '="' + module.escape.string(tabPath) + '"]');
},
tabElement: function(tabPath) {
var
$fullPathTab,
$simplePathTab,
tabPathArray,
lastTab
;
tabPath = tabPath || activeTabPath;
tabPathArray = module.utilities.pathToArray(tabPath);
lastTab = module.utilities.last(tabPathArray);
$fullPathTab = $tabs.filter('[data-' + metadata.tab + '="' + module.escape.string(tabPath) + '"]');
$simplePathTab = $tabs.filter('[data-' + metadata.tab + '="' + module.escape.string(lastTab) + '"]');
return ($fullPathTab.length > 0)
? $fullPathTab
: $simplePathTab
;
},
tab: function() {
return activeTabPath;
}
},
determine: {
activeTab: function() {
var activeTab = null;
$tabs.each(function(_index, tab) {
var $tab = $(tab);
if( $tab.hasClass(className.active) ) {
var
tabPath = $(this).data(metadata.tab),
$anchor = $allModules.filter('[data-' + metadata.tab + '="' + module.escape.string(tabPath) + '"]')
;
if( $anchor.hasClass(className.active) ) {
activeTab = tabPath;
}
}
});
return activeTab;
}
},
utilities: {
filterArray: function(keepArray, removeArray) {
return $.grep(keepArray, function(keepValue) {
return ( $.inArray(keepValue, removeArray) == -1);
});
},
last: function(array) {
return Array.isArray(array)
? array[ array.length - 1]
: false
;
},
pathToArray: function(pathName) {
if(pathName === undefined) {
pathName = activeTabPath;
}
return typeof pathName == 'string'
? pathName.split('/')
: [pathName]
;
},
arrayToPath: function(pathArray) {
return Array.isArray(pathArray)
? pathArray.join('/')
: false
;
}
},
setting: function(name, value) {
module.debug('Changing setting', name, value);
if( $.isPlainObject(name) ) {
$.extend(true, settings, name);
}
else if(value !== undefined) {
if($.isPlainObject(settings[name])) {
$.extend(true, settings[name], value);
}
else {
settings[name] = value;
}
}
else {
return settings[name];
}
},
internal: function(name, value) {
if( $.isPlainObject(name) ) {
$.extend(true, module, name);
}
else if(value !== undefined) {
module[name] = value;
}
else {
return module[name];
}
},
debug: function() {
if(!settings.silent && settings.debug) {
if(settings.performance) {
module.performance.log(arguments);
}
else {
module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
module.debug.apply(console, arguments);
}
}
},
verbose: function() {
if(!settings.silent && settings.verbose && settings.debug) {
if(settings.performance) {
module.performance.log(arguments);
}
else {
module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
module.verbose.apply(console, arguments);
}
}
},
error: function() {
if(!settings.silent) {
module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
module.error.apply(console, arguments);
}
},
performance: {
log: function(message) {
var
currentTime,
executionTime,
previousTime
;
if(settings.performance) {
currentTime = new Date().getTime();
previousTime = time || currentTime;
executionTime = currentTime - previousTime;
time = currentTime;
performance.push({
'Name' : message[0],
'Arguments' : [].slice.call(message, 1) || '',
'Element' : element,
'Execution Time' : executionTime
});
}
clearTimeout(module.performance.timer);
module.performance.timer = setTimeout(module.performance.display, 500);
},
display: function() {
var
title = settings.name + ':',
totalTime = 0
;
time = false;
clearTimeout(module.performance.timer);
$.each(performance, function(index, data) {
totalTime += data['Execution Time'];
});
title += ' ' + totalTime + 'ms';
if(moduleSelector) {
title += ' \'' + moduleSelector + '\'';
}
if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
console.groupCollapsed(title);
if(console.table) {
console.table(performance);
}
else {
$.each(performance, function(index, data) {
console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
});
}
console.groupEnd();
}
performance = [];
}
},
invoke: function(query, passedArguments, context) {
var
object = instance,
maxDepth,
found,
response
;
passedArguments = passedArguments || queryArguments;
context = element || context;
if(typeof query == 'string' && object !== undefined) {
query = query.split(/[\. ]/);
maxDepth = query.length - 1;
$.each(query, function(depth, value) {
var camelCaseValue = (depth != maxDepth)
? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
: query
;
if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
object = object[camelCaseValue];
}
else if( object[camelCaseValue] !== undefined ) {
found = object[camelCaseValue];
return false;
}
else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
object = object[value];
}
else if( object[value] !== undefined ) {
found = object[value];
return false;
}
else {
module.error(error.method, query);
return false;
}
});
}
if ( $.isFunction( found ) ) {
response = found.apply(context, passedArguments);
}
else if(found !== undefined) {
response = found;
}
if(Array.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
;
};
// shortcut for tabbed content with no defined navigation
$.tab = function() {
$(window).tab.apply(this, arguments);
};
$.fn.tab.settings = {
name : 'Tab',
namespace : 'tab',
silent : false,
debug : false,
verbose : false,
performance : true,
auto : false, // uses pjax style endpoints fetching content from same url with remote-content headers
history : false, // use browser history
historyType : 'hash', // #/ or html5 state
path : false, // base path of url
context : false, // specify a context that tabs must appear inside
childrenOnly : false, // use only tabs that are children of context
maxDepth : 25, // max depth a tab can be nested
deactivate : 'siblings', // whether tabs should deactivate sibling menu elements or all elements initialized together
alwaysRefresh : false, // load tab content new every tab click
cache : true, // cache the content requests to pull locally
loadOnce : false, // Whether tab data should only be loaded once when using remote content
cacheType : 'response', // Whether to cache exact response, or to html cache contents after scripts execute
ignoreFirstLoad : false, // don't load remote content on first load
apiSettings : false, // settings for api call
evaluateScripts : 'once', // whether inline scripts should be parsed (true/false/once). Once will not re-evaluate on cached content
autoTabActivation: true, // whether a non existing active tab will auto activate the first available tab
onFirstLoad : function(tabPath, parameterArray, historyEvent) {}, // called first time loaded
onLoad : function(tabPath, parameterArray, historyEvent) {}, // called on every load
onVisible : function(tabPath, parameterArray, historyEvent) {}, // called every time tab visible
onRequest : function(tabPath, parameterArray, historyEvent) {}, // called ever time a tab beings loading remote content
templates : {
determineTitle: function(tabArray) {} // returns page title for path
},
error: {
api : 'You attempted to load content without API module',
method : 'The method you called is not defined',
missingTab : 'Activated tab cannot be found. Tabs are case-sensitive.',
noContent : 'The tab you specified is missing a content url.',
path : 'History enabled, but no path was specified',
recursion : 'Max recursive depth reached',
legacyInit : 'onTabInit has been renamed to onFirstLoad in 2.0, please adjust your code.',
legacyLoad : 'onTabLoad has been renamed to onLoad in 2.0. Please adjust your code',
state : 'History requires Asual\'s Address library '
},
regExp : {
escape : /[-[\]{}()*+?.,\\^$|#\s:=@]/g
},
metadata : {
tab : 'tab',
loaded : 'loaded',
promise: 'promise'
},
className : {
loading : 'loading',
active : 'active'
},
selector : {
tabs : '.ui.tab',
ui : '.ui'
}
};
})( jQuery, window, document );
/*!
* # Fomantic-UI 2.8.8 - Toast
* http://github.com/fomantic/Fomantic-UI/
*
*
* Released under the MIT license
* http://opensource.org/licenses/MIT
*
*/
;(function ($, window, document, undefined) {
'use strict';
$.isFunction = $.isFunction || function(obj) {
return typeof obj === "function" && typeof obj.nodeType !== "number";
};
window = (typeof window != 'undefined' && window.Math == Math)
? window
: (typeof self != 'undefined' && self.Math == Math)
? self
: Function('return this')()
;
$.fn.toast = function(parameters) {
var
$allModules = $(this),
moduleSelector = $allModules.selector || '',
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.toast.settings, parameters)
: $.extend({}, $.fn.toast.settings),
className = settings.className,
selector = settings.selector,
error = settings.error,
namespace = settings.namespace,
fields = settings.fields,
eventNamespace = '.' + namespace,
moduleNamespace = namespace + '-module',
$module = $(this),
$toastBox,
$toast,
$actions,
$progress,
$progressBar,
$animationObject,
$close,
$context = (settings.context)
? $(settings.context)
: $('body'),
isToastComponent = $module.hasClass('toast') || $module.hasClass('message') || $module.hasClass('card'),
element = this,
instance = isToastComponent ? $module.data(moduleNamespace) : undefined,
module
;
module = {
initialize: function() {
module.verbose('Initializing element');
if (!module.has.container()) {
module.create.container();
}
if(isToastComponent || settings.message !== '' || settings.title !== '' || module.get.iconClass() !== '' || settings.showImage || module.has.configActions()) {
if(typeof settings.showProgress !== 'string' || [className.top,className.bottom].indexOf(settings.showProgress) === -1 ) {
settings.showProgress = false;
}
module.create.toast();
if(settings.closeOnClick && (settings.closeIcon || $($toast).find(selector.input).length > 0 || module.has.configActions())){
settings.closeOnClick = false;
}
if(!settings.closeOnClick) {
$toastBox.addClass(className.unclickable);
}
module.bind.events();
}
module.instantiate();
if($toastBox) {
module.show();
}
},
instantiate: function() {
module.verbose('Storing instance of toast');
instance = module;
$module
.data(moduleNamespace, instance)
;
},
destroy: function() {
if($toastBox) {
module.debug('Removing toast', $toastBox);
module.unbind.events();
$toastBox.remove();
$toastBox = undefined;
$toast = undefined;
$animationObject = undefined;
settings.onRemove.call($toastBox, element);
$progress = undefined;
$progressBar = undefined;
$close = undefined;
}
$module
.removeData(moduleNamespace)
;
},
show: function(callback) {
callback = callback || function(){};
module.debug('Showing toast');
if(settings.onShow.call($toastBox, element) === false) {
module.debug('onShow callback returned false, cancelling toast animation');
return;
}
module.animate.show(callback);
},
close: function(callback) {
callback = callback || function(){};
module.remove.visible();
module.unbind.events();
module.animate.close(callback);
},
create: {
container: function() {
module.verbose('Creating container');
$context.append($('',{class: settings.position + ' ' + className.container + ' ' +(settings.horizontal ? className.horizontal : '')}));
},
toast: function() {
$toastBox = $('', {class: className.box});
var iconClass = module.get.iconClass();
if (!isToastComponent) {
module.verbose('Creating toast');
$toast = $('');
var $content = $('', {class: className.content});
if (iconClass !== '') {
$toast.append($('', {class: iconClass + ' ' + className.icon}));
}
if (settings.showImage) {
$toast.append($('', {
class: className.image + ' ' + settings.classImage,
src: settings.showImage
}));
}
if (settings.title !== '') {
$content.append($('', {
class: className.title,
text: settings.title
}));
}
$content.append($('', {class: className.message, html: module.helpers.escape(settings.message, settings.preserveHTML)}));
$toast
.addClass(settings.class + ' ' + className.toast)
.append($content)
;
$toast.css('opacity', settings.opacity);
if (settings.closeIcon) {
$close = $('', {class: className.close + ' ' + (typeof settings.closeIcon === 'string' ? settings.closeIcon : '')});
if($close.hasClass(className.left)) {
$toast.prepend($close);
} else {
$toast.append($close);
}
}
} else {
$toast = settings.cloneModule ? $module.clone().removeAttr('id') : $module;
$close = $toast.find('> i'+module.helpers.toClass(className.close));
settings.closeIcon = ($close.length > 0);
if (iconClass !== '') {
$toast.find(selector.icon).attr('class',iconClass + ' ' + className.icon);
}
if (settings.showImage) {
$toast.find(selector.image).attr('src',settings.showImage);
}
if (settings.title !== '') {
$toast.find(selector.title).html(module.helpers.escape(settings.title, settings.preserveHTML));
}
if (settings.message !== '') {
$toast.find(selector.message).html(module.helpers.escape(settings.message, settings.preserveHTML));
}
}
if ($toast.hasClass(className.compact)) {
settings.compact = true;
}
if ($toast.hasClass('card')) {
settings.compact = false;
}
$actions = $toast.find('.actions');
if (module.has.configActions()) {
if ($actions.length === 0) {
$actions = $('', {class: className.actions + ' ' + (settings.classActions || '')}).appendTo($toast);
}
if($toast.hasClass('card') && !$actions.hasClass(className.attached)) {
$actions.addClass(className.extraContent);
if($actions.hasClass(className.vertical)) {
$actions.removeClass(className.vertical);
module.error(error.verticalCard);
}
}
settings.actions.forEach(function (el) {
var icon = el[fields.icon] ? '' : '',
text = module.helpers.escape(el[fields.text] || '', settings.preserveHTML),
cls = module.helpers.deQuote(el[fields.class] || ''),
click = el[fields.click] && $.isFunction(el[fields.click]) ? el[fields.click] : function () {};
$actions.append($('', {
html: icon + text,
class: className.button + ' ' + cls,
click: function () {
if (click.call(element, $module) === false) {
return;
}
module.close();
}
}));
});
}
if ($actions && $actions.hasClass(className.vertical)) {
$toast.addClass(className.vertical);
}
if($actions.length > 0 && !$actions.hasClass(className.attached)) {
if ($actions && (!$actions.hasClass(className.basic) || $actions.hasClass(className.left))) {
$toast.addClass(className.actions);
}
}
if(settings.displayTime === 'auto'){
settings.displayTime = Math.max(settings.minDisplayTime, $toast.text().split(" ").length / settings.wordsPerMinute * 60000);
}
$toastBox.append($toast);
if($actions.length > 0 && $actions.hasClass(className.attached)) {
$actions.addClass(className.buttons);
$actions.detach();
$toast.addClass(className.attached);
if (!$actions.hasClass(className.vertical)) {
if ($actions.hasClass(className.top)) {
$toastBox.prepend($actions);
$toast.addClass(className.bottom);
} else {
$toastBox.append($actions);
$toast.addClass(className.top);
}
} else {
$toast.wrap(
$('',{
class:className.vertical + ' ' +
className.attached + ' ' +
(settings.compact ? className.compact : '')
})
);
if($actions.hasClass(className.left)) {
$toast.addClass(className.left).parent().addClass(className.left).prepend($actions);
} else {
$toast.parent().append($actions);
}
}
}
if($module !== $toast) {
$module = $toast;
element = $toast[0];
}
if(settings.displayTime > 0) {
var progressingClass = className.progressing+' '+(settings.pauseOnHover ? className.pausable:'');
if (!!settings.showProgress) {
$progress = $('', {
class: className.progress + ' ' + (settings.classProgress || settings.class),
'data-percent': ''
});
if(!settings.classProgress) {
if ($toast.hasClass('toast') && !$toast.hasClass(className.inverted)) {
$progress.addClass(className.inverted);
} else {
$progress.removeClass(className.inverted);
}
}
$progressBar = $('', {class: 'bar '+(settings.progressUp ? 'up ' : 'down ')+progressingClass});
$progress
.addClass(settings.showProgress)
.append($progressBar);
if ($progress.hasClass(className.top)) {
$toastBox.prepend($progress);
} else {
$toastBox.append($progress);
}
$progressBar.css('animation-duration', settings.displayTime / 1000 + 's');
}
$animationObject = $('',{class:'wait '+progressingClass});
$animationObject.css('animation-duration', settings.displayTime / 1000 + 's');
$animationObject.appendTo($toast);
}
if (settings.compact) {
$toastBox.addClass(className.compact);
$toast.addClass(className.compact);
if($progress) {
$progress.addClass(className.compact);
}
}
if (settings.newestOnTop) {
$toastBox.prependTo(module.get.container());
}
else {
$toastBox.appendTo(module.get.container());
}
}
},
bind: {
events: function() {
module.debug('Binding events to toast');
if(settings.closeOnClick || settings.closeIcon) {
(settings.closeIcon ? $close : $toast)
.on('click' + eventNamespace, module.event.click)
;
}
if($animationObject) {
$animationObject.on('animationend' + eventNamespace, module.close);
}
$toastBox
.on('click' + eventNamespace, selector.approve, module.event.approve)
.on('click' + eventNamespace, selector.deny, module.event.deny)
;
}
},
unbind: {
events: function() {
module.debug('Unbinding events to toast');
if(settings.closeOnClick || settings.closeIcon) {
(settings.closeIcon ? $close : $toast)
.off('click' + eventNamespace)
;
}
if($animationObject) {
$animationObject.off('animationend' + eventNamespace);
}
$toastBox
.off('click' + eventNamespace)
;
}
},
animate: {
show: function(callback) {
callback = $.isFunction(callback) ? callback : function(){};
if(settings.transition && module.can.useElement('transition') && $module.transition('is supported')) {
module.set.visible();
$toastBox
.transition({
animation : settings.transition.showMethod + ' in',
queue : false,
debug : settings.debug,
verbose : settings.verbose,
duration : settings.transition.showDuration,
onComplete : function() {
callback.call($toastBox, element);
settings.onVisible.call($toastBox, element);
}
})
;
}
},
close: function(callback) {
callback = $.isFunction(callback) ? callback : function(){};
module.debug('Closing toast');
if(settings.onHide.call($toastBox, element) === false) {
module.debug('onHide callback returned false, cancelling toast animation');
return;
}
if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
$toastBox
.transition({
animation : settings.transition.hideMethod + ' out',
queue : false,
duration : settings.transition.hideDuration,
debug : settings.debug,
verbose : settings.verbose,
interval : 50,
onBeforeHide: function(callback){
callback = $.isFunction(callback)?callback : function(){};
if(settings.transition.closeEasing !== ''){
if($toastBox) {
$toastBox.css('opacity', 0);
$toastBox.wrap('').parent().hide(settings.transition.closeDuration, settings.transition.closeEasing, function () {
if ($toastBox) {
$toastBox.parent().remove();
callback.call($toastBox);
}
});
}
} else {
callback.call($toastBox);
}
},
onComplete : function() {
callback.call($toastBox, element);
settings.onHidden.call($toastBox, element);
module.destroy();
}
})
;
}
else {
module.error(error.noTransition);
}
},
pause: function() {
$animationObject.css('animationPlayState','paused');
if($progressBar) {
$progressBar.css('animationPlayState', 'paused');
}
},
continue: function() {
$animationObject.css('animationPlayState','running');
if($progressBar) {
$progressBar.css('animationPlayState', 'running');
}
}
},
has: {
container: function() {
module.verbose('Determining if there is already a container');
return ($context.find(module.helpers.toClass(settings.position) + selector.container + (settings.horizontal ? module.helpers.toClass(className.horizontal) : '')).length > 0);
},
toast: function(){
return !!module.get.toast();
},
toasts: function(){
return module.get.toasts().length > 0;
},
configActions: function () {
return Array.isArray(settings.actions) && settings.actions.length > 0;
}
},
get: {
container: function() {
return ($context.find(module.helpers.toClass(settings.position) + selector.container)[0]);
},
toastBox: function() {
return $toastBox || null;
},
toast: function() {
return $toast || null;
},
toasts: function() {
return $(module.get.container()).find(selector.box);
},
iconClass: function() {
return typeof settings.showIcon === 'string' ? settings.showIcon : settings.showIcon && settings.icons[settings.class] ? settings.icons[settings.class] : '';
},
remainingTime: function() {
return $animationObject ? $animationObject.css('opacity') * settings.displayTime : 0;
}
},
set: {
visible: function() {
$toast.addClass(className.visible);
}
},
remove: {
visible: function() {
$toast.removeClass(className.visible);
}
},
event: {
click: function(event) {
if($(event.target).closest('a').length === 0) {
settings.onClick.call($toastBox, element);
module.close();
}
},
approve: function() {
if(settings.onApprove.call(element, $module) === false) {
module.verbose('Approve callback returned false cancelling close');
return;
}
module.close();
},
deny: function() {
if(settings.onDeny.call(element, $module) === false) {
module.verbose('Deny callback returned false cancelling close');
return;
}
module.close();
}
},
helpers: {
toClass: function(selector) {
var
classes = selector.split(' '),
result = ''
;
classes.forEach(function (element) {
result += '.' + element;
});
return result;
},
deQuote: function(string) {
return String(string).replace(/"/g,"");
},
escape: function(string, preserveHTML) {
if (preserveHTML){
return string;
}
var
badChars = /[<>"'`]/g,
shouldEscape = /[&<>"'`]/,
escape = {
"<": "<",
">": ">",
'"': """,
"'": "'",
"`": "`"
},
escapedChar = function(chr) {
return escape[chr];
}
;
if(shouldEscape.test(string)) {
string = string.replace(/&(?![a-z0-9#]{1,6};)/, "&");
return string.replace(badChars, escapedChar);
}
return string;
}
},
can: {
useElement: function(element){
if ($.fn[element] !== undefined) {
return true;
}
module.error(error.noElement.replace('{element}',element));
return false;
}
},
setting: function(name, value) {
module.debug('Changing setting', name, value);
if( $.isPlainObject(name) ) {
$.extend(true, settings, name);
}
else if(value !== undefined) {
if($.isPlainObject(settings[name])) {
$.extend(true, settings[name], value);
}
else {
settings[name] = value;
}
}
else {
return settings[name];
}
},
internal: function(name, value) {
if( $.isPlainObject(name) ) {
$.extend(true, module, name);
}
else if(value !== undefined) {
module[name] = value;
}
else {
return module[name];
}
},
debug: function() {
if(!settings.silent && settings.debug) {
if(settings.performance) {
module.performance.log(arguments);
}
else {
module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
module.debug.apply(console, arguments);
}
}
},
verbose: function() {
if(!settings.silent && settings.verbose && settings.debug) {
if(settings.performance) {
module.performance.log(arguments);
}
else {
module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
module.verbose.apply(console, arguments);
}
}
},
error: function() {
if(!settings.silent) {
module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
module.error.apply(console, arguments);
}
},
performance: {
log: function(message) {
var
currentTime,
executionTime,
previousTime
;
if(settings.performance) {
currentTime = new Date().getTime();
previousTime = time || currentTime;
executionTime = currentTime - previousTime;
time = currentTime;
performance.push({
'Name' : message[0],
'Arguments' : [].slice.call(message, 1) || '',
'Element' : element,
'Execution Time' : executionTime
});
}
clearTimeout(module.performance.timer);
module.performance.timer = setTimeout(module.performance.display, 500);
},
display: function() {
var
title = settings.name + ':',
totalTime = 0
;
time = false;
clearTimeout(module.performance.timer);
$.each(performance, function(index, data) {
totalTime += data['Execution Time'];
});
title += ' ' + totalTime + 'ms';
if(moduleSelector) {
title += ' \'' + moduleSelector + '\'';
}
if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
console.groupCollapsed(title);
if(console.table) {
console.table(performance);
}
else {
$.each(performance, function(index, data) {
console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
});
}
console.groupEnd();
}
performance = [];
}
},
invoke: function(query, passedArguments, context) {
var
object = instance,
maxDepth,
found,
response
;
passedArguments = passedArguments || queryArguments;
context = element || context;
if(typeof query == 'string' && object !== undefined) {
query = query.split(/[\. ]/);
maxDepth = query.length - 1;
$.each(query, function(depth, value) {
var camelCaseValue = (depth != maxDepth)
? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
: query
;
if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
object = object[camelCaseValue];
}
else if( object[camelCaseValue] !== undefined ) {
found = object[camelCaseValue];
return false;
}
else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
object = object[value];
}
else if( object[value] !== undefined ) {
found = object[value];
return false;
}
else {
module.error(error.method, query);
return false;
}
});
}
if ( $.isFunction( found ) ) {
response = found.apply(context, passedArguments);
}
else if(found !== undefined) {
response = found;
}
if(Array.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();
returnedValue = $module;
}
})
;
return (returnedValue !== undefined)
? returnedValue
: this
;
};
$.fn.toast.settings = {
name : 'Toast',
namespace : 'toast',
silent : false,
debug : false,
verbose : false,
performance : true,
context : 'body',
position : 'top right',
horizontal : false,
class : 'neutral',
classProgress : false,
classActions : false,
classImage : 'mini',
title : '',
message : '',
displayTime : 3000, // set to zero to require manually dismissal, otherwise hides on its own
minDisplayTime : 1000, // minimum displaytime in case displayTime is set to 'auto'
wordsPerMinute : 120,
showIcon : false,
newestOnTop : false,
showProgress : false,
pauseOnHover : true,
progressUp : false, //if true, the bar will start at 0% and increase to 100%
opacity : 1,
compact : true,
closeIcon : false,
closeOnClick : true,
cloneModule : true,
actions : false,
preserveHTML : true,
showImage : false,
// transition settings
transition : {
showMethod : 'scale',
showDuration : 500,
hideMethod : 'scale',
hideDuration : 500,
closeEasing : 'easeOutCubic', //Set to empty string to stack the closed toast area immediately (old behaviour)
closeDuration: 500
},
error: {
method : 'The method you called is not defined.',
noElement : 'This module requires ui {element}',
verticalCard : 'Vertical but not attached actions are not supported for card layout'
},
className : {
container : 'ui toast-container',
box : 'floating toast-box',
progress : 'ui attached active progress',
toast : 'ui toast',
icon : 'centered icon',
visible : 'visible',
content : 'content',
title : 'ui header',
message : 'message',
actions : 'actions',
extraContent : 'extra content',
button : 'ui button',
buttons : 'ui buttons',
close : 'close icon',
image : 'ui image',
vertical : 'vertical',
horizontal : 'horizontal',
attached : 'attached',
inverted : 'inverted',
compact : 'compact',
pausable : 'pausable',
progressing : 'progressing',
top : 'top',
bottom : 'bottom',
left : 'left',
basic : 'basic',
unclickable : 'unclickable'
},
icons : {
info : 'info',
success : 'checkmark',
warning : 'warning',
error : 'times'
},
selector : {
container : '.ui.toast-container',
box : '.toast-box',
toast : '.ui.toast',
title : '.header',
message : '.message:not(.ui)',
image : '> img.image, > .image > img',
icon : '> i.icon',
input : 'input:not([type="hidden"]), textarea, select, button, .ui.button, ui.dropdown',
approve : '.actions .positive, .actions .approve, .actions .ok',
deny : '.actions .negative, .actions .deny, .actions .cancel'
},
fields : {
class : 'class',
text : 'text',
icon : 'icon',
click : 'click'
},
// callbacks
onShow : function(){},
onVisible : function(){},
onClick : function(){},
onHide : function(){},
onHidden : function(){},
onRemove : function(){},
onApprove : function(){},
onDeny : function(){}
};
$.extend( $.easing, {
easeOutBounce: function (x, t, b, c, d) {
if ((t/=d) < (1/2.75)) {
return c*(7.5625*t*t) + b;
} else if (t < (2/2.75)) {
return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
} else if (t < (2.5/2.75)) {
return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
} else {
return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
}
},
easeOutCubic: function (t) {
return (--t)*t*t+1;
}
});
})( jQuery, window, document );
/*!
* # Fomantic-UI 2.8.8 - API
* http://github.com/fomantic/Fomantic-UI/
*
*
* Released under the MIT license
* http://opensource.org/licenses/MIT
*
*/
;(function ($, window, document, undefined) {
'use strict';
$.isWindow = $.isWindow || function(obj) {
return obj != null && obj === obj.window;
};
window = (typeof window != 'undefined' && window.Math == Math)
? window
: (typeof self != 'undefined' && self.Math == Math)
? self
: Function('return this')()
;
$.api = $.fn.api = function(parameters) {
var
// use window context if none specified
$allModules = $.isFunction(this)
? $(window)
: $(this),
moduleSelector = $allModules.selector || '',
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.api.settings, parameters)
: $.extend({}, $.fn.api.settings),
// internal aliases
namespace = settings.namespace,
metadata = settings.metadata,
selector = settings.selector,
error = settings.error,
className = settings.className,
// define namespaces for modules
eventNamespace = '.' + namespace,
moduleNamespace = 'module-' + namespace,
// element that creates request
$module = $(this),
$form = $module.closest(selector.form),
// context used for state
$context = (settings.stateContext)
? $(settings.stateContext)
: $module,
// request details
ajaxSettings,
requestSettings,
url,
data,
requestStartTime,
// standard module
element = this,
context = $context[0],
instance = $module.data(moduleNamespace),
module
;
module = {
initialize: function() {
if(!methodInvoked) {
module.bind.events();
}
module.instantiate();
},
instantiate: function() {
module.verbose('Storing instance of module', module);
instance = module;
$module
.data(moduleNamespace, instance)
;
},
destroy: function() {
module.verbose('Destroying previous module for', element);
$module
.removeData(moduleNamespace)
.off(eventNamespace)
;
},
bind: {
events: function() {
var
triggerEvent = module.get.event()
;
if( triggerEvent ) {
module.verbose('Attaching API events to element', triggerEvent);
$module
.on(triggerEvent + eventNamespace, module.event.trigger)
;
}
else if(settings.on == 'now') {
module.debug('Querying API endpoint immediately');
module.query();
}
}
},
decode: {
json: function(response) {
if(response !== undefined && typeof response == 'string') {
try {
response = JSON.parse(response);
}
catch(e) {
// isnt json string
}
}
return response;
}
},
read: {
cachedResponse: function(url) {
var
response
;
if(window.Storage === undefined) {
module.error(error.noStorage);
return;
}
response = sessionStorage.getItem(url);
module.debug('Using cached response', url, response);
response = module.decode.json(response);
return response;
}
},
write: {
cachedResponse: function(url, response) {
if(response && response === '') {
module.debug('Response empty, not caching', response);
return;
}
if(window.Storage === undefined) {
module.error(error.noStorage);
return;
}
if( $.isPlainObject(response) ) {
response = JSON.stringify(response);
}
sessionStorage.setItem(url, response);
module.verbose('Storing cached response for url', url, response);
}
},
query: function() {
if(module.is.disabled()) {
module.debug('Element is disabled API request aborted');
return;
}
if(module.is.loading()) {
if(settings.interruptRequests) {
module.debug('Interrupting previous request');
module.abort();
}
else {
module.debug('Cancelling request, previous request is still pending');
return;
}
}
// pass element metadata to url (value, text)
if(settings.defaultData) {
$.extend(true, settings.urlData, module.get.defaultData());
}
// Add form content
if(settings.serializeForm) {
settings.data = module.add.formData(settings.data);
}
// call beforesend and get any settings changes
requestSettings = module.get.settings();
// check if before send cancelled request
if(requestSettings === false) {
module.cancelled = true;
module.error(error.beforeSend);
return;
}
else {
module.cancelled = false;
}
// get url
url = module.get.templatedURL();
if(!url && !module.is.mocked()) {
module.error(error.missingURL);
return;
}
// replace variables
url = module.add.urlData( url );
// missing url parameters
if( !url && !module.is.mocked()) {
return;
}
requestSettings.url = settings.base + url;
// look for jQuery ajax parameters in settings
ajaxSettings = $.extend(true, {}, settings, {
type : settings.method || settings.type,
data : data,
url : settings.base + url,
beforeSend : settings.beforeXHR,
success : function() {},
failure : function() {},
complete : function() {}
});
module.debug('Querying URL', ajaxSettings.url);
module.verbose('Using AJAX settings', ajaxSettings);
if(settings.cache === 'local' && module.read.cachedResponse(url)) {
module.debug('Response returned from local cache');
module.request = module.create.request();
module.request.resolveWith(context, [ module.read.cachedResponse(url) ]);
return;
}
if( !settings.throttle ) {
module.debug('Sending request', data, ajaxSettings.method);
module.send.request();
}
else {
if(!settings.throttleFirstRequest && !module.timer) {
module.debug('Sending request', data, ajaxSettings.method);
module.send.request();
module.timer = setTimeout(function(){}, settings.throttle);
}
else {
module.debug('Throttling request', settings.throttle);
clearTimeout(module.timer);
module.timer = setTimeout(function() {
if(module.timer) {
delete module.timer;
}
module.debug('Sending throttled request', data, ajaxSettings.method);
module.send.request();
}, settings.throttle);
}
}
},
should: {
removeError: function() {
return ( settings.hideError === true || (settings.hideError === 'auto' && !module.is.form()) );
}
},
is: {
disabled: function() {
return ($module.filter(selector.disabled).length > 0);
},
expectingJSON: function() {
return settings.dataType === 'json' || settings.dataType === 'jsonp';
},
form: function() {
return $module.is('form') || $context.is('form');
},
mocked: function() {
return (settings.mockResponse || settings.mockResponseAsync || settings.response || settings.responseAsync);
},
input: function() {
return $module.is('input');
},
loading: function() {
return (module.request)
? (module.request.state() == 'pending')
: false
;
},
abortedRequest: function(xhr) {
if(xhr && xhr.readyState !== undefined && xhr.readyState === 0) {
module.verbose('XHR request determined to be aborted');
return true;
}
else {
module.verbose('XHR request was not aborted');
return false;
}
},
validResponse: function(response) {
if( (!module.is.expectingJSON()) || !$.isFunction(settings.successTest) ) {
module.verbose('Response is not JSON, skipping validation', settings.successTest, response);
return true;
}
module.debug('Checking JSON returned success', settings.successTest, response);
if( settings.successTest(response) ) {
module.debug('Response passed success test', response);
return true;
}
else {
module.debug('Response failed success test', response);
return false;
}
}
},
was: {
cancelled: function() {
return (module.cancelled || false);
},
succesful: function() {
module.verbose('This behavior will be deleted due to typo. Use "was successful" instead.');
return module.was.successful();
},
successful: function() {
return (module.request && module.request.state() == 'resolved');
},
failure: function() {
return (module.request && module.request.state() == 'rejected');
},
complete: function() {
return (module.request && (module.request.state() == 'resolved' || module.request.state() == 'rejected') );
}
},
add: {
urlData: function(url, urlData) {
var
requiredVariables,
optionalVariables
;
if(url) {
requiredVariables = url.match(settings.regExp.required);
optionalVariables = url.match(settings.regExp.optional);
urlData = urlData || settings.urlData;
if(requiredVariables) {
module.debug('Looking for required URL variables', requiredVariables);
$.each(requiredVariables, function(index, templatedString) {
var
// allow legacy {$var} style
variable = (templatedString.indexOf('$') !== -1)
? templatedString.substr(2, templatedString.length - 3)
: templatedString.substr(1, templatedString.length - 2),
value = ($.isPlainObject(urlData) && urlData[variable] !== undefined)
? urlData[variable]
: ($module.data(variable) !== undefined)
? $module.data(variable)
: ($context.data(variable) !== undefined)
? $context.data(variable)
: urlData[variable]
;
// remove value
if(value === undefined) {
module.error(error.requiredParameter, variable, url);
url = false;
return false;
}
else {
module.verbose('Found required variable', variable, value);
value = (settings.encodeParameters)
? module.get.urlEncodedValue(value)
: value
;
url = url.replace(templatedString, value);
}
});
}
if(optionalVariables) {
module.debug('Looking for optional URL variables', requiredVariables);
$.each(optionalVariables, function(index, templatedString) {
var
// allow legacy {/$var} style
variable = (templatedString.indexOf('$') !== -1)
? templatedString.substr(3, templatedString.length - 4)
: templatedString.substr(2, templatedString.length - 3),
value = ($.isPlainObject(urlData) && urlData[variable] !== undefined)
? urlData[variable]
: ($module.data(variable) !== undefined)
? $module.data(variable)
: ($context.data(variable) !== undefined)
? $context.data(variable)
: urlData[variable]
;
// optional replacement
if(value !== undefined) {
module.verbose('Optional variable Found', variable, value);
url = url.replace(templatedString, value);
}
else {
module.verbose('Optional variable not found', variable);
// remove preceding slash if set
if(url.indexOf('/' + templatedString) !== -1) {
url = url.replace('/' + templatedString, '');
}
else {
url = url.replace(templatedString, '');
}
}
});
}
}
return url;
},
formData: function(data) {
var
canSerialize = ($.fn.serializeObject !== undefined),
formData = (canSerialize)
? $form.serializeObject()
: $form.serialize(),
hasOtherData
;
data = data || settings.data;
hasOtherData = $.isPlainObject(data);
if(hasOtherData) {
if(canSerialize) {
module.debug('Extending existing data with form data', data, formData);
data = $.extend(true, {}, data, formData);
}
else {
module.error(error.missingSerialize);
module.debug('Cant extend data. Replacing data with form data', data, formData);
data = formData;
}
}
else {
module.debug('Adding form data', formData);
data = formData;
}
return data;
}
},
send: {
request: function() {
module.set.loading();
module.request = module.create.request();
if( module.is.mocked() ) {
module.mockedXHR = module.create.mockedXHR();
}
else {
module.xhr = module.create.xhr();
}
settings.onRequest.call(context, module.request, module.xhr);
}
},
event: {
trigger: function(event) {
module.query();
if(event.type == 'submit' || event.type == 'click') {
event.preventDefault();
}
},
xhr: {
always: function() {
// nothing special
},
done: function(response, textStatus, xhr) {
var
context = this,
elapsedTime = (new Date().getTime() - requestStartTime),
timeLeft = (settings.loadingDuration - elapsedTime),
translatedResponse = ( $.isFunction(settings.onResponse) )
? module.is.expectingJSON() && !settings.rawResponse
? settings.onResponse.call(context, $.extend(true, {}, response))
: settings.onResponse.call(context, response)
: false
;
timeLeft = (timeLeft > 0)
? timeLeft
: 0
;
if(translatedResponse) {
module.debug('Modified API response in onResponse callback', settings.onResponse, translatedResponse, response);
response = translatedResponse;
}
if(timeLeft > 0) {
module.debug('Response completed early delaying state change by', timeLeft);
}
setTimeout(function() {
if( module.is.validResponse(response) ) {
module.request.resolveWith(context, [response, xhr]);
}
else {
module.request.rejectWith(context, [xhr, 'invalid']);
}
}, timeLeft);
},
fail: function(xhr, status, httpMessage) {
var
context = this,
elapsedTime = (new Date().getTime() - requestStartTime),
timeLeft = (settings.loadingDuration - elapsedTime)
;
timeLeft = (timeLeft > 0)
? timeLeft
: 0
;
if(timeLeft > 0) {
module.debug('Response completed early delaying state change by', timeLeft);
}
setTimeout(function() {
if( module.is.abortedRequest(xhr) ) {
module.request.rejectWith(context, [xhr, 'aborted', httpMessage]);
}
else {
module.request.rejectWith(context, [xhr, 'error', status, httpMessage]);
}
}, timeLeft);
}
},
request: {
done: function(response, xhr) {
module.debug('Successful API Response', response);
if(settings.cache === 'local' && url) {
module.write.cachedResponse(url, response);
module.debug('Saving server response locally', module.cache);
}
settings.onSuccess.call(context, response, $module, xhr);
},
complete: function(firstParameter, secondParameter) {
var
xhr,
response
;
// have to guess callback parameters based on request success
if( module.was.successful() ) {
response = firstParameter;
xhr = secondParameter;
}
else {
xhr = firstParameter;
response = module.get.responseFromXHR(xhr);
}
module.remove.loading();
settings.onComplete.call(context, response, $module, xhr);
},
fail: function(xhr, status, httpMessage) {
var
// pull response from xhr if available
response = module.get.responseFromXHR(xhr),
errorMessage = module.get.errorFromRequest(response, status, httpMessage)
;
if(status == 'aborted') {
module.debug('XHR Aborted (Most likely caused by page navigation or CORS Policy)', status, httpMessage);
settings.onAbort.call(context, status, $module, xhr);
return true;
}
else if(status == 'invalid') {
module.debug('JSON did not pass success test. A server-side error has most likely occurred', response);
}
else if(status == 'error') {
if(xhr !== undefined) {
module.debug('XHR produced a server error', status, httpMessage);
// make sure we have an error to display to console
if( (xhr.status < 200 || xhr.status >= 300) && httpMessage !== undefined && httpMessage !== '') {
module.error(error.statusMessage + httpMessage, ajaxSettings.url);
}
settings.onError.call(context, errorMessage, $module, xhr);
}
}
if(settings.errorDuration && status !== 'aborted') {
module.debug('Adding error state');
module.set.error();
if( module.should.removeError() ) {
setTimeout(module.remove.error, settings.errorDuration);
}
}
module.debug('API Request failed', errorMessage, xhr);
settings.onFailure.call(context, response, $module, xhr);
}
}
},
create: {
request: function() {
// api request promise
return $.Deferred()
.always(module.event.request.complete)
.done(module.event.request.done)
.fail(module.event.request.fail)
;
},
mockedXHR: function () {
var
// xhr does not simulate these properties of xhr but must return them
textStatus = false,
status = false,
httpMessage = false,
responder = settings.mockResponse || settings.response,
asyncResponder = settings.mockResponseAsync || settings.responseAsync,
asyncCallback,
response,
mockedXHR
;
mockedXHR = $.Deferred()
.always(module.event.xhr.complete)
.done(module.event.xhr.done)
.fail(module.event.xhr.fail)
;
if(responder) {
if( $.isFunction(responder) ) {
module.debug('Using specified synchronous callback', responder);
response = responder.call(context, requestSettings);
}
else {
module.debug('Using settings specified response', responder);
response = responder;
}
// simulating response
mockedXHR.resolveWith(context, [ response, textStatus, { responseText: response }]);
}
else if( $.isFunction(asyncResponder) ) {
asyncCallback = function(response) {
module.debug('Async callback returned response', response);
if(response) {
mockedXHR.resolveWith(context, [ response, textStatus, { responseText: response }]);
}
else {
mockedXHR.rejectWith(context, [{ responseText: response }, status, httpMessage]);
}
};
module.debug('Using specified async response callback', asyncResponder);
asyncResponder.call(context, requestSettings, asyncCallback);
}
return mockedXHR;
},
xhr: function() {
var
xhr
;
// ajax request promise
xhr = $.ajax(ajaxSettings)
.always(module.event.xhr.always)
.done(module.event.xhr.done)
.fail(module.event.xhr.fail)
;
module.verbose('Created server request', xhr, ajaxSettings);
return xhr;
}
},
set: {
error: function() {
module.verbose('Adding error state to element', $context);
$context.addClass(className.error);
},
loading: function() {
module.verbose('Adding loading state to element', $context);
$context.addClass(className.loading);
requestStartTime = new Date().getTime();
}
},
remove: {
error: function() {
module.verbose('Removing error state from element', $context);
$context.removeClass(className.error);
},
loading: function() {
module.verbose('Removing loading state from element', $context);
$context.removeClass(className.loading);
}
},
get: {
responseFromXHR: function(xhr) {
return $.isPlainObject(xhr)
? (module.is.expectingJSON())
? module.decode.json(xhr.responseText)
: xhr.responseText
: false
;
},
errorFromRequest: function(response, status, httpMessage) {
return ($.isPlainObject(response) && response.error !== undefined)
? response.error // use json error message
: (settings.error[status] !== undefined) // use server error message
? settings.error[status]
: httpMessage
;
},
request: function() {
return module.request || false;
},
xhr: function() {
return module.xhr || false;
},
settings: function() {
var
runSettings
;
runSettings = settings.beforeSend.call($module, settings);
if(runSettings) {
if(runSettings.success !== undefined) {
module.debug('Legacy success callback detected', runSettings);
module.error(error.legacyParameters, runSettings.success);
runSettings.onSuccess = runSettings.success;
}
if(runSettings.failure !== undefined) {
module.debug('Legacy failure callback detected', runSettings);
module.error(error.legacyParameters, runSettings.failure);
runSettings.onFailure = runSettings.failure;
}
if(runSettings.complete !== undefined) {
module.debug('Legacy complete callback detected', runSettings);
module.error(error.legacyParameters, runSettings.complete);
runSettings.onComplete = runSettings.complete;
}
}
if(runSettings === undefined) {
module.error(error.noReturnedValue);
}
if(runSettings === false) {
return runSettings;
}
return (runSettings !== undefined)
? $.extend(true, {}, runSettings)
: $.extend(true, {}, settings)
;
},
urlEncodedValue: function(value) {
var
decodedValue = window.decodeURIComponent(value),
encodedValue = window.encodeURIComponent(value),
alreadyEncoded = (decodedValue !== value)
;
if(alreadyEncoded) {
module.debug('URL value is already encoded, avoiding double encoding', value);
return value;
}
module.verbose('Encoding value using encodeURIComponent', value, encodedValue);
return encodedValue;
},
defaultData: function() {
var
data = {}
;
if( !$.isWindow(element) ) {
if( module.is.input() ) {
data.value = $module.val();
}
else if( module.is.form() ) {
}
else {
data.text = $module.text();
}
}
return data;
},
event: function() {
if( $.isWindow(element) || settings.on == 'now' ) {
module.debug('API called without element, no events attached');
return false;
}
else if(settings.on == 'auto') {
if( $module.is('input') ) {
return (element.oninput !== undefined)
? 'input'
: (element.onpropertychange !== undefined)
? 'propertychange'
: 'keyup'
;
}
else if( $module.is('form') ) {
return 'submit';
}
else {
return 'click';
}
}
else {
return settings.on;
}
},
templatedURL: function(action) {
action = action || $module.data(metadata.action) || settings.action || false;
url = $module.data(metadata.url) || settings.url || false;
if(url) {
module.debug('Using specified url', url);
return url;
}
if(action) {
module.debug('Looking up url for action', action, settings.api);
if(settings.api[action] === undefined && !module.is.mocked()) {
module.error(error.missingAction, settings.action, settings.api);
return;
}
url = settings.api[action];
}
else if( module.is.form() ) {
url = $module.attr('action') || $context.attr('action') || false;
module.debug('No url or action specified, defaulting to form action', url);
}
return url;
}
},
abort: function() {
var
xhr = module.get.xhr()
;
if( xhr && xhr.state() !== 'resolved') {
module.debug('Cancelling API request');
xhr.abort();
}
},
// reset state
reset: function() {
module.remove.error();
module.remove.loading();
},
setting: function(name, value) {
module.debug('Changing setting', name, value);
if( $.isPlainObject(name) ) {
$.extend(true, settings, name);
}
else if(value !== undefined) {
if($.isPlainObject(settings[name])) {
$.extend(true, settings[name], value);
}
else {
settings[name] = value;
}
}
else {
return settings[name];
}
},
internal: function(name, value) {
if( $.isPlainObject(name) ) {
$.extend(true, module, name);
}
else if(value !== undefined) {
module[name] = value;
}
else {
return module[name];
}
},
debug: function() {
if(!settings.silent && settings.debug) {
if(settings.performance) {
module.performance.log(arguments);
}
else {
module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
module.debug.apply(console, arguments);
}
}
},
verbose: function() {
if(!settings.silent && settings.verbose && settings.debug) {
if(settings.performance) {
module.performance.log(arguments);
}
else {
module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
module.verbose.apply(console, arguments);
}
}
},
error: function() {
if(!settings.silent) {
module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
module.error.apply(console, arguments);
}
},
performance: {
log: function(message) {
var
currentTime,
executionTime,
previousTime
;
if(settings.performance) {
currentTime = new Date().getTime();
previousTime = time || currentTime;
executionTime = currentTime - previousTime;
time = currentTime;
performance.push({
'Name' : message[0],
'Arguments' : [].slice.call(message, 1) || '',
//'Element' : element,
'Execution Time' : executionTime
});
}
clearTimeout(module.performance.timer);
module.performance.timer = setTimeout(module.performance.display, 500);
},
display: function() {
var
title = settings.name + ':',
totalTime = 0
;
time = false;
clearTimeout(module.performance.timer);
$.each(performance, function(index, data) {
totalTime += data['Execution Time'];
});
title += ' ' + totalTime + 'ms';
if(moduleSelector) {
title += ' \'' + moduleSelector + '\'';
}
if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
console.groupCollapsed(title);
if(console.table) {
console.table(performance);
}
else {
$.each(performance, function(index, data) {
console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
});
}
console.groupEnd();
}
performance = [];
}
},
invoke: function(query, passedArguments, context) {
var
object = instance,
maxDepth,
found,
response
;
passedArguments = passedArguments || queryArguments;
context = element || context;
if(typeof query == 'string' && object !== undefined) {
query = query.split(/[\. ]/);
maxDepth = query.length - 1;
$.each(query, function(depth, value) {
var camelCaseValue = (depth != maxDepth)
? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
: query
;
if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
object = object[camelCaseValue];
}
else if( object[camelCaseValue] !== undefined ) {
found = object[camelCaseValue];
return false;
}
else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
object = object[value];
}
else if( object[value] !== undefined ) {
found = object[value];
return false;
}
else {
module.error(error.method, query);
return false;
}
});
}
if ( $.isFunction( found ) ) {
response = found.apply(context, passedArguments);
}
else if(found !== undefined) {
response = found;
}
if(Array.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
;
};
$.api.settings = {
name : 'API',
namespace : 'api',
debug : false,
verbose : false,
performance : true,
// object containing all templates endpoints
api : {},
// whether to cache responses
cache : true,
// whether new requests should abort previous requests
interruptRequests : true,
// event binding
on : 'auto',
// context for applying state classes
stateContext : false,
// duration for loading state
loadingDuration : 0,
// whether to hide errors after a period of time
hideError : 'auto',
// duration for error state
errorDuration : 2000,
// whether parameters should be encoded with encodeURIComponent
encodeParameters : true,
// API action to use
action : false,
// templated URL to use
url : false,
// base URL to apply to all endpoints
base : '',
// data that will
urlData : {},
// whether to add default data to url data
defaultData : true,
// whether to serialize closest form
serializeForm : false,
// how long to wait before request should occur
throttle : 0,
// whether to throttle first request or only repeated
throttleFirstRequest : true,
// standard ajax settings
method : 'get',
data : {},
dataType : 'json',
// mock response
mockResponse : false,
mockResponseAsync : false,
// aliases for mock
response : false,
responseAsync : false,
// whether onResponse should work with response value without force converting into an object
rawResponse : false,
// callbacks before request
beforeSend : function(settings) { return settings; },
beforeXHR : function(xhr) {},
onRequest : function(promise, xhr) {},
// after request
onResponse : false, // function(response) { },
// response was successful, if JSON passed validation
onSuccess : function(response, $module) {},
// request finished without aborting
onComplete : function(response, $module) {},
// failed JSON success test
onFailure : function(response, $module) {},
// server error
onError : function(errorMessage, $module) {},
// request aborted
onAbort : function(errorMessage, $module) {},
successTest : false,
// errors
error : {
beforeSend : 'The before send function has aborted the request',
error : 'There was an error with your request',
exitConditions : 'API Request Aborted. Exit conditions met',
JSONParse : 'JSON could not be parsed during error handling',
legacyParameters : 'You are using legacy API success callback names',
method : 'The method you called is not defined',
missingAction : 'API action used but no url was defined',
missingSerialize : 'jquery-serialize-object is required to add form data to an existing data object',
missingURL : 'No URL specified for api event',
noReturnedValue : 'The beforeSend callback must return a settings object, beforeSend ignored.',
noStorage : 'Caching responses locally requires session storage',
parseError : 'There was an error parsing your request',
requiredParameter : 'Missing a required URL parameter: ',
statusMessage : 'Server gave an error: ',
timeout : 'Your request timed out'
},
regExp : {
required : /\{\$*[A-z0-9]+\}/g,
optional : /\{\/\$*[A-z0-9]+\}/g,
},
className: {
loading : 'loading',
error : 'error'
},
selector: {
disabled : '.disabled',
form : 'form'
},
metadata: {
action : 'action',
url : 'url'
}
};
})( jQuery, window, document );
/*!
* # Fomantic-UI 2.8.8 - Transition
* http://github.com/fomantic/Fomantic-UI/
*
*
* Released under the MIT license
* http://opensource.org/licenses/MIT
*
*/
;(function ($, window, document, undefined) {
'use strict';
$.isFunction = $.isFunction || function(obj) {
return typeof obj === "function" && typeof obj.nodeType !== "number";
};
window = (typeof window != 'undefined' && window.Math == Math)
? window
: (typeof self != 'undefined' && self.Math == Math)
? self
: Function('return this')()
;
$.fn.transition = function() {
var
$allModules = $(this),
moduleSelector = $allModules.selector || '',
time = new Date().getTime(),
performance = [],
moduleArguments = arguments,
query = moduleArguments[0],
queryArguments = [].slice.call(arguments, 1),
methodInvoked = (typeof query === 'string'),
returnedValue
;
$allModules
.each(function(index) {
var
$module = $(this),
element = this,
// set at run time
settings,
instance,
error,
className,
metadata,
animationEnd,
moduleNamespace,
eventNamespace,
module
;
module = {
initialize: function() {
// get full settings
settings = module.get.settings.apply(element, moduleArguments);
// shorthand
className = settings.className;
error = settings.error;
metadata = settings.metadata;
// define namespace
eventNamespace = '.' + settings.namespace;
moduleNamespace = 'module-' + settings.namespace;
instance = $module.data(moduleNamespace) || module;
// get vendor specific events
animationEnd = module.get.animationEndEvent();
if(methodInvoked) {
methodInvoked = module.invoke(query);
}
// method not invoked, lets run an animation
if(methodInvoked === false) {
module.verbose('Converted arguments into settings object', settings);
if(settings.interval) {
module.delay(settings.animate);
}
else {
module.animate();
}
module.instantiate();
}
},
instantiate: function() {
module.verbose('Storing instance of module', module);
instance = module;
$module
.data(moduleNamespace, instance)
;
},
destroy: function() {
module.verbose('Destroying previous module for', element);
$module
.removeData(moduleNamespace)
;
},
refresh: function() {
module.verbose('Refreshing display type on next animation');
delete module.displayType;
},
forceRepaint: function() {
module.verbose('Forcing element repaint');
var
$parentElement = $module.parent(),
$nextElement = $module.next()
;
if($nextElement.length === 0) {
$module.detach().appendTo($parentElement);
}
else {
$module.detach().insertBefore($nextElement);
}
},
repaint: function() {
module.verbose('Repainting element');
var
fakeAssignment = element.offsetWidth
;
},
delay: function(interval) {
var
direction = module.get.animationDirection(),
shouldReverse,
delay
;
if(!direction) {
direction = module.can.transition()
? module.get.direction()
: 'static'
;
}
interval = (interval !== undefined)
? interval
: settings.interval
;
shouldReverse = (settings.reverse == 'auto' && direction == className.outward);
delay = (shouldReverse || settings.reverse == true)
? ($allModules.length - index) * settings.interval
: index * settings.interval
;
module.debug('Delaying animation by', delay);
setTimeout(module.animate, delay);
},
animate: function(overrideSettings) {
settings = overrideSettings || settings;
if(!module.is.supported()) {
module.error(error.support);
return false;
}
module.debug('Preparing animation', settings.animation);
if(module.is.animating()) {
if(settings.queue) {
if(!settings.allowRepeats && module.has.direction() && module.is.occurring() && module.queuing !== true) {
module.debug('Animation is currently occurring, preventing queueing same animation', settings.animation);
}
else {
module.queue(settings.animation);
}
return false;
}
else if(!settings.allowRepeats && module.is.occurring()) {
module.debug('Animation is already occurring, will not execute repeated animation', settings.animation);
return false;
}
else {
module.debug('New animation started, completing previous early', settings.animation);
instance.complete();
}
}
if( module.can.animate() ) {
module.set.animating(settings.animation);
}
else {
module.error(error.noAnimation, settings.animation, element);
}
},
reset: function() {
module.debug('Resetting animation to beginning conditions');
module.remove.animationCallbacks();
module.restore.conditions();
module.remove.animating();
},
queue: function(animation) {
module.debug('Queueing animation of', animation);
module.queuing = true;
$module
.one(animationEnd + '.queue' + eventNamespace, function() {
module.queuing = false;
module.repaint();
module.animate.apply(this, settings);
})
;
},
complete: function (event) {
if(event && event.target === element) {
event.stopPropagation();
}
module.debug('Animation complete', settings.animation);
module.remove.completeCallback();
module.remove.failSafe();
if(!module.is.looping()) {
if( module.is.outward() ) {
module.verbose('Animation is outward, hiding element');
module.restore.conditions();
module.hide();
}
else if( module.is.inward() ) {
module.verbose('Animation is outward, showing element');
module.restore.conditions();
module.show();
}
else {
module.verbose('Static animation completed');
module.restore.conditions();
settings.onComplete.call(element);
}
}
},
force: {
visible: function() {
var
style = $module.attr('style'),
userStyle = module.get.userStyle(style),
displayType = module.get.displayType(),
overrideStyle = userStyle + 'display: ' + displayType + ' !important;',
inlineDisplay = $module[0].style.display,
mustStayHidden = !displayType || (inlineDisplay === 'none' && settings.skipInlineHidden) || $module[0].tagName.match(/(script|link|style)/i)
;
if (mustStayHidden){
module.remove.transition();
return false;
}
module.verbose('Overriding default display to show element', displayType);
$module
.attr('style', overrideStyle)
;
return true;
},
hidden: function() {
var
style = $module.attr('style'),
currentDisplay = $module.css('display'),
emptyStyle = (style === undefined || style === '')
;
if(currentDisplay !== 'none' && !module.is.hidden()) {
module.verbose('Overriding default display to hide element');
$module
.css('display', 'none')
;
}
else if(emptyStyle) {
$module
.removeAttr('style')
;
}
}
},
has: {
direction: function(animation) {
var
hasDirection = false
;
animation = animation || settings.animation;
if(typeof animation === 'string') {
animation = animation.split(' ');
$.each(animation, function(index, word){
if(word === className.inward || word === className.outward) {
hasDirection = true;
}
});
}
return hasDirection;
},
inlineDisplay: function() {
var
style = $module.attr('style') || ''
;
return Array.isArray(style.match(/display.*?;/, ''));
}
},
set: {
animating: function(animation) {
// remove previous callbacks
module.remove.completeCallback();
// determine exact animation
animation = animation || settings.animation;
var animationClass = module.get.animationClass(animation);
// save animation class in cache to restore class names
module.save.animation(animationClass);
if(module.force.visible()) {
module.remove.hidden();
module.remove.direction();
module.start.animation(animationClass);
}
},
duration: function(animationName, duration) {
duration = duration || settings.duration;
duration = (typeof duration == 'number')
? duration + 'ms'
: duration
;
if(duration || duration === 0) {
module.verbose('Setting animation duration', duration);
$module
.css({
'animation-duration': duration
})
;
}
},
direction: function(direction) {
direction = direction || module.get.direction();
if(direction == className.inward) {
module.set.inward();
}
else {
module.set.outward();
}
},
looping: function() {
module.debug('Transition set to loop');
$module
.addClass(className.looping)
;
},
hidden: function() {
$module
.addClass(className.transition)
.addClass(className.hidden)
;
},
inward: function() {
module.debug('Setting direction to inward');
$module
.removeClass(className.outward)
.addClass(className.inward)
;
},
outward: function() {
module.debug('Setting direction to outward');
$module
.removeClass(className.inward)
.addClass(className.outward)
;
},
visible: function() {
$module
.addClass(className.transition)
.addClass(className.visible)
;
}
},
start: {
animation: function(animationClass) {
animationClass = animationClass || module.get.animationClass();
module.debug('Starting tween', animationClass);
$module
.addClass(animationClass)
.one(animationEnd + '.complete' + eventNamespace, module.complete)
;
if(settings.useFailSafe) {
module.add.failSafe();
}
module.set.duration(settings.duration);
settings.onStart.call(element);
}
},
save: {
animation: function(animation) {
if(!module.cache) {
module.cache = {};
}
module.cache.animation = animation;
},
displayType: function(displayType) {
if(displayType !== 'none') {
$module.data(metadata.displayType, displayType);
}
},
transitionExists: function(animation, exists) {
$.fn.transition.exists[animation] = exists;
module.verbose('Saving existence of transition', animation, exists);
}
},
restore: {
conditions: function() {
var
animation = module.get.currentAnimation()
;
if(animation) {
$module
.removeClass(animation)
;
module.verbose('Removing animation class', module.cache);
}
module.remove.duration();
}
},
add: {
failSafe: function() {
var
duration = module.get.duration()
;
module.timer = setTimeout(function() {
$module.triggerHandler(animationEnd);
}, duration + settings.failSafeDelay);
module.verbose('Adding fail safe timer', module.timer);
}
},
remove: {
animating: function() {
$module.removeClass(className.animating);
},
animationCallbacks: function() {
module.remove.queueCallback();
module.remove.completeCallback();
},
queueCallback: function() {
$module.off('.queue' + eventNamespace);
},
completeCallback: function() {
$module.off('.complete' + eventNamespace);
},
display: function() {
$module.css('display', '');
},
direction: function() {
$module
.removeClass(className.inward)
.removeClass(className.outward)
;
},
duration: function() {
$module
.css('animation-duration', '')
;
},
failSafe: function() {
module.verbose('Removing fail safe timer', module.timer);
if(module.timer) {
clearTimeout(module.timer);
}
},
hidden: function() {
$module.removeClass(className.hidden);
},
visible: function() {
$module.removeClass(className.visible);
},
looping: function() {
module.debug('Transitions are no longer looping');
if( module.is.looping() ) {
module.reset();
$module
.removeClass(className.looping)
;
}
},
transition: function() {
$module
.removeClass(className.transition)
.removeClass(className.visible)
.removeClass(className.hidden)
;
}
},
get: {
settings: function(animation, duration, onComplete) {
// single settings object
if(typeof animation == 'object') {
return $.extend(true, {}, $.fn.transition.settings, animation);
}
// all arguments provided
else if(typeof onComplete == 'function') {
return $.extend({}, $.fn.transition.settings, {
animation : animation,
onComplete : onComplete,
duration : duration
});
}
// only duration provided
else if(typeof duration == 'string' || typeof duration == 'number') {
return $.extend({}, $.fn.transition.settings, {
animation : animation,
duration : duration
});
}
// duration is actually settings object
else if(typeof duration == 'object') {
return $.extend({}, $.fn.transition.settings, duration, {
animation : animation
});
}
// duration is actually callback
else if(typeof duration == 'function') {
return $.extend({}, $.fn.transition.settings, {
animation : animation,
onComplete : duration
});
}
// only animation provided
else {
return $.extend({}, $.fn.transition.settings, {
animation : animation
});
}
},
animationClass: function(animation) {
var
animationClass = animation || settings.animation,
directionClass = (module.can.transition() && !module.has.direction())
? module.get.direction() + ' '
: ''
;
return className.animating + ' '
+ className.transition + ' '
+ directionClass
+ animationClass
;
},
currentAnimation: function() {
return (module.cache && module.cache.animation !== undefined)
? module.cache.animation
: false
;
},
currentDirection: function() {
return module.is.inward()
? className.inward
: className.outward
;
},
direction: function() {
return module.is.hidden() || !module.is.visible()
? className.inward
: className.outward
;
},
animationDirection: function(animation) {
var
direction
;
animation = animation || settings.animation;
if(typeof animation === 'string') {
animation = animation.split(' ');
// search animation name for out/in class
$.each(animation, function(index, word){
if(word === className.inward) {
direction = className.inward;
}
else if(word === className.outward) {
direction = className.outward;
}
});
}
// return found direction
if(direction) {
return direction;
}
return false;
},
duration: function(duration) {
duration = duration || settings.duration;
if(duration === false) {
duration = $module.css('animation-duration') || 0;
}
return (typeof duration === 'string')
? (duration.indexOf('ms') > -1)
? parseFloat(duration)
: parseFloat(duration) * 1000
: duration
;
},
displayType: function(shouldDetermine) {
shouldDetermine = (shouldDetermine !== undefined)
? shouldDetermine
: true
;
if(settings.displayType) {
return settings.displayType;
}
if(shouldDetermine && $module.data(metadata.displayType) === undefined) {
var currentDisplay = $module.css('display');
if(currentDisplay === '' || currentDisplay === 'none'){
// create fake element to determine display state
module.can.transition(true);
} else {
module.save.displayType(currentDisplay);
}
}
return $module.data(metadata.displayType);
},
userStyle: function(style) {
style = style || $module.attr('style') || '';
return style.replace(/display.*?;/, '');
},
transitionExists: function(animation) {
return $.fn.transition.exists[animation];
},
animationStartEvent: function() {
var
element = document.createElement('div'),
animations = {
'animation' :'animationstart',
'OAnimation' :'oAnimationStart',
'MozAnimation' :'mozAnimationStart',
'WebkitAnimation' :'webkitAnimationStart'
},
animation
;
for(animation in animations){
if( element.style[animation] !== undefined ){
return animations[animation];
}
}
return false;
},
animationEndEvent: function() {
var
element = document.createElement('div'),
animations = {
'animation' :'animationend',
'OAnimation' :'oAnimationEnd',
'MozAnimation' :'mozAnimationEnd',
'WebkitAnimation' :'webkitAnimationEnd'
},
animation
;
for(animation in animations){
if( element.style[animation] !== undefined ){
return animations[animation];
}
}
return false;
}
},
can: {
transition: function(forced) {
var
animation = settings.animation,
transitionExists = module.get.transitionExists(animation),
displayType = module.get.displayType(false),
elementClass,
tagName,
$clone,
currentAnimation,
inAnimation,
directionExists
;
if( transitionExists === undefined || forced) {
module.verbose('Determining whether animation exists');
elementClass = $module.attr('class');
tagName = $module.prop('tagName');
$clone = $('<' + tagName + ' />').addClass( elementClass ).insertAfter($module);
currentAnimation = $clone
.addClass(animation)
.removeClass(className.inward)
.removeClass(className.outward)
.addClass(className.animating)
.addClass(className.transition)
.css('animationName')
;
inAnimation = $clone
.addClass(className.inward)
.css('animationName')
;
if(!displayType) {
displayType = $clone
.attr('class', elementClass)
.removeAttr('style')
.removeClass(className.hidden)
.removeClass(className.visible)
.show()
.css('display')
;
module.verbose('Determining final display state', displayType);
module.save.displayType(displayType);
}
$clone.remove();
if(currentAnimation != inAnimation) {
module.debug('Direction exists for animation', animation);
directionExists = true;
}
else if(currentAnimation == 'none' || !currentAnimation) {
module.debug('No animation defined in css', animation);
return;
}
else {
module.debug('Static animation found', animation, displayType);
directionExists = false;
}
module.save.transitionExists(animation, directionExists);
}
return (transitionExists !== undefined)
? transitionExists
: directionExists
;
},
animate: function() {
// can transition does not return a value if animation does not exist
return (module.can.transition() !== undefined);
}
},
is: {
animating: function() {
return $module.hasClass(className.animating);
},
inward: function() {
return $module.hasClass(className.inward);
},
outward: function() {
return $module.hasClass(className.outward);
},
looping: function() {
return $module.hasClass(className.looping);
},
occurring: function(animation) {
animation = animation || settings.animation;
animation = '.' + animation.replace(' ', '.');
return ( $module.filter(animation).length > 0 );
},
visible: function() {
return $module.is(':visible');
},
hidden: function() {
return $module.css('visibility') === 'hidden';
},
supported: function() {
return(animationEnd !== false);
}
},
hide: function() {
module.verbose('Hiding element');
if( module.is.animating() ) {
module.reset();
}
element.blur(); // IE will trigger focus change if element is not blurred before hiding
module.remove.display();
module.remove.visible();
if($.isFunction(settings.onBeforeHide)){
settings.onBeforeHide.call(element,function(){
module.hideNow();
});
} else {
module.hideNow();
}
},
hideNow: function() {
module.set.hidden();
module.force.hidden();
settings.onHide.call(element);
settings.onComplete.call(element);
// module.repaint();
},
show: function(display) {
module.verbose('Showing element', display);
if(module.force.visible()) {
module.remove.hidden();
module.set.visible();
settings.onShow.call(element);
settings.onComplete.call(element);
// module.repaint();
}
},
toggle: function() {
if( module.is.visible() ) {
module.hide();
}
else {
module.show();
}
},
stop: function() {
module.debug('Stopping current animation');
$module.triggerHandler(animationEnd);
},
stopAll: function() {
module.debug('Stopping all animation');
module.remove.queueCallback();
$module.triggerHandler(animationEnd);
},
clear: {
queue: function() {
module.debug('Clearing animation queue');
module.remove.queueCallback();
}
},
enable: function() {
module.verbose('Starting animation');
$module.removeClass(className.disabled);
},
disable: function() {
module.debug('Stopping animation');
$module.addClass(className.disabled);
},
setting: function(name, value) {
module.debug('Changing setting', name, value);
if( $.isPlainObject(name) ) {
$.extend(true, settings, name);
}
else if(value !== undefined) {
if($.isPlainObject(settings[name])) {
$.extend(true, settings[name], value);
}
else {
settings[name] = value;
}
}
else {
return settings[name];
}
},
internal: function(name, value) {
if( $.isPlainObject(name) ) {
$.extend(true, module, name);
}
else if(value !== undefined) {
module[name] = value;
}
else {
return module[name];
}
},
debug: function() {
if(!settings.silent && settings.debug) {
if(settings.performance) {
module.performance.log(arguments);
}
else {
module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
module.debug.apply(console, arguments);
}
}
},
verbose: function() {
if(!settings.silent && settings.verbose && settings.debug) {
if(settings.performance) {
module.performance.log(arguments);
}
else {
module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
module.verbose.apply(console, arguments);
}
}
},
error: function() {
if(!settings.silent) {
module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
module.error.apply(console, arguments);
}
},
performance: {
log: function(message) {
var
currentTime,
executionTime,
previousTime
;
if(settings.performance) {
currentTime = new Date().getTime();
previousTime = time || currentTime;
executionTime = currentTime - previousTime;
time = currentTime;
performance.push({
'Name' : message[0],
'Arguments' : [].slice.call(message, 1) || '',
'Element' : element,
'Execution Time' : executionTime
});
}
clearTimeout(module.performance.timer);
module.performance.timer = setTimeout(module.performance.display, 500);
},
display: function() {
var
title = settings.name + ':',
totalTime = 0
;
time = false;
clearTimeout(module.performance.timer);
$.each(performance, function(index, data) {
totalTime += data['Execution Time'];
});
title += ' ' + totalTime + 'ms';
if(moduleSelector) {
title += ' \'' + moduleSelector + '\'';
}
if($allModules.length > 1) {
title += ' ' + '(' + $allModules.length + ')';
}
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 = [];
}
},
// modified for transition to return invoke success
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(Array.isArray(returnedValue)) {
returnedValue.push(response);
}
else if(returnedValue !== undefined) {
returnedValue = [returnedValue, response];
}
else if(response !== undefined) {
returnedValue = response;
}
return (found !== undefined)
? found
: false
;
}
};
module.initialize();
})
;
return (returnedValue !== undefined)
? returnedValue
: this
;
};
// Records if CSS transition is available
$.fn.transition.exists = {};
$.fn.transition.settings = {
// module info
name : 'Transition',
// hide all output from this component regardless of other settings
silent : false,
// debug content outputted to console
debug : false,
// verbose debug output
verbose : false,
// performance data output
performance : true,
// event namespace
namespace : 'transition',
// delay between animations in group
interval : 0,
// whether group animations should be reversed
reverse : 'auto',
// animation callback event
onStart : function() {},
onComplete : function() {},
onShow : function() {},
onHide : function() {},
// whether timeout should be used to ensure callback fires in cases animationend does not
useFailSafe : true,
// delay in ms for fail safe
failSafeDelay : 100,
// whether EXACT animation can occur twice in a row
allowRepeats : false,
// Override final display type on visible
displayType : false,
// animation duration
animation : 'fade',
duration : false,
// new animations will occur after previous ones
queue : true,
// whether initially inline hidden objects should be skipped for transition
skipInlineHidden: false,
metadata : {
displayType: 'display'
},
className : {
animating : 'animating',
disabled : 'disabled',
hidden : 'hidden',
inward : 'in',
loading : 'loading',
looping : 'looping',
outward : 'out',
transition : 'transition',
visible : 'visible'
},
// possible errors
error: {
noAnimation : 'Element is no longer attached to DOM. Unable to animate. Use silent setting to surpress this warning in production.',
repeated : 'That animation is already occurring, cancelling repeated animation',
method : 'The method you called is not defined',
support : 'This browser does not support CSS animations'
}
};
})( jQuery, window, document );