@@ 20874-21571 (lines=698) @@ | ||
20871 | * |
|
20872 | */ |
|
20873 | ||
20874 | ;(function ($, window, document, undefined) { |
|
20875 | ||
20876 | "use strict"; |
|
20877 | ||
20878 | window = (typeof window != 'undefined' && window.Math == Math) |
|
20879 | ? window |
|
20880 | : (typeof self != 'undefined' && self.Math == Math) |
|
20881 | ? self |
|
20882 | : Function('return this')() |
|
20883 | ; |
|
20884 | ||
20885 | $.fn.state = function(parameters) { |
|
20886 | var |
|
20887 | $allModules = $(this), |
|
20888 | ||
20889 | moduleSelector = $allModules.selector || '', |
|
20890 | ||
20891 | hasTouch = ('ontouchstart' in document.documentElement), |
|
20892 | time = new Date().getTime(), |
|
20893 | performance = [], |
|
20894 | ||
20895 | query = arguments[0], |
|
20896 | methodInvoked = (typeof query == 'string'), |
|
20897 | queryArguments = [].slice.call(arguments, 1), |
|
20898 | ||
20899 | returnedValue |
|
20900 | ; |
|
20901 | $allModules |
|
20902 | .each(function() { |
|
20903 | var |
|
20904 | settings = ( $.isPlainObject(parameters) ) |
|
20905 | ? $.extend(true, {}, $.fn.state.settings, parameters) |
|
20906 | : $.extend({}, $.fn.state.settings), |
|
20907 | ||
20908 | error = settings.error, |
|
20909 | metadata = settings.metadata, |
|
20910 | className = settings.className, |
|
20911 | namespace = settings.namespace, |
|
20912 | states = settings.states, |
|
20913 | text = settings.text, |
|
20914 | ||
20915 | eventNamespace = '.' + namespace, |
|
20916 | moduleNamespace = namespace + '-module', |
|
20917 | ||
20918 | $module = $(this), |
|
20919 | ||
20920 | element = this, |
|
20921 | instance = $module.data(moduleNamespace), |
|
20922 | ||
20923 | module |
|
20924 | ; |
|
20925 | module = { |
|
20926 | ||
20927 | initialize: function() { |
|
20928 | module.verbose('Initializing module'); |
|
20929 | ||
20930 | // allow module to guess desired state based on element |
|
20931 | if(settings.automatic) { |
|
20932 | module.add.defaults(); |
|
20933 | } |
|
20934 | ||
20935 | // bind events with delegated events |
|
20936 | if(settings.context && moduleSelector !== '') { |
|
20937 | $(settings.context) |
|
20938 | .on(moduleSelector, 'mouseenter' + eventNamespace, module.change.text) |
|
20939 | .on(moduleSelector, 'mouseleave' + eventNamespace, module.reset.text) |
|
20940 | .on(moduleSelector, 'click' + eventNamespace, module.toggle.state) |
|
20941 | ; |
|
20942 | } |
|
20943 | else { |
|
20944 | $module |
|
20945 | .on('mouseenter' + eventNamespace, module.change.text) |
|
20946 | .on('mouseleave' + eventNamespace, module.reset.text) |
|
20947 | .on('click' + eventNamespace, module.toggle.state) |
|
20948 | ; |
|
20949 | } |
|
20950 | module.instantiate(); |
|
20951 | }, |
|
20952 | ||
20953 | instantiate: function() { |
|
20954 | module.verbose('Storing instance of module', module); |
|
20955 | instance = module; |
|
20956 | $module |
|
20957 | .data(moduleNamespace, module) |
|
20958 | ; |
|
20959 | }, |
|
20960 | ||
20961 | destroy: function() { |
|
20962 | module.verbose('Destroying previous module', instance); |
|
20963 | $module |
|
20964 | .off(eventNamespace) |
|
20965 | .removeData(moduleNamespace) |
|
20966 | ; |
|
20967 | }, |
|
20968 | ||
20969 | refresh: function() { |
|
20970 | module.verbose('Refreshing selector cache'); |
|
20971 | $module = $(element); |
|
20972 | }, |
|
20973 | ||
20974 | add: { |
|
20975 | defaults: function() { |
|
20976 | var |
|
20977 | userStates = parameters && $.isPlainObject(parameters.states) |
|
20978 | ? parameters.states |
|
20979 | : {} |
|
20980 | ; |
|
20981 | $.each(settings.defaults, function(type, typeStates) { |
|
20982 | if( module.is[type] !== undefined && module.is[type]() ) { |
|
20983 | module.verbose('Adding default states', type, element); |
|
20984 | $.extend(settings.states, typeStates, userStates); |
|
20985 | } |
|
20986 | }); |
|
20987 | } |
|
20988 | }, |
|
20989 | ||
20990 | is: { |
|
20991 | ||
20992 | active: function() { |
|
20993 | return $module.hasClass(className.active); |
|
20994 | }, |
|
20995 | loading: function() { |
|
20996 | return $module.hasClass(className.loading); |
|
20997 | }, |
|
20998 | inactive: function() { |
|
20999 | return !( $module.hasClass(className.active) ); |
|
21000 | }, |
|
21001 | state: function(state) { |
|
21002 | if(className[state] === undefined) { |
|
21003 | return false; |
|
21004 | } |
|
21005 | return $module.hasClass( className[state] ); |
|
21006 | }, |
|
21007 | ||
21008 | enabled: function() { |
|
21009 | return !( $module.is(settings.filter.active) ); |
|
21010 | }, |
|
21011 | disabled: function() { |
|
21012 | return ( $module.is(settings.filter.active) ); |
|
21013 | }, |
|
21014 | textEnabled: function() { |
|
21015 | return !( $module.is(settings.filter.text) ); |
|
21016 | }, |
|
21017 | ||
21018 | // definitions for automatic type detection |
|
21019 | button: function() { |
|
21020 | return $module.is('.button:not(a, .submit)'); |
|
21021 | }, |
|
21022 | input: function() { |
|
21023 | return $module.is('input'); |
|
21024 | }, |
|
21025 | progress: function() { |
|
21026 | return $module.is('.ui.progress'); |
|
21027 | } |
|
21028 | }, |
|
21029 | ||
21030 | allow: function(state) { |
|
21031 | module.debug('Now allowing state', state); |
|
21032 | states[state] = true; |
|
21033 | }, |
|
21034 | disallow: function(state) { |
|
21035 | module.debug('No longer allowing', state); |
|
21036 | states[state] = false; |
|
21037 | }, |
|
21038 | ||
21039 | allows: function(state) { |
|
21040 | return states[state] || false; |
|
21041 | }, |
|
21042 | ||
21043 | enable: function() { |
|
21044 | $module.removeClass(className.disabled); |
|
21045 | }, |
|
21046 | ||
21047 | disable: function() { |
|
21048 | $module.addClass(className.disabled); |
|
21049 | }, |
|
21050 | ||
21051 | setState: function(state) { |
|
21052 | if(module.allows(state)) { |
|
21053 | $module.addClass( className[state] ); |
|
21054 | } |
|
21055 | }, |
|
21056 | ||
21057 | removeState: function(state) { |
|
21058 | if(module.allows(state)) { |
|
21059 | $module.removeClass( className[state] ); |
|
21060 | } |
|
21061 | }, |
|
21062 | ||
21063 | toggle: { |
|
21064 | state: function() { |
|
21065 | var |
|
21066 | apiRequest, |
|
21067 | requestCancelled |
|
21068 | ; |
|
21069 | if( module.allows('active') && module.is.enabled() ) { |
|
21070 | module.refresh(); |
|
21071 | if($.fn.api !== undefined) { |
|
21072 | apiRequest = $module.api('get request'); |
|
21073 | requestCancelled = $module.api('was cancelled'); |
|
21074 | if( requestCancelled ) { |
|
21075 | module.debug('API Request cancelled by beforesend'); |
|
21076 | settings.activateTest = function(){ return false; }; |
|
21077 | settings.deactivateTest = function(){ return false; }; |
|
21078 | } |
|
21079 | else if(apiRequest) { |
|
21080 | module.listenTo(apiRequest); |
|
21081 | return; |
|
21082 | } |
|
21083 | } |
|
21084 | module.change.state(); |
|
21085 | } |
|
21086 | } |
|
21087 | }, |
|
21088 | ||
21089 | listenTo: function(apiRequest) { |
|
21090 | module.debug('API request detected, waiting for state signal', apiRequest); |
|
21091 | if(apiRequest) { |
|
21092 | if(text.loading) { |
|
21093 | module.update.text(text.loading); |
|
21094 | } |
|
21095 | $.when(apiRequest) |
|
21096 | .then(function() { |
|
21097 | if(apiRequest.state() == 'resolved') { |
|
21098 | module.debug('API request succeeded'); |
|
21099 | settings.activateTest = function(){ return true; }; |
|
21100 | settings.deactivateTest = function(){ return true; }; |
|
21101 | } |
|
21102 | else { |
|
21103 | module.debug('API request failed'); |
|
21104 | settings.activateTest = function(){ return false; }; |
|
21105 | settings.deactivateTest = function(){ return false; }; |
|
21106 | } |
|
21107 | module.change.state(); |
|
21108 | }) |
|
21109 | ; |
|
21110 | } |
|
21111 | }, |
|
21112 | ||
21113 | // checks whether active/inactive state can be given |
|
21114 | change: { |
|
21115 | ||
21116 | state: function() { |
|
21117 | module.debug('Determining state change direction'); |
|
21118 | // inactive to active change |
|
21119 | if( module.is.inactive() ) { |
|
21120 | module.activate(); |
|
21121 | } |
|
21122 | else { |
|
21123 | module.deactivate(); |
|
21124 | } |
|
21125 | if(settings.sync) { |
|
21126 | module.sync(); |
|
21127 | } |
|
21128 | settings.onChange.call(element); |
|
21129 | }, |
|
21130 | ||
21131 | text: function() { |
|
21132 | if( module.is.textEnabled() ) { |
|
21133 | if(module.is.disabled() ) { |
|
21134 | module.verbose('Changing text to disabled text', text.hover); |
|
21135 | module.update.text(text.disabled); |
|
21136 | } |
|
21137 | else if( module.is.active() ) { |
|
21138 | if(text.hover) { |
|
21139 | module.verbose('Changing text to hover text', text.hover); |
|
21140 | module.update.text(text.hover); |
|
21141 | } |
|
21142 | else if(text.deactivate) { |
|
21143 | module.verbose('Changing text to deactivating text', text.deactivate); |
|
21144 | module.update.text(text.deactivate); |
|
21145 | } |
|
21146 | } |
|
21147 | else { |
|
21148 | if(text.hover) { |
|
21149 | module.verbose('Changing text to hover text', text.hover); |
|
21150 | module.update.text(text.hover); |
|
21151 | } |
|
21152 | else if(text.activate){ |
|
21153 | module.verbose('Changing text to activating text', text.activate); |
|
21154 | module.update.text(text.activate); |
|
21155 | } |
|
21156 | } |
|
21157 | } |
|
21158 | } |
|
21159 | ||
21160 | }, |
|
21161 | ||
21162 | activate: function() { |
|
21163 | if( settings.activateTest.call(element) ) { |
|
21164 | module.debug('Setting state to active'); |
|
21165 | $module |
|
21166 | .addClass(className.active) |
|
21167 | ; |
|
21168 | module.update.text(text.active); |
|
21169 | settings.onActivate.call(element); |
|
21170 | } |
|
21171 | }, |
|
21172 | ||
21173 | deactivate: function() { |
|
21174 | if( settings.deactivateTest.call(element) ) { |
|
21175 | module.debug('Setting state to inactive'); |
|
21176 | $module |
|
21177 | .removeClass(className.active) |
|
21178 | ; |
|
21179 | module.update.text(text.inactive); |
|
21180 | settings.onDeactivate.call(element); |
|
21181 | } |
|
21182 | }, |
|
21183 | ||
21184 | sync: function() { |
|
21185 | module.verbose('Syncing other buttons to current state'); |
|
21186 | if( module.is.active() ) { |
|
21187 | $allModules |
|
21188 | .not($module) |
|
21189 | .state('activate'); |
|
21190 | } |
|
21191 | else { |
|
21192 | $allModules |
|
21193 | .not($module) |
|
21194 | .state('deactivate') |
|
21195 | ; |
|
21196 | } |
|
21197 | }, |
|
21198 | ||
21199 | get: { |
|
21200 | text: function() { |
|
21201 | return (settings.selector.text) |
|
21202 | ? $module.find(settings.selector.text).text() |
|
21203 | : $module.html() |
|
21204 | ; |
|
21205 | }, |
|
21206 | textFor: function(state) { |
|
21207 | return text[state] || false; |
|
21208 | } |
|
21209 | }, |
|
21210 | ||
21211 | flash: { |
|
21212 | text: function(text, duration, callback) { |
|
21213 | var |
|
21214 | previousText = module.get.text() |
|
21215 | ; |
|
21216 | module.debug('Flashing text message', text, duration); |
|
21217 | text = text || settings.text.flash; |
|
21218 | duration = duration || settings.flashDuration; |
|
21219 | callback = callback || function() {}; |
|
21220 | module.update.text(text); |
|
21221 | setTimeout(function(){ |
|
21222 | module.update.text(previousText); |
|
21223 | callback.call(element); |
|
21224 | }, duration); |
|
21225 | } |
|
21226 | }, |
|
21227 | ||
21228 | reset: { |
|
21229 | // on mouseout sets text to previous value |
|
21230 | text: function() { |
|
21231 | var |
|
21232 | activeText = text.active || $module.data(metadata.storedText), |
|
21233 | inactiveText = text.inactive || $module.data(metadata.storedText) |
|
21234 | ; |
|
21235 | if( module.is.textEnabled() ) { |
|
21236 | if( module.is.active() && activeText) { |
|
21237 | module.verbose('Resetting active text', activeText); |
|
21238 | module.update.text(activeText); |
|
21239 | } |
|
21240 | else if(inactiveText) { |
|
21241 | module.verbose('Resetting inactive text', activeText); |
|
21242 | module.update.text(inactiveText); |
|
21243 | } |
|
21244 | } |
|
21245 | } |
|
21246 | }, |
|
21247 | ||
21248 | update: { |
|
21249 | text: function(text) { |
|
21250 | var |
|
21251 | currentText = module.get.text() |
|
21252 | ; |
|
21253 | if(text && text !== currentText) { |
|
21254 | module.debug('Updating text', text); |
|
21255 | if(settings.selector.text) { |
|
21256 | $module |
|
21257 | .data(metadata.storedText, text) |
|
21258 | .find(settings.selector.text) |
|
21259 | .text(text) |
|
21260 | ; |
|
21261 | } |
|
21262 | else { |
|
21263 | $module |
|
21264 | .data(metadata.storedText, text) |
|
21265 | .html(text) |
|
21266 | ; |
|
21267 | } |
|
21268 | } |
|
21269 | else { |
|
21270 | module.debug('Text is already set, ignoring update', text); |
|
21271 | } |
|
21272 | } |
|
21273 | }, |
|
21274 | ||
21275 | setting: function(name, value) { |
|
21276 | module.debug('Changing setting', name, value); |
|
21277 | if( $.isPlainObject(name) ) { |
|
21278 | $.extend(true, settings, name); |
|
21279 | } |
|
21280 | else if(value !== undefined) { |
|
21281 | if($.isPlainObject(settings[name])) { |
|
21282 | $.extend(true, settings[name], value); |
|
21283 | } |
|
21284 | else { |
|
21285 | settings[name] = value; |
|
21286 | } |
|
21287 | } |
|
21288 | else { |
|
21289 | return settings[name]; |
|
21290 | } |
|
21291 | }, |
|
21292 | internal: function(name, value) { |
|
21293 | if( $.isPlainObject(name) ) { |
|
21294 | $.extend(true, module, name); |
|
21295 | } |
|
21296 | else if(value !== undefined) { |
|
21297 | module[name] = value; |
|
21298 | } |
|
21299 | else { |
|
21300 | return module[name]; |
|
21301 | } |
|
21302 | }, |
|
21303 | debug: function() { |
|
21304 | if(!settings.silent && settings.debug) { |
|
21305 | if(settings.performance) { |
|
21306 | module.performance.log(arguments); |
|
21307 | } |
|
21308 | else { |
|
21309 | module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':'); |
|
21310 | module.debug.apply(console, arguments); |
|
21311 | } |
|
21312 | } |
|
21313 | }, |
|
21314 | verbose: function() { |
|
21315 | if(!settings.silent && settings.verbose && settings.debug) { |
|
21316 | if(settings.performance) { |
|
21317 | module.performance.log(arguments); |
|
21318 | } |
|
21319 | else { |
|
21320 | module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':'); |
|
21321 | module.verbose.apply(console, arguments); |
|
21322 | } |
|
21323 | } |
|
21324 | }, |
|
21325 | error: function() { |
|
21326 | if(!settings.silent) { |
|
21327 | module.error = Function.prototype.bind.call(console.error, console, settings.name + ':'); |
|
21328 | module.error.apply(console, arguments); |
|
21329 | } |
|
21330 | }, |
|
21331 | performance: { |
|
21332 | log: function(message) { |
|
21333 | var |
|
21334 | currentTime, |
|
21335 | executionTime, |
|
21336 | previousTime |
|
21337 | ; |
|
21338 | if(settings.performance) { |
|
21339 | currentTime = new Date().getTime(); |
|
21340 | previousTime = time || currentTime; |
|
21341 | executionTime = currentTime - previousTime; |
|
21342 | time = currentTime; |
|
21343 | performance.push({ |
|
21344 | 'Name' : message[0], |
|
21345 | 'Arguments' : [].slice.call(message, 1) || '', |
|
21346 | 'Element' : element, |
|
21347 | 'Execution Time' : executionTime |
|
21348 | }); |
|
21349 | } |
|
21350 | clearTimeout(module.performance.timer); |
|
21351 | module.performance.timer = setTimeout(module.performance.display, 500); |
|
21352 | }, |
|
21353 | display: function() { |
|
21354 | var |
|
21355 | title = settings.name + ':', |
|
21356 | totalTime = 0 |
|
21357 | ; |
|
21358 | time = false; |
|
21359 | clearTimeout(module.performance.timer); |
|
21360 | $.each(performance, function(index, data) { |
|
21361 | totalTime += data['Execution Time']; |
|
21362 | }); |
|
21363 | title += ' ' + totalTime + 'ms'; |
|
21364 | if(moduleSelector) { |
|
21365 | title += ' \'' + moduleSelector + '\''; |
|
21366 | } |
|
21367 | if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) { |
|
21368 | console.groupCollapsed(title); |
|
21369 | if(console.table) { |
|
21370 | console.table(performance); |
|
21371 | } |
|
21372 | else { |
|
21373 | $.each(performance, function(index, data) { |
|
21374 | console.log(data['Name'] + ': ' + data['Execution Time']+'ms'); |
|
21375 | }); |
|
21376 | } |
|
21377 | console.groupEnd(); |
|
21378 | } |
|
21379 | performance = []; |
|
21380 | } |
|
21381 | }, |
|
21382 | invoke: function(query, passedArguments, context) { |
|
21383 | var |
|
21384 | object = instance, |
|
21385 | maxDepth, |
|
21386 | found, |
|
21387 | response |
|
21388 | ; |
|
21389 | passedArguments = passedArguments || queryArguments; |
|
21390 | context = element || context; |
|
21391 | if(typeof query == 'string' && object !== undefined) { |
|
21392 | query = query.split(/[\. ]/); |
|
21393 | maxDepth = query.length - 1; |
|
21394 | $.each(query, function(depth, value) { |
|
21395 | var camelCaseValue = (depth != maxDepth) |
|
21396 | ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1) |
|
21397 | : query |
|
21398 | ; |
|
21399 | if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) { |
|
21400 | object = object[camelCaseValue]; |
|
21401 | } |
|
21402 | else if( object[camelCaseValue] !== undefined ) { |
|
21403 | found = object[camelCaseValue]; |
|
21404 | return false; |
|
21405 | } |
|
21406 | else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) { |
|
21407 | object = object[value]; |
|
21408 | } |
|
21409 | else if( object[value] !== undefined ) { |
|
21410 | found = object[value]; |
|
21411 | return false; |
|
21412 | } |
|
21413 | else { |
|
21414 | module.error(error.method, query); |
|
21415 | return false; |
|
21416 | } |
|
21417 | }); |
|
21418 | } |
|
21419 | if ( $.isFunction( found ) ) { |
|
21420 | response = found.apply(context, passedArguments); |
|
21421 | } |
|
21422 | else if(found !== undefined) { |
|
21423 | response = found; |
|
21424 | } |
|
21425 | if($.isArray(returnedValue)) { |
|
21426 | returnedValue.push(response); |
|
21427 | } |
|
21428 | else if(returnedValue !== undefined) { |
|
21429 | returnedValue = [returnedValue, response]; |
|
21430 | } |
|
21431 | else if(response !== undefined) { |
|
21432 | returnedValue = response; |
|
21433 | } |
|
21434 | return found; |
|
21435 | } |
|
21436 | }; |
|
21437 | ||
21438 | if(methodInvoked) { |
|
21439 | if(instance === undefined) { |
|
21440 | module.initialize(); |
|
21441 | } |
|
21442 | module.invoke(query); |
|
21443 | } |
|
21444 | else { |
|
21445 | if(instance !== undefined) { |
|
21446 | instance.invoke('destroy'); |
|
21447 | } |
|
21448 | module.initialize(); |
|
21449 | } |
|
21450 | }) |
|
21451 | ; |
|
21452 | ||
21453 | return (returnedValue !== undefined) |
|
21454 | ? returnedValue |
|
21455 | : this |
|
21456 | ; |
|
21457 | }; |
|
21458 | ||
21459 | $.fn.state.settings = { |
|
21460 | ||
21461 | // module info |
|
21462 | name : 'State', |
|
21463 | ||
21464 | // debug output |
|
21465 | debug : false, |
|
21466 | ||
21467 | // verbose debug output |
|
21468 | verbose : false, |
|
21469 | ||
21470 | // namespace for events |
|
21471 | namespace : 'state', |
|
21472 | ||
21473 | // debug data includes performance |
|
21474 | performance : true, |
|
21475 | ||
21476 | // callback occurs on state change |
|
21477 | onActivate : function() {}, |
|
21478 | onDeactivate : function() {}, |
|
21479 | onChange : function() {}, |
|
21480 | ||
21481 | // state test functions |
|
21482 | activateTest : function() { return true; }, |
|
21483 | deactivateTest : function() { return true; }, |
|
21484 | ||
21485 | // whether to automatically map default states |
|
21486 | automatic : true, |
|
21487 | ||
21488 | // activate / deactivate changes all elements instantiated at same time |
|
21489 | sync : false, |
|
21490 | ||
21491 | // default flash text duration, used for temporarily changing text of an element |
|
21492 | flashDuration : 1000, |
|
21493 | ||
21494 | // selector filter |
|
21495 | filter : { |
|
21496 | text : '.loading, .disabled', |
|
21497 | active : '.disabled' |
|
21498 | }, |
|
21499 | ||
21500 | context : false, |
|
21501 | ||
21502 | // error |
|
21503 | error: { |
|
21504 | beforeSend : 'The before send function has cancelled state change', |
|
21505 | method : 'The method you called is not defined.' |
|
21506 | }, |
|
21507 | ||
21508 | // metadata |
|
21509 | metadata: { |
|
21510 | promise : 'promise', |
|
21511 | storedText : 'stored-text' |
|
21512 | }, |
|
21513 | ||
21514 | // change class on state |
|
21515 | className: { |
|
21516 | active : 'active', |
|
21517 | disabled : 'disabled', |
|
21518 | error : 'error', |
|
21519 | loading : 'loading', |
|
21520 | success : 'success', |
|
21521 | warning : 'warning' |
|
21522 | }, |
|
21523 | ||
21524 | selector: { |
|
21525 | // selector for text node |
|
21526 | text: false |
|
21527 | }, |
|
21528 | ||
21529 | defaults : { |
|
21530 | input: { |
|
21531 | disabled : true, |
|
21532 | loading : true, |
|
21533 | active : true |
|
21534 | }, |
|
21535 | button: { |
|
21536 | disabled : true, |
|
21537 | loading : true, |
|
21538 | active : true, |
|
21539 | }, |
|
21540 | progress: { |
|
21541 | active : true, |
|
21542 | success : true, |
|
21543 | warning : true, |
|
21544 | error : true |
|
21545 | } |
|
21546 | }, |
|
21547 | ||
21548 | states : { |
|
21549 | active : true, |
|
21550 | disabled : true, |
|
21551 | error : true, |
|
21552 | loading : true, |
|
21553 | success : true, |
|
21554 | warning : true |
|
21555 | }, |
|
21556 | ||
21557 | text : { |
|
21558 | disabled : false, |
|
21559 | flash : false, |
|
21560 | hover : false, |
|
21561 | active : false, |
|
21562 | inactive : false, |
|
21563 | activate : false, |
|
21564 | deactivate : false |
|
21565 | } |
|
21566 | ||
21567 | }; |
|
21568 | ||
21569 | ||
21570 | ||
21571 | })( jQuery, window, document ); |
|
21572 | ||
21573 | /*! |
|
21574 | * # Semantic UI 2.2.11 - Visibility |
@@ 11-708 (lines=698) @@ | ||
8 | * |
|
9 | */ |
|
10 | ||
11 | ;(function ($, window, document, undefined) { |
|
12 | ||
13 | "use strict"; |
|
14 | ||
15 | window = (typeof window != 'undefined' && window.Math == Math) |
|
16 | ? window |
|
17 | : (typeof self != 'undefined' && self.Math == Math) |
|
18 | ? self |
|
19 | : Function('return this')() |
|
20 | ; |
|
21 | ||
22 | $.fn.state = function(parameters) { |
|
23 | var |
|
24 | $allModules = $(this), |
|
25 | ||
26 | moduleSelector = $allModules.selector || '', |
|
27 | ||
28 | hasTouch = ('ontouchstart' in document.documentElement), |
|
29 | time = new Date().getTime(), |
|
30 | performance = [], |
|
31 | ||
32 | query = arguments[0], |
|
33 | methodInvoked = (typeof query == 'string'), |
|
34 | queryArguments = [].slice.call(arguments, 1), |
|
35 | ||
36 | returnedValue |
|
37 | ; |
|
38 | $allModules |
|
39 | .each(function() { |
|
40 | var |
|
41 | settings = ( $.isPlainObject(parameters) ) |
|
42 | ? $.extend(true, {}, $.fn.state.settings, parameters) |
|
43 | : $.extend({}, $.fn.state.settings), |
|
44 | ||
45 | error = settings.error, |
|
46 | metadata = settings.metadata, |
|
47 | className = settings.className, |
|
48 | namespace = settings.namespace, |
|
49 | states = settings.states, |
|
50 | text = settings.text, |
|
51 | ||
52 | eventNamespace = '.' + namespace, |
|
53 | moduleNamespace = namespace + '-module', |
|
54 | ||
55 | $module = $(this), |
|
56 | ||
57 | element = this, |
|
58 | instance = $module.data(moduleNamespace), |
|
59 | ||
60 | module |
|
61 | ; |
|
62 | module = { |
|
63 | ||
64 | initialize: function() { |
|
65 | module.verbose('Initializing module'); |
|
66 | ||
67 | // allow module to guess desired state based on element |
|
68 | if(settings.automatic) { |
|
69 | module.add.defaults(); |
|
70 | } |
|
71 | ||
72 | // bind events with delegated events |
|
73 | if(settings.context && moduleSelector !== '') { |
|
74 | $(settings.context) |
|
75 | .on(moduleSelector, 'mouseenter' + eventNamespace, module.change.text) |
|
76 | .on(moduleSelector, 'mouseleave' + eventNamespace, module.reset.text) |
|
77 | .on(moduleSelector, 'click' + eventNamespace, module.toggle.state) |
|
78 | ; |
|
79 | } |
|
80 | else { |
|
81 | $module |
|
82 | .on('mouseenter' + eventNamespace, module.change.text) |
|
83 | .on('mouseleave' + eventNamespace, module.reset.text) |
|
84 | .on('click' + eventNamespace, module.toggle.state) |
|
85 | ; |
|
86 | } |
|
87 | module.instantiate(); |
|
88 | }, |
|
89 | ||
90 | instantiate: function() { |
|
91 | module.verbose('Storing instance of module', module); |
|
92 | instance = module; |
|
93 | $module |
|
94 | .data(moduleNamespace, module) |
|
95 | ; |
|
96 | }, |
|
97 | ||
98 | destroy: function() { |
|
99 | module.verbose('Destroying previous module', instance); |
|
100 | $module |
|
101 | .off(eventNamespace) |
|
102 | .removeData(moduleNamespace) |
|
103 | ; |
|
104 | }, |
|
105 | ||
106 | refresh: function() { |
|
107 | module.verbose('Refreshing selector cache'); |
|
108 | $module = $(element); |
|
109 | }, |
|
110 | ||
111 | add: { |
|
112 | defaults: function() { |
|
113 | var |
|
114 | userStates = parameters && $.isPlainObject(parameters.states) |
|
115 | ? parameters.states |
|
116 | : {} |
|
117 | ; |
|
118 | $.each(settings.defaults, function(type, typeStates) { |
|
119 | if( module.is[type] !== undefined && module.is[type]() ) { |
|
120 | module.verbose('Adding default states', type, element); |
|
121 | $.extend(settings.states, typeStates, userStates); |
|
122 | } |
|
123 | }); |
|
124 | } |
|
125 | }, |
|
126 | ||
127 | is: { |
|
128 | ||
129 | active: function() { |
|
130 | return $module.hasClass(className.active); |
|
131 | }, |
|
132 | loading: function() { |
|
133 | return $module.hasClass(className.loading); |
|
134 | }, |
|
135 | inactive: function() { |
|
136 | return !( $module.hasClass(className.active) ); |
|
137 | }, |
|
138 | state: function(state) { |
|
139 | if(className[state] === undefined) { |
|
140 | return false; |
|
141 | } |
|
142 | return $module.hasClass( className[state] ); |
|
143 | }, |
|
144 | ||
145 | enabled: function() { |
|
146 | return !( $module.is(settings.filter.active) ); |
|
147 | }, |
|
148 | disabled: function() { |
|
149 | return ( $module.is(settings.filter.active) ); |
|
150 | }, |
|
151 | textEnabled: function() { |
|
152 | return !( $module.is(settings.filter.text) ); |
|
153 | }, |
|
154 | ||
155 | // definitions for automatic type detection |
|
156 | button: function() { |
|
157 | return $module.is('.button:not(a, .submit)'); |
|
158 | }, |
|
159 | input: function() { |
|
160 | return $module.is('input'); |
|
161 | }, |
|
162 | progress: function() { |
|
163 | return $module.is('.ui.progress'); |
|
164 | } |
|
165 | }, |
|
166 | ||
167 | allow: function(state) { |
|
168 | module.debug('Now allowing state', state); |
|
169 | states[state] = true; |
|
170 | }, |
|
171 | disallow: function(state) { |
|
172 | module.debug('No longer allowing', state); |
|
173 | states[state] = false; |
|
174 | }, |
|
175 | ||
176 | allows: function(state) { |
|
177 | return states[state] || false; |
|
178 | }, |
|
179 | ||
180 | enable: function() { |
|
181 | $module.removeClass(className.disabled); |
|
182 | }, |
|
183 | ||
184 | disable: function() { |
|
185 | $module.addClass(className.disabled); |
|
186 | }, |
|
187 | ||
188 | setState: function(state) { |
|
189 | if(module.allows(state)) { |
|
190 | $module.addClass( className[state] ); |
|
191 | } |
|
192 | }, |
|
193 | ||
194 | removeState: function(state) { |
|
195 | if(module.allows(state)) { |
|
196 | $module.removeClass( className[state] ); |
|
197 | } |
|
198 | }, |
|
199 | ||
200 | toggle: { |
|
201 | state: function() { |
|
202 | var |
|
203 | apiRequest, |
|
204 | requestCancelled |
|
205 | ; |
|
206 | if( module.allows('active') && module.is.enabled() ) { |
|
207 | module.refresh(); |
|
208 | if($.fn.api !== undefined) { |
|
209 | apiRequest = $module.api('get request'); |
|
210 | requestCancelled = $module.api('was cancelled'); |
|
211 | if( requestCancelled ) { |
|
212 | module.debug('API Request cancelled by beforesend'); |
|
213 | settings.activateTest = function(){ return false; }; |
|
214 | settings.deactivateTest = function(){ return false; }; |
|
215 | } |
|
216 | else if(apiRequest) { |
|
217 | module.listenTo(apiRequest); |
|
218 | return; |
|
219 | } |
|
220 | } |
|
221 | module.change.state(); |
|
222 | } |
|
223 | } |
|
224 | }, |
|
225 | ||
226 | listenTo: function(apiRequest) { |
|
227 | module.debug('API request detected, waiting for state signal', apiRequest); |
|
228 | if(apiRequest) { |
|
229 | if(text.loading) { |
|
230 | module.update.text(text.loading); |
|
231 | } |
|
232 | $.when(apiRequest) |
|
233 | .then(function() { |
|
234 | if(apiRequest.state() == 'resolved') { |
|
235 | module.debug('API request succeeded'); |
|
236 | settings.activateTest = function(){ return true; }; |
|
237 | settings.deactivateTest = function(){ return true; }; |
|
238 | } |
|
239 | else { |
|
240 | module.debug('API request failed'); |
|
241 | settings.activateTest = function(){ return false; }; |
|
242 | settings.deactivateTest = function(){ return false; }; |
|
243 | } |
|
244 | module.change.state(); |
|
245 | }) |
|
246 | ; |
|
247 | } |
|
248 | }, |
|
249 | ||
250 | // checks whether active/inactive state can be given |
|
251 | change: { |
|
252 | ||
253 | state: function() { |
|
254 | module.debug('Determining state change direction'); |
|
255 | // inactive to active change |
|
256 | if( module.is.inactive() ) { |
|
257 | module.activate(); |
|
258 | } |
|
259 | else { |
|
260 | module.deactivate(); |
|
261 | } |
|
262 | if(settings.sync) { |
|
263 | module.sync(); |
|
264 | } |
|
265 | settings.onChange.call(element); |
|
266 | }, |
|
267 | ||
268 | text: function() { |
|
269 | if( module.is.textEnabled() ) { |
|
270 | if(module.is.disabled() ) { |
|
271 | module.verbose('Changing text to disabled text', text.hover); |
|
272 | module.update.text(text.disabled); |
|
273 | } |
|
274 | else if( module.is.active() ) { |
|
275 | if(text.hover) { |
|
276 | module.verbose('Changing text to hover text', text.hover); |
|
277 | module.update.text(text.hover); |
|
278 | } |
|
279 | else if(text.deactivate) { |
|
280 | module.verbose('Changing text to deactivating text', text.deactivate); |
|
281 | module.update.text(text.deactivate); |
|
282 | } |
|
283 | } |
|
284 | else { |
|
285 | if(text.hover) { |
|
286 | module.verbose('Changing text to hover text', text.hover); |
|
287 | module.update.text(text.hover); |
|
288 | } |
|
289 | else if(text.activate){ |
|
290 | module.verbose('Changing text to activating text', text.activate); |
|
291 | module.update.text(text.activate); |
|
292 | } |
|
293 | } |
|
294 | } |
|
295 | } |
|
296 | ||
297 | }, |
|
298 | ||
299 | activate: function() { |
|
300 | if( settings.activateTest.call(element) ) { |
|
301 | module.debug('Setting state to active'); |
|
302 | $module |
|
303 | .addClass(className.active) |
|
304 | ; |
|
305 | module.update.text(text.active); |
|
306 | settings.onActivate.call(element); |
|
307 | } |
|
308 | }, |
|
309 | ||
310 | deactivate: function() { |
|
311 | if( settings.deactivateTest.call(element) ) { |
|
312 | module.debug('Setting state to inactive'); |
|
313 | $module |
|
314 | .removeClass(className.active) |
|
315 | ; |
|
316 | module.update.text(text.inactive); |
|
317 | settings.onDeactivate.call(element); |
|
318 | } |
|
319 | }, |
|
320 | ||
321 | sync: function() { |
|
322 | module.verbose('Syncing other buttons to current state'); |
|
323 | if( module.is.active() ) { |
|
324 | $allModules |
|
325 | .not($module) |
|
326 | .state('activate'); |
|
327 | } |
|
328 | else { |
|
329 | $allModules |
|
330 | .not($module) |
|
331 | .state('deactivate') |
|
332 | ; |
|
333 | } |
|
334 | }, |
|
335 | ||
336 | get: { |
|
337 | text: function() { |
|
338 | return (settings.selector.text) |
|
339 | ? $module.find(settings.selector.text).text() |
|
340 | : $module.html() |
|
341 | ; |
|
342 | }, |
|
343 | textFor: function(state) { |
|
344 | return text[state] || false; |
|
345 | } |
|
346 | }, |
|
347 | ||
348 | flash: { |
|
349 | text: function(text, duration, callback) { |
|
350 | var |
|
351 | previousText = module.get.text() |
|
352 | ; |
|
353 | module.debug('Flashing text message', text, duration); |
|
354 | text = text || settings.text.flash; |
|
355 | duration = duration || settings.flashDuration; |
|
356 | callback = callback || function() {}; |
|
357 | module.update.text(text); |
|
358 | setTimeout(function(){ |
|
359 | module.update.text(previousText); |
|
360 | callback.call(element); |
|
361 | }, duration); |
|
362 | } |
|
363 | }, |
|
364 | ||
365 | reset: { |
|
366 | // on mouseout sets text to previous value |
|
367 | text: function() { |
|
368 | var |
|
369 | activeText = text.active || $module.data(metadata.storedText), |
|
370 | inactiveText = text.inactive || $module.data(metadata.storedText) |
|
371 | ; |
|
372 | if( module.is.textEnabled() ) { |
|
373 | if( module.is.active() && activeText) { |
|
374 | module.verbose('Resetting active text', activeText); |
|
375 | module.update.text(activeText); |
|
376 | } |
|
377 | else if(inactiveText) { |
|
378 | module.verbose('Resetting inactive text', activeText); |
|
379 | module.update.text(inactiveText); |
|
380 | } |
|
381 | } |
|
382 | } |
|
383 | }, |
|
384 | ||
385 | update: { |
|
386 | text: function(text) { |
|
387 | var |
|
388 | currentText = module.get.text() |
|
389 | ; |
|
390 | if(text && text !== currentText) { |
|
391 | module.debug('Updating text', text); |
|
392 | if(settings.selector.text) { |
|
393 | $module |
|
394 | .data(metadata.storedText, text) |
|
395 | .find(settings.selector.text) |
|
396 | .text(text) |
|
397 | ; |
|
398 | } |
|
399 | else { |
|
400 | $module |
|
401 | .data(metadata.storedText, text) |
|
402 | .html(text) |
|
403 | ; |
|
404 | } |
|
405 | } |
|
406 | else { |
|
407 | module.debug('Text is already set, ignoring update', text); |
|
408 | } |
|
409 | } |
|
410 | }, |
|
411 | ||
412 | setting: function(name, value) { |
|
413 | module.debug('Changing setting', name, value); |
|
414 | if( $.isPlainObject(name) ) { |
|
415 | $.extend(true, settings, name); |
|
416 | } |
|
417 | else if(value !== undefined) { |
|
418 | if($.isPlainObject(settings[name])) { |
|
419 | $.extend(true, settings[name], value); |
|
420 | } |
|
421 | else { |
|
422 | settings[name] = value; |
|
423 | } |
|
424 | } |
|
425 | else { |
|
426 | return settings[name]; |
|
427 | } |
|
428 | }, |
|
429 | internal: function(name, value) { |
|
430 | if( $.isPlainObject(name) ) { |
|
431 | $.extend(true, module, name); |
|
432 | } |
|
433 | else if(value !== undefined) { |
|
434 | module[name] = value; |
|
435 | } |
|
436 | else { |
|
437 | return module[name]; |
|
438 | } |
|
439 | }, |
|
440 | debug: function() { |
|
441 | if(!settings.silent && settings.debug) { |
|
442 | if(settings.performance) { |
|
443 | module.performance.log(arguments); |
|
444 | } |
|
445 | else { |
|
446 | module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':'); |
|
447 | module.debug.apply(console, arguments); |
|
448 | } |
|
449 | } |
|
450 | }, |
|
451 | verbose: function() { |
|
452 | if(!settings.silent && settings.verbose && settings.debug) { |
|
453 | if(settings.performance) { |
|
454 | module.performance.log(arguments); |
|
455 | } |
|
456 | else { |
|
457 | module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':'); |
|
458 | module.verbose.apply(console, arguments); |
|
459 | } |
|
460 | } |
|
461 | }, |
|
462 | error: function() { |
|
463 | if(!settings.silent) { |
|
464 | module.error = Function.prototype.bind.call(console.error, console, settings.name + ':'); |
|
465 | module.error.apply(console, arguments); |
|
466 | } |
|
467 | }, |
|
468 | performance: { |
|
469 | log: function(message) { |
|
470 | var |
|
471 | currentTime, |
|
472 | executionTime, |
|
473 | previousTime |
|
474 | ; |
|
475 | if(settings.performance) { |
|
476 | currentTime = new Date().getTime(); |
|
477 | previousTime = time || currentTime; |
|
478 | executionTime = currentTime - previousTime; |
|
479 | time = currentTime; |
|
480 | performance.push({ |
|
481 | 'Name' : message[0], |
|
482 | 'Arguments' : [].slice.call(message, 1) || '', |
|
483 | 'Element' : element, |
|
484 | 'Execution Time' : executionTime |
|
485 | }); |
|
486 | } |
|
487 | clearTimeout(module.performance.timer); |
|
488 | module.performance.timer = setTimeout(module.performance.display, 500); |
|
489 | }, |
|
490 | display: function() { |
|
491 | var |
|
492 | title = settings.name + ':', |
|
493 | totalTime = 0 |
|
494 | ; |
|
495 | time = false; |
|
496 | clearTimeout(module.performance.timer); |
|
497 | $.each(performance, function(index, data) { |
|
498 | totalTime += data['Execution Time']; |
|
499 | }); |
|
500 | title += ' ' + totalTime + 'ms'; |
|
501 | if(moduleSelector) { |
|
502 | title += ' \'' + moduleSelector + '\''; |
|
503 | } |
|
504 | if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) { |
|
505 | console.groupCollapsed(title); |
|
506 | if(console.table) { |
|
507 | console.table(performance); |
|
508 | } |
|
509 | else { |
|
510 | $.each(performance, function(index, data) { |
|
511 | console.log(data['Name'] + ': ' + data['Execution Time']+'ms'); |
|
512 | }); |
|
513 | } |
|
514 | console.groupEnd(); |
|
515 | } |
|
516 | performance = []; |
|
517 | } |
|
518 | }, |
|
519 | invoke: function(query, passedArguments, context) { |
|
520 | var |
|
521 | object = instance, |
|
522 | maxDepth, |
|
523 | found, |
|
524 | response |
|
525 | ; |
|
526 | passedArguments = passedArguments || queryArguments; |
|
527 | context = element || context; |
|
528 | if(typeof query == 'string' && object !== undefined) { |
|
529 | query = query.split(/[\. ]/); |
|
530 | maxDepth = query.length - 1; |
|
531 | $.each(query, function(depth, value) { |
|
532 | var camelCaseValue = (depth != maxDepth) |
|
533 | ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1) |
|
534 | : query |
|
535 | ; |
|
536 | if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) { |
|
537 | object = object[camelCaseValue]; |
|
538 | } |
|
539 | else if( object[camelCaseValue] !== undefined ) { |
|
540 | found = object[camelCaseValue]; |
|
541 | return false; |
|
542 | } |
|
543 | else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) { |
|
544 | object = object[value]; |
|
545 | } |
|
546 | else if( object[value] !== undefined ) { |
|
547 | found = object[value]; |
|
548 | return false; |
|
549 | } |
|
550 | else { |
|
551 | module.error(error.method, query); |
|
552 | return false; |
|
553 | } |
|
554 | }); |
|
555 | } |
|
556 | if ( $.isFunction( found ) ) { |
|
557 | response = found.apply(context, passedArguments); |
|
558 | } |
|
559 | else if(found !== undefined) { |
|
560 | response = found; |
|
561 | } |
|
562 | if($.isArray(returnedValue)) { |
|
563 | returnedValue.push(response); |
|
564 | } |
|
565 | else if(returnedValue !== undefined) { |
|
566 | returnedValue = [returnedValue, response]; |
|
567 | } |
|
568 | else if(response !== undefined) { |
|
569 | returnedValue = response; |
|
570 | } |
|
571 | return found; |
|
572 | } |
|
573 | }; |
|
574 | ||
575 | if(methodInvoked) { |
|
576 | if(instance === undefined) { |
|
577 | module.initialize(); |
|
578 | } |
|
579 | module.invoke(query); |
|
580 | } |
|
581 | else { |
|
582 | if(instance !== undefined) { |
|
583 | instance.invoke('destroy'); |
|
584 | } |
|
585 | module.initialize(); |
|
586 | } |
|
587 | }) |
|
588 | ; |
|
589 | ||
590 | return (returnedValue !== undefined) |
|
591 | ? returnedValue |
|
592 | : this |
|
593 | ; |
|
594 | }; |
|
595 | ||
596 | $.fn.state.settings = { |
|
597 | ||
598 | // module info |
|
599 | name : 'State', |
|
600 | ||
601 | // debug output |
|
602 | debug : false, |
|
603 | ||
604 | // verbose debug output |
|
605 | verbose : false, |
|
606 | ||
607 | // namespace for events |
|
608 | namespace : 'state', |
|
609 | ||
610 | // debug data includes performance |
|
611 | performance : true, |
|
612 | ||
613 | // callback occurs on state change |
|
614 | onActivate : function() {}, |
|
615 | onDeactivate : function() {}, |
|
616 | onChange : function() {}, |
|
617 | ||
618 | // state test functions |
|
619 | activateTest : function() { return true; }, |
|
620 | deactivateTest : function() { return true; }, |
|
621 | ||
622 | // whether to automatically map default states |
|
623 | automatic : true, |
|
624 | ||
625 | // activate / deactivate changes all elements instantiated at same time |
|
626 | sync : false, |
|
627 | ||
628 | // default flash text duration, used for temporarily changing text of an element |
|
629 | flashDuration : 1000, |
|
630 | ||
631 | // selector filter |
|
632 | filter : { |
|
633 | text : '.loading, .disabled', |
|
634 | active : '.disabled' |
|
635 | }, |
|
636 | ||
637 | context : false, |
|
638 | ||
639 | // error |
|
640 | error: { |
|
641 | beforeSend : 'The before send function has cancelled state change', |
|
642 | method : 'The method you called is not defined.' |
|
643 | }, |
|
644 | ||
645 | // metadata |
|
646 | metadata: { |
|
647 | promise : 'promise', |
|
648 | storedText : 'stored-text' |
|
649 | }, |
|
650 | ||
651 | // change class on state |
|
652 | className: { |
|
653 | active : 'active', |
|
654 | disabled : 'disabled', |
|
655 | error : 'error', |
|
656 | loading : 'loading', |
|
657 | success : 'success', |
|
658 | warning : 'warning' |
|
659 | }, |
|
660 | ||
661 | selector: { |
|
662 | // selector for text node |
|
663 | text: false |
|
664 | }, |
|
665 | ||
666 | defaults : { |
|
667 | input: { |
|
668 | disabled : true, |
|
669 | loading : true, |
|
670 | active : true |
|
671 | }, |
|
672 | button: { |
|
673 | disabled : true, |
|
674 | loading : true, |
|
675 | active : true, |
|
676 | }, |
|
677 | progress: { |
|
678 | active : true, |
|
679 | success : true, |
|
680 | warning : true, |
|
681 | error : true |
|
682 | } |
|
683 | }, |
|
684 | ||
685 | states : { |
|
686 | active : true, |
|
687 | disabled : true, |
|
688 | error : true, |
|
689 | loading : true, |
|
690 | success : true, |
|
691 | warning : true |
|
692 | }, |
|
693 | ||
694 | text : { |
|
695 | disabled : false, |
|
696 | flash : false, |
|
697 | hover : false, |
|
698 | active : false, |
|
699 | inactive : false, |
|
700 | activate : false, |
|
701 | deactivate : false |
|
702 | } |
|
703 | ||
704 | }; |
|
705 | ||
706 | ||
707 | ||
708 | })( jQuery, window, document ); |
|
709 |