Total Complexity | 4604 |
Complexity/F | 2.55 |
Lines of Code | 22863 |
Function Count | 1804 |
Duplicated Lines | 22642 |
Ratio | 99.03 % |
Changes | 0 |
Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like public/lib/semantic/semantic.js often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
1 | /* |
||
21 | View Code Duplication | ;(function ($, window, document, undefined) { |
|
|
|||
22 | |||
23 | $.site = $.fn.site = function(parameters) { |
||
24 | var |
||
25 | time = new Date().getTime(), |
||
26 | performance = [], |
||
27 | |||
28 | query = arguments[0], |
||
29 | methodInvoked = (typeof query == 'string'), |
||
30 | queryArguments = [].slice.call(arguments, 1), |
||
31 | |||
32 | settings = ( $.isPlainObject(parameters) ) |
||
33 | ? $.extend(true, {}, $.site.settings, parameters) |
||
34 | : $.extend({}, $.site.settings), |
||
35 | |||
36 | namespace = settings.namespace, |
||
37 | error = settings.error, |
||
38 | |||
39 | eventNamespace = '.' + namespace, |
||
40 | moduleNamespace = 'module-' + namespace, |
||
41 | |||
42 | $document = $(document), |
||
43 | $module = $document, |
||
44 | element = this, |
||
45 | instance = $module.data(moduleNamespace), |
||
46 | |||
47 | module, |
||
48 | returnedValue |
||
49 | ; |
||
50 | module = { |
||
51 | |||
52 | initialize: function() { |
||
53 | module.instantiate(); |
||
54 | }, |
||
55 | |||
56 | instantiate: function() { |
||
57 | module.verbose('Storing instance of site', module); |
||
58 | instance = module; |
||
59 | $module |
||
60 | .data(moduleNamespace, module) |
||
61 | ; |
||
62 | }, |
||
63 | |||
64 | normalize: function() { |
||
65 | module.fix.console(); |
||
66 | module.fix.requestAnimationFrame(); |
||
67 | }, |
||
68 | |||
69 | fix: { |
||
70 | console: function() { |
||
71 | module.debug('Normalizing window.console'); |
||
72 | if (console === undefined || console.log === undefined) { |
||
73 | module.verbose('Console not available, normalizing events'); |
||
74 | module.disable.console(); |
||
75 | } |
||
76 | if (typeof console.group == 'undefined' || typeof console.groupEnd == 'undefined' || typeof console.groupCollapsed == 'undefined') { |
||
77 | module.verbose('Console group not available, normalizing events'); |
||
78 | window.console.group = function() {}; |
||
79 | window.console.groupEnd = function() {}; |
||
80 | window.console.groupCollapsed = function() {}; |
||
81 | } |
||
82 | if (typeof console.markTimeline == 'undefined') { |
||
83 | module.verbose('Mark timeline not available, normalizing events'); |
||
84 | window.console.markTimeline = function() {}; |
||
85 | } |
||
86 | }, |
||
87 | consoleClear: function() { |
||
88 | module.debug('Disabling programmatic console clearing'); |
||
89 | window.console.clear = function() {}; |
||
90 | }, |
||
91 | requestAnimationFrame: function() { |
||
92 | module.debug('Normalizing requestAnimationFrame'); |
||
93 | if(window.requestAnimationFrame === undefined) { |
||
94 | module.debug('RequestAnimationFrame not available, normalizing event'); |
||
95 | window.requestAnimationFrame = window.requestAnimationFrame |
||
96 | || window.mozRequestAnimationFrame |
||
97 | || window.webkitRequestAnimationFrame |
||
98 | || window.msRequestAnimationFrame |
||
99 | || function(callback) { setTimeout(callback, 0); } |
||
100 | ; |
||
101 | } |
||
102 | } |
||
103 | }, |
||
104 | |||
105 | moduleExists: function(name) { |
||
106 | return ($.fn[name] !== undefined && $.fn[name].settings !== undefined); |
||
107 | }, |
||
108 | |||
109 | enabled: { |
||
110 | modules: function(modules) { |
||
111 | var |
||
112 | enabledModules = [] |
||
113 | ; |
||
114 | modules = modules || settings.modules; |
||
115 | $.each(modules, function(index, name) { |
||
116 | if(module.moduleExists(name)) { |
||
117 | enabledModules.push(name); |
||
118 | } |
||
119 | }); |
||
120 | return enabledModules; |
||
121 | } |
||
122 | }, |
||
123 | |||
124 | disabled: { |
||
125 | modules: function(modules) { |
||
126 | var |
||
127 | disabledModules = [] |
||
128 | ; |
||
129 | modules = modules || settings.modules; |
||
130 | $.each(modules, function(index, name) { |
||
131 | if(!module.moduleExists(name)) { |
||
132 | disabledModules.push(name); |
||
133 | } |
||
134 | }); |
||
135 | return disabledModules; |
||
136 | } |
||
137 | }, |
||
138 | |||
139 | change: { |
||
140 | setting: function(setting, value, modules, modifyExisting) { |
||
141 | modules = (typeof modules === 'string') |
||
142 | ? (modules === 'all') |
||
143 | ? settings.modules |
||
144 | : [modules] |
||
145 | : modules || settings.modules |
||
146 | ; |
||
147 | modifyExisting = (modifyExisting !== undefined) |
||
148 | ? modifyExisting |
||
149 | : true |
||
150 | ; |
||
151 | $.each(modules, function(index, name) { |
||
152 | var |
||
153 | namespace = (module.moduleExists(name)) |
||
154 | ? $.fn[name].settings.namespace || false |
||
155 | : true, |
||
156 | $existingModules |
||
157 | ; |
||
158 | if(module.moduleExists(name)) { |
||
159 | module.verbose('Changing default setting', setting, value, name); |
||
160 | $.fn[name].settings[setting] = value; |
||
161 | if(modifyExisting && namespace) { |
||
162 | $existingModules = $(':data(module-' + namespace + ')'); |
||
163 | if($existingModules.length > 0) { |
||
164 | module.verbose('Modifying existing settings', $existingModules); |
||
165 | $existingModules[name]('setting', setting, value); |
||
166 | } |
||
167 | } |
||
168 | } |
||
169 | }); |
||
170 | }, |
||
171 | settings: function(newSettings, modules, modifyExisting) { |
||
172 | modules = (typeof modules === 'string') |
||
173 | ? [modules] |
||
174 | : modules || settings.modules |
||
175 | ; |
||
176 | modifyExisting = (modifyExisting !== undefined) |
||
177 | ? modifyExisting |
||
178 | : true |
||
179 | ; |
||
180 | $.each(modules, function(index, name) { |
||
181 | var |
||
182 | $existingModules |
||
183 | ; |
||
184 | if(module.moduleExists(name)) { |
||
185 | module.verbose('Changing default setting', newSettings, name); |
||
186 | $.extend(true, $.fn[name].settings, newSettings); |
||
187 | if(modifyExisting && namespace) { |
||
188 | $existingModules = $(':data(module-' + namespace + ')'); |
||
189 | if($existingModules.length > 0) { |
||
190 | module.verbose('Modifying existing settings', $existingModules); |
||
191 | $existingModules[name]('setting', newSettings); |
||
192 | } |
||
193 | } |
||
194 | } |
||
195 | }); |
||
196 | } |
||
197 | }, |
||
198 | |||
199 | enable: { |
||
200 | console: function() { |
||
201 | module.console(true); |
||
202 | }, |
||
203 | debug: function(modules, modifyExisting) { |
||
204 | modules = modules || settings.modules; |
||
205 | module.debug('Enabling debug for modules', modules); |
||
206 | module.change.setting('debug', true, modules, modifyExisting); |
||
207 | }, |
||
208 | verbose: function(modules, modifyExisting) { |
||
209 | modules = modules || settings.modules; |
||
210 | module.debug('Enabling verbose debug for modules', modules); |
||
211 | module.change.setting('verbose', true, modules, modifyExisting); |
||
212 | } |
||
213 | }, |
||
214 | disable: { |
||
215 | console: function() { |
||
216 | module.console(false); |
||
217 | }, |
||
218 | debug: function(modules, modifyExisting) { |
||
219 | modules = modules || settings.modules; |
||
220 | module.debug('Disabling debug for modules', modules); |
||
221 | module.change.setting('debug', false, modules, modifyExisting); |
||
222 | }, |
||
223 | verbose: function(modules, modifyExisting) { |
||
224 | modules = modules || settings.modules; |
||
225 | module.debug('Disabling verbose debug for modules', modules); |
||
226 | module.change.setting('verbose', false, modules, modifyExisting); |
||
227 | } |
||
228 | }, |
||
229 | |||
230 | console: function(enable) { |
||
231 | if(enable) { |
||
232 | if(instance.cache.console === undefined) { |
||
233 | module.error(error.console); |
||
234 | return; |
||
235 | } |
||
236 | module.debug('Restoring console function'); |
||
237 | window.console = instance.cache.console; |
||
238 | } |
||
239 | else { |
||
240 | module.debug('Disabling console function'); |
||
241 | instance.cache.console = window.console; |
||
242 | window.console = { |
||
243 | clear : function(){}, |
||
244 | error : function(){}, |
||
245 | group : function(){}, |
||
246 | groupCollapsed : function(){}, |
||
247 | groupEnd : function(){}, |
||
248 | info : function(){}, |
||
249 | log : function(){}, |
||
250 | markTimeline : function(){}, |
||
251 | warn : function(){} |
||
252 | }; |
||
253 | } |
||
254 | }, |
||
255 | |||
256 | destroy: function() { |
||
257 | module.verbose('Destroying previous site for', $module); |
||
258 | $module |
||
259 | .removeData(moduleNamespace) |
||
260 | ; |
||
261 | }, |
||
262 | |||
263 | cache: {}, |
||
264 | |||
265 | setting: function(name, value) { |
||
266 | if( $.isPlainObject(name) ) { |
||
267 | $.extend(true, settings, name); |
||
268 | } |
||
269 | else if(value !== undefined) { |
||
270 | settings[name] = value; |
||
271 | } |
||
272 | else { |
||
273 | return settings[name]; |
||
274 | } |
||
275 | }, |
||
276 | internal: function(name, value) { |
||
277 | if( $.isPlainObject(name) ) { |
||
278 | $.extend(true, module, name); |
||
279 | } |
||
280 | else if(value !== undefined) { |
||
281 | module[name] = value; |
||
282 | } |
||
283 | else { |
||
284 | return module[name]; |
||
285 | } |
||
286 | }, |
||
287 | debug: function() { |
||
288 | if(settings.debug) { |
||
289 | if(settings.performance) { |
||
290 | module.performance.log(arguments); |
||
291 | } |
||
292 | else { |
||
293 | module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':'); |
||
294 | module.debug.apply(console, arguments); |
||
295 | } |
||
296 | } |
||
297 | }, |
||
298 | verbose: function() { |
||
299 | if(settings.verbose && settings.debug) { |
||
300 | if(settings.performance) { |
||
301 | module.performance.log(arguments); |
||
302 | } |
||
303 | else { |
||
304 | module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':'); |
||
305 | module.verbose.apply(console, arguments); |
||
306 | } |
||
307 | } |
||
308 | }, |
||
309 | error: function() { |
||
310 | module.error = Function.prototype.bind.call(console.error, console, settings.name + ':'); |
||
311 | module.error.apply(console, arguments); |
||
312 | }, |
||
313 | performance: { |
||
314 | log: function(message) { |
||
315 | var |
||
316 | currentTime, |
||
317 | executionTime, |
||
318 | previousTime |
||
319 | ; |
||
320 | if(settings.performance) { |
||
321 | currentTime = new Date().getTime(); |
||
322 | previousTime = time || currentTime; |
||
323 | executionTime = currentTime - previousTime; |
||
324 | time = currentTime; |
||
325 | performance.push({ |
||
326 | 'Element' : element, |
||
327 | 'Name' : message[0], |
||
328 | 'Arguments' : [].slice.call(message, 1) || '', |
||
329 | 'Execution Time' : executionTime |
||
330 | }); |
||
331 | } |
||
332 | clearTimeout(module.performance.timer); |
||
333 | module.performance.timer = setTimeout(module.performance.display, 500); |
||
334 | }, |
||
335 | display: function() { |
||
336 | var |
||
337 | title = settings.name + ':', |
||
338 | totalTime = 0 |
||
339 | ; |
||
340 | time = false; |
||
341 | clearTimeout(module.performance.timer); |
||
342 | $.each(performance, function(index, data) { |
||
343 | totalTime += data['Execution Time']; |
||
344 | }); |
||
345 | title += ' ' + totalTime + 'ms'; |
||
346 | if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) { |
||
347 | console.groupCollapsed(title); |
||
348 | if(console.table) { |
||
349 | console.table(performance); |
||
350 | } |
||
351 | else { |
||
352 | $.each(performance, function(index, data) { |
||
353 | console.log(data['Name'] + ': ' + data['Execution Time']+'ms'); |
||
354 | }); |
||
355 | } |
||
356 | console.groupEnd(); |
||
357 | } |
||
358 | performance = []; |
||
359 | } |
||
360 | }, |
||
361 | invoke: function(query, passedArguments, context) { |
||
362 | var |
||
363 | object = instance, |
||
364 | maxDepth, |
||
365 | found, |
||
366 | response |
||
367 | ; |
||
368 | passedArguments = passedArguments || queryArguments; |
||
369 | context = element || context; |
||
370 | if(typeof query == 'string' && object !== undefined) { |
||
371 | query = query.split(/[\. ]/); |
||
372 | maxDepth = query.length - 1; |
||
373 | $.each(query, function(depth, value) { |
||
374 | var camelCaseValue = (depth != maxDepth) |
||
375 | ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1) |
||
376 | : query |
||
377 | ; |
||
378 | if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) { |
||
379 | object = object[camelCaseValue]; |
||
380 | } |
||
381 | else if( object[camelCaseValue] !== undefined ) { |
||
382 | found = object[camelCaseValue]; |
||
383 | return false; |
||
384 | } |
||
385 | else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) { |
||
386 | object = object[value]; |
||
387 | } |
||
388 | else if( object[value] !== undefined ) { |
||
389 | found = object[value]; |
||
390 | return false; |
||
391 | } |
||
392 | else { |
||
393 | module.error(error.method, query); |
||
394 | return false; |
||
395 | } |
||
396 | }); |
||
397 | } |
||
398 | if ( $.isFunction( found ) ) { |
||
399 | response = found.apply(context, passedArguments); |
||
400 | } |
||
401 | else if(found !== undefined) { |
||
402 | response = found; |
||
403 | } |
||
404 | if($.isArray(returnedValue)) { |
||
405 | returnedValue.push(response); |
||
406 | } |
||
407 | else if(returnedValue !== undefined) { |
||
408 | returnedValue = [returnedValue, response]; |
||
409 | } |
||
410 | else if(response !== undefined) { |
||
411 | returnedValue = response; |
||
412 | } |
||
413 | return found; |
||
414 | } |
||
415 | }; |
||
416 | |||
417 | if(methodInvoked) { |
||
418 | if(instance === undefined) { |
||
419 | module.initialize(); |
||
420 | } |
||
421 | module.invoke(query); |
||
422 | } |
||
423 | else { |
||
424 | if(instance !== undefined) { |
||
425 | module.destroy(); |
||
426 | } |
||
427 | module.initialize(); |
||
428 | } |
||
429 | return (returnedValue !== undefined) |
||
430 | ? returnedValue |
||
431 | : this |
||
432 | ; |
||
433 | }; |
||
434 | |||
435 | $.site.settings = { |
||
436 | |||
437 | name : 'Site', |
||
438 | namespace : 'site', |
||
439 | |||
440 | error : { |
||
441 | console : 'Console cannot be restored, most likely it was overwritten outside of module', |
||
442 | method : 'The method you called is not defined.' |
||
443 | }, |
||
444 | |||
445 | debug : false, |
||
446 | verbose : false, |
||
447 | performance : true, |
||
448 | |||
449 | modules: [ |
||
450 | 'accordion', |
||
451 | 'api', |
||
452 | 'checkbox', |
||
453 | 'dimmer', |
||
454 | 'dropdown', |
||
455 | 'embed', |
||
456 | 'form', |
||
457 | 'modal', |
||
458 | 'nag', |
||
459 | 'popup', |
||
460 | 'rating', |
||
461 | 'shape', |
||
462 | 'sidebar', |
||
463 | 'state', |
||
464 | 'sticky', |
||
465 | 'tab', |
||
466 | 'transition', |
||
467 | 'visit', |
||
468 | 'visibility' |
||
469 | ], |
||
470 | |||
471 | siteNamespace : 'site', |
||
472 | namespaceStub : { |
||
473 | cache : {}, |
||
474 | config : {}, |
||
475 | sections : {}, |
||
476 | section : {}, |
||
477 | utilities : {} |
||
478 | } |
||
479 | |||
480 | }; |
||
481 | |||
482 | // allows for selection of elements with data attributes |
||
483 | $.extend($.expr[ ":" ], { |
||
484 | data: ($.expr.createPseudo) |
||
485 | ? $.expr.createPseudo(function(dataName) { |
||
486 | return function(elem) { |
||
487 | return !!$.data(elem, dataName); |
||
488 | }; |
||
489 | }) |
||
490 | : function(elem, i, match) { |
||
491 | // support: jQuery < 1.8 |
||
492 | return !!$.data(elem, match[ 3 ]); |
||
493 | } |
||
494 | }); |
||
495 | |||
496 | |||
497 | })( jQuery, window, document ); |
||
498 | |||
499 | /*! |
||
500 | * # Semantic UI 2.2.11 - Form Validation |
||
501 | * http://github.com/semantic-org/semantic-ui/ |
||
502 | * |
||
503 | * |
||
504 | * Released under the MIT license |
||
505 | * http://opensource.org/licenses/MIT |
||
506 | * |
||
507 | */ |
||
508 | |||
509 | View Code Duplication | ;(function ($, window, document, undefined) { |
|
510 | |||
511 | "use strict"; |
||
512 | |||
513 | window = (typeof window != 'undefined' && window.Math == Math) |
||
514 | ? window |
||
515 | : (typeof self != 'undefined' && self.Math == Math) |
||
516 | ? self |
||
517 | : Function('return this')() |
||
518 | ; |
||
519 | |||
520 | $.fn.form = function(parameters) { |
||
521 | var |
||
522 | $allModules = $(this), |
||
523 | moduleSelector = $allModules.selector || '', |
||
524 | |||
525 | time = new Date().getTime(), |
||
526 | performance = [], |
||
527 | |||
528 | query = arguments[0], |
||
529 | legacyParameters = arguments[1], |
||
530 | methodInvoked = (typeof query == 'string'), |
||
531 | queryArguments = [].slice.call(arguments, 1), |
||
532 | returnedValue |
||
533 | ; |
||
534 | $allModules |
||
535 | .each(function() { |
||
536 | var |
||
537 | $module = $(this), |
||
538 | element = this, |
||
539 | |||
540 | formErrors = [], |
||
541 | keyHeldDown = false, |
||
542 | |||
543 | // set at run-time |
||
544 | $field, |
||
545 | $group, |
||
546 | $message, |
||
547 | $prompt, |
||
548 | $submit, |
||
549 | $clear, |
||
550 | $reset, |
||
551 | |||
552 | settings, |
||
553 | validation, |
||
554 | |||
555 | metadata, |
||
556 | selector, |
||
557 | className, |
||
558 | regExp, |
||
559 | error, |
||
560 | |||
561 | namespace, |
||
562 | moduleNamespace, |
||
563 | eventNamespace, |
||
564 | |||
565 | instance, |
||
566 | module |
||
567 | ; |
||
568 | |||
569 | module = { |
||
570 | |||
571 | initialize: function() { |
||
572 | |||
573 | // settings grabbed at run time |
||
574 | module.get.settings(); |
||
575 | if(methodInvoked) { |
||
576 | if(instance === undefined) { |
||
577 | module.instantiate(); |
||
578 | } |
||
579 | module.invoke(query); |
||
580 | } |
||
581 | else { |
||
582 | if(instance !== undefined) { |
||
583 | instance.invoke('destroy'); |
||
584 | } |
||
585 | module.verbose('Initializing form validation', $module, settings); |
||
586 | module.bindEvents(); |
||
587 | module.set.defaults(); |
||
588 | module.instantiate(); |
||
589 | } |
||
590 | }, |
||
591 | |||
592 | instantiate: function() { |
||
593 | module.verbose('Storing instance of module', module); |
||
594 | instance = module; |
||
595 | $module |
||
596 | .data(moduleNamespace, module) |
||
597 | ; |
||
598 | }, |
||
599 | |||
600 | destroy: function() { |
||
601 | module.verbose('Destroying previous module', instance); |
||
602 | module.removeEvents(); |
||
603 | $module |
||
604 | .removeData(moduleNamespace) |
||
605 | ; |
||
606 | }, |
||
607 | |||
608 | refresh: function() { |
||
609 | module.verbose('Refreshing selector cache'); |
||
610 | $field = $module.find(selector.field); |
||
611 | $group = $module.find(selector.group); |
||
612 | $message = $module.find(selector.message); |
||
613 | $prompt = $module.find(selector.prompt); |
||
614 | |||
615 | $submit = $module.find(selector.submit); |
||
616 | $clear = $module.find(selector.clear); |
||
617 | $reset = $module.find(selector.reset); |
||
618 | }, |
||
619 | |||
620 | submit: function() { |
||
621 | module.verbose('Submitting form', $module); |
||
622 | $module |
||
623 | .submit() |
||
624 | ; |
||
625 | }, |
||
626 | |||
627 | attachEvents: function(selector, action) { |
||
628 | action = action || 'submit'; |
||
629 | $(selector) |
||
630 | .on('click' + eventNamespace, function(event) { |
||
631 | module[action](); |
||
632 | event.preventDefault(); |
||
633 | }) |
||
634 | ; |
||
635 | }, |
||
636 | |||
637 | bindEvents: function() { |
||
638 | module.verbose('Attaching form events'); |
||
639 | $module |
||
640 | .on('submit' + eventNamespace, module.validate.form) |
||
641 | .on('blur' + eventNamespace, selector.field, module.event.field.blur) |
||
642 | .on('click' + eventNamespace, selector.submit, module.submit) |
||
643 | .on('click' + eventNamespace, selector.reset, module.reset) |
||
644 | .on('click' + eventNamespace, selector.clear, module.clear) |
||
645 | ; |
||
646 | if(settings.keyboardShortcuts) { |
||
647 | $module |
||
648 | .on('keydown' + eventNamespace, selector.field, module.event.field.keydown) |
||
649 | ; |
||
650 | } |
||
651 | $field |
||
652 | .each(function() { |
||
653 | var |
||
654 | $input = $(this), |
||
655 | type = $input.prop('type'), |
||
656 | inputEvent = module.get.changeEvent(type, $input) |
||
657 | ; |
||
658 | $(this) |
||
659 | .on(inputEvent + eventNamespace, module.event.field.change) |
||
660 | ; |
||
661 | }) |
||
662 | ; |
||
663 | }, |
||
664 | |||
665 | clear: function() { |
||
666 | $field |
||
667 | .each(function () { |
||
668 | var |
||
669 | $field = $(this), |
||
670 | $element = $field.parent(), |
||
671 | $fieldGroup = $field.closest($group), |
||
672 | $prompt = $fieldGroup.find(selector.prompt), |
||
673 | defaultValue = $field.data(metadata.defaultValue) || '', |
||
674 | isCheckbox = $element.is(selector.uiCheckbox), |
||
675 | isDropdown = $element.is(selector.uiDropdown), |
||
676 | isErrored = $fieldGroup.hasClass(className.error) |
||
677 | ; |
||
678 | if(isErrored) { |
||
679 | module.verbose('Resetting error on field', $fieldGroup); |
||
680 | $fieldGroup.removeClass(className.error); |
||
681 | $prompt.remove(); |
||
682 | } |
||
683 | if(isDropdown) { |
||
684 | module.verbose('Resetting dropdown value', $element, defaultValue); |
||
685 | $element.dropdown('clear'); |
||
686 | } |
||
687 | else if(isCheckbox) { |
||
688 | $field.prop('checked', false); |
||
689 | } |
||
690 | else { |
||
691 | module.verbose('Resetting field value', $field, defaultValue); |
||
692 | $field.val(''); |
||
693 | } |
||
694 | }) |
||
695 | ; |
||
696 | }, |
||
697 | |||
698 | reset: function() { |
||
699 | $field |
||
700 | .each(function () { |
||
701 | var |
||
702 | $field = $(this), |
||
703 | $element = $field.parent(), |
||
704 | $fieldGroup = $field.closest($group), |
||
705 | $prompt = $fieldGroup.find(selector.prompt), |
||
706 | defaultValue = $field.data(metadata.defaultValue), |
||
707 | isCheckbox = $element.is(selector.uiCheckbox), |
||
708 | isDropdown = $element.is(selector.uiDropdown), |
||
709 | isErrored = $fieldGroup.hasClass(className.error) |
||
710 | ; |
||
711 | if(defaultValue === undefined) { |
||
712 | return; |
||
713 | } |
||
714 | if(isErrored) { |
||
715 | module.verbose('Resetting error on field', $fieldGroup); |
||
716 | $fieldGroup.removeClass(className.error); |
||
717 | $prompt.remove(); |
||
718 | } |
||
719 | if(isDropdown) { |
||
720 | module.verbose('Resetting dropdown value', $element, defaultValue); |
||
721 | $element.dropdown('restore defaults'); |
||
722 | } |
||
723 | else if(isCheckbox) { |
||
724 | module.verbose('Resetting checkbox value', $element, defaultValue); |
||
725 | $field.prop('checked', defaultValue); |
||
726 | } |
||
727 | else { |
||
728 | module.verbose('Resetting field value', $field, defaultValue); |
||
729 | $field.val(defaultValue); |
||
730 | } |
||
731 | }) |
||
732 | ; |
||
733 | }, |
||
734 | |||
735 | determine: { |
||
736 | isValid: function() { |
||
737 | var |
||
738 | allValid = true |
||
739 | ; |
||
740 | $.each(validation, function(fieldName, field) { |
||
741 | if( !( module.validate.field(field, fieldName, true) ) ) { |
||
742 | allValid = false; |
||
743 | } |
||
744 | }); |
||
745 | return allValid; |
||
746 | } |
||
747 | }, |
||
748 | |||
749 | is: { |
||
750 | bracketedRule: function(rule) { |
||
751 | return (rule.type && rule.type.match(settings.regExp.bracket)); |
||
752 | }, |
||
753 | shorthandFields: function(fields) { |
||
754 | var |
||
755 | fieldKeys = Object.keys(fields), |
||
756 | firstRule = fields[fieldKeys[0]] |
||
757 | ; |
||
758 | return module.is.shorthandRules(firstRule); |
||
759 | }, |
||
760 | // duck type rule test |
||
761 | shorthandRules: function(rules) { |
||
762 | return (typeof rules == 'string' || $.isArray(rules)); |
||
763 | }, |
||
764 | empty: function($field) { |
||
765 | if(!$field || $field.length === 0) { |
||
766 | return true; |
||
767 | } |
||
768 | else if($field.is('input[type="checkbox"]')) { |
||
769 | return !$field.is(':checked'); |
||
770 | } |
||
771 | else { |
||
772 | return module.is.blank($field); |
||
773 | } |
||
774 | }, |
||
775 | blank: function($field) { |
||
776 | return $.trim($field.val()) === ''; |
||
777 | }, |
||
778 | valid: function(field) { |
||
779 | var |
||
780 | allValid = true |
||
781 | ; |
||
782 | if(field) { |
||
783 | module.verbose('Checking if field is valid', field); |
||
784 | return module.validate.field(validation[field], field, false); |
||
785 | } |
||
786 | else { |
||
787 | module.verbose('Checking if form is valid'); |
||
788 | $.each(validation, function(fieldName, field) { |
||
789 | if( !module.is.valid(fieldName) ) { |
||
790 | allValid = false; |
||
791 | } |
||
792 | }); |
||
793 | return allValid; |
||
794 | } |
||
795 | } |
||
796 | }, |
||
797 | |||
798 | removeEvents: function() { |
||
799 | $module |
||
800 | .off(eventNamespace) |
||
801 | ; |
||
802 | $field |
||
803 | .off(eventNamespace) |
||
804 | ; |
||
805 | $submit |
||
806 | .off(eventNamespace) |
||
807 | ; |
||
808 | $field |
||
809 | .off(eventNamespace) |
||
810 | ; |
||
811 | }, |
||
812 | |||
813 | event: { |
||
814 | field: { |
||
815 | keydown: function(event) { |
||
816 | var |
||
817 | $field = $(this), |
||
818 | key = event.which, |
||
819 | isInput = $field.is(selector.input), |
||
820 | isCheckbox = $field.is(selector.checkbox), |
||
821 | isInDropdown = ($field.closest(selector.uiDropdown).length > 0), |
||
822 | keyCode = { |
||
823 | enter : 13, |
||
824 | escape : 27 |
||
825 | } |
||
826 | ; |
||
827 | if( key == keyCode.escape) { |
||
828 | module.verbose('Escape key pressed blurring field'); |
||
829 | $field |
||
830 | .blur() |
||
831 | ; |
||
832 | } |
||
833 | if(!event.ctrlKey && key == keyCode.enter && isInput && !isInDropdown && !isCheckbox) { |
||
834 | if(!keyHeldDown) { |
||
835 | $field |
||
836 | .one('keyup' + eventNamespace, module.event.field.keyup) |
||
837 | ; |
||
838 | module.submit(); |
||
839 | module.debug('Enter pressed on input submitting form'); |
||
840 | } |
||
841 | keyHeldDown = true; |
||
842 | } |
||
843 | }, |
||
844 | keyup: function() { |
||
845 | keyHeldDown = false; |
||
846 | }, |
||
847 | blur: function(event) { |
||
848 | var |
||
849 | $field = $(this), |
||
850 | $fieldGroup = $field.closest($group), |
||
851 | validationRules = module.get.validation($field) |
||
852 | ; |
||
853 | if( $fieldGroup.hasClass(className.error) ) { |
||
854 | module.debug('Revalidating field', $field, validationRules); |
||
855 | if(validationRules) { |
||
856 | module.validate.field( validationRules ); |
||
857 | } |
||
858 | } |
||
859 | else if(settings.on == 'blur' || settings.on == 'change') { |
||
860 | if(validationRules) { |
||
861 | module.validate.field( validationRules ); |
||
862 | } |
||
863 | } |
||
864 | }, |
||
865 | change: function(event) { |
||
866 | var |
||
867 | $field = $(this), |
||
868 | $fieldGroup = $field.closest($group), |
||
869 | validationRules = module.get.validation($field) |
||
870 | ; |
||
871 | if(validationRules && (settings.on == 'change' || ( $fieldGroup.hasClass(className.error) && settings.revalidate) )) { |
||
872 | clearTimeout(module.timer); |
||
873 | module.timer = setTimeout(function() { |
||
874 | module.debug('Revalidating field', $field, module.get.validation($field)); |
||
875 | module.validate.field( validationRules ); |
||
876 | }, settings.delay); |
||
877 | } |
||
878 | } |
||
879 | } |
||
880 | |||
881 | }, |
||
882 | |||
883 | get: { |
||
884 | ancillaryValue: function(rule) { |
||
885 | if(!rule.type || (!rule.value && !module.is.bracketedRule(rule))) { |
||
886 | return false; |
||
887 | } |
||
888 | return (rule.value !== undefined) |
||
889 | ? rule.value |
||
890 | : rule.type.match(settings.regExp.bracket)[1] + '' |
||
891 | ; |
||
892 | }, |
||
893 | ruleName: function(rule) { |
||
894 | if( module.is.bracketedRule(rule) ) { |
||
895 | return rule.type.replace(rule.type.match(settings.regExp.bracket)[0], ''); |
||
896 | } |
||
897 | return rule.type; |
||
898 | }, |
||
899 | changeEvent: function(type, $input) { |
||
900 | if(type == 'checkbox' || type == 'radio' || type == 'hidden' || $input.is('select')) { |
||
901 | return 'change'; |
||
902 | } |
||
903 | else { |
||
904 | return module.get.inputEvent(); |
||
905 | } |
||
906 | }, |
||
907 | inputEvent: function() { |
||
908 | return (document.createElement('input').oninput !== undefined) |
||
909 | ? 'input' |
||
910 | : (document.createElement('input').onpropertychange !== undefined) |
||
911 | ? 'propertychange' |
||
912 | : 'keyup' |
||
913 | ; |
||
914 | }, |
||
915 | fieldsFromShorthand: function(fields) { |
||
916 | var |
||
917 | fullFields = {} |
||
918 | ; |
||
919 | $.each(fields, function(name, rules) { |
||
920 | if(typeof rules == 'string') { |
||
921 | rules = [rules]; |
||
922 | } |
||
923 | fullFields[name] = { |
||
924 | rules: [] |
||
925 | }; |
||
926 | $.each(rules, function(index, rule) { |
||
927 | fullFields[name].rules.push({ type: rule }); |
||
928 | }); |
||
929 | }); |
||
930 | return fullFields; |
||
931 | }, |
||
932 | prompt: function(rule, field) { |
||
933 | var |
||
934 | ruleName = module.get.ruleName(rule), |
||
935 | ancillary = module.get.ancillaryValue(rule), |
||
936 | prompt = rule.prompt || settings.prompt[ruleName] || settings.text.unspecifiedRule, |
||
937 | requiresValue = (prompt.search('{value}') !== -1), |
||
938 | requiresName = (prompt.search('{name}') !== -1), |
||
939 | $label, |
||
940 | $field, |
||
941 | name |
||
942 | ; |
||
943 | if(requiresName || requiresValue) { |
||
944 | $field = module.get.field(field.identifier); |
||
945 | } |
||
946 | if(requiresValue) { |
||
947 | prompt = prompt.replace('{value}', $field.val()); |
||
948 | } |
||
949 | if(requiresName) { |
||
950 | $label = $field.closest(selector.group).find('label').eq(0); |
||
951 | name = ($label.length == 1) |
||
952 | ? $label.text() |
||
953 | : $field.prop('placeholder') || settings.text.unspecifiedField |
||
954 | ; |
||
955 | prompt = prompt.replace('{name}', name); |
||
956 | } |
||
957 | prompt = prompt.replace('{identifier}', field.identifier); |
||
958 | prompt = prompt.replace('{ruleValue}', ancillary); |
||
959 | if(!rule.prompt) { |
||
960 | module.verbose('Using default validation prompt for type', prompt, ruleName); |
||
961 | } |
||
962 | return prompt; |
||
963 | }, |
||
964 | settings: function() { |
||
965 | if($.isPlainObject(parameters)) { |
||
966 | var |
||
967 | keys = Object.keys(parameters), |
||
968 | isLegacySettings = (keys.length > 0) |
||
969 | ? (parameters[keys[0]].identifier !== undefined && parameters[keys[0]].rules !== undefined) |
||
970 | : false, |
||
971 | ruleKeys |
||
972 | ; |
||
973 | if(isLegacySettings) { |
||
974 | // 1.x (ducktyped) |
||
975 | settings = $.extend(true, {}, $.fn.form.settings, legacyParameters); |
||
976 | validation = $.extend({}, $.fn.form.settings.defaults, parameters); |
||
977 | module.error(settings.error.oldSyntax, element); |
||
978 | module.verbose('Extending settings from legacy parameters', validation, settings); |
||
979 | } |
||
980 | else { |
||
981 | // 2.x |
||
982 | if(parameters.fields && module.is.shorthandFields(parameters.fields)) { |
||
983 | parameters.fields = module.get.fieldsFromShorthand(parameters.fields); |
||
984 | } |
||
985 | settings = $.extend(true, {}, $.fn.form.settings, parameters); |
||
986 | validation = $.extend({}, $.fn.form.settings.defaults, settings.fields); |
||
987 | module.verbose('Extending settings', validation, settings); |
||
988 | } |
||
989 | } |
||
990 | else { |
||
991 | settings = $.fn.form.settings; |
||
992 | validation = $.fn.form.settings.defaults; |
||
993 | module.verbose('Using default form validation', validation, settings); |
||
994 | } |
||
995 | |||
996 | // shorthand |
||
997 | namespace = settings.namespace; |
||
998 | metadata = settings.metadata; |
||
999 | selector = settings.selector; |
||
1000 | className = settings.className; |
||
1001 | regExp = settings.regExp; |
||
1002 | error = settings.error; |
||
1003 | moduleNamespace = 'module-' + namespace; |
||
1004 | eventNamespace = '.' + namespace; |
||
1005 | |||
1006 | // grab instance |
||
1007 | instance = $module.data(moduleNamespace); |
||
1008 | |||
1009 | // refresh selector cache |
||
1010 | module.refresh(); |
||
1011 | }, |
||
1012 | field: function(identifier) { |
||
1013 | module.verbose('Finding field with identifier', identifier); |
||
1014 | identifier = module.escape.string(identifier); |
||
1015 | if($field.filter('#' + identifier).length > 0 ) { |
||
1016 | return $field.filter('#' + identifier); |
||
1017 | } |
||
1018 | else if( $field.filter('[name="' + identifier +'"]').length > 0 ) { |
||
1019 | return $field.filter('[name="' + identifier +'"]'); |
||
1020 | } |
||
1021 | else if( $field.filter('[name="' + identifier +'[]"]').length > 0 ) { |
||
1022 | return $field.filter('[name="' + identifier +'[]"]'); |
||
1023 | } |
||
1024 | else if( $field.filter('[data-' + metadata.validate + '="'+ identifier +'"]').length > 0 ) { |
||
1025 | return $field.filter('[data-' + metadata.validate + '="'+ identifier +'"]'); |
||
1026 | } |
||
1027 | return $('<input/>'); |
||
1028 | }, |
||
1029 | fields: function(fields) { |
||
1030 | var |
||
1031 | $fields = $() |
||
1032 | ; |
||
1033 | $.each(fields, function(index, name) { |
||
1034 | $fields = $fields.add( module.get.field(name) ); |
||
1035 | }); |
||
1036 | return $fields; |
||
1037 | }, |
||
1038 | validation: function($field) { |
||
1039 | var |
||
1040 | fieldValidation, |
||
1041 | identifier |
||
1042 | ; |
||
1043 | if(!validation) { |
||
1044 | return false; |
||
1045 | } |
||
1046 | $.each(validation, function(fieldName, field) { |
||
1047 | identifier = field.identifier || fieldName; |
||
1048 | if( module.get.field(identifier)[0] == $field[0] ) { |
||
1049 | field.identifier = identifier; |
||
1050 | fieldValidation = field; |
||
1051 | } |
||
1052 | }); |
||
1053 | return fieldValidation || false; |
||
1054 | }, |
||
1055 | value: function (field) { |
||
1056 | var |
||
1057 | fields = [], |
||
1058 | results |
||
1059 | ; |
||
1060 | fields.push(field); |
||
1061 | results = module.get.values.call(element, fields); |
||
1062 | return results[field]; |
||
1063 | }, |
||
1064 | values: function (fields) { |
||
1065 | var |
||
1066 | $fields = $.isArray(fields) |
||
1067 | ? module.get.fields(fields) |
||
1068 | : $field, |
||
1069 | values = {} |
||
1070 | ; |
||
1071 | $fields.each(function(index, field) { |
||
1072 | var |
||
1073 | $field = $(field), |
||
1074 | type = $field.prop('type'), |
||
1075 | name = $field.prop('name'), |
||
1076 | value = $field.val(), |
||
1077 | isCheckbox = $field.is(selector.checkbox), |
||
1078 | isRadio = $field.is(selector.radio), |
||
1079 | isMultiple = (name.indexOf('[]') !== -1), |
||
1080 | isChecked = (isCheckbox) |
||
1081 | ? $field.is(':checked') |
||
1082 | : false |
||
1083 | ; |
||
1084 | if(name) { |
||
1085 | if(isMultiple) { |
||
1086 | name = name.replace('[]', ''); |
||
1087 | if(!values[name]) { |
||
1088 | values[name] = []; |
||
1089 | } |
||
1090 | if(isCheckbox) { |
||
1091 | if(isChecked) { |
||
1092 | values[name].push(value || true); |
||
1093 | } |
||
1094 | else { |
||
1095 | values[name].push(false); |
||
1096 | } |
||
1097 | } |
||
1098 | else { |
||
1099 | values[name].push(value); |
||
1100 | } |
||
1101 | } |
||
1102 | else { |
||
1103 | if(isRadio) { |
||
1104 | if(values[name] === undefined) { |
||
1105 | values[name] = (isChecked) |
||
1106 | ? true |
||
1107 | : false |
||
1108 | ; |
||
1109 | } |
||
1110 | } |
||
1111 | else if(isCheckbox) { |
||
1112 | if(isChecked) { |
||
1113 | values[name] = value || true; |
||
1114 | } |
||
1115 | else { |
||
1116 | values[name] = false; |
||
1117 | } |
||
1118 | } |
||
1119 | else { |
||
1120 | values[name] = value; |
||
1121 | } |
||
1122 | } |
||
1123 | } |
||
1124 | }); |
||
1125 | return values; |
||
1126 | } |
||
1127 | }, |
||
1128 | |||
1129 | has: { |
||
1130 | |||
1131 | field: function(identifier) { |
||
1132 | module.verbose('Checking for existence of a field with identifier', identifier); |
||
1133 | identifier = module.escape.string(identifier); |
||
1134 | if(typeof identifier !== 'string') { |
||
1135 | module.error(error.identifier, identifier); |
||
1136 | } |
||
1137 | if($field.filter('#' + identifier).length > 0 ) { |
||
1138 | return true; |
||
1139 | } |
||
1140 | else if( $field.filter('[name="' + identifier +'"]').length > 0 ) { |
||
1141 | return true; |
||
1142 | } |
||
1143 | else if( $field.filter('[data-' + metadata.validate + '="'+ identifier +'"]').length > 0 ) { |
||
1144 | return true; |
||
1145 | } |
||
1146 | return false; |
||
1147 | } |
||
1148 | |||
1149 | }, |
||
1150 | |||
1151 | escape: { |
||
1152 | string: function(text) { |
||
1153 | text = String(text); |
||
1154 | return text.replace(regExp.escape, '\\$&'); |
||
1155 | } |
||
1156 | }, |
||
1157 | |||
1158 | add: { |
||
1159 | // alias |
||
1160 | rule: function(name, rules) { |
||
1161 | module.add.field(name, rules); |
||
1162 | }, |
||
1163 | field: function(name, rules) { |
||
1164 | var |
||
1165 | newValidation = {} |
||
1166 | ; |
||
1167 | if(module.is.shorthandRules(rules)) { |
||
1168 | rules = $.isArray(rules) |
||
1169 | ? rules |
||
1170 | : [rules] |
||
1171 | ; |
||
1172 | newValidation[name] = { |
||
1173 | rules: [] |
||
1174 | }; |
||
1175 | $.each(rules, function(index, rule) { |
||
1176 | newValidation[name].rules.push({ type: rule }); |
||
1177 | }); |
||
1178 | } |
||
1179 | else { |
||
1180 | newValidation[name] = rules; |
||
1181 | } |
||
1182 | validation = $.extend({}, validation, newValidation); |
||
1183 | module.debug('Adding rules', newValidation, validation); |
||
1184 | }, |
||
1185 | fields: function(fields) { |
||
1186 | var |
||
1187 | newValidation |
||
1188 | ; |
||
1189 | if(fields && module.is.shorthandFields(fields)) { |
||
1190 | newValidation = module.get.fieldsFromShorthand(fields); |
||
1191 | } |
||
1192 | else { |
||
1193 | newValidation = fields; |
||
1194 | } |
||
1195 | validation = $.extend({}, validation, newValidation); |
||
1196 | }, |
||
1197 | prompt: function(identifier, errors) { |
||
1198 | var |
||
1199 | $field = module.get.field(identifier), |
||
1200 | $fieldGroup = $field.closest($group), |
||
1201 | $prompt = $fieldGroup.children(selector.prompt), |
||
1202 | promptExists = ($prompt.length !== 0) |
||
1203 | ; |
||
1204 | errors = (typeof errors == 'string') |
||
1205 | ? [errors] |
||
1206 | : errors |
||
1207 | ; |
||
1208 | module.verbose('Adding field error state', identifier); |
||
1209 | $fieldGroup |
||
1210 | .addClass(className.error) |
||
1211 | ; |
||
1212 | if(settings.inline) { |
||
1213 | if(!promptExists) { |
||
1214 | $prompt = settings.templates.prompt(errors); |
||
1215 | $prompt |
||
1216 | .appendTo($fieldGroup) |
||
1217 | ; |
||
1218 | } |
||
1219 | $prompt |
||
1220 | .html(errors[0]) |
||
1221 | ; |
||
1222 | if(!promptExists) { |
||
1223 | if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) { |
||
1224 | module.verbose('Displaying error with css transition', settings.transition); |
||
1225 | $prompt.transition(settings.transition + ' in', settings.duration); |
||
1226 | } |
||
1227 | else { |
||
1228 | module.verbose('Displaying error with fallback javascript animation'); |
||
1229 | $prompt |
||
1230 | .fadeIn(settings.duration) |
||
1231 | ; |
||
1232 | } |
||
1233 | } |
||
1234 | else { |
||
1235 | module.verbose('Inline errors are disabled, no inline error added', identifier); |
||
1236 | } |
||
1237 | } |
||
1238 | }, |
||
1239 | errors: function(errors) { |
||
1240 | module.debug('Adding form error messages', errors); |
||
1241 | module.set.error(); |
||
1242 | $message |
||
1243 | .html( settings.templates.error(errors) ) |
||
1244 | ; |
||
1245 | } |
||
1246 | }, |
||
1247 | |||
1248 | remove: { |
||
1249 | rule: function(field, rule) { |
||
1250 | var |
||
1251 | rules = $.isArray(rule) |
||
1252 | ? rule |
||
1253 | : [rule] |
||
1254 | ; |
||
1255 | if(rule == undefined) { |
||
1256 | module.debug('Removed all rules'); |
||
1257 | validation[field].rules = []; |
||
1258 | return; |
||
1259 | } |
||
1260 | if(validation[field] == undefined || !$.isArray(validation[field].rules)) { |
||
1261 | return; |
||
1262 | } |
||
1263 | $.each(validation[field].rules, function(index, rule) { |
||
1264 | if(rules.indexOf(rule.type) !== -1) { |
||
1265 | module.debug('Removed rule', rule.type); |
||
1266 | validation[field].rules.splice(index, 1); |
||
1267 | } |
||
1268 | }); |
||
1269 | }, |
||
1270 | field: function(field) { |
||
1271 | var |
||
1272 | fields = $.isArray(field) |
||
1273 | ? field |
||
1274 | : [field] |
||
1275 | ; |
||
1276 | $.each(fields, function(index, field) { |
||
1277 | module.remove.rule(field); |
||
1278 | }); |
||
1279 | }, |
||
1280 | // alias |
||
1281 | rules: function(field, rules) { |
||
1282 | if($.isArray(field)) { |
||
1283 | $.each(fields, function(index, field) { |
||
1284 | module.remove.rule(field, rules); |
||
1285 | }); |
||
1286 | } |
||
1287 | else { |
||
1288 | module.remove.rule(field, rules); |
||
1289 | } |
||
1290 | }, |
||
1291 | fields: function(fields) { |
||
1292 | module.remove.field(fields); |
||
1293 | }, |
||
1294 | prompt: function(identifier) { |
||
1295 | var |
||
1296 | $field = module.get.field(identifier), |
||
1297 | $fieldGroup = $field.closest($group), |
||
1298 | $prompt = $fieldGroup.children(selector.prompt) |
||
1299 | ; |
||
1300 | $fieldGroup |
||
1301 | .removeClass(className.error) |
||
1302 | ; |
||
1303 | if(settings.inline && $prompt.is(':visible')) { |
||
1304 | module.verbose('Removing prompt for field', identifier); |
||
1305 | if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) { |
||
1306 | $prompt.transition(settings.transition + ' out', settings.duration, function() { |
||
1307 | $prompt.remove(); |
||
1308 | }); |
||
1309 | } |
||
1310 | else { |
||
1311 | $prompt |
||
1312 | .fadeOut(settings.duration, function(){ |
||
1313 | $prompt.remove(); |
||
1314 | }) |
||
1315 | ; |
||
1316 | } |
||
1317 | } |
||
1318 | } |
||
1319 | }, |
||
1320 | |||
1321 | set: { |
||
1322 | success: function() { |
||
1323 | $module |
||
1324 | .removeClass(className.error) |
||
1325 | .addClass(className.success) |
||
1326 | ; |
||
1327 | }, |
||
1328 | defaults: function () { |
||
1329 | $field |
||
1330 | .each(function () { |
||
1331 | var |
||
1332 | $field = $(this), |
||
1333 | isCheckbox = ($field.filter(selector.checkbox).length > 0), |
||
1334 | value = (isCheckbox) |
||
1335 | ? $field.is(':checked') |
||
1336 | : $field.val() |
||
1337 | ; |
||
1338 | $field.data(metadata.defaultValue, value); |
||
1339 | }) |
||
1340 | ; |
||
1341 | }, |
||
1342 | error: function() { |
||
1343 | $module |
||
1344 | .removeClass(className.success) |
||
1345 | .addClass(className.error) |
||
1346 | ; |
||
1347 | }, |
||
1348 | value: function (field, value) { |
||
1349 | var |
||
1350 | fields = {} |
||
1351 | ; |
||
1352 | fields[field] = value; |
||
1353 | return module.set.values.call(element, fields); |
||
1354 | }, |
||
1355 | values: function (fields) { |
||
1356 | if($.isEmptyObject(fields)) { |
||
1357 | return; |
||
1358 | } |
||
1359 | $.each(fields, function(key, value) { |
||
1360 | var |
||
1361 | $field = module.get.field(key), |
||
1362 | $element = $field.parent(), |
||
1363 | isMultiple = $.isArray(value), |
||
1364 | isCheckbox = $element.is(selector.uiCheckbox), |
||
1365 | isDropdown = $element.is(selector.uiDropdown), |
||
1366 | isRadio = ($field.is(selector.radio) && isCheckbox), |
||
1367 | fieldExists = ($field.length > 0), |
||
1368 | $multipleField |
||
1369 | ; |
||
1370 | if(fieldExists) { |
||
1371 | if(isMultiple && isCheckbox) { |
||
1372 | module.verbose('Selecting multiple', value, $field); |
||
1373 | $element.checkbox('uncheck'); |
||
1374 | $.each(value, function(index, value) { |
||
1375 | $multipleField = $field.filter('[value="' + value + '"]'); |
||
1376 | $element = $multipleField.parent(); |
||
1377 | if($multipleField.length > 0) { |
||
1378 | $element.checkbox('check'); |
||
1379 | } |
||
1380 | }); |
||
1381 | } |
||
1382 | else if(isRadio) { |
||
1383 | module.verbose('Selecting radio value', value, $field); |
||
1384 | $field.filter('[value="' + value + '"]') |
||
1385 | .parent(selector.uiCheckbox) |
||
1386 | .checkbox('check') |
||
1387 | ; |
||
1388 | } |
||
1389 | else if(isCheckbox) { |
||
1390 | module.verbose('Setting checkbox value', value, $element); |
||
1391 | if(value === true) { |
||
1392 | $element.checkbox('check'); |
||
1393 | } |
||
1394 | else { |
||
1395 | $element.checkbox('uncheck'); |
||
1396 | } |
||
1397 | } |
||
1398 | else if(isDropdown) { |
||
1399 | module.verbose('Setting dropdown value', value, $element); |
||
1400 | $element.dropdown('set selected', value); |
||
1401 | } |
||
1402 | else { |
||
1403 | module.verbose('Setting field value', value, $field); |
||
1404 | $field.val(value); |
||
1405 | } |
||
1406 | } |
||
1407 | }); |
||
1408 | } |
||
1409 | }, |
||
1410 | |||
1411 | validate: { |
||
1412 | |||
1413 | form: function(event, ignoreCallbacks) { |
||
1414 | var |
||
1415 | values = module.get.values(), |
||
1416 | apiRequest |
||
1417 | ; |
||
1418 | |||
1419 | // input keydown event will fire submit repeatedly by browser default |
||
1420 | if(keyHeldDown) { |
||
1421 | return false; |
||
1422 | } |
||
1423 | |||
1424 | // reset errors |
||
1425 | formErrors = []; |
||
1426 | if( module.determine.isValid() ) { |
||
1427 | module.debug('Form has no validation errors, submitting'); |
||
1428 | module.set.success(); |
||
1429 | if(ignoreCallbacks !== true) { |
||
1430 | return settings.onSuccess.call(element, event, values); |
||
1431 | } |
||
1432 | } |
||
1433 | else { |
||
1434 | module.debug('Form has errors'); |
||
1435 | module.set.error(); |
||
1436 | if(!settings.inline) { |
||
1437 | module.add.errors(formErrors); |
||
1438 | } |
||
1439 | // prevent ajax submit |
||
1440 | if($module.data('moduleApi') !== undefined) { |
||
1441 | event.stopImmediatePropagation(); |
||
1442 | } |
||
1443 | if(ignoreCallbacks !== true) { |
||
1444 | return settings.onFailure.call(element, formErrors, values); |
||
1445 | } |
||
1446 | } |
||
1447 | }, |
||
1448 | |||
1449 | // takes a validation object and returns whether field passes validation |
||
1450 | field: function(field, fieldName, showErrors) { |
||
1451 | showErrors = (showErrors !== undefined) |
||
1452 | ? showErrors |
||
1453 | : true |
||
1454 | ; |
||
1455 | if(typeof field == 'string') { |
||
1456 | module.verbose('Validating field', field); |
||
1457 | fieldName = field; |
||
1458 | field = validation[field]; |
||
1459 | } |
||
1460 | var |
||
1461 | identifier = field.identifier || fieldName, |
||
1462 | $field = module.get.field(identifier), |
||
1463 | $dependsField = (field.depends) |
||
1464 | ? module.get.field(field.depends) |
||
1465 | : false, |
||
1466 | fieldValid = true, |
||
1467 | fieldErrors = [] |
||
1468 | ; |
||
1469 | if(!field.identifier) { |
||
1470 | module.debug('Using field name as identifier', identifier); |
||
1471 | field.identifier = identifier; |
||
1472 | } |
||
1473 | if($field.prop('disabled')) { |
||
1474 | module.debug('Field is disabled. Skipping', identifier); |
||
1475 | fieldValid = true; |
||
1476 | } |
||
1477 | else if(field.optional && module.is.blank($field)){ |
||
1478 | module.debug('Field is optional and blank. Skipping', identifier); |
||
1479 | fieldValid = true; |
||
1480 | } |
||
1481 | else if(field.depends && module.is.empty($dependsField)) { |
||
1482 | module.debug('Field depends on another value that is not present or empty. Skipping', $dependsField); |
||
1483 | fieldValid = true; |
||
1484 | } |
||
1485 | else if(field.rules !== undefined) { |
||
1486 | $.each(field.rules, function(index, rule) { |
||
1487 | if( module.has.field(identifier) && !( module.validate.rule(field, rule) ) ) { |
||
1488 | module.debug('Field is invalid', identifier, rule.type); |
||
1489 | fieldErrors.push(module.get.prompt(rule, field)); |
||
1490 | fieldValid = false; |
||
1491 | } |
||
1492 | }); |
||
1493 | } |
||
1494 | if(fieldValid) { |
||
1495 | if(showErrors) { |
||
1496 | module.remove.prompt(identifier, fieldErrors); |
||
1497 | settings.onValid.call($field); |
||
1498 | } |
||
1499 | } |
||
1500 | else { |
||
1501 | if(showErrors) { |
||
1502 | formErrors = formErrors.concat(fieldErrors); |
||
1503 | module.add.prompt(identifier, fieldErrors); |
||
1504 | settings.onInvalid.call($field, fieldErrors); |
||
1505 | } |
||
1506 | return false; |
||
1507 | } |
||
1508 | return true; |
||
1509 | }, |
||
1510 | |||
1511 | // takes validation rule and returns whether field passes rule |
||
1512 | rule: function(field, rule) { |
||
1513 | var |
||
1514 | $field = module.get.field(field.identifier), |
||
1515 | type = rule.type, |
||
1516 | value = $field.val(), |
||
1517 | isValid = true, |
||
1518 | ancillary = module.get.ancillaryValue(rule), |
||
1519 | ruleName = module.get.ruleName(rule), |
||
1520 | ruleFunction = settings.rules[ruleName] |
||
1521 | ; |
||
1522 | if( !$.isFunction(ruleFunction) ) { |
||
1523 | module.error(error.noRule, ruleName); |
||
1524 | return; |
||
1525 | } |
||
1526 | // cast to string avoiding encoding special values |
||
1527 | value = (value === undefined || value === '' || value === null) |
||
1528 | ? '' |
||
1529 | : $.trim(value + '') |
||
1530 | ; |
||
1531 | return ruleFunction.call($field, value, ancillary); |
||
1532 | } |
||
1533 | }, |
||
1534 | |||
1535 | setting: function(name, value) { |
||
1536 | if( $.isPlainObject(name) ) { |
||
1537 | $.extend(true, settings, name); |
||
1538 | } |
||
1539 | else if(value !== undefined) { |
||
1540 | settings[name] = value; |
||
1541 | } |
||
1542 | else { |
||
1543 | return settings[name]; |
||
1544 | } |
||
1545 | }, |
||
1546 | internal: function(name, value) { |
||
1547 | if( $.isPlainObject(name) ) { |
||
1548 | $.extend(true, module, name); |
||
1549 | } |
||
1550 | else if(value !== undefined) { |
||
1551 | module[name] = value; |
||
1552 | } |
||
1553 | else { |
||
1554 | return module[name]; |
||
1555 | } |
||
1556 | }, |
||
1557 | debug: function() { |
||
1558 | if(!settings.silent && settings.debug) { |
||
1559 | if(settings.performance) { |
||
1560 | module.performance.log(arguments); |
||
1561 | } |
||
1562 | else { |
||
1563 | module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':'); |
||
1564 | module.debug.apply(console, arguments); |
||
1565 | } |
||
1566 | } |
||
1567 | }, |
||
1568 | verbose: function() { |
||
1569 | if(!settings.silent && settings.verbose && settings.debug) { |
||
1570 | if(settings.performance) { |
||
1571 | module.performance.log(arguments); |
||
1572 | } |
||
1573 | else { |
||
1574 | module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':'); |
||
1575 | module.verbose.apply(console, arguments); |
||
1576 | } |
||
1577 | } |
||
1578 | }, |
||
1579 | error: function() { |
||
1580 | if(!settings.silent) { |
||
1581 | module.error = Function.prototype.bind.call(console.error, console, settings.name + ':'); |
||
1582 | module.error.apply(console, arguments); |
||
1583 | } |
||
1584 | }, |
||
1585 | performance: { |
||
1586 | log: function(message) { |
||
1587 | var |
||
1588 | currentTime, |
||
1589 | executionTime, |
||
1590 | previousTime |
||
1591 | ; |
||
1592 | if(settings.performance) { |
||
1593 | currentTime = new Date().getTime(); |
||
1594 | previousTime = time || currentTime; |
||
1595 | executionTime = currentTime - previousTime; |
||
1596 | time = currentTime; |
||
1597 | performance.push({ |
||
1598 | 'Name' : message[0], |
||
1599 | 'Arguments' : [].slice.call(message, 1) || '', |
||
1600 | 'Element' : element, |
||
1601 | 'Execution Time' : executionTime |
||
1602 | }); |
||
1603 | } |
||
1604 | clearTimeout(module.performance.timer); |
||
1605 | module.performance.timer = setTimeout(module.performance.display, 500); |
||
1606 | }, |
||
1607 | display: function() { |
||
1608 | var |
||
1609 | title = settings.name + ':', |
||
1610 | totalTime = 0 |
||
1611 | ; |
||
1612 | time = false; |
||
1613 | clearTimeout(module.performance.timer); |
||
1614 | $.each(performance, function(index, data) { |
||
1615 | totalTime += data['Execution Time']; |
||
1616 | }); |
||
1617 | title += ' ' + totalTime + 'ms'; |
||
1618 | if(moduleSelector) { |
||
1619 | title += ' \'' + moduleSelector + '\''; |
||
1620 | } |
||
1621 | if($allModules.length > 1) { |
||
1622 | title += ' ' + '(' + $allModules.length + ')'; |
||
1623 | } |
||
1624 | if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) { |
||
1625 | console.groupCollapsed(title); |
||
1626 | if(console.table) { |
||
1627 | console.table(performance); |
||
1628 | } |
||
1629 | else { |
||
1630 | $.each(performance, function(index, data) { |
||
1631 | console.log(data['Name'] + ': ' + data['Execution Time']+'ms'); |
||
1632 | }); |
||
1633 | } |
||
1634 | console.groupEnd(); |
||
1635 | } |
||
1636 | performance = []; |
||
1637 | } |
||
1638 | }, |
||
1639 | invoke: function(query, passedArguments, context) { |
||
1640 | var |
||
1641 | object = instance, |
||
1642 | maxDepth, |
||
1643 | found, |
||
1644 | response |
||
1645 | ; |
||
1646 | passedArguments = passedArguments || queryArguments; |
||
1647 | context = element || context; |
||
1648 | if(typeof query == 'string' && object !== undefined) { |
||
1649 | query = query.split(/[\. ]/); |
||
1650 | maxDepth = query.length - 1; |
||
1651 | $.each(query, function(depth, value) { |
||
1652 | var camelCaseValue = (depth != maxDepth) |
||
1653 | ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1) |
||
1654 | : query |
||
1655 | ; |
||
1656 | if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) { |
||
1657 | object = object[camelCaseValue]; |
||
1658 | } |
||
1659 | else if( object[camelCaseValue] !== undefined ) { |
||
1660 | found = object[camelCaseValue]; |
||
1661 | return false; |
||
1662 | } |
||
1663 | else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) { |
||
1664 | object = object[value]; |
||
1665 | } |
||
1666 | else if( object[value] !== undefined ) { |
||
1667 | found = object[value]; |
||
1668 | return false; |
||
1669 | } |
||
1670 | else { |
||
1671 | return false; |
||
1672 | } |
||
1673 | }); |
||
1674 | } |
||
1675 | if( $.isFunction( found ) ) { |
||
1676 | response = found.apply(context, passedArguments); |
||
1677 | } |
||
1678 | else if(found !== undefined) { |
||
1679 | response = found; |
||
1680 | } |
||
1681 | if($.isArray(returnedValue)) { |
||
1682 | returnedValue.push(response); |
||
1683 | } |
||
1684 | else if(returnedValue !== undefined) { |
||
1685 | returnedValue = [returnedValue, response]; |
||
1686 | } |
||
1687 | else if(response !== undefined) { |
||
1688 | returnedValue = response; |
||
1689 | } |
||
1690 | return found; |
||
1691 | } |
||
1692 | }; |
||
1693 | module.initialize(); |
||
1694 | }) |
||
1695 | ; |
||
1696 | |||
1697 | return (returnedValue !== undefined) |
||
1698 | ? returnedValue |
||
1699 | : this |
||
1700 | ; |
||
1701 | }; |
||
1702 | |||
1703 | $.fn.form.settings = { |
||
1704 | |||
1705 | name : 'Form', |
||
1706 | namespace : 'form', |
||
1707 | |||
1708 | debug : false, |
||
1709 | verbose : false, |
||
1710 | performance : true, |
||
1711 | |||
1712 | fields : false, |
||
1713 | |||
1714 | keyboardShortcuts : true, |
||
1715 | on : 'submit', |
||
1716 | inline : false, |
||
1717 | |||
1718 | delay : 200, |
||
1719 | revalidate : true, |
||
1720 | |||
1721 | transition : 'scale', |
||
1722 | duration : 200, |
||
1723 | |||
1724 | onValid : function() {}, |
||
1725 | onInvalid : function() {}, |
||
1726 | onSuccess : function() { return true; }, |
||
1727 | onFailure : function() { return false; }, |
||
1728 | |||
1729 | metadata : { |
||
1730 | defaultValue : 'default', |
||
1731 | validate : 'validate' |
||
1732 | }, |
||
1733 | |||
1734 | regExp: { |
||
1735 | htmlID : /^[a-zA-Z][\w:.-]*$/g, |
||
1736 | bracket : /\[(.*)\]/i, |
||
1737 | decimal : /^\d+\.?\d*$/, |
||
1738 | email : /^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i, |
||
1739 | escape : /[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, |
||
1740 | flags : /^\/(.*)\/(.*)?/, |
||
1741 | integer : /^\-?\d+$/, |
||
1742 | number : /^\-?\d*(\.\d+)?$/, |
||
1743 | url : /(https?:\/\/(?:www\.|(?!www))[^\s\.]+\.[^\s]{2,}|www\.[^\s]+\.[^\s]{2,})/i |
||
1744 | }, |
||
1745 | |||
1746 | text: { |
||
1747 | unspecifiedRule : 'Please enter a valid value', |
||
1748 | unspecifiedField : 'This field' |
||
1749 | }, |
||
1750 | |||
1751 | prompt: { |
||
1752 | empty : '{name} must have a value', |
||
1753 | checked : '{name} must be checked', |
||
1754 | email : '{name} must be a valid e-mail', |
||
1755 | url : '{name} must be a valid url', |
||
1756 | regExp : '{name} is not formatted correctly', |
||
1757 | integer : '{name} must be an integer', |
||
1758 | decimal : '{name} must be a decimal number', |
||
1759 | number : '{name} must be set to a number', |
||
1760 | is : '{name} must be "{ruleValue}"', |
||
1761 | isExactly : '{name} must be exactly "{ruleValue}"', |
||
1762 | not : '{name} cannot be set to "{ruleValue}"', |
||
1763 | notExactly : '{name} cannot be set to exactly "{ruleValue}"', |
||
1764 | contain : '{name} cannot contain "{ruleValue}"', |
||
1765 | containExactly : '{name} cannot contain exactly "{ruleValue}"', |
||
1766 | doesntContain : '{name} must contain "{ruleValue}"', |
||
1767 | doesntContainExactly : '{name} must contain exactly "{ruleValue}"', |
||
1768 | minLength : '{name} must be at least {ruleValue} characters', |
||
1769 | length : '{name} must be at least {ruleValue} characters', |
||
1770 | exactLength : '{name} must be exactly {ruleValue} characters', |
||
1771 | maxLength : '{name} cannot be longer than {ruleValue} characters', |
||
1772 | match : '{name} must match {ruleValue} field', |
||
1773 | different : '{name} must have a different value than {ruleValue} field', |
||
1774 | creditCard : '{name} must be a valid credit card number', |
||
1775 | minCount : '{name} must have at least {ruleValue} choices', |
||
1776 | exactCount : '{name} must have exactly {ruleValue} choices', |
||
1777 | maxCount : '{name} must have {ruleValue} or less choices' |
||
1778 | }, |
||
1779 | |||
1780 | selector : { |
||
1781 | checkbox : 'input[type="checkbox"], input[type="radio"]', |
||
1782 | clear : '.clear', |
||
1783 | field : 'input, textarea, select', |
||
1784 | group : '.field', |
||
1785 | input : 'input', |
||
1786 | message : '.error.message', |
||
1787 | prompt : '.prompt.label', |
||
1788 | radio : 'input[type="radio"]', |
||
1789 | reset : '.reset:not([type="reset"])', |
||
1790 | submit : '.submit:not([type="submit"])', |
||
1791 | uiCheckbox : '.ui.checkbox', |
||
1792 | uiDropdown : '.ui.dropdown' |
||
1793 | }, |
||
1794 | |||
1795 | className : { |
||
1796 | error : 'error', |
||
1797 | label : 'ui prompt label', |
||
1798 | pressed : 'down', |
||
1799 | success : 'success' |
||
1800 | }, |
||
1801 | |||
1802 | error: { |
||
1803 | identifier : 'You must specify a string identifier for each field', |
||
1804 | method : 'The method you called is not defined.', |
||
1805 | noRule : 'There is no rule matching the one you specified', |
||
1806 | oldSyntax : 'Starting in 2.0 forms now only take a single settings object. Validation settings converted to new syntax automatically.' |
||
1807 | }, |
||
1808 | |||
1809 | templates: { |
||
1810 | |||
1811 | // template that produces error message |
||
1812 | error: function(errors) { |
||
1813 | var |
||
1814 | html = '<ul class="list">' |
||
1815 | ; |
||
1816 | $.each(errors, function(index, value) { |
||
1817 | html += '<li>' + value + '</li>'; |
||
1818 | }); |
||
1819 | html += '</ul>'; |
||
1820 | return $(html); |
||
1821 | }, |
||
1822 | |||
1823 | // template that produces label |
||
1824 | prompt: function(errors) { |
||
1825 | return $('<div/>') |
||
1826 | .addClass('ui basic red pointing prompt label') |
||
1827 | .html(errors[0]) |
||
1828 | ; |
||
1829 | } |
||
1830 | }, |
||
1831 | |||
1832 | rules: { |
||
1833 | |||
1834 | // is not empty or blank string |
||
1835 | empty: function(value) { |
||
1836 | return !(value === undefined || '' === value || $.isArray(value) && value.length === 0); |
||
1837 | }, |
||
1838 | |||
1839 | // checkbox checked |
||
1840 | checked: function() { |
||
1841 | return ($(this).filter(':checked').length > 0); |
||
1842 | }, |
||
1843 | |||
1844 | // is most likely an email |
||
1845 | email: function(value){ |
||
1846 | return $.fn.form.settings.regExp.email.test(value); |
||
1847 | }, |
||
1848 | |||
1849 | // value is most likely url |
||
1850 | url: function(value) { |
||
1851 | return $.fn.form.settings.regExp.url.test(value); |
||
1852 | }, |
||
1853 | |||
1854 | // matches specified regExp |
||
1855 | regExp: function(value, regExp) { |
||
1856 | if(regExp instanceof RegExp) { |
||
1857 | return value.match(regExp); |
||
1858 | } |
||
1859 | var |
||
1860 | regExpParts = regExp.match($.fn.form.settings.regExp.flags), |
||
1861 | flags |
||
1862 | ; |
||
1863 | // regular expression specified as /baz/gi (flags) |
||
1864 | if(regExpParts) { |
||
1865 | regExp = (regExpParts.length >= 2) |
||
1866 | ? regExpParts[1] |
||
1867 | : regExp |
||
1868 | ; |
||
1869 | flags = (regExpParts.length >= 3) |
||
1870 | ? regExpParts[2] |
||
1871 | : '' |
||
1872 | ; |
||
1873 | } |
||
1874 | return value.match( new RegExp(regExp, flags) ); |
||
1875 | }, |
||
1876 | |||
1877 | // is valid integer or matches range |
||
1878 | integer: function(value, range) { |
||
1879 | var |
||
1880 | intRegExp = $.fn.form.settings.regExp.integer, |
||
1881 | min, |
||
1882 | max, |
||
1883 | parts |
||
1884 | ; |
||
1885 | if( !range || ['', '..'].indexOf(range) !== -1) { |
||
1886 | // do nothing |
||
1887 | } |
||
1888 | else if(range.indexOf('..') == -1) { |
||
1889 | if(intRegExp.test(range)) { |
||
1890 | min = max = range - 0; |
||
1891 | } |
||
1892 | } |
||
1893 | else { |
||
1894 | parts = range.split('..', 2); |
||
1895 | if(intRegExp.test(parts[0])) { |
||
1896 | min = parts[0] - 0; |
||
1897 | } |
||
1898 | if(intRegExp.test(parts[1])) { |
||
1899 | max = parts[1] - 0; |
||
1900 | } |
||
1901 | } |
||
1902 | return ( |
||
1903 | intRegExp.test(value) && |
||
1904 | (min === undefined || value >= min) && |
||
1905 | (max === undefined || value <= max) |
||
1906 | ); |
||
1907 | }, |
||
1908 | |||
1909 | // is valid number (with decimal) |
||
1910 | decimal: function(value) { |
||
1911 | return $.fn.form.settings.regExp.decimal.test(value); |
||
1912 | }, |
||
1913 | |||
1914 | // is valid number |
||
1915 | number: function(value) { |
||
1916 | return $.fn.form.settings.regExp.number.test(value); |
||
1917 | }, |
||
1918 | |||
1919 | // is value (case insensitive) |
||
1920 | is: function(value, text) { |
||
1921 | text = (typeof text == 'string') |
||
1922 | ? text.toLowerCase() |
||
1923 | : text |
||
1924 | ; |
||
1925 | value = (typeof value == 'string') |
||
1926 | ? value.toLowerCase() |
||
1927 | : value |
||
1928 | ; |
||
1929 | return (value == text); |
||
1930 | }, |
||
1931 | |||
1932 | // is value |
||
1933 | isExactly: function(value, text) { |
||
1934 | return (value == text); |
||
1935 | }, |
||
1936 | |||
1937 | // value is not another value (case insensitive) |
||
1938 | not: function(value, notValue) { |
||
1939 | value = (typeof value == 'string') |
||
1940 | ? value.toLowerCase() |
||
1941 | : value |
||
1942 | ; |
||
1943 | notValue = (typeof notValue == 'string') |
||
1944 | ? notValue.toLowerCase() |
||
1945 | : notValue |
||
1946 | ; |
||
1947 | return (value != notValue); |
||
1948 | }, |
||
1949 | |||
1950 | // value is not another value (case sensitive) |
||
1951 | notExactly: function(value, notValue) { |
||
1952 | return (value != notValue); |
||
1953 | }, |
||
1954 | |||
1955 | // value contains text (insensitive) |
||
1956 | contains: function(value, text) { |
||
1957 | // escape regex characters |
||
1958 | text = text.replace($.fn.form.settings.regExp.escape, "\\$&"); |
||
1959 | return (value.search( new RegExp(text, 'i') ) !== -1); |
||
1960 | }, |
||
1961 | |||
1962 | // value contains text (case sensitive) |
||
1963 | containsExactly: function(value, text) { |
||
1964 | // escape regex characters |
||
1965 | text = text.replace($.fn.form.settings.regExp.escape, "\\$&"); |
||
1966 | return (value.search( new RegExp(text) ) !== -1); |
||
1967 | }, |
||
1968 | |||
1969 | // value contains text (insensitive) |
||
1970 | doesntContain: function(value, text) { |
||
1971 | // escape regex characters |
||
1972 | text = text.replace($.fn.form.settings.regExp.escape, "\\$&"); |
||
1973 | return (value.search( new RegExp(text, 'i') ) === -1); |
||
1974 | }, |
||
1975 | |||
1976 | // value contains text (case sensitive) |
||
1977 | doesntContainExactly: function(value, text) { |
||
1978 | // escape regex characters |
||
1979 | text = text.replace($.fn.form.settings.regExp.escape, "\\$&"); |
||
1980 | return (value.search( new RegExp(text) ) === -1); |
||
1981 | }, |
||
1982 | |||
1983 | // is at least string length |
||
1984 | minLength: function(value, requiredLength) { |
||
1985 | return (value !== undefined) |
||
1986 | ? (value.length >= requiredLength) |
||
1987 | : false |
||
1988 | ; |
||
1989 | }, |
||
1990 | |||
1991 | // see rls notes for 2.0.6 (this is a duplicate of minLength) |
||
1992 | length: function(value, requiredLength) { |
||
1993 | return (value !== undefined) |
||
1994 | ? (value.length >= requiredLength) |
||
1995 | : false |
||
1996 | ; |
||
1997 | }, |
||
1998 | |||
1999 | // is exactly length |
||
2000 | exactLength: function(value, requiredLength) { |
||
2001 | return (value !== undefined) |
||
2002 | ? (value.length == requiredLength) |
||
2003 | : false |
||
2004 | ; |
||
2005 | }, |
||
2006 | |||
2007 | // is less than length |
||
2008 | maxLength: function(value, maxLength) { |
||
2009 | return (value !== undefined) |
||
2010 | ? (value.length <= maxLength) |
||
2011 | : false |
||
2012 | ; |
||
2013 | }, |
||
2014 | |||
2015 | // matches another field |
||
2016 | match: function(value, identifier) { |
||
2017 | var |
||
2018 | $form = $(this), |
||
2019 | matchingValue |
||
2020 | ; |
||
2021 | if( $('[data-validate="'+ identifier +'"]').length > 0 ) { |
||
2022 | matchingValue = $('[data-validate="'+ identifier +'"]').val(); |
||
2023 | } |
||
2024 | else if($('#' + identifier).length > 0) { |
||
2025 | matchingValue = $('#' + identifier).val(); |
||
2026 | } |
||
2027 | else if($('[name="' + identifier +'"]').length > 0) { |
||
2028 | matchingValue = $('[name="' + identifier + '"]').val(); |
||
2029 | } |
||
2030 | else if( $('[name="' + identifier +'[]"]').length > 0 ) { |
||
2031 | matchingValue = $('[name="' + identifier +'[]"]'); |
||
2032 | } |
||
2033 | return (matchingValue !== undefined) |
||
2034 | ? ( value.toString() == matchingValue.toString() ) |
||
2035 | : false |
||
2036 | ; |
||
2037 | }, |
||
2038 | |||
2039 | // different than another field |
||
2040 | different: function(value, identifier) { |
||
2041 | // use either id or name of field |
||
2042 | var |
||
2043 | $form = $(this), |
||
2044 | matchingValue |
||
2045 | ; |
||
2046 | if( $('[data-validate="'+ identifier +'"]').length > 0 ) { |
||
2047 | matchingValue = $('[data-validate="'+ identifier +'"]').val(); |
||
2048 | } |
||
2049 | else if($('#' + identifier).length > 0) { |
||
2050 | matchingValue = $('#' + identifier).val(); |
||
2051 | } |
||
2052 | else if($('[name="' + identifier +'"]').length > 0) { |
||
2053 | matchingValue = $('[name="' + identifier + '"]').val(); |
||
2054 | } |
||
2055 | else if( $('[name="' + identifier +'[]"]').length > 0 ) { |
||
2056 | matchingValue = $('[name="' + identifier +'[]"]'); |
||
2057 | } |
||
2058 | return (matchingValue !== undefined) |
||
2059 | ? ( value.toString() !== matchingValue.toString() ) |
||
2060 | : false |
||
2061 | ; |
||
2062 | }, |
||
2063 | |||
2064 | creditCard: function(cardNumber, cardTypes) { |
||
2065 | var |
||
2066 | cards = { |
||
2067 | visa: { |
||
2068 | pattern : /^4/, |
||
2069 | length : [16] |
||
2070 | }, |
||
2071 | amex: { |
||
2072 | pattern : /^3[47]/, |
||
2073 | length : [15] |
||
2074 | }, |
||
2075 | mastercard: { |
||
2076 | pattern : /^5[1-5]/, |
||
2077 | length : [16] |
||
2078 | }, |
||
2079 | discover: { |
||
2080 | pattern : /^(6011|622(12[6-9]|1[3-9][0-9]|[2-8][0-9]{2}|9[0-1][0-9]|92[0-5]|64[4-9])|65)/, |
||
2081 | length : [16] |
||
2082 | }, |
||
2083 | unionPay: { |
||
2084 | pattern : /^(62|88)/, |
||
2085 | length : [16, 17, 18, 19] |
||
2086 | }, |
||
2087 | jcb: { |
||
2088 | pattern : /^35(2[89]|[3-8][0-9])/, |
||
2089 | length : [16] |
||
2090 | }, |
||
2091 | maestro: { |
||
2092 | pattern : /^(5018|5020|5038|6304|6759|676[1-3])/, |
||
2093 | length : [12, 13, 14, 15, 16, 17, 18, 19] |
||
2094 | }, |
||
2095 | dinersClub: { |
||
2096 | pattern : /^(30[0-5]|^36)/, |
||
2097 | length : [14] |
||
2098 | }, |
||
2099 | laser: { |
||
2100 | pattern : /^(6304|670[69]|6771)/, |
||
2101 | length : [16, 17, 18, 19] |
||
2102 | }, |
||
2103 | visaElectron: { |
||
2104 | pattern : /^(4026|417500|4508|4844|491(3|7))/, |
||
2105 | length : [16] |
||
2106 | } |
||
2107 | }, |
||
2108 | valid = {}, |
||
2109 | validCard = false, |
||
2110 | requiredTypes = (typeof cardTypes == 'string') |
||
2111 | ? cardTypes.split(',') |
||
2112 | : false, |
||
2113 | unionPay, |
||
2114 | validation |
||
2115 | ; |
||
2116 | |||
2117 | if(typeof cardNumber !== 'string' || cardNumber.length === 0) { |
||
2118 | return; |
||
2119 | } |
||
2120 | |||
2121 | // allow dashes in card |
||
2122 | cardNumber = cardNumber.replace(/[\-]/g, ''); |
||
2123 | |||
2124 | // verify card types |
||
2125 | if(requiredTypes) { |
||
2126 | $.each(requiredTypes, function(index, type){ |
||
2127 | // verify each card type |
||
2128 | validation = cards[type]; |
||
2129 | if(validation) { |
||
2130 | valid = { |
||
2131 | length : ($.inArray(cardNumber.length, validation.length) !== -1), |
||
2132 | pattern : (cardNumber.search(validation.pattern) !== -1) |
||
2133 | }; |
||
2134 | if(valid.length && valid.pattern) { |
||
2135 | validCard = true; |
||
2136 | } |
||
2137 | } |
||
2138 | }); |
||
2139 | |||
2140 | if(!validCard) { |
||
2141 | return false; |
||
2142 | } |
||
2143 | } |
||
2144 | |||
2145 | // skip luhn for UnionPay |
||
2146 | unionPay = { |
||
2147 | number : ($.inArray(cardNumber.length, cards.unionPay.length) !== -1), |
||
2148 | pattern : (cardNumber.search(cards.unionPay.pattern) !== -1) |
||
2149 | }; |
||
2150 | if(unionPay.number && unionPay.pattern) { |
||
2151 | return true; |
||
2152 | } |
||
2153 | |||
2154 | // verify luhn, adapted from <https://gist.github.com/2134376> |
||
2155 | var |
||
2156 | length = cardNumber.length, |
||
2157 | multiple = 0, |
||
2158 | producedValue = [ |
||
2159 | [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], |
||
2160 | [0, 2, 4, 6, 8, 1, 3, 5, 7, 9] |
||
2161 | ], |
||
2162 | sum = 0 |
||
2163 | ; |
||
2164 | while (length--) { |
||
2165 | sum += producedValue[multiple][parseInt(cardNumber.charAt(length), 10)]; |
||
2166 | multiple ^= 1; |
||
2167 | } |
||
2168 | return (sum % 10 === 0 && sum > 0); |
||
2169 | }, |
||
2170 | |||
2171 | minCount: function(value, minCount) { |
||
2172 | if(minCount == 0) { |
||
2173 | return true; |
||
2174 | } |
||
2175 | if(minCount == 1) { |
||
2176 | return (value !== ''); |
||
2177 | } |
||
2178 | return (value.split(',').length >= minCount); |
||
2179 | }, |
||
2180 | |||
2181 | exactCount: function(value, exactCount) { |
||
2182 | if(exactCount == 0) { |
||
2183 | return (value === ''); |
||
2184 | } |
||
2185 | if(exactCount == 1) { |
||
2186 | return (value !== '' && value.search(',') === -1); |
||
2187 | } |
||
2188 | return (value.split(',').length == exactCount); |
||
2189 | }, |
||
2190 | |||
2191 | maxCount: function(value, maxCount) { |
||
2192 | if(maxCount == 0) { |
||
2193 | return false; |
||
2194 | } |
||
2195 | if(maxCount == 1) { |
||
2196 | return (value.search(',') === -1); |
||
2197 | } |
||
2198 | return (value.split(',').length <= maxCount); |
||
2199 | } |
||
2200 | } |
||
2201 | |||
2202 | }; |
||
2203 | |||
2204 | })( jQuery, window, document ); |
||
2205 | |||
2206 | /*! |
||
2207 | * # Semantic UI 2.2.11 - Accordion |
||
2208 | * http://github.com/semantic-org/semantic-ui/ |
||
2209 | * |
||
2210 | * |
||
2211 | * Released under the MIT license |
||
2212 | * http://opensource.org/licenses/MIT |
||
2213 | * |
||
2214 | */ |
||
2215 | |||
2216 | View Code Duplication | ;(function ($, window, document, undefined) { |
|
2217 | |||
2218 | "use strict"; |
||
2219 | |||
2220 | window = (typeof window != 'undefined' && window.Math == Math) |
||
2221 | ? window |
||
2222 | : (typeof self != 'undefined' && self.Math == Math) |
||
2223 | ? self |
||
2224 | : Function('return this')() |
||
2225 | ; |
||
2226 | |||
2227 | $.fn.accordion = function(parameters) { |
||
2228 | var |
||
2229 | $allModules = $(this), |
||
2230 | |||
2231 | time = new Date().getTime(), |
||
2232 | performance = [], |
||
2233 | |||
2234 | query = arguments[0], |
||
2235 | methodInvoked = (typeof query == 'string'), |
||
2236 | queryArguments = [].slice.call(arguments, 1), |
||
2237 | |||
2238 | requestAnimationFrame = window.requestAnimationFrame |
||
2239 | || window.mozRequestAnimationFrame |
||
2240 | || window.webkitRequestAnimationFrame |
||
2241 | || window.msRequestAnimationFrame |
||
2242 | || function(callback) { setTimeout(callback, 0); }, |
||
2243 | |||
2244 | returnedValue |
||
2245 | ; |
||
2246 | $allModules |
||
2247 | .each(function() { |
||
2248 | var |
||
2249 | settings = ( $.isPlainObject(parameters) ) |
||
2250 | ? $.extend(true, {}, $.fn.accordion.settings, parameters) |
||
2251 | : $.extend({}, $.fn.accordion.settings), |
||
2252 | |||
2253 | className = settings.className, |
||
2254 | namespace = settings.namespace, |
||
2255 | selector = settings.selector, |
||
2256 | error = settings.error, |
||
2257 | |||
2258 | eventNamespace = '.' + namespace, |
||
2259 | moduleNamespace = 'module-' + namespace, |
||
2260 | moduleSelector = $allModules.selector || '', |
||
2261 | |||
2262 | $module = $(this), |
||
2263 | $title = $module.find(selector.title), |
||
2264 | $content = $module.find(selector.content), |
||
2265 | |||
2266 | element = this, |
||
2267 | instance = $module.data(moduleNamespace), |
||
2268 | observer, |
||
2269 | module |
||
2270 | ; |
||
2271 | |||
2272 | module = { |
||
2273 | |||
2274 | initialize: function() { |
||
2275 | module.debug('Initializing', $module); |
||
2276 | module.bind.events(); |
||
2277 | if(settings.observeChanges) { |
||
2278 | module.observeChanges(); |
||
2279 | } |
||
2280 | module.instantiate(); |
||
2281 | }, |
||
2282 | |||
2283 | instantiate: function() { |
||
2284 | instance = module; |
||
2285 | $module |
||
2286 | .data(moduleNamespace, module) |
||
2287 | ; |
||
2288 | }, |
||
2289 | |||
2290 | destroy: function() { |
||
2291 | module.debug('Destroying previous instance', $module); |
||
2292 | $module |
||
2293 | .off(eventNamespace) |
||
2294 | .removeData(moduleNamespace) |
||
2295 | ; |
||
2296 | }, |
||
2297 | |||
2298 | refresh: function() { |
||
2299 | $title = $module.find(selector.title); |
||
2300 | $content = $module.find(selector.content); |
||
2301 | }, |
||
2302 | |||
2303 | observeChanges: function() { |
||
2304 | if('MutationObserver' in window) { |
||
2305 | observer = new MutationObserver(function(mutations) { |
||
2306 | module.debug('DOM tree modified, updating selector cache'); |
||
2307 | module.refresh(); |
||
2308 | }); |
||
2309 | observer.observe(element, { |
||
2310 | childList : true, |
||
2311 | subtree : true |
||
2312 | }); |
||
2313 | module.debug('Setting up mutation observer', observer); |
||
2314 | } |
||
2315 | }, |
||
2316 | |||
2317 | bind: { |
||
2318 | events: function() { |
||
2319 | module.debug('Binding delegated events'); |
||
2320 | $module |
||
2321 | .on(settings.on + eventNamespace, selector.trigger, module.event.click) |
||
2322 | ; |
||
2323 | } |
||
2324 | }, |
||
2325 | |||
2326 | event: { |
||
2327 | click: function() { |
||
2328 | module.toggle.call(this); |
||
2329 | } |
||
2330 | }, |
||
2331 | |||
2332 | toggle: function(query) { |
||
2333 | var |
||
2334 | $activeTitle = (query !== undefined) |
||
2335 | ? (typeof query === 'number') |
||
2336 | ? $title.eq(query) |
||
2337 | : $(query).closest(selector.title) |
||
2338 | : $(this).closest(selector.title), |
||
2339 | $activeContent = $activeTitle.next($content), |
||
2340 | isAnimating = $activeContent.hasClass(className.animating), |
||
2341 | isActive = $activeContent.hasClass(className.active), |
||
2342 | isOpen = (isActive && !isAnimating), |
||
2343 | isOpening = (!isActive && isAnimating) |
||
2344 | ; |
||
2345 | module.debug('Toggling visibility of content', $activeTitle); |
||
2346 | if(isOpen || isOpening) { |
||
2347 | if(settings.collapsible) { |
||
2348 | module.close.call($activeTitle); |
||
2349 | } |
||
2350 | else { |
||
2351 | module.debug('Cannot close accordion content collapsing is disabled'); |
||
2352 | } |
||
2353 | } |
||
2354 | else { |
||
2355 | module.open.call($activeTitle); |
||
2356 | } |
||
2357 | }, |
||
2358 | |||
2359 | open: function(query) { |
||
2360 | var |
||
2361 | $activeTitle = (query !== undefined) |
||
2362 | ? (typeof query === 'number') |
||
2363 | ? $title.eq(query) |
||
2364 | : $(query).closest(selector.title) |
||
2365 | : $(this).closest(selector.title), |
||
2366 | $activeContent = $activeTitle.next($content), |
||
2367 | isAnimating = $activeContent.hasClass(className.animating), |
||
2368 | isActive = $activeContent.hasClass(className.active), |
||
2369 | isOpen = (isActive || isAnimating) |
||
2370 | ; |
||
2371 | if(isOpen) { |
||
2372 | module.debug('Accordion already open, skipping', $activeContent); |
||
2373 | return; |
||
2374 | } |
||
2375 | module.debug('Opening accordion content', $activeTitle); |
||
2376 | settings.onOpening.call($activeContent); |
||
2377 | if(settings.exclusive) { |
||
2378 | module.closeOthers.call($activeTitle); |
||
2379 | } |
||
2380 | $activeTitle |
||
2381 | .addClass(className.active) |
||
2382 | ; |
||
2383 | $activeContent |
||
2384 | .stop(true, true) |
||
2385 | .addClass(className.animating) |
||
2386 | ; |
||
2387 | if(settings.animateChildren) { |
||
2388 | if($.fn.transition !== undefined && $module.transition('is supported')) { |
||
2389 | $activeContent |
||
2390 | .children() |
||
2391 | .transition({ |
||
2392 | animation : 'fade in', |
||
2393 | queue : false, |
||
2394 | useFailSafe : true, |
||
2395 | debug : settings.debug, |
||
2396 | verbose : settings.verbose, |
||
2397 | duration : settings.duration |
||
2398 | }) |
||
2399 | ; |
||
2400 | } |
||
2401 | else { |
||
2402 | $activeContent |
||
2403 | .children() |
||
2404 | .stop(true, true) |
||
2405 | .animate({ |
||
2406 | opacity: 1 |
||
2407 | }, settings.duration, module.resetOpacity) |
||
2408 | ; |
||
2409 | } |
||
2410 | } |
||
2411 | $activeContent |
||
2412 | .slideDown(settings.duration, settings.easing, function() { |
||
2413 | $activeContent |
||
2414 | .removeClass(className.animating) |
||
2415 | .addClass(className.active) |
||
2416 | ; |
||
2417 | module.reset.display.call(this); |
||
2418 | settings.onOpen.call(this); |
||
2419 | settings.onChange.call(this); |
||
2420 | }) |
||
2421 | ; |
||
2422 | }, |
||
2423 | |||
2424 | close: function(query) { |
||
2425 | var |
||
2426 | $activeTitle = (query !== undefined) |
||
2427 | ? (typeof query === 'number') |
||
2428 | ? $title.eq(query) |
||
2429 | : $(query).closest(selector.title) |
||
2430 | : $(this).closest(selector.title), |
||
2431 | $activeContent = $activeTitle.next($content), |
||
2432 | isAnimating = $activeContent.hasClass(className.animating), |
||
2433 | isActive = $activeContent.hasClass(className.active), |
||
2434 | isOpening = (!isActive && isAnimating), |
||
2435 | isClosing = (isActive && isAnimating) |
||
2436 | ; |
||
2437 | if((isActive || isOpening) && !isClosing) { |
||
2438 | module.debug('Closing accordion content', $activeContent); |
||
2439 | settings.onClosing.call($activeContent); |
||
2440 | $activeTitle |
||
2441 | .removeClass(className.active) |
||
2442 | ; |
||
2443 | $activeContent |
||
2444 | .stop(true, true) |
||
2445 | .addClass(className.animating) |
||
2446 | ; |
||
2447 | if(settings.animateChildren) { |
||
2448 | if($.fn.transition !== undefined && $module.transition('is supported')) { |
||
2449 | $activeContent |
||
2450 | .children() |
||
2451 | .transition({ |
||
2452 | animation : 'fade out', |
||
2453 | queue : false, |
||
2454 | useFailSafe : true, |
||
2455 | debug : settings.debug, |
||
2456 | verbose : settings.verbose, |
||
2457 | duration : settings.duration |
||
2458 | }) |
||
2459 | ; |
||
2460 | } |
||
2461 | else { |
||
2462 | $activeContent |
||
2463 | .children() |
||
2464 | .stop(true, true) |
||
2465 | .animate({ |
||
2466 | opacity: 0 |
||
2467 | }, settings.duration, module.resetOpacity) |
||
2468 | ; |
||
2469 | } |
||
2470 | } |
||
2471 | $activeContent |
||
2472 | .slideUp(settings.duration, settings.easing, function() { |
||
2473 | $activeContent |
||
2474 | .removeClass(className.animating) |
||
2475 | .removeClass(className.active) |
||
2476 | ; |
||
2477 | module.reset.display.call(this); |
||
2478 | settings.onClose.call(this); |
||
2479 | settings.onChange.call(this); |
||
2480 | }) |
||
2481 | ; |
||
2482 | } |
||
2483 | }, |
||
2484 | |||
2485 | closeOthers: function(index) { |
||
2486 | var |
||
2487 | $activeTitle = (index !== undefined) |
||
2488 | ? $title.eq(index) |
||
2489 | : $(this).closest(selector.title), |
||
2490 | $parentTitles = $activeTitle.parents(selector.content).prev(selector.title), |
||
2491 | $activeAccordion = $activeTitle.closest(selector.accordion), |
||
2492 | activeSelector = selector.title + '.' + className.active + ':visible', |
||
2493 | activeContent = selector.content + '.' + className.active + ':visible', |
||
2494 | $openTitles, |
||
2495 | $nestedTitles, |
||
2496 | $openContents |
||
2497 | ; |
||
2498 | if(settings.closeNested) { |
||
2499 | $openTitles = $activeAccordion.find(activeSelector).not($parentTitles); |
||
2500 | $openContents = $openTitles.next($content); |
||
2501 | } |
||
2502 | else { |
||
2503 | $openTitles = $activeAccordion.find(activeSelector).not($parentTitles); |
||
2504 | $nestedTitles = $activeAccordion.find(activeContent).find(activeSelector).not($parentTitles); |
||
2505 | $openTitles = $openTitles.not($nestedTitles); |
||
2506 | $openContents = $openTitles.next($content); |
||
2507 | } |
||
2508 | if( ($openTitles.length > 0) ) { |
||
2509 | module.debug('Exclusive enabled, closing other content', $openTitles); |
||
2510 | $openTitles |
||
2511 | .removeClass(className.active) |
||
2512 | ; |
||
2513 | $openContents |
||
2514 | .removeClass(className.animating) |
||
2515 | .stop(true, true) |
||
2516 | ; |
||
2517 | if(settings.animateChildren) { |
||
2518 | if($.fn.transition !== undefined && $module.transition('is supported')) { |
||
2519 | $openContents |
||
2520 | .children() |
||
2521 | .transition({ |
||
2522 | animation : 'fade out', |
||
2523 | useFailSafe : true, |
||
2524 | debug : settings.debug, |
||
2525 | verbose : settings.verbose, |
||
2526 | duration : settings.duration |
||
2527 | }) |
||
2528 | ; |
||
2529 | } |
||
2530 | else { |
||
2531 | $openContents |
||
2532 | .children() |
||
2533 | .stop(true, true) |
||
2534 | .animate({ |
||
2535 | opacity: 0 |
||
2536 | }, settings.duration, module.resetOpacity) |
||
2537 | ; |
||
2538 | } |
||
2539 | } |
||
2540 | $openContents |
||
2541 | .slideUp(settings.duration , settings.easing, function() { |
||
2542 | $(this).removeClass(className.active); |
||
2543 | module.reset.display.call(this); |
||
2544 | }) |
||
2545 | ; |
||
2546 | } |
||
2547 | }, |
||
2548 | |||
2549 | reset: { |
||
2550 | |||
2551 | display: function() { |
||
2552 | module.verbose('Removing inline display from element', this); |
||
2553 | $(this).css('display', ''); |
||
2554 | if( $(this).attr('style') === '') { |
||
2555 | $(this) |
||
2556 | .attr('style', '') |
||
2557 | .removeAttr('style') |
||
2558 | ; |
||
2559 | } |
||
2560 | }, |
||
2561 | |||
2562 | opacity: function() { |
||
2563 | module.verbose('Removing inline opacity from element', this); |
||
2564 | $(this).css('opacity', ''); |
||
2565 | if( $(this).attr('style') === '') { |
||
2566 | $(this) |
||
2567 | .attr('style', '') |
||
2568 | .removeAttr('style') |
||
2569 | ; |
||
2570 | } |
||
2571 | }, |
||
2572 | |||
2573 | }, |
||
2574 | |||
2575 | setting: function(name, value) { |
||
2576 | module.debug('Changing setting', name, value); |
||
2577 | if( $.isPlainObject(name) ) { |
||
2578 | $.extend(true, settings, name); |
||
2579 | } |
||
2580 | else if(value !== undefined) { |
||
2581 | if($.isPlainObject(settings[name])) { |
||
2582 | $.extend(true, settings[name], value); |
||
2583 | } |
||
2584 | else { |
||
2585 | settings[name] = value; |
||
2586 | } |
||
2587 | } |
||
2588 | else { |
||
2589 | return settings[name]; |
||
2590 | } |
||
2591 | }, |
||
2592 | internal: function(name, value) { |
||
2593 | module.debug('Changing internal', name, value); |
||
2594 | if(value !== undefined) { |
||
2595 | if( $.isPlainObject(name) ) { |
||
2596 | $.extend(true, module, name); |
||
2597 | } |
||
2598 | else { |
||
2599 | module[name] = value; |
||
2600 | } |
||
2601 | } |
||
2602 | else { |
||
2603 | return module[name]; |
||
2604 | } |
||
2605 | }, |
||
2606 | debug: function() { |
||
2607 | if(!settings.silent && settings.debug) { |
||
2608 | if(settings.performance) { |
||
2609 | module.performance.log(arguments); |
||
2610 | } |
||
2611 | else { |
||
2612 | module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':'); |
||
2613 | module.debug.apply(console, arguments); |
||
2614 | } |
||
2615 | } |
||
2616 | }, |
||
2617 | verbose: function() { |
||
2618 | if(!settings.silent && settings.verbose && settings.debug) { |
||
2619 | if(settings.performance) { |
||
2620 | module.performance.log(arguments); |
||
2621 | } |
||
2622 | else { |
||
2623 | module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':'); |
||
2624 | module.verbose.apply(console, arguments); |
||
2625 | } |
||
2626 | } |
||
2627 | }, |
||
2628 | error: function() { |
||
2629 | if(!settings.silent) { |
||
2630 | module.error = Function.prototype.bind.call(console.error, console, settings.name + ':'); |
||
2631 | module.error.apply(console, arguments); |
||
2632 | } |
||
2633 | }, |
||
2634 | performance: { |
||
2635 | log: function(message) { |
||
2636 | var |
||
2637 | currentTime, |
||
2638 | executionTime, |
||
2639 | previousTime |
||
2640 | ; |
||
2641 | if(settings.performance) { |
||
2642 | currentTime = new Date().getTime(); |
||
2643 | previousTime = time || currentTime; |
||
2644 | executionTime = currentTime - previousTime; |
||
2645 | time = currentTime; |
||
2646 | performance.push({ |
||
2647 | 'Name' : message[0], |
||
2648 | 'Arguments' : [].slice.call(message, 1) || '', |
||
2649 | 'Element' : element, |
||
2650 | 'Execution Time' : executionTime |
||
2651 | }); |
||
2652 | } |
||
2653 | clearTimeout(module.performance.timer); |
||
2654 | module.performance.timer = setTimeout(module.performance.display, 500); |
||
2655 | }, |
||
2656 | display: function() { |
||
2657 | var |
||
2658 | title = settings.name + ':', |
||
2659 | totalTime = 0 |
||
2660 | ; |
||
2661 | time = false; |
||
2662 | clearTimeout(module.performance.timer); |
||
2663 | $.each(performance, function(index, data) { |
||
2664 | totalTime += data['Execution Time']; |
||
2665 | }); |
||
2666 | title += ' ' + totalTime + 'ms'; |
||
2667 | if(moduleSelector) { |
||
2668 | title += ' \'' + moduleSelector + '\''; |
||
2669 | } |
||
2670 | if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) { |
||
2671 | console.groupCollapsed(title); |
||
2672 | if(console.table) { |
||
2673 | console.table(performance); |
||
2674 | } |
||
2675 | else { |
||
2676 | $.each(performance, function(index, data) { |
||
2677 | console.log(data['Name'] + ': ' + data['Execution Time']+'ms'); |
||
2678 | }); |
||
2679 | } |
||
2680 | console.groupEnd(); |
||
2681 | } |
||
2682 | performance = []; |
||
2683 | } |
||
2684 | }, |
||
2685 | invoke: function(query, passedArguments, context) { |
||
2686 | var |
||
2687 | object = instance, |
||
2688 | maxDepth, |
||
2689 | found, |
||
2690 | response |
||
2691 | ; |
||
2692 | passedArguments = passedArguments || queryArguments; |
||
2693 | context = element || context; |
||
2694 | if(typeof query == 'string' && object !== undefined) { |
||
2695 | query = query.split(/[\. ]/); |
||
2696 | maxDepth = query.length - 1; |
||
2697 | $.each(query, function(depth, value) { |
||
2698 | var camelCaseValue = (depth != maxDepth) |
||
2699 | ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1) |
||
2700 | : query |
||
2701 | ; |
||
2702 | if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) { |
||
2703 | object = object[camelCaseValue]; |
||
2704 | } |
||
2705 | else if( object[camelCaseValue] !== undefined ) { |
||
2706 | found = object[camelCaseValue]; |
||
2707 | return false; |
||
2708 | } |
||
2709 | else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) { |
||
2710 | object = object[value]; |
||
2711 | } |
||
2712 | else if( object[value] !== undefined ) { |
||
2713 | found = object[value]; |
||
2714 | return false; |
||
2715 | } |
||
2716 | else { |
||
2717 | module.error(error.method, query); |
||
2718 | return false; |
||
2719 | } |
||
2720 | }); |
||
2721 | } |
||
2722 | if ( $.isFunction( found ) ) { |
||
2723 | response = found.apply(context, passedArguments); |
||
2724 | } |
||
2725 | else if(found !== undefined) { |
||
2726 | response = found; |
||
2727 | } |
||
2728 | if($.isArray(returnedValue)) { |
||
2729 | returnedValue.push(response); |
||
2730 | } |
||
2731 | else if(returnedValue !== undefined) { |
||
2732 | returnedValue = [returnedValue, response]; |
||
2733 | } |
||
2734 | else if(response !== undefined) { |
||
2735 | returnedValue = response; |
||
2736 | } |
||
2737 | return found; |
||
2738 | } |
||
2739 | }; |
||
2740 | if(methodInvoked) { |
||
2741 | if(instance === undefined) { |
||
2742 | module.initialize(); |
||
2743 | } |
||
2744 | module.invoke(query); |
||
2745 | } |
||
2746 | else { |
||
2747 | if(instance !== undefined) { |
||
2748 | instance.invoke('destroy'); |
||
2749 | } |
||
2750 | module.initialize(); |
||
2751 | } |
||
2752 | }) |
||
2753 | ; |
||
2754 | return (returnedValue !== undefined) |
||
2755 | ? returnedValue |
||
2756 | : this |
||
2757 | ; |
||
2758 | }; |
||
2759 | |||
2760 | $.fn.accordion.settings = { |
||
2761 | |||
2762 | name : 'Accordion', |
||
2763 | namespace : 'accordion', |
||
2764 | |||
2765 | silent : false, |
||
2766 | debug : false, |
||
2767 | verbose : false, |
||
2768 | performance : true, |
||
2769 | |||
2770 | on : 'click', // event on title that opens accordion |
||
2771 | |||
2772 | observeChanges : true, // whether accordion should automatically refresh on DOM insertion |
||
2773 | |||
2774 | exclusive : true, // whether a single accordion content panel should be open at once |
||
2775 | collapsible : true, // whether accordion content can be closed |
||
2776 | closeNested : false, // whether nested content should be closed when a panel is closed |
||
2777 | animateChildren : true, // whether children opacity should be animated |
||
2778 | |||
2779 | duration : 350, // duration of animation |
||
2780 | easing : 'easeOutQuad', // easing equation for animation |
||
2781 | |||
2782 | |||
2783 | onOpening : function(){}, // callback before open animation |
||
2784 | onOpen : function(){}, // callback after open animation |
||
2785 | onClosing : function(){}, // callback before closing animation |
||
2786 | onClose : function(){}, // callback after closing animation |
||
2787 | onChange : function(){}, // callback after closing or opening animation |
||
2788 | |||
2789 | error: { |
||
2790 | method : 'The method you called is not defined' |
||
2791 | }, |
||
2792 | |||
2793 | className : { |
||
2794 | active : 'active', |
||
2795 | animating : 'animating' |
||
2796 | }, |
||
2797 | |||
2798 | selector : { |
||
2799 | accordion : '.accordion', |
||
2800 | title : '.title', |
||
2801 | trigger : '.title', |
||
2802 | content : '.content' |
||
2803 | } |
||
2804 | |||
2805 | }; |
||
2806 | |||
2807 | // Adds easing |
||
2808 | $.extend( $.easing, { |
||
2809 | easeOutQuad: function (x, t, b, c, d) { |
||
2810 | return -c *(t/=d)*(t-2) + b; |
||
2811 | } |
||
2812 | }); |
||
2813 | |||
2814 | })( jQuery, window, document ); |
||
2815 | |||
2816 | |||
2817 | /*! |
||
2818 | * # Semantic UI 2.2.11 - Checkbox |
||
2819 | * http://github.com/semantic-org/semantic-ui/ |
||
2820 | * |
||
2821 | * |
||
2822 | * Released under the MIT license |
||
2823 | * http://opensource.org/licenses/MIT |
||
2824 | * |
||
2825 | */ |
||
2826 | |||
2827 | View Code Duplication | ;(function ($, window, document, undefined) { |
|
2828 | |||
2829 | "use strict"; |
||
2830 | |||
2831 | window = (typeof window != 'undefined' && window.Math == Math) |
||
2832 | ? window |
||
2833 | : (typeof self != 'undefined' && self.Math == Math) |
||
2834 | ? self |
||
2835 | : Function('return this')() |
||
2836 | ; |
||
2837 | |||
2838 | $.fn.checkbox = function(parameters) { |
||
2839 | var |
||
2840 | $allModules = $(this), |
||
2841 | moduleSelector = $allModules.selector || '', |
||
2842 | |||
2843 | time = new Date().getTime(), |
||
2844 | performance = [], |
||
2845 | |||
2846 | query = arguments[0], |
||
2847 | methodInvoked = (typeof query == 'string'), |
||
2848 | queryArguments = [].slice.call(arguments, 1), |
||
2849 | returnedValue |
||
2850 | ; |
||
2851 | |||
2852 | $allModules |
||
2853 | .each(function() { |
||
2854 | var |
||
2855 | settings = $.extend(true, {}, $.fn.checkbox.settings, parameters), |
||
2856 | |||
2857 | className = settings.className, |
||
2858 | namespace = settings.namespace, |
||
2859 | selector = settings.selector, |
||
2860 | error = settings.error, |
||
2861 | |||
2862 | eventNamespace = '.' + namespace, |
||
2863 | moduleNamespace = 'module-' + namespace, |
||
2864 | |||
2865 | $module = $(this), |
||
2866 | $label = $(this).children(selector.label), |
||
2867 | $input = $(this).children(selector.input), |
||
2868 | input = $input[0], |
||
2869 | |||
2870 | initialLoad = false, |
||
2871 | shortcutPressed = false, |
||
2872 | instance = $module.data(moduleNamespace), |
||
2873 | |||
2874 | observer, |
||
2875 | element = this, |
||
2876 | module |
||
2877 | ; |
||
2878 | |||
2879 | module = { |
||
2880 | |||
2881 | initialize: function() { |
||
2882 | module.verbose('Initializing checkbox', settings); |
||
2883 | |||
2884 | module.create.label(); |
||
2885 | module.bind.events(); |
||
2886 | |||
2887 | module.set.tabbable(); |
||
2888 | module.hide.input(); |
||
2889 | |||
2890 | module.observeChanges(); |
||
2891 | module.instantiate(); |
||
2892 | module.setup(); |
||
2893 | }, |
||
2894 | |||
2895 | instantiate: function() { |
||
2896 | module.verbose('Storing instance of module', module); |
||
2897 | instance = module; |
||
2898 | $module |
||
2899 | .data(moduleNamespace, module) |
||
2900 | ; |
||
2901 | }, |
||
2902 | |||
2903 | destroy: function() { |
||
2904 | module.verbose('Destroying module'); |
||
2905 | module.unbind.events(); |
||
2906 | module.show.input(); |
||
2907 | $module.removeData(moduleNamespace); |
||
2908 | }, |
||
2909 | |||
2910 | fix: { |
||
2911 | reference: function() { |
||
2912 | if( $module.is(selector.input) ) { |
||
2913 | module.debug('Behavior called on <input> adjusting invoked element'); |
||
2914 | $module = $module.closest(selector.checkbox); |
||
2915 | module.refresh(); |
||
2916 | } |
||
2917 | } |
||
2918 | }, |
||
2919 | |||
2920 | setup: function() { |
||
2921 | module.set.initialLoad(); |
||
2922 | if( module.is.indeterminate() ) { |
||
2923 | module.debug('Initial value is indeterminate'); |
||
2924 | module.indeterminate(); |
||
2925 | } |
||
2926 | else if( module.is.checked() ) { |
||
2927 | module.debug('Initial value is checked'); |
||
2928 | module.check(); |
||
2929 | } |
||
2930 | else { |
||
2931 | module.debug('Initial value is unchecked'); |
||
2932 | module.uncheck(); |
||
2933 | } |
||
2934 | module.remove.initialLoad(); |
||
2935 | }, |
||
2936 | |||
2937 | refresh: function() { |
||
2938 | $label = $module.children(selector.label); |
||
2939 | $input = $module.children(selector.input); |
||
2940 | input = $input[0]; |
||
2941 | }, |
||
2942 | |||
2943 | hide: { |
||
2944 | input: function() { |
||
2945 | module.verbose('Modifying <input> z-index to be unselectable'); |
||
2946 | $input.addClass(className.hidden); |
||
2947 | } |
||
2948 | }, |
||
2949 | show: { |
||
2950 | input: function() { |
||
2951 | module.verbose('Modifying <input> z-index to be selectable'); |
||
2952 | $input.removeClass(className.hidden); |
||
2953 | } |
||
2954 | }, |
||
2955 | |||
2956 | observeChanges: function() { |
||
2957 | if('MutationObserver' in window) { |
||
2958 | observer = new MutationObserver(function(mutations) { |
||
2959 | module.debug('DOM tree modified, updating selector cache'); |
||
2960 | module.refresh(); |
||
2961 | }); |
||
2962 | observer.observe(element, { |
||
2963 | childList : true, |
||
2964 | subtree : true |
||
2965 | }); |
||
2966 | module.debug('Setting up mutation observer', observer); |
||
2967 | } |
||
2968 | }, |
||
2969 | |||
2970 | attachEvents: function(selector, event) { |
||
2971 | var |
||
2972 | $element = $(selector) |
||
2973 | ; |
||
2974 | event = $.isFunction(module[event]) |
||
2975 | ? module[event] |
||
2976 | : module.toggle |
||
2977 | ; |
||
2978 | if($element.length > 0) { |
||
2979 | module.debug('Attaching checkbox events to element', selector, event); |
||
2980 | $element |
||
2981 | .on('click' + eventNamespace, event) |
||
2982 | ; |
||
2983 | } |
||
2984 | else { |
||
2985 | module.error(error.notFound); |
||
2986 | } |
||
2987 | }, |
||
2988 | |||
2989 | event: { |
||
2990 | click: function(event) { |
||
2991 | var |
||
2992 | $target = $(event.target) |
||
2993 | ; |
||
2994 | if( $target.is(selector.input) ) { |
||
2995 | module.verbose('Using default check action on initialized checkbox'); |
||
2996 | return; |
||
2997 | } |
||
2998 | if( $target.is(selector.link) ) { |
||
2999 | module.debug('Clicking link inside checkbox, skipping toggle'); |
||
3000 | return; |
||
3001 | } |
||
3002 | module.toggle(); |
||
3003 | $input.focus(); |
||
3004 | event.preventDefault(); |
||
3005 | }, |
||
3006 | keydown: function(event) { |
||
3007 | var |
||
3008 | key = event.which, |
||
3009 | keyCode = { |
||
3010 | enter : 13, |
||
3011 | space : 32, |
||
3012 | escape : 27 |
||
3013 | } |
||
3014 | ; |
||
3015 | if(key == keyCode.escape) { |
||
3016 | module.verbose('Escape key pressed blurring field'); |
||
3017 | $input.blur(); |
||
3018 | shortcutPressed = true; |
||
3019 | } |
||
3020 | else if(!event.ctrlKey && ( key == keyCode.space || key == keyCode.enter) ) { |
||
3021 | module.verbose('Enter/space key pressed, toggling checkbox'); |
||
3022 | module.toggle(); |
||
3023 | shortcutPressed = true; |
||
3024 | } |
||
3025 | else { |
||
3026 | shortcutPressed = false; |
||
3027 | } |
||
3028 | }, |
||
3029 | keyup: function(event) { |
||
3030 | if(shortcutPressed) { |
||
3031 | event.preventDefault(); |
||
3032 | } |
||
3033 | } |
||
3034 | }, |
||
3035 | |||
3036 | check: function() { |
||
3037 | if( !module.should.allowCheck() ) { |
||
3038 | return; |
||
3039 | } |
||
3040 | module.debug('Checking checkbox', $input); |
||
3041 | module.set.checked(); |
||
3042 | if( !module.should.ignoreCallbacks() ) { |
||
3043 | settings.onChecked.call(input); |
||
3044 | settings.onChange.call(input); |
||
3045 | } |
||
3046 | }, |
||
3047 | |||
3048 | uncheck: function() { |
||
3049 | if( !module.should.allowUncheck() ) { |
||
3050 | return; |
||
3051 | } |
||
3052 | module.debug('Unchecking checkbox'); |
||
3053 | module.set.unchecked(); |
||
3054 | if( !module.should.ignoreCallbacks() ) { |
||
3055 | settings.onUnchecked.call(input); |
||
3056 | settings.onChange.call(input); |
||
3057 | } |
||
3058 | }, |
||
3059 | |||
3060 | indeterminate: function() { |
||
3061 | if( module.should.allowIndeterminate() ) { |
||
3062 | module.debug('Checkbox is already indeterminate'); |
||
3063 | return; |
||
3064 | } |
||
3065 | module.debug('Making checkbox indeterminate'); |
||
3066 | module.set.indeterminate(); |
||
3067 | if( !module.should.ignoreCallbacks() ) { |
||
3068 | settings.onIndeterminate.call(input); |
||
3069 | settings.onChange.call(input); |
||
3070 | } |
||
3071 | }, |
||
3072 | |||
3073 | determinate: function() { |
||
3074 | if( module.should.allowDeterminate() ) { |
||
3075 | module.debug('Checkbox is already determinate'); |
||
3076 | return; |
||
3077 | } |
||
3078 | module.debug('Making checkbox determinate'); |
||
3079 | module.set.determinate(); |
||
3080 | if( !module.should.ignoreCallbacks() ) { |
||
3081 | settings.onDeterminate.call(input); |
||
3082 | settings.onChange.call(input); |
||
3083 | } |
||
3084 | }, |
||
3085 | |||
3086 | enable: function() { |
||
3087 | if( module.is.enabled() ) { |
||
3088 | module.debug('Checkbox is already enabled'); |
||
3089 | return; |
||
3090 | } |
||
3091 | module.debug('Enabling checkbox'); |
||
3092 | module.set.enabled(); |
||
3093 | settings.onEnable.call(input); |
||
3094 | // preserve legacy callbacks |
||
3095 | settings.onEnabled.call(input); |
||
3096 | }, |
||
3097 | |||
3098 | disable: function() { |
||
3099 | if( module.is.disabled() ) { |
||
3100 | module.debug('Checkbox is already disabled'); |
||
3101 | return; |
||
3102 | } |
||
3103 | module.debug('Disabling checkbox'); |
||
3104 | module.set.disabled(); |
||
3105 | settings.onDisable.call(input); |
||
3106 | // preserve legacy callbacks |
||
3107 | settings.onDisabled.call(input); |
||
3108 | }, |
||
3109 | |||
3110 | get: { |
||
3111 | radios: function() { |
||
3112 | var |
||
3113 | name = module.get.name() |
||
3114 | ; |
||
3115 | return $('input[name="' + name + '"]').closest(selector.checkbox); |
||
3116 | }, |
||
3117 | otherRadios: function() { |
||
3118 | return module.get.radios().not($module); |
||
3119 | }, |
||
3120 | name: function() { |
||
3121 | return $input.attr('name'); |
||
3122 | } |
||
3123 | }, |
||
3124 | |||
3125 | is: { |
||
3126 | initialLoad: function() { |
||
3127 | return initialLoad; |
||
3128 | }, |
||
3129 | radio: function() { |
||
3130 | return ($input.hasClass(className.radio) || $input.attr('type') == 'radio'); |
||
3131 | }, |
||
3132 | indeterminate: function() { |
||
3133 | return $input.prop('indeterminate') !== undefined && $input.prop('indeterminate'); |
||
3134 | }, |
||
3135 | checked: function() { |
||
3136 | return $input.prop('checked') !== undefined && $input.prop('checked'); |
||
3137 | }, |
||
3138 | disabled: function() { |
||
3139 | return $input.prop('disabled') !== undefined && $input.prop('disabled'); |
||
3140 | }, |
||
3141 | enabled: function() { |
||
3142 | return !module.is.disabled(); |
||
3143 | }, |
||
3144 | determinate: function() { |
||
3145 | return !module.is.indeterminate(); |
||
3146 | }, |
||
3147 | unchecked: function() { |
||
3148 | return !module.is.checked(); |
||
3149 | } |
||
3150 | }, |
||
3151 | |||
3152 | should: { |
||
3153 | allowCheck: function() { |
||
3154 | if(module.is.determinate() && module.is.checked() && !module.should.forceCallbacks() ) { |
||
3155 | module.debug('Should not allow check, checkbox is already checked'); |
||
3156 | return false; |
||
3157 | } |
||
3158 | if(settings.beforeChecked.apply(input) === false) { |
||
3159 | module.debug('Should not allow check, beforeChecked cancelled'); |
||
3160 | return false; |
||
3161 | } |
||
3162 | return true; |
||
3163 | }, |
||
3164 | allowUncheck: function() { |
||
3165 | if(module.is.determinate() && module.is.unchecked() && !module.should.forceCallbacks() ) { |
||
3166 | module.debug('Should not allow uncheck, checkbox is already unchecked'); |
||
3167 | return false; |
||
3168 | } |
||
3169 | if(settings.beforeUnchecked.apply(input) === false) { |
||
3170 | module.debug('Should not allow uncheck, beforeUnchecked cancelled'); |
||
3171 | return false; |
||
3172 | } |
||
3173 | return true; |
||
3174 | }, |
||
3175 | allowIndeterminate: function() { |
||
3176 | if(module.is.indeterminate() && !module.should.forceCallbacks() ) { |
||
3177 | module.debug('Should not allow indeterminate, checkbox is already indeterminate'); |
||
3178 | return false; |
||
3179 | } |
||
3180 | if(settings.beforeIndeterminate.apply(input) === false) { |
||
3181 | module.debug('Should not allow indeterminate, beforeIndeterminate cancelled'); |
||
3182 | return false; |
||
3183 | } |
||
3184 | return true; |
||
3185 | }, |
||
3186 | allowDeterminate: function() { |
||
3187 | if(module.is.determinate() && !module.should.forceCallbacks() ) { |
||
3188 | module.debug('Should not allow determinate, checkbox is already determinate'); |
||
3189 | return false; |
||
3190 | } |
||
3191 | if(settings.beforeDeterminate.apply(input) === false) { |
||
3192 | module.debug('Should not allow determinate, beforeDeterminate cancelled'); |
||
3193 | return false; |
||
3194 | } |
||
3195 | return true; |
||
3196 | }, |
||
3197 | forceCallbacks: function() { |
||
3198 | return (module.is.initialLoad() && settings.fireOnInit); |
||
3199 | }, |
||
3200 | ignoreCallbacks: function() { |
||
3201 | return (initialLoad && !settings.fireOnInit); |
||
3202 | } |
||
3203 | }, |
||
3204 | |||
3205 | can: { |
||
3206 | change: function() { |
||
3207 | return !( $module.hasClass(className.disabled) || $module.hasClass(className.readOnly) || $input.prop('disabled') || $input.prop('readonly') ); |
||
3208 | }, |
||
3209 | uncheck: function() { |
||
3210 | return (typeof settings.uncheckable === 'boolean') |
||
3211 | ? settings.uncheckable |
||
3212 | : !module.is.radio() |
||
3213 | ; |
||
3214 | } |
||
3215 | }, |
||
3216 | |||
3217 | set: { |
||
3218 | initialLoad: function() { |
||
3219 | initialLoad = true; |
||
3220 | }, |
||
3221 | checked: function() { |
||
3222 | module.verbose('Setting class to checked'); |
||
3223 | $module |
||
3224 | .removeClass(className.indeterminate) |
||
3225 | .addClass(className.checked) |
||
3226 | ; |
||
3227 | if( module.is.radio() ) { |
||
3228 | module.uncheckOthers(); |
||
3229 | } |
||
3230 | if(!module.is.indeterminate() && module.is.checked()) { |
||
3231 | module.debug('Input is already checked, skipping input property change'); |
||
3232 | return; |
||
3233 | } |
||
3234 | module.verbose('Setting state to checked', input); |
||
3235 | $input |
||
3236 | .prop('indeterminate', false) |
||
3237 | .prop('checked', true) |
||
3238 | ; |
||
3239 | module.trigger.change(); |
||
3240 | }, |
||
3241 | unchecked: function() { |
||
3242 | module.verbose('Removing checked class'); |
||
3243 | $module |
||
3244 | .removeClass(className.indeterminate) |
||
3245 | .removeClass(className.checked) |
||
3246 | ; |
||
3247 | if(!module.is.indeterminate() && module.is.unchecked() ) { |
||
3248 | module.debug('Input is already unchecked'); |
||
3249 | return; |
||
3250 | } |
||
3251 | module.debug('Setting state to unchecked'); |
||
3252 | $input |
||
3253 | .prop('indeterminate', false) |
||
3254 | .prop('checked', false) |
||
3255 | ; |
||
3256 | module.trigger.change(); |
||
3257 | }, |
||
3258 | indeterminate: function() { |
||
3259 | module.verbose('Setting class to indeterminate'); |
||
3260 | $module |
||
3261 | .addClass(className.indeterminate) |
||
3262 | ; |
||
3263 | if( module.is.indeterminate() ) { |
||
3264 | module.debug('Input is already indeterminate, skipping input property change'); |
||
3265 | return; |
||
3266 | } |
||
3267 | module.debug('Setting state to indeterminate'); |
||
3268 | $input |
||
3269 | .prop('indeterminate', true) |
||
3270 | ; |
||
3271 | module.trigger.change(); |
||
3272 | }, |
||
3273 | determinate: function() { |
||
3274 | module.verbose('Removing indeterminate class'); |
||
3275 | $module |
||
3276 | .removeClass(className.indeterminate) |
||
3277 | ; |
||
3278 | if( module.is.determinate() ) { |
||
3279 | module.debug('Input is already determinate, skipping input property change'); |
||
3280 | return; |
||
3281 | } |
||
3282 | module.debug('Setting state to determinate'); |
||
3283 | $input |
||
3284 | .prop('indeterminate', false) |
||
3285 | ; |
||
3286 | }, |
||
3287 | disabled: function() { |
||
3288 | module.verbose('Setting class to disabled'); |
||
3289 | $module |
||
3290 | .addClass(className.disabled) |
||
3291 | ; |
||
3292 | if( module.is.disabled() ) { |
||
3293 | module.debug('Input is already disabled, skipping input property change'); |
||
3294 | return; |
||
3295 | } |
||
3296 | module.debug('Setting state to disabled'); |
||
3297 | $input |
||
3298 | .prop('disabled', 'disabled') |
||
3299 | ; |
||
3300 | module.trigger.change(); |
||
3301 | }, |
||
3302 | enabled: function() { |
||
3303 | module.verbose('Removing disabled class'); |
||
3304 | $module.removeClass(className.disabled); |
||
3305 | if( module.is.enabled() ) { |
||
3306 | module.debug('Input is already enabled, skipping input property change'); |
||
3307 | return; |
||
3308 | } |
||
3309 | module.debug('Setting state to enabled'); |
||
3310 | $input |
||
3311 | .prop('disabled', false) |
||
3312 | ; |
||
3313 | module.trigger.change(); |
||
3314 | }, |
||
3315 | tabbable: function() { |
||
3316 | module.verbose('Adding tabindex to checkbox'); |
||
3317 | if( $input.attr('tabindex') === undefined) { |
||
3318 | $input.attr('tabindex', 0); |
||
3319 | } |
||
3320 | } |
||
3321 | }, |
||
3322 | |||
3323 | remove: { |
||
3324 | initialLoad: function() { |
||
3325 | initialLoad = false; |
||
3326 | } |
||
3327 | }, |
||
3328 | |||
3329 | trigger: { |
||
3330 | change: function() { |
||
3331 | var |
||
3332 | events = document.createEvent('HTMLEvents'), |
||
3333 | inputElement = $input[0] |
||
3334 | ; |
||
3335 | if(inputElement) { |
||
3336 | module.verbose('Triggering native change event'); |
||
3337 | events.initEvent('change', true, false); |
||
3338 | inputElement.dispatchEvent(events); |
||
3339 | } |
||
3340 | } |
||
3341 | }, |
||
3342 | |||
3343 | |||
3344 | create: { |
||
3345 | label: function() { |
||
3346 | if($input.prevAll(selector.label).length > 0) { |
||
3347 | $input.prev(selector.label).detach().insertAfter($input); |
||
3348 | module.debug('Moving existing label', $label); |
||
3349 | } |
||
3350 | else if( !module.has.label() ) { |
||
3351 | $label = $('<label>').insertAfter($input); |
||
3352 | module.debug('Creating label', $label); |
||
3353 | } |
||
3354 | } |
||
3355 | }, |
||
3356 | |||
3357 | has: { |
||
3358 | label: function() { |
||
3359 | return ($label.length > 0); |
||
3360 | } |
||
3361 | }, |
||
3362 | |||
3363 | bind: { |
||
3364 | events: function() { |
||
3365 | module.verbose('Attaching checkbox events'); |
||
3366 | $module |
||
3367 | .on('click' + eventNamespace, module.event.click) |
||
3368 | .on('keydown' + eventNamespace, selector.input, module.event.keydown) |
||
3369 | .on('keyup' + eventNamespace, selector.input, module.event.keyup) |
||
3370 | ; |
||
3371 | } |
||
3372 | }, |
||
3373 | |||
3374 | unbind: { |
||
3375 | events: function() { |
||
3376 | module.debug('Removing events'); |
||
3377 | $module |
||
3378 | .off(eventNamespace) |
||
3379 | ; |
||
3380 | } |
||
3381 | }, |
||
3382 | |||
3383 | uncheckOthers: function() { |
||
3384 | var |
||
3385 | $radios = module.get.otherRadios() |
||
3386 | ; |
||
3387 | module.debug('Unchecking other radios', $radios); |
||
3388 | $radios.removeClass(className.checked); |
||
3389 | }, |
||
3390 | |||
3391 | toggle: function() { |
||
3392 | if( !module.can.change() ) { |
||
3393 | if(!module.is.radio()) { |
||
3394 | module.debug('Checkbox is read-only or disabled, ignoring toggle'); |
||
3395 | } |
||
3396 | return; |
||
3397 | } |
||
3398 | if( module.is.indeterminate() || module.is.unchecked() ) { |
||
3399 | module.debug('Currently unchecked'); |
||
3400 | module.check(); |
||
3401 | } |
||
3402 | else if( module.is.checked() && module.can.uncheck() ) { |
||
3403 | module.debug('Currently checked'); |
||
3404 | module.uncheck(); |
||
3405 | } |
||
3406 | }, |
||
3407 | setting: function(name, value) { |
||
3408 | module.debug('Changing setting', name, value); |
||
3409 | if( $.isPlainObject(name) ) { |
||
3410 | $.extend(true, settings, name); |
||
3411 | } |
||
3412 | else if(value !== undefined) { |
||
3413 | if($.isPlainObject(settings[name])) { |
||
3414 | $.extend(true, settings[name], value); |
||
3415 | } |
||
3416 | else { |
||
3417 | settings[name] = value; |
||
3418 | } |
||
3419 | } |
||
3420 | else { |
||
3421 | return settings[name]; |
||
3422 | } |
||
3423 | }, |
||
3424 | internal: function(name, value) { |
||
3425 | if( $.isPlainObject(name) ) { |
||
3426 | $.extend(true, module, name); |
||
3427 | } |
||
3428 | else if(value !== undefined) { |
||
3429 | module[name] = value; |
||
3430 | } |
||
3431 | else { |
||
3432 | return module[name]; |
||
3433 | } |
||
3434 | }, |
||
3435 | debug: function() { |
||
3436 | if(!settings.silent && settings.debug) { |
||
3437 | if(settings.performance) { |
||
3438 | module.performance.log(arguments); |
||
3439 | } |
||
3440 | else { |
||
3441 | module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':'); |
||
3442 | module.debug.apply(console, arguments); |
||
3443 | } |
||
3444 | } |
||
3445 | }, |
||
3446 | verbose: function() { |
||
3447 | if(!settings.silent && settings.verbose && settings.debug) { |
||
3448 | if(settings.performance) { |
||
3449 | module.performance.log(arguments); |
||
3450 | } |
||
3451 | else { |
||
3452 | module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':'); |
||
3453 | module.verbose.apply(console, arguments); |
||
3454 | } |
||
3455 | } |
||
3456 | }, |
||
3457 | error: function() { |
||
3458 | if(!settings.silent) { |
||
3459 | module.error = Function.prototype.bind.call(console.error, console, settings.name + ':'); |
||
3460 | module.error.apply(console, arguments); |
||
3461 | } |
||
3462 | }, |
||
3463 | performance: { |
||
3464 | log: function(message) { |
||
3465 | var |
||
3466 | currentTime, |
||
3467 | executionTime, |
||
3468 | previousTime |
||
3469 | ; |
||
3470 | if(settings.performance) { |
||
3471 | currentTime = new Date().getTime(); |
||
3472 | previousTime = time || currentTime; |
||
3473 | executionTime = currentTime - previousTime; |
||
3474 | time = currentTime; |
||
3475 | performance.push({ |
||
3476 | 'Name' : message[0], |
||
3477 | 'Arguments' : [].slice.call(message, 1) || '', |
||
3478 | 'Element' : element, |
||
3479 | 'Execution Time' : executionTime |
||
3480 | }); |
||
3481 | } |
||
3482 | clearTimeout(module.performance.timer); |
||
3483 | module.performance.timer = setTimeout(module.performance.display, 500); |
||
3484 | }, |
||
3485 | display: function() { |
||
3486 | var |
||
3487 | title = settings.name + ':', |
||
3488 | totalTime = 0 |
||
3489 | ; |
||
3490 | time = false; |
||
3491 | clearTimeout(module.performance.timer); |
||
3492 | $.each(performance, function(index, data) { |
||
3493 | totalTime += data['Execution Time']; |
||
3494 | }); |
||
3495 | title += ' ' + totalTime + 'ms'; |
||
3496 | if(moduleSelector) { |
||
3497 | title += ' \'' + moduleSelector + '\''; |
||
3498 | } |
||
3499 | if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) { |
||
3500 | console.groupCollapsed(title); |
||
3501 | if(console.table) { |
||
3502 | console.table(performance); |
||
3503 | } |
||
3504 | else { |
||
3505 | $.each(performance, function(index, data) { |
||
3506 | console.log(data['Name'] + ': ' + data['Execution Time']+'ms'); |
||
3507 | }); |
||
3508 | } |
||
3509 | console.groupEnd(); |
||
3510 | } |
||
3511 | performance = []; |
||
3512 | } |
||
3513 | }, |
||
3514 | invoke: function(query, passedArguments, context) { |
||
3515 | var |
||
3516 | object = instance, |
||
3517 | maxDepth, |
||
3518 | found, |
||
3519 | response |
||
3520 | ; |
||
3521 | passedArguments = passedArguments || queryArguments; |
||
3522 | context = element || context; |
||
3523 | if(typeof query == 'string' && object !== undefined) { |
||
3524 | query = query.split(/[\. ]/); |
||
3525 | maxDepth = query.length - 1; |
||
3526 | $.each(query, function(depth, value) { |
||
3527 | var camelCaseValue = (depth != maxDepth) |
||
3528 | ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1) |
||
3529 | : query |
||
3530 | ; |
||
3531 | if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) { |
||
3532 | object = object[camelCaseValue]; |
||
3533 | } |
||
3534 | else if( object[camelCaseValue] !== undefined ) { |
||
3535 | found = object[camelCaseValue]; |
||
3536 | return false; |
||
3537 | } |
||
3538 | else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) { |
||
3539 | object = object[value]; |
||
3540 | } |
||
3541 | else if( object[value] !== undefined ) { |
||
3542 | found = object[value]; |
||
3543 | return false; |
||
3544 | } |
||
3545 | else { |
||
3546 | module.error(error.method, query); |
||
3547 | return false; |
||
3548 | } |
||
3549 | }); |
||
3550 | } |
||
3551 | if ( $.isFunction( found ) ) { |
||
3552 | response = found.apply(context, passedArguments); |
||
3553 | } |
||
3554 | else if(found !== undefined) { |
||
3555 | response = found; |
||
3556 | } |
||
3557 | if($.isArray(returnedValue)) { |
||
3558 | returnedValue.push(response); |
||
3559 | } |
||
3560 | else if(returnedValue !== undefined) { |
||
3561 | returnedValue = [returnedValue, response]; |
||
3562 | } |
||
3563 | else if(response !== undefined) { |
||
3564 | returnedValue = response; |
||
3565 | } |
||
3566 | return found; |
||
3567 | } |
||
3568 | }; |
||
3569 | |||
3570 | if(methodInvoked) { |
||
3571 | if(instance === undefined) { |
||
3572 | module.initialize(); |
||
3573 | } |
||
3574 | module.invoke(query); |
||
3575 | } |
||
3576 | else { |
||
3577 | if(instance !== undefined) { |
||
3578 | instance.invoke('destroy'); |
||
3579 | } |
||
3580 | module.initialize(); |
||
3581 | } |
||
3582 | }) |
||
3583 | ; |
||
3584 | |||
3585 | return (returnedValue !== undefined) |
||
3586 | ? returnedValue |
||
3587 | : this |
||
3588 | ; |
||
3589 | }; |
||
3590 | |||
3591 | $.fn.checkbox.settings = { |
||
3592 | |||
3593 | name : 'Checkbox', |
||
3594 | namespace : 'checkbox', |
||
3595 | |||
3596 | silent : false, |
||
3597 | debug : false, |
||
3598 | verbose : true, |
||
3599 | performance : true, |
||
3600 | |||
3601 | // delegated event context |
||
3602 | uncheckable : 'auto', |
||
3603 | fireOnInit : false, |
||
3604 | |||
3605 | onChange : function(){}, |
||
3606 | |||
3607 | beforeChecked : function(){}, |
||
3608 | beforeUnchecked : function(){}, |
||
3609 | beforeDeterminate : function(){}, |
||
3610 | beforeIndeterminate : function(){}, |
||
3611 | |||
3612 | onChecked : function(){}, |
||
3613 | onUnchecked : function(){}, |
||
3614 | |||
3615 | onDeterminate : function() {}, |
||
3616 | onIndeterminate : function() {}, |
||
3617 | |||
3618 | onEnable : function(){}, |
||
3619 | onDisable : function(){}, |
||
3620 | |||
3621 | // preserve misspelled callbacks (will be removed in 3.0) |
||
3622 | onEnabled : function(){}, |
||
3623 | onDisabled : function(){}, |
||
3624 | |||
3625 | className : { |
||
3626 | checked : 'checked', |
||
3627 | indeterminate : 'indeterminate', |
||
3628 | disabled : 'disabled', |
||
3629 | hidden : 'hidden', |
||
3630 | radio : 'radio', |
||
3631 | readOnly : 'read-only' |
||
3632 | }, |
||
3633 | |||
3634 | error : { |
||
3635 | method : 'The method you called is not defined' |
||
3636 | }, |
||
3637 | |||
3638 | selector : { |
||
3639 | checkbox : '.ui.checkbox', |
||
3640 | label : 'label, .box', |
||
3641 | input : 'input[type="checkbox"], input[type="radio"]', |
||
3642 | link : 'a[href]' |
||
3643 | } |
||
3644 | |||
3645 | }; |
||
3646 | |||
3647 | })( jQuery, window, document ); |
||
3648 | |||
3649 | /*! |
||
3650 | * # Semantic UI 2.2.11 - Dimmer |
||
3651 | * http://github.com/semantic-org/semantic-ui/ |
||
3652 | * |
||
3653 | * |
||
3654 | * Released under the MIT license |
||
3655 | * http://opensource.org/licenses/MIT |
||
3656 | * |
||
3657 | */ |
||
3658 | |||
3659 | View Code Duplication | ;(function ($, window, document, undefined) { |
|
3660 | |||
3661 | "use strict"; |
||
3662 | |||
3663 | window = (typeof window != 'undefined' && window.Math == Math) |
||
3664 | ? window |
||
3665 | : (typeof self != 'undefined' && self.Math == Math) |
||
3666 | ? self |
||
3667 | : Function('return this')() |
||
3668 | ; |
||
3669 | |||
3670 | $.fn.dimmer = function(parameters) { |
||
3671 | var |
||
3672 | $allModules = $(this), |
||
3673 | |||
3674 | time = new Date().getTime(), |
||
3675 | performance = [], |
||
3676 | |||
3677 | query = arguments[0], |
||
3678 | methodInvoked = (typeof query == 'string'), |
||
3679 | queryArguments = [].slice.call(arguments, 1), |
||
3680 | |||
3681 | returnedValue |
||
3682 | ; |
||
3683 | |||
3684 | $allModules |
||
3685 | .each(function() { |
||
3686 | var |
||
3687 | settings = ( $.isPlainObject(parameters) ) |
||
3688 | ? $.extend(true, {}, $.fn.dimmer.settings, parameters) |
||
3689 | : $.extend({}, $.fn.dimmer.settings), |
||
3690 | |||
3691 | selector = settings.selector, |
||
3692 | namespace = settings.namespace, |
||
3693 | className = settings.className, |
||
3694 | error = settings.error, |
||
3695 | |||
3696 | eventNamespace = '.' + namespace, |
||
3697 | moduleNamespace = 'module-' + namespace, |
||
3698 | moduleSelector = $allModules.selector || '', |
||
3699 | |||
3700 | clickEvent = ('ontouchstart' in document.documentElement) |
||
3701 | ? 'touchstart' |
||
3702 | : 'click', |
||
3703 | |||
3704 | $module = $(this), |
||
3705 | $dimmer, |
||
3706 | $dimmable, |
||
3707 | |||
3708 | element = this, |
||
3709 | instance = $module.data(moduleNamespace), |
||
3710 | module |
||
3711 | ; |
||
3712 | |||
3713 | module = { |
||
3714 | |||
3715 | preinitialize: function() { |
||
3716 | if( module.is.dimmer() ) { |
||
3717 | |||
3718 | $dimmable = $module.parent(); |
||
3719 | $dimmer = $module; |
||
3720 | } |
||
3721 | else { |
||
3722 | $dimmable = $module; |
||
3723 | if( module.has.dimmer() ) { |
||
3724 | if(settings.dimmerName) { |
||
3725 | $dimmer = $dimmable.find(selector.dimmer).filter('.' + settings.dimmerName); |
||
3726 | } |
||
3727 | else { |
||
3728 | $dimmer = $dimmable.find(selector.dimmer); |
||
3729 | } |
||
3730 | } |
||
3731 | else { |
||
3732 | $dimmer = module.create(); |
||
3733 | } |
||
3734 | module.set.variation(); |
||
3735 | } |
||
3736 | }, |
||
3737 | |||
3738 | initialize: function() { |
||
3739 | module.debug('Initializing dimmer', settings); |
||
3740 | |||
3741 | module.bind.events(); |
||
3742 | module.set.dimmable(); |
||
3743 | module.instantiate(); |
||
3744 | }, |
||
3745 | |||
3746 | instantiate: function() { |
||
3747 | module.verbose('Storing instance of module', module); |
||
3748 | instance = module; |
||
3749 | $module |
||
3750 | .data(moduleNamespace, instance) |
||
3751 | ; |
||
3752 | }, |
||
3753 | |||
3754 | destroy: function() { |
||
3755 | module.verbose('Destroying previous module', $dimmer); |
||
3756 | module.unbind.events(); |
||
3757 | module.remove.variation(); |
||
3758 | $dimmable |
||
3759 | .off(eventNamespace) |
||
3760 | ; |
||
3761 | }, |
||
3762 | |||
3763 | bind: { |
||
3764 | events: function() { |
||
3765 | if(settings.on == 'hover') { |
||
3766 | $dimmable |
||
3767 | .on('mouseenter' + eventNamespace, module.show) |
||
3768 | .on('mouseleave' + eventNamespace, module.hide) |
||
3769 | ; |
||
3770 | } |
||
3771 | else if(settings.on == 'click') { |
||
3772 | $dimmable |
||
3773 | .on(clickEvent + eventNamespace, module.toggle) |
||
3774 | ; |
||
3775 | } |
||
3776 | if( module.is.page() ) { |
||
3777 | module.debug('Setting as a page dimmer', $dimmable); |
||
3778 | module.set.pageDimmer(); |
||
3779 | } |
||
3780 | |||
3781 | if( module.is.closable() ) { |
||
3782 | module.verbose('Adding dimmer close event', $dimmer); |
||
3783 | $dimmable |
||
3784 | .on(clickEvent + eventNamespace, selector.dimmer, module.event.click) |
||
3785 | ; |
||
3786 | } |
||
3787 | } |
||
3788 | }, |
||
3789 | |||
3790 | unbind: { |
||
3791 | events: function() { |
||
3792 | $module |
||
3793 | .removeData(moduleNamespace) |
||
3794 | ; |
||
3795 | $dimmable |
||
3796 | .off(eventNamespace) |
||
3797 | ; |
||
3798 | } |
||
3799 | }, |
||
3800 | |||
3801 | event: { |
||
3802 | click: function(event) { |
||
3803 | module.verbose('Determining if event occured on dimmer', event); |
||
3804 | if( $dimmer.find(event.target).length === 0 || $(event.target).is(selector.content) ) { |
||
3805 | module.hide(); |
||
3806 | event.stopImmediatePropagation(); |
||
3807 | } |
||
3808 | } |
||
3809 | }, |
||
3810 | |||
3811 | addContent: function(element) { |
||
3812 | var |
||
3813 | $content = $(element) |
||
3814 | ; |
||
3815 | module.debug('Add content to dimmer', $content); |
||
3816 | if($content.parent()[0] !== $dimmer[0]) { |
||
3817 | $content.detach().appendTo($dimmer); |
||
3818 | } |
||
3819 | }, |
||
3820 | |||
3821 | create: function() { |
||
3822 | var |
||
3823 | $element = $( settings.template.dimmer() ) |
||
3824 | ; |
||
3825 | if(settings.dimmerName) { |
||
3826 | module.debug('Creating named dimmer', settings.dimmerName); |
||
3827 | $element.addClass(settings.dimmerName); |
||
3828 | } |
||
3829 | $element |
||
3830 | .appendTo($dimmable) |
||
3831 | ; |
||
3832 | return $element; |
||
3833 | }, |
||
3834 | |||
3835 | show: function(callback) { |
||
3836 | callback = $.isFunction(callback) |
||
3837 | ? callback |
||
3838 | : function(){} |
||
3839 | ; |
||
3840 | module.debug('Showing dimmer', $dimmer, settings); |
||
3841 | if( (!module.is.dimmed() || module.is.animating()) && module.is.enabled() ) { |
||
3842 | module.animate.show(callback); |
||
3843 | settings.onShow.call(element); |
||
3844 | settings.onChange.call(element); |
||
3845 | } |
||
3846 | else { |
||
3847 | module.debug('Dimmer is already shown or disabled'); |
||
3848 | } |
||
3849 | }, |
||
3850 | |||
3851 | hide: function(callback) { |
||
3852 | callback = $.isFunction(callback) |
||
3853 | ? callback |
||
3854 | : function(){} |
||
3855 | ; |
||
3856 | if( module.is.dimmed() || module.is.animating() ) { |
||
3857 | module.debug('Hiding dimmer', $dimmer); |
||
3858 | module.animate.hide(callback); |
||
3859 | settings.onHide.call(element); |
||
3860 | settings.onChange.call(element); |
||
3861 | } |
||
3862 | else { |
||
3863 | module.debug('Dimmer is not visible'); |
||
3864 | } |
||
3865 | }, |
||
3866 | |||
3867 | toggle: function() { |
||
3868 | module.verbose('Toggling dimmer visibility', $dimmer); |
||
3869 | if( !module.is.dimmed() ) { |
||
3870 | module.show(); |
||
3871 | } |
||
3872 | else { |
||
3873 | module.hide(); |
||
3874 | } |
||
3875 | }, |
||
3876 | |||
3877 | animate: { |
||
3878 | show: function(callback) { |
||
3879 | callback = $.isFunction(callback) |
||
3880 | ? callback |
||
3881 | : function(){} |
||
3882 | ; |
||
3883 | if(settings.useCSS && $.fn.transition !== undefined && $dimmer.transition('is supported')) { |
||
3884 | if(settings.opacity !== 'auto') { |
||
3885 | module.set.opacity(); |
||
3886 | } |
||
3887 | $dimmer |
||
3888 | .transition({ |
||
3889 | animation : settings.transition + ' in', |
||
3890 | queue : false, |
||
3891 | duration : module.get.duration(), |
||
3892 | useFailSafe : true, |
||
3893 | onStart : function() { |
||
3894 | module.set.dimmed(); |
||
3895 | }, |
||
3896 | onComplete : function() { |
||
3897 | module.set.active(); |
||
3898 | callback(); |
||
3899 | } |
||
3900 | }) |
||
3901 | ; |
||
3902 | } |
||
3903 | else { |
||
3904 | module.verbose('Showing dimmer animation with javascript'); |
||
3905 | module.set.dimmed(); |
||
3906 | if(settings.opacity == 'auto') { |
||
3907 | settings.opacity = 0.8; |
||
3908 | } |
||
3909 | $dimmer |
||
3910 | .stop() |
||
3911 | .css({ |
||
3912 | opacity : 0, |
||
3913 | width : '100%', |
||
3914 | height : '100%' |
||
3915 | }) |
||
3916 | .fadeTo(module.get.duration(), settings.opacity, function() { |
||
3917 | $dimmer.removeAttr('style'); |
||
3918 | module.set.active(); |
||
3919 | callback(); |
||
3920 | }) |
||
3921 | ; |
||
3922 | } |
||
3923 | }, |
||
3924 | hide: function(callback) { |
||
3925 | callback = $.isFunction(callback) |
||
3926 | ? callback |
||
3927 | : function(){} |
||
3928 | ; |
||
3929 | if(settings.useCSS && $.fn.transition !== undefined && $dimmer.transition('is supported')) { |
||
3930 | module.verbose('Hiding dimmer with css'); |
||
3931 | $dimmer |
||
3932 | .transition({ |
||
3933 | animation : settings.transition + ' out', |
||
3934 | queue : false, |
||
3935 | duration : module.get.duration(), |
||
3936 | useFailSafe : true, |
||
3937 | onStart : function() { |
||
3938 | module.remove.dimmed(); |
||
3939 | }, |
||
3940 | onComplete : function() { |
||
3941 | module.remove.active(); |
||
3942 | callback(); |
||
3943 | } |
||
3944 | }) |
||
3945 | ; |
||
3946 | } |
||
3947 | else { |
||
3948 | module.verbose('Hiding dimmer with javascript'); |
||
3949 | module.remove.dimmed(); |
||
3950 | $dimmer |
||
3951 | .stop() |
||
3952 | .fadeOut(module.get.duration(), function() { |
||
3953 | module.remove.active(); |
||
3954 | $dimmer.removeAttr('style'); |
||
3955 | callback(); |
||
3956 | }) |
||
3957 | ; |
||
3958 | } |
||
3959 | } |
||
3960 | }, |
||
3961 | |||
3962 | get: { |
||
3963 | dimmer: function() { |
||
3964 | return $dimmer; |
||
3965 | }, |
||
3966 | duration: function() { |
||
3967 | if(typeof settings.duration == 'object') { |
||
3968 | if( module.is.active() ) { |
||
3969 | return settings.duration.hide; |
||
3970 | } |
||
3971 | else { |
||
3972 | return settings.duration.show; |
||
3973 | } |
||
3974 | } |
||
3975 | return settings.duration; |
||
3976 | } |
||
3977 | }, |
||
3978 | |||
3979 | has: { |
||
3980 | dimmer: function() { |
||
3981 | if(settings.dimmerName) { |
||
3982 | return ($module.find(selector.dimmer).filter('.' + settings.dimmerName).length > 0); |
||
3983 | } |
||
3984 | else { |
||
3985 | return ( $module.find(selector.dimmer).length > 0 ); |
||
3986 | } |
||
3987 | } |
||
3988 | }, |
||
3989 | |||
3990 | is: { |
||
3991 | active: function() { |
||
3992 | return $dimmer.hasClass(className.active); |
||
3993 | }, |
||
3994 | animating: function() { |
||
3995 | return ( $dimmer.is(':animated') || $dimmer.hasClass(className.animating) ); |
||
3996 | }, |
||
3997 | closable: function() { |
||
3998 | if(settings.closable == 'auto') { |
||
3999 | if(settings.on == 'hover') { |
||
4000 | return false; |
||
4001 | } |
||
4002 | return true; |
||
4003 | } |
||
4004 | return settings.closable; |
||
4005 | }, |
||
4006 | dimmer: function() { |
||
4007 | return $module.hasClass(className.dimmer); |
||
4008 | }, |
||
4009 | dimmable: function() { |
||
4010 | return $module.hasClass(className.dimmable); |
||
4011 | }, |
||
4012 | dimmed: function() { |
||
4013 | return $dimmable.hasClass(className.dimmed); |
||
4014 | }, |
||
4015 | disabled: function() { |
||
4016 | return $dimmable.hasClass(className.disabled); |
||
4017 | }, |
||
4018 | enabled: function() { |
||
4019 | return !module.is.disabled(); |
||
4020 | }, |
||
4021 | page: function () { |
||
4022 | return $dimmable.is('body'); |
||
4023 | }, |
||
4024 | pageDimmer: function() { |
||
4025 | return $dimmer.hasClass(className.pageDimmer); |
||
4026 | } |
||
4027 | }, |
||
4028 | |||
4029 | can: { |
||
4030 | show: function() { |
||
4031 | return !$dimmer.hasClass(className.disabled); |
||
4032 | } |
||
4033 | }, |
||
4034 | |||
4035 | set: { |
||
4036 | opacity: function(opacity) { |
||
4037 | var |
||
4038 | color = $dimmer.css('background-color'), |
||
4039 | colorArray = color.split(','), |
||
4040 | isRGB = (colorArray && colorArray.length == 3), |
||
4041 | isRGBA = (colorArray && colorArray.length == 4) |
||
4042 | ; |
||
4043 | opacity = settings.opacity === 0 ? 0 : settings.opacity || opacity; |
||
4044 | if(isRGB || isRGBA) { |
||
4045 | colorArray[3] = opacity + ')'; |
||
4046 | color = colorArray.join(','); |
||
4047 | } |
||
4048 | else { |
||
4049 | color = 'rgba(0, 0, 0, ' + opacity + ')'; |
||
4050 | } |
||
4051 | module.debug('Setting opacity to', opacity); |
||
4052 | $dimmer.css('background-color', color); |
||
4053 | }, |
||
4054 | active: function() { |
||
4055 | $dimmer.addClass(className.active); |
||
4056 | }, |
||
4057 | dimmable: function() { |
||
4058 | $dimmable.addClass(className.dimmable); |
||
4059 | }, |
||
4060 | dimmed: function() { |
||
4061 | $dimmable.addClass(className.dimmed); |
||
4062 | }, |
||
4063 | pageDimmer: function() { |
||
4064 | $dimmer.addClass(className.pageDimmer); |
||
4065 | }, |
||
4066 | disabled: function() { |
||
4067 | $dimmer.addClass(className.disabled); |
||
4068 | }, |
||
4069 | variation: function(variation) { |
||
4070 | variation = variation || settings.variation; |
||
4071 | if(variation) { |
||
4072 | $dimmer.addClass(variation); |
||
4073 | } |
||
4074 | } |
||
4075 | }, |
||
4076 | |||
4077 | remove: { |
||
4078 | active: function() { |
||
4079 | $dimmer |
||
4080 | .removeClass(className.active) |
||
4081 | ; |
||
4082 | }, |
||
4083 | dimmed: function() { |
||
4084 | $dimmable.removeClass(className.dimmed); |
||
4085 | }, |
||
4086 | disabled: function() { |
||
4087 | $dimmer.removeClass(className.disabled); |
||
4088 | }, |
||
4089 | variation: function(variation) { |
||
4090 | variation = variation || settings.variation; |
||
4091 | if(variation) { |
||
4092 | $dimmer.removeClass(variation); |
||
4093 | } |
||
4094 | } |
||
4095 | }, |
||
4096 | |||
4097 | setting: function(name, value) { |
||
4098 | module.debug('Changing setting', name, value); |
||
4099 | if( $.isPlainObject(name) ) { |
||
4100 | $.extend(true, settings, name); |
||
4101 | } |
||
4102 | else if(value !== undefined) { |
||
4103 | if($.isPlainObject(settings[name])) { |
||
4104 | $.extend(true, settings[name], value); |
||
4105 | } |
||
4106 | else { |
||
4107 | settings[name] = value; |
||
4108 | } |
||
4109 | } |
||
4110 | else { |
||
4111 | return settings[name]; |
||
4112 | } |
||
4113 | }, |
||
4114 | internal: function(name, value) { |
||
4115 | if( $.isPlainObject(name) ) { |
||
4116 | $.extend(true, module, name); |
||
4117 | } |
||
4118 | else if(value !== undefined) { |
||
4119 | module[name] = value; |
||
4120 | } |
||
4121 | else { |
||
4122 | return module[name]; |
||
4123 | } |
||
4124 | }, |
||
4125 | debug: function() { |
||
4126 | if(!settings.silent && settings.debug) { |
||
4127 | if(settings.performance) { |
||
4128 | module.performance.log(arguments); |
||
4129 | } |
||
4130 | else { |
||
4131 | module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':'); |
||
4132 | module.debug.apply(console, arguments); |
||
4133 | } |
||
4134 | } |
||
4135 | }, |
||
4136 | verbose: function() { |
||
4137 | if(!settings.silent && settings.verbose && settings.debug) { |
||
4138 | if(settings.performance) { |
||
4139 | module.performance.log(arguments); |
||
4140 | } |
||
4141 | else { |
||
4142 | module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':'); |
||
4143 | module.verbose.apply(console, arguments); |
||
4144 | } |
||
4145 | } |
||
4146 | }, |
||
4147 | error: function() { |
||
4148 | if(!settings.silent) { |
||
4149 | module.error = Function.prototype.bind.call(console.error, console, settings.name + ':'); |
||
4150 | module.error.apply(console, arguments); |
||
4151 | } |
||
4152 | }, |
||
4153 | performance: { |
||
4154 | log: function(message) { |
||
4155 | var |
||
4156 | currentTime, |
||
4157 | executionTime, |
||
4158 | previousTime |
||
4159 | ; |
||
4160 | if(settings.performance) { |
||
4161 | currentTime = new Date().getTime(); |
||
4162 | previousTime = time || currentTime; |
||
4163 | executionTime = currentTime - previousTime; |
||
4164 | time = currentTime; |
||
4165 | performance.push({ |
||
4166 | 'Name' : message[0], |
||
4167 | 'Arguments' : [].slice.call(message, 1) || '', |
||
4168 | 'Element' : element, |
||
4169 | 'Execution Time' : executionTime |
||
4170 | }); |
||
4171 | } |
||
4172 | clearTimeout(module.performance.timer); |
||
4173 | module.performance.timer = setTimeout(module.performance.display, 500); |
||
4174 | }, |
||
4175 | display: function() { |
||
4176 | var |
||
4177 | title = settings.name + ':', |
||
4178 | totalTime = 0 |
||
4179 | ; |
||
4180 | time = false; |
||
4181 | clearTimeout(module.performance.timer); |
||
4182 | $.each(performance, function(index, data) { |
||
4183 | totalTime += data['Execution Time']; |
||
4184 | }); |
||
4185 | title += ' ' + totalTime + 'ms'; |
||
4186 | if(moduleSelector) { |
||
4187 | title += ' \'' + moduleSelector + '\''; |
||
4188 | } |
||
4189 | if($allModules.length > 1) { |
||
4190 | title += ' ' + '(' + $allModules.length + ')'; |
||
4191 | } |
||
4192 | if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) { |
||
4193 | console.groupCollapsed(title); |
||
4194 | if(console.table) { |
||
4195 | console.table(performance); |
||
4196 | } |
||
4197 | else { |
||
4198 | $.each(performance, function(index, data) { |
||
4199 | console.log(data['Name'] + ': ' + data['Execution Time']+'ms'); |
||
4200 | }); |
||
4201 | } |
||
4202 | console.groupEnd(); |
||
4203 | } |
||
4204 | performance = []; |
||
4205 | } |
||
4206 | }, |
||
4207 | invoke: function(query, passedArguments, context) { |
||
4208 | var |
||
4209 | object = instance, |
||
4210 | maxDepth, |
||
4211 | found, |
||
4212 | response |
||
4213 | ; |
||
4214 | passedArguments = passedArguments || queryArguments; |
||
4215 | context = element || context; |
||
4216 | if(typeof query == 'string' && object !== undefined) { |
||
4217 | query = query.split(/[\. ]/); |
||
4218 | maxDepth = query.length - 1; |
||
4219 | $.each(query, function(depth, value) { |
||
4220 | var camelCaseValue = (depth != maxDepth) |
||
4221 | ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1) |
||
4222 | : query |
||
4223 | ; |
||
4224 | if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) { |
||
4225 | object = object[camelCaseValue]; |
||
4226 | } |
||
4227 | else if( object[camelCaseValue] !== undefined ) { |
||
4228 | found = object[camelCaseValue]; |
||
4229 | return false; |
||
4230 | } |
||
4231 | else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) { |
||
4232 | object = object[value]; |
||
4233 | } |
||
4234 | else if( object[value] !== undefined ) { |
||
4235 | found = object[value]; |
||
4236 | return false; |
||
4237 | } |
||
4238 | else { |
||
4239 | module.error(error.method, query); |
||
4240 | return false; |
||
4241 | } |
||
4242 | }); |
||
4243 | } |
||
4244 | if ( $.isFunction( found ) ) { |
||
4245 | response = found.apply(context, passedArguments); |
||
4246 | } |
||
4247 | else if(found !== undefined) { |
||
4248 | response = found; |
||
4249 | } |
||
4250 | if($.isArray(returnedValue)) { |
||
4251 | returnedValue.push(response); |
||
4252 | } |
||
4253 | else if(returnedValue !== undefined) { |
||
4254 | returnedValue = [returnedValue, response]; |
||
4255 | } |
||
4256 | else if(response !== undefined) { |
||
4257 | returnedValue = response; |
||
4258 | } |
||
4259 | return found; |
||
4260 | } |
||
4261 | }; |
||
4262 | |||
4263 | module.preinitialize(); |
||
4264 | |||
4265 | if(methodInvoked) { |
||
4266 | if(instance === undefined) { |
||
4267 | module.initialize(); |
||
4268 | } |
||
4269 | module.invoke(query); |
||
4270 | } |
||
4271 | else { |
||
4272 | if(instance !== undefined) { |
||
4273 | instance.invoke('destroy'); |
||
4274 | } |
||
4275 | module.initialize(); |
||
4276 | } |
||
4277 | }) |
||
4278 | ; |
||
4279 | |||
4280 | return (returnedValue !== undefined) |
||
4281 | ? returnedValue |
||
4282 | : this |
||
4283 | ; |
||
4284 | }; |
||
4285 | |||
4286 | $.fn.dimmer.settings = { |
||
4287 | |||
4288 | name : 'Dimmer', |
||
4289 | namespace : 'dimmer', |
||
4290 | |||
4291 | silent : false, |
||
4292 | debug : false, |
||
4293 | verbose : false, |
||
4294 | performance : true, |
||
4295 | |||
4296 | // name to distinguish between multiple dimmers in context |
||
4297 | dimmerName : false, |
||
4298 | |||
4299 | // whether to add a variation type |
||
4300 | variation : false, |
||
4301 | |||
4302 | // whether to bind close events |
||
4303 | closable : 'auto', |
||
4304 | |||
4305 | // whether to use css animations |
||
4306 | useCSS : true, |
||
4307 | |||
4308 | // css animation to use |
||
4309 | transition : 'fade', |
||
4310 | |||
4311 | // event to bind to |
||
4312 | on : false, |
||
4313 | |||
4314 | // overriding opacity value |
||
4315 | opacity : 'auto', |
||
4316 | |||
4317 | // transition durations |
||
4318 | duration : { |
||
4319 | show : 500, |
||
4320 | hide : 500 |
||
4321 | }, |
||
4322 | |||
4323 | onChange : function(){}, |
||
4324 | onShow : function(){}, |
||
4325 | onHide : function(){}, |
||
4326 | |||
4327 | error : { |
||
4328 | method : 'The method you called is not defined.' |
||
4329 | }, |
||
4330 | |||
4331 | className : { |
||
4332 | active : 'active', |
||
4333 | animating : 'animating', |
||
4334 | dimmable : 'dimmable', |
||
4335 | dimmed : 'dimmed', |
||
4336 | dimmer : 'dimmer', |
||
4337 | disabled : 'disabled', |
||
4338 | hide : 'hide', |
||
4339 | pageDimmer : 'page', |
||
4340 | show : 'show' |
||
4341 | }, |
||
4342 | |||
4343 | selector: { |
||
4344 | dimmer : '> .ui.dimmer', |
||
4345 | content : '.ui.dimmer > .content, .ui.dimmer > .content > .center' |
||
4346 | }, |
||
4347 | |||
4348 | template: { |
||
4349 | dimmer: function() { |
||
4350 | return $('<div />').attr('class', 'ui dimmer'); |
||
4351 | } |
||
4352 | } |
||
4353 | |||
4354 | }; |
||
4355 | |||
4356 | })( jQuery, window, document ); |
||
4357 | |||
4358 | /*! |
||
4359 | * # Semantic UI 2.2.11 - Dropdown |
||
4360 | * http://github.com/semantic-org/semantic-ui/ |
||
4361 | * |
||
4362 | * |
||
4363 | * Released under the MIT license |
||
4364 | * http://opensource.org/licenses/MIT |
||
4365 | * |
||
4366 | */ |
||
4367 | |||
4368 | View Code Duplication | ;(function ($, window, document, undefined) { |
|
4369 | |||
4370 | "use strict"; |
||
4371 | |||
4372 | window = (typeof window != 'undefined' && window.Math == Math) |
||
4373 | ? window |
||
4374 | : (typeof self != 'undefined' && self.Math == Math) |
||
4375 | ? self |
||
4376 | : Function('return this')() |
||
4377 | ; |
||
4378 | |||
4379 | $.fn.dropdown = function(parameters) { |
||
4380 | var |
||
4381 | $allModules = $(this), |
||
4382 | $document = $(document), |
||
4383 | |||
4384 | moduleSelector = $allModules.selector || '', |
||
4385 | |||
4386 | hasTouch = ('ontouchstart' in document.documentElement), |
||
4387 | time = new Date().getTime(), |
||
4388 | performance = [], |
||
4389 | |||
4390 | query = arguments[0], |
||
4391 | methodInvoked = (typeof query == 'string'), |
||
4392 | queryArguments = [].slice.call(arguments, 1), |
||
4393 | returnedValue |
||
4394 | ; |
||
4395 | |||
4396 | $allModules |
||
4397 | .each(function(elementIndex) { |
||
4398 | var |
||
4399 | settings = ( $.isPlainObject(parameters) ) |
||
4400 | ? $.extend(true, {}, $.fn.dropdown.settings, parameters) |
||
4401 | : $.extend({}, $.fn.dropdown.settings), |
||
4402 | |||
4403 | className = settings.className, |
||
4404 | message = settings.message, |
||
4405 | fields = settings.fields, |
||
4406 | keys = settings.keys, |
||
4407 | metadata = settings.metadata, |
||
4408 | namespace = settings.namespace, |
||
4409 | regExp = settings.regExp, |
||
4410 | selector = settings.selector, |
||
4411 | error = settings.error, |
||
4412 | templates = settings.templates, |
||
4413 | |||
4414 | eventNamespace = '.' + namespace, |
||
4415 | moduleNamespace = 'module-' + namespace, |
||
4416 | |||
4417 | $module = $(this), |
||
4418 | $context = $(settings.context), |
||
4419 | $text = $module.find(selector.text), |
||
4420 | $search = $module.find(selector.search), |
||
4421 | $sizer = $module.find(selector.sizer), |
||
4422 | $input = $module.find(selector.input), |
||
4423 | $icon = $module.find(selector.icon), |
||
4424 | |||
4425 | $combo = ($module.prev().find(selector.text).length > 0) |
||
4426 | ? $module.prev().find(selector.text) |
||
4427 | : $module.prev(), |
||
4428 | |||
4429 | $menu = $module.children(selector.menu), |
||
4430 | $item = $menu.find(selector.item), |
||
4431 | |||
4432 | activated = false, |
||
4433 | itemActivated = false, |
||
4434 | internalChange = false, |
||
4435 | element = this, |
||
4436 | instance = $module.data(moduleNamespace), |
||
4437 | |||
4438 | initialLoad, |
||
4439 | pageLostFocus, |
||
4440 | willRefocus, |
||
4441 | elementNamespace, |
||
4442 | id, |
||
4443 | selectObserver, |
||
4444 | menuObserver, |
||
4445 | module |
||
4446 | ; |
||
4447 | |||
4448 | module = { |
||
4449 | |||
4450 | initialize: function() { |
||
4451 | module.debug('Initializing dropdown', settings); |
||
4452 | |||
4453 | if( module.is.alreadySetup() ) { |
||
4454 | module.setup.reference(); |
||
4455 | } |
||
4456 | else { |
||
4457 | module.setup.layout(); |
||
4458 | module.refreshData(); |
||
4459 | |||
4460 | module.save.defaults(); |
||
4461 | module.restore.selected(); |
||
4462 | |||
4463 | module.create.id(); |
||
4464 | module.bind.events(); |
||
4465 | |||
4466 | module.observeChanges(); |
||
4467 | module.instantiate(); |
||
4468 | } |
||
4469 | |||
4470 | }, |
||
4471 | |||
4472 | instantiate: function() { |
||
4473 | module.verbose('Storing instance of dropdown', module); |
||
4474 | instance = module; |
||
4475 | $module |
||
4476 | .data(moduleNamespace, module) |
||
4477 | ; |
||
4478 | }, |
||
4479 | |||
4480 | destroy: function() { |
||
4481 | module.verbose('Destroying previous dropdown', $module); |
||
4482 | module.remove.tabbable(); |
||
4483 | $module |
||
4484 | .off(eventNamespace) |
||
4485 | .removeData(moduleNamespace) |
||
4486 | ; |
||
4487 | $menu |
||
4488 | .off(eventNamespace) |
||
4489 | ; |
||
4490 | $document |
||
4491 | .off(elementNamespace) |
||
4492 | ; |
||
4493 | module.disconnect.menuObserver(); |
||
4494 | module.disconnect.selectObserver(); |
||
4495 | }, |
||
4496 | |||
4497 | observeChanges: function() { |
||
4498 | if('MutationObserver' in window) { |
||
4499 | selectObserver = new MutationObserver(module.event.select.mutation); |
||
4500 | menuObserver = new MutationObserver(module.event.menu.mutation); |
||
4501 | module.debug('Setting up mutation observer', selectObserver, menuObserver); |
||
4502 | module.observe.select(); |
||
4503 | module.observe.menu(); |
||
4504 | } |
||
4505 | }, |
||
4506 | |||
4507 | disconnect: { |
||
4508 | menuObserver: function() { |
||
4509 | if(menuObserver) { |
||
4510 | menuObserver.disconnect(); |
||
4511 | } |
||
4512 | }, |
||
4513 | selectObserver: function() { |
||
4514 | if(selectObserver) { |
||
4515 | selectObserver.disconnect(); |
||
4516 | } |
||
4517 | } |
||
4518 | }, |
||
4519 | observe: { |
||
4520 | select: function() { |
||
4521 | if(module.has.input()) { |
||
4522 | selectObserver.observe($input[0], { |
||
4523 | childList : true, |
||
4524 | subtree : true |
||
4525 | }); |
||
4526 | } |
||
4527 | }, |
||
4528 | menu: function() { |
||
4529 | if(module.has.menu()) { |
||
4530 | menuObserver.observe($menu[0], { |
||
4531 | childList : true, |
||
4532 | subtree : true |
||
4533 | }); |
||
4534 | } |
||
4535 | } |
||
4536 | }, |
||
4537 | |||
4538 | create: { |
||
4539 | id: function() { |
||
4540 | id = (Math.random().toString(16) + '000000000').substr(2, 8); |
||
4541 | elementNamespace = '.' + id; |
||
4542 | module.verbose('Creating unique id for element', id); |
||
4543 | }, |
||
4544 | userChoice: function(values) { |
||
4545 | var |
||
4546 | $userChoices, |
||
4547 | $userChoice, |
||
4548 | isUserValue, |
||
4549 | html |
||
4550 | ; |
||
4551 | values = values || module.get.userValues(); |
||
4552 | if(!values) { |
||
4553 | return false; |
||
4554 | } |
||
4555 | values = $.isArray(values) |
||
4556 | ? values |
||
4557 | : [values] |
||
4558 | ; |
||
4559 | $.each(values, function(index, value) { |
||
4560 | if(module.get.item(value) === false) { |
||
4561 | html = settings.templates.addition( module.add.variables(message.addResult, value) ); |
||
4562 | $userChoice = $('<div />') |
||
4563 | .html(html) |
||
4564 | .attr('data-' + metadata.value, value) |
||
4565 | .attr('data-' + metadata.text, value) |
||
4566 | .addClass(className.addition) |
||
4567 | .addClass(className.item) |
||
4568 | ; |
||
4569 | if(settings.hideAdditions) { |
||
4570 | $userChoice.addClass(className.hidden); |
||
4571 | } |
||
4572 | $userChoices = ($userChoices === undefined) |
||
4573 | ? $userChoice |
||
4574 | : $userChoices.add($userChoice) |
||
4575 | ; |
||
4576 | module.verbose('Creating user choices for value', value, $userChoice); |
||
4577 | } |
||
4578 | }); |
||
4579 | return $userChoices; |
||
4580 | }, |
||
4581 | userLabels: function(value) { |
||
4582 | var |
||
4583 | userValues = module.get.userValues() |
||
4584 | ; |
||
4585 | if(userValues) { |
||
4586 | module.debug('Adding user labels', userValues); |
||
4587 | $.each(userValues, function(index, value) { |
||
4588 | module.verbose('Adding custom user value'); |
||
4589 | module.add.label(value, value); |
||
4590 | }); |
||
4591 | } |
||
4592 | }, |
||
4593 | menu: function() { |
||
4594 | $menu = $('<div />') |
||
4595 | .addClass(className.menu) |
||
4596 | .appendTo($module) |
||
4597 | ; |
||
4598 | }, |
||
4599 | sizer: function() { |
||
4600 | $sizer = $('<span />') |
||
4601 | .addClass(className.sizer) |
||
4602 | .insertAfter($search) |
||
4603 | ; |
||
4604 | } |
||
4605 | }, |
||
4606 | |||
4607 | search: function(query) { |
||
4608 | query = (query !== undefined) |
||
4609 | ? query |
||
4610 | : module.get.query() |
||
4611 | ; |
||
4612 | module.verbose('Searching for query', query); |
||
4613 | if(module.has.minCharacters(query)) { |
||
4614 | module.filter(query); |
||
4615 | } |
||
4616 | else { |
||
4617 | module.hide(); |
||
4618 | } |
||
4619 | }, |
||
4620 | |||
4621 | select: { |
||
4622 | firstUnfiltered: function() { |
||
4623 | module.verbose('Selecting first non-filtered element'); |
||
4624 | module.remove.selectedItem(); |
||
4625 | $item |
||
4626 | .not(selector.unselectable) |
||
4627 | .not(selector.addition + selector.hidden) |
||
4628 | .eq(0) |
||
4629 | .addClass(className.selected) |
||
4630 | ; |
||
4631 | }, |
||
4632 | nextAvailable: function($selected) { |
||
4633 | $selected = $selected.eq(0); |
||
4634 | var |
||
4635 | $nextAvailable = $selected.nextAll(selector.item).not(selector.unselectable).eq(0), |
||
4636 | $prevAvailable = $selected.prevAll(selector.item).not(selector.unselectable).eq(0), |
||
4637 | hasNext = ($nextAvailable.length > 0) |
||
4638 | ; |
||
4639 | if(hasNext) { |
||
4640 | module.verbose('Moving selection to', $nextAvailable); |
||
4641 | $nextAvailable.addClass(className.selected); |
||
4642 | } |
||
4643 | else { |
||
4644 | module.verbose('Moving selection to', $prevAvailable); |
||
4645 | $prevAvailable.addClass(className.selected); |
||
4646 | } |
||
4647 | } |
||
4648 | }, |
||
4649 | |||
4650 | setup: { |
||
4651 | api: function() { |
||
4652 | var |
||
4653 | apiSettings = { |
||
4654 | debug : settings.debug, |
||
4655 | urlData : { |
||
4656 | value : module.get.value(), |
||
4657 | query : module.get.query() |
||
4658 | }, |
||
4659 | on : false |
||
4660 | } |
||
4661 | ; |
||
4662 | module.verbose('First request, initializing API'); |
||
4663 | $module |
||
4664 | .api(apiSettings) |
||
4665 | ; |
||
4666 | }, |
||
4667 | layout: function() { |
||
4668 | if( $module.is('select') ) { |
||
4669 | module.setup.select(); |
||
4670 | module.setup.returnedObject(); |
||
4671 | } |
||
4672 | if( !module.has.menu() ) { |
||
4673 | module.create.menu(); |
||
4674 | } |
||
4675 | if( module.is.search() && !module.has.search() ) { |
||
4676 | module.verbose('Adding search input'); |
||
4677 | $search = $('<input />') |
||
4678 | .addClass(className.search) |
||
4679 | .prop('autocomplete', 'off') |
||
4680 | .insertBefore($text) |
||
4681 | ; |
||
4682 | } |
||
4683 | if( module.is.multiple() && module.is.searchSelection() && !module.has.sizer()) { |
||
4684 | module.create.sizer(); |
||
4685 | } |
||
4686 | if(settings.allowTab) { |
||
4687 | module.set.tabbable(); |
||
4688 | } |
||
4689 | }, |
||
4690 | select: function() { |
||
4691 | var |
||
4692 | selectValues = module.get.selectValues() |
||
4693 | ; |
||
4694 | module.debug('Dropdown initialized on a select', selectValues); |
||
4695 | if( $module.is('select') ) { |
||
4696 | $input = $module; |
||
4697 | } |
||
4698 | // see if select is placed correctly already |
||
4699 | if($input.parent(selector.dropdown).length > 0) { |
||
4700 | module.debug('UI dropdown already exists. Creating dropdown menu only'); |
||
4701 | $module = $input.closest(selector.dropdown); |
||
4702 | if( !module.has.menu() ) { |
||
4703 | module.create.menu(); |
||
4704 | } |
||
4705 | $menu = $module.children(selector.menu); |
||
4706 | module.setup.menu(selectValues); |
||
4707 | } |
||
4708 | else { |
||
4709 | module.debug('Creating entire dropdown from select'); |
||
4710 | $module = $('<div />') |
||
4711 | .attr('class', $input.attr('class') ) |
||
4712 | .addClass(className.selection) |
||
4713 | .addClass(className.dropdown) |
||
4714 | .html( templates.dropdown(selectValues) ) |
||
4715 | .insertBefore($input) |
||
4716 | ; |
||
4717 | if($input.hasClass(className.multiple) && $input.prop('multiple') === false) { |
||
4718 | module.error(error.missingMultiple); |
||
4719 | $input.prop('multiple', true); |
||
4720 | } |
||
4721 | if($input.is('[multiple]')) { |
||
4722 | module.set.multiple(); |
||
4723 | } |
||
4724 | if ($input.prop('disabled')) { |
||
4725 | module.debug('Disabling dropdown'); |
||
4726 | $module.addClass(className.disabled); |
||
4727 | } |
||
4728 | $input |
||
4729 | .removeAttr('class') |
||
4730 | .detach() |
||
4731 | .prependTo($module) |
||
4732 | ; |
||
4733 | } |
||
4734 | module.refresh(); |
||
4735 | }, |
||
4736 | menu: function(values) { |
||
4737 | $menu.html( templates.menu(values, fields)); |
||
4738 | $item = $menu.find(selector.item); |
||
4739 | }, |
||
4740 | reference: function() { |
||
4741 | module.debug('Dropdown behavior was called on select, replacing with closest dropdown'); |
||
4742 | // replace module reference |
||
4743 | $module = $module.parent(selector.dropdown); |
||
4744 | module.refresh(); |
||
4745 | module.setup.returnedObject(); |
||
4746 | // invoke method in context of current instance |
||
4747 | if(methodInvoked) { |
||
4748 | instance = module; |
||
4749 | module.invoke(query); |
||
4750 | } |
||
4751 | }, |
||
4752 | returnedObject: function() { |
||
4753 | var |
||
4754 | $firstModules = $allModules.slice(0, elementIndex), |
||
4755 | $lastModules = $allModules.slice(elementIndex + 1) |
||
4756 | ; |
||
4757 | // adjust all modules to use correct reference |
||
4758 | $allModules = $firstModules.add($module).add($lastModules); |
||
4759 | } |
||
4760 | }, |
||
4761 | |||
4762 | refresh: function() { |
||
4763 | module.refreshSelectors(); |
||
4764 | module.refreshData(); |
||
4765 | }, |
||
4766 | |||
4767 | refreshItems: function() { |
||
4768 | $item = $menu.find(selector.item); |
||
4769 | }, |
||
4770 | |||
4771 | refreshSelectors: function() { |
||
4772 | module.verbose('Refreshing selector cache'); |
||
4773 | $text = $module.find(selector.text); |
||
4774 | $search = $module.find(selector.search); |
||
4775 | $input = $module.find(selector.input); |
||
4776 | $icon = $module.find(selector.icon); |
||
4777 | $combo = ($module.prev().find(selector.text).length > 0) |
||
4778 | ? $module.prev().find(selector.text) |
||
4779 | : $module.prev() |
||
4780 | ; |
||
4781 | $menu = $module.children(selector.menu); |
||
4782 | $item = $menu.find(selector.item); |
||
4783 | }, |
||
4784 | |||
4785 | refreshData: function() { |
||
4786 | module.verbose('Refreshing cached metadata'); |
||
4787 | $item |
||
4788 | .removeData(metadata.text) |
||
4789 | .removeData(metadata.value) |
||
4790 | ; |
||
4791 | }, |
||
4792 | |||
4793 | clearData: function() { |
||
4794 | module.verbose('Clearing metadata'); |
||
4795 | $item |
||
4796 | .removeData(metadata.text) |
||
4797 | .removeData(metadata.value) |
||
4798 | ; |
||
4799 | $module |
||
4800 | .removeData(metadata.defaultText) |
||
4801 | .removeData(metadata.defaultValue) |
||
4802 | .removeData(metadata.placeholderText) |
||
4803 | ; |
||
4804 | }, |
||
4805 | |||
4806 | toggle: function() { |
||
4807 | module.verbose('Toggling menu visibility'); |
||
4808 | if( !module.is.active() ) { |
||
4809 | module.show(); |
||
4810 | } |
||
4811 | else { |
||
4812 | module.hide(); |
||
4813 | } |
||
4814 | }, |
||
4815 | |||
4816 | show: function(callback) { |
||
4817 | callback = $.isFunction(callback) |
||
4818 | ? callback |
||
4819 | : function(){} |
||
4820 | ; |
||
4821 | if(!module.can.show() && module.is.remote()) { |
||
4822 | module.debug('No API results retrieved, searching before show'); |
||
4823 | module.queryRemote(module.get.query(), module.show); |
||
4824 | } |
||
4825 | if( module.can.show() && !module.is.active() ) { |
||
4826 | module.debug('Showing dropdown'); |
||
4827 | if(module.has.message() && !(module.has.maxSelections() || module.has.allResultsFiltered()) ) { |
||
4828 | module.remove.message(); |
||
4829 | } |
||
4830 | if(module.is.allFiltered()) { |
||
4831 | return true; |
||
4832 | } |
||
4833 | if(settings.onShow.call(element) !== false) { |
||
4834 | module.animate.show(function() { |
||
4835 | if( module.can.click() ) { |
||
4836 | module.bind.intent(); |
||
4837 | } |
||
4838 | if(module.has.menuSearch()) { |
||
4839 | module.focusSearch(); |
||
4840 | } |
||
4841 | module.set.visible(); |
||
4842 | callback.call(element); |
||
4843 | }); |
||
4844 | } |
||
4845 | } |
||
4846 | }, |
||
4847 | |||
4848 | hide: function(callback) { |
||
4849 | callback = $.isFunction(callback) |
||
4850 | ? callback |
||
4851 | : function(){} |
||
4852 | ; |
||
4853 | if( module.is.active() ) { |
||
4854 | module.debug('Hiding dropdown'); |
||
4855 | if(settings.onHide.call(element) !== false) { |
||
4856 | module.animate.hide(function() { |
||
4857 | module.remove.visible(); |
||
4858 | callback.call(element); |
||
4859 | }); |
||
4860 | } |
||
4861 | } |
||
4862 | }, |
||
4863 | |||
4864 | hideOthers: function() { |
||
4865 | module.verbose('Finding other dropdowns to hide'); |
||
4866 | $allModules |
||
4867 | .not($module) |
||
4868 | .has(selector.menu + '.' + className.visible) |
||
4869 | .dropdown('hide') |
||
4870 | ; |
||
4871 | }, |
||
4872 | |||
4873 | hideMenu: function() { |
||
4874 | module.verbose('Hiding menu instantaneously'); |
||
4875 | module.remove.active(); |
||
4876 | module.remove.visible(); |
||
4877 | $menu.transition('hide'); |
||
4878 | }, |
||
4879 | |||
4880 | hideSubMenus: function() { |
||
4881 | var |
||
4882 | $subMenus = $menu.children(selector.item).find(selector.menu) |
||
4883 | ; |
||
4884 | module.verbose('Hiding sub menus', $subMenus); |
||
4885 | $subMenus.transition('hide'); |
||
4886 | }, |
||
4887 | |||
4888 | bind: { |
||
4889 | events: function() { |
||
4890 | if(hasTouch) { |
||
4891 | module.bind.touchEvents(); |
||
4892 | } |
||
4893 | module.bind.keyboardEvents(); |
||
4894 | module.bind.inputEvents(); |
||
4895 | module.bind.mouseEvents(); |
||
4896 | }, |
||
4897 | touchEvents: function() { |
||
4898 | module.debug('Touch device detected binding additional touch events'); |
||
4899 | if( module.is.searchSelection() ) { |
||
4900 | // do nothing special yet |
||
4901 | } |
||
4902 | else if( module.is.single() ) { |
||
4903 | $module |
||
4904 | .on('touchstart' + eventNamespace, module.event.test.toggle) |
||
4905 | ; |
||
4906 | } |
||
4907 | $menu |
||
4908 | .on('touchstart' + eventNamespace, selector.item, module.event.item.mouseenter) |
||
4909 | ; |
||
4910 | }, |
||
4911 | keyboardEvents: function() { |
||
4912 | module.verbose('Binding keyboard events'); |
||
4913 | $module |
||
4914 | .on('keydown' + eventNamespace, module.event.keydown) |
||
4915 | ; |
||
4916 | if( module.has.search() ) { |
||
4917 | $module |
||
4918 | .on(module.get.inputEvent() + eventNamespace, selector.search, module.event.input) |
||
4919 | ; |
||
4920 | } |
||
4921 | if( module.is.multiple() ) { |
||
4922 | $document |
||
4923 | .on('keydown' + elementNamespace, module.event.document.keydown) |
||
4924 | ; |
||
4925 | } |
||
4926 | }, |
||
4927 | inputEvents: function() { |
||
4928 | module.verbose('Binding input change events'); |
||
4929 | $module |
||
4930 | .on('change' + eventNamespace, selector.input, module.event.change) |
||
4931 | ; |
||
4932 | }, |
||
4933 | mouseEvents: function() { |
||
4934 | module.verbose('Binding mouse events'); |
||
4935 | if(module.is.multiple()) { |
||
4936 | $module |
||
4937 | .on('click' + eventNamespace, selector.label, module.event.label.click) |
||
4938 | .on('click' + eventNamespace, selector.remove, module.event.remove.click) |
||
4939 | ; |
||
4940 | } |
||
4941 | if( module.is.searchSelection() ) { |
||
4942 | $module |
||
4943 | .on('mousedown' + eventNamespace, module.event.mousedown) |
||
4944 | .on('mouseup' + eventNamespace, module.event.mouseup) |
||
4945 | .on('mousedown' + eventNamespace, selector.menu, module.event.menu.mousedown) |
||
4946 | .on('mouseup' + eventNamespace, selector.menu, module.event.menu.mouseup) |
||
4947 | .on('click' + eventNamespace, selector.icon, module.event.icon.click) |
||
4948 | .on('focus' + eventNamespace, selector.search, module.event.search.focus) |
||
4949 | .on('click' + eventNamespace, selector.search, module.event.search.focus) |
||
4950 | .on('blur' + eventNamespace, selector.search, module.event.search.blur) |
||
4951 | .on('click' + eventNamespace, selector.text, module.event.text.focus) |
||
4952 | ; |
||
4953 | if(module.is.multiple()) { |
||
4954 | $module |
||
4955 | .on('click' + eventNamespace, module.event.click) |
||
4956 | ; |
||
4957 | } |
||
4958 | } |
||
4959 | else { |
||
4960 | if(settings.on == 'click') { |
||
4961 | $module |
||
4962 | .on('click' + eventNamespace, selector.icon, module.event.icon.click) |
||
4963 | .on('click' + eventNamespace, module.event.test.toggle) |
||
4964 | ; |
||
4965 | } |
||
4966 | else if(settings.on == 'hover') { |
||
4967 | $module |
||
4968 | .on('mouseenter' + eventNamespace, module.delay.show) |
||
4969 | .on('mouseleave' + eventNamespace, module.delay.hide) |
||
4970 | ; |
||
4971 | } |
||
4972 | else { |
||
4973 | $module |
||
4974 | .on(settings.on + eventNamespace, module.toggle) |
||
4975 | ; |
||
4976 | } |
||
4977 | $module |
||
4978 | .on('mousedown' + eventNamespace, module.event.mousedown) |
||
4979 | .on('mouseup' + eventNamespace, module.event.mouseup) |
||
4980 | .on('focus' + eventNamespace, module.event.focus) |
||
4981 | ; |
||
4982 | if(module.has.menuSearch() ) { |
||
4983 | $module |
||
4984 | .on('blur' + eventNamespace, selector.search, module.event.search.blur) |
||
4985 | ; |
||
4986 | } |
||
4987 | else { |
||
4988 | $module |
||
4989 | .on('blur' + eventNamespace, module.event.blur) |
||
4990 | ; |
||
4991 | } |
||
4992 | } |
||
4993 | $menu |
||
4994 | .on('mouseenter' + eventNamespace, selector.item, module.event.item.mouseenter) |
||
4995 | .on('mouseleave' + eventNamespace, selector.item, module.event.item.mouseleave) |
||
4996 | .on('click' + eventNamespace, selector.item, module.event.item.click) |
||
4997 | ; |
||
4998 | }, |
||
4999 | intent: function() { |
||
5000 | module.verbose('Binding hide intent event to document'); |
||
5001 | if(hasTouch) { |
||
5002 | $document |
||
5003 | .on('touchstart' + elementNamespace, module.event.test.touch) |
||
5004 | .on('touchmove' + elementNamespace, module.event.test.touch) |
||
5005 | ; |
||
5006 | } |
||
5007 | $document |
||
5008 | .on('click' + elementNamespace, module.event.test.hide) |
||
5009 | ; |
||
5010 | } |
||
5011 | }, |
||
5012 | |||
5013 | unbind: { |
||
5014 | intent: function() { |
||
5015 | module.verbose('Removing hide intent event from document'); |
||
5016 | if(hasTouch) { |
||
5017 | $document |
||
5018 | .off('touchstart' + elementNamespace) |
||
5019 | .off('touchmove' + elementNamespace) |
||
5020 | ; |
||
5021 | } |
||
5022 | $document |
||
5023 | .off('click' + elementNamespace) |
||
5024 | ; |
||
5025 | } |
||
5026 | }, |
||
5027 | |||
5028 | filter: function(query) { |
||
5029 | var |
||
5030 | searchTerm = (query !== undefined) |
||
5031 | ? query |
||
5032 | : module.get.query(), |
||
5033 | afterFiltered = function() { |
||
5034 | if(module.is.multiple()) { |
||
5035 | module.filterActive(); |
||
5036 | } |
||
5037 | if(query || (!query && module.get.activeItem().length == 0)) { |
||
5038 | module.select.firstUnfiltered(); |
||
5039 | } |
||
5040 | if( module.has.allResultsFiltered() ) { |
||
5041 | if( settings.onNoResults.call(element, searchTerm) ) { |
||
5042 | if(settings.allowAdditions) { |
||
5043 | if(settings.hideAdditions) { |
||
5044 | module.verbose('User addition with no menu, setting empty style'); |
||
5045 | module.set.empty(); |
||
5046 | module.hideMenu(); |
||
5047 | } |
||
5048 | } |
||
5049 | else { |
||
5050 | module.verbose('All items filtered, showing message', searchTerm); |
||
5051 | module.add.message(message.noResults); |
||
5052 | } |
||
5053 | } |
||
5054 | else { |
||
5055 | module.verbose('All items filtered, hiding dropdown', searchTerm); |
||
5056 | module.hideMenu(); |
||
5057 | } |
||
5058 | } |
||
5059 | else { |
||
5060 | module.remove.empty(); |
||
5061 | module.remove.message(); |
||
5062 | } |
||
5063 | if(settings.allowAdditions) { |
||
5064 | module.add.userSuggestion(query); |
||
5065 | } |
||
5066 | if(module.is.searchSelection() && module.can.show() && module.is.focusedOnSearch() ) { |
||
5067 | module.show(); |
||
5068 | } |
||
5069 | } |
||
5070 | ; |
||
5071 | if(settings.useLabels && module.has.maxSelections()) { |
||
5072 | return; |
||
5073 | } |
||
5074 | if(settings.apiSettings) { |
||
5075 | if( module.can.useAPI() ) { |
||
5076 | module.queryRemote(searchTerm, function() { |
||
5077 | if(settings.filterRemoteData) { |
||
5078 | module.filterItems(searchTerm); |
||
5079 | } |
||
5080 | afterFiltered(); |
||
5081 | }); |
||
5082 | } |
||
5083 | else { |
||
5084 | module.error(error.noAPI); |
||
5085 | } |
||
5086 | } |
||
5087 | else { |
||
5088 | module.filterItems(searchTerm); |
||
5089 | afterFiltered(); |
||
5090 | } |
||
5091 | }, |
||
5092 | |||
5093 | queryRemote: function(query, callback) { |
||
5094 | var |
||
5095 | apiSettings = { |
||
5096 | errorDuration : false, |
||
5097 | cache : 'local', |
||
5098 | throttle : settings.throttle, |
||
5099 | urlData : { |
||
5100 | query: query |
||
5101 | }, |
||
5102 | onError: function() { |
||
5103 | module.add.message(message.serverError); |
||
5104 | callback(); |
||
5105 | }, |
||
5106 | onFailure: function() { |
||
5107 | module.add.message(message.serverError); |
||
5108 | callback(); |
||
5109 | }, |
||
5110 | onSuccess : function(response) { |
||
5111 | module.remove.message(); |
||
5112 | module.setup.menu({ |
||
5113 | values: response[fields.remoteValues] |
||
5114 | }); |
||
5115 | callback(); |
||
5116 | } |
||
5117 | } |
||
5118 | ; |
||
5119 | if( !$module.api('get request') ) { |
||
5120 | module.setup.api(); |
||
5121 | } |
||
5122 | apiSettings = $.extend(true, {}, apiSettings, settings.apiSettings); |
||
5123 | $module |
||
5124 | .api('setting', apiSettings) |
||
5125 | .api('query') |
||
5126 | ; |
||
5127 | }, |
||
5128 | |||
5129 | filterItems: function(query) { |
||
5130 | var |
||
5131 | searchTerm = (query !== undefined) |
||
5132 | ? query |
||
5133 | : module.get.query(), |
||
5134 | results = null, |
||
5135 | escapedTerm = module.escape.string(searchTerm), |
||
5136 | beginsWithRegExp = new RegExp('^' + escapedTerm, 'igm') |
||
5137 | ; |
||
5138 | // avoid loop if we're matching nothing |
||
5139 | if( module.has.query() ) { |
||
5140 | results = []; |
||
5141 | |||
5142 | module.verbose('Searching for matching values', searchTerm); |
||
5143 | $item |
||
5144 | .each(function(){ |
||
5145 | var |
||
5146 | $choice = $(this), |
||
5147 | text, |
||
5148 | value |
||
5149 | ; |
||
5150 | if(settings.match == 'both' || settings.match == 'text') { |
||
5151 | text = String(module.get.choiceText($choice, false)); |
||
5152 | if(text.search(beginsWithRegExp) !== -1) { |
||
5153 | results.push(this); |
||
5154 | return true; |
||
5155 | } |
||
5156 | else if (settings.fullTextSearch === 'exact' && module.exactSearch(searchTerm, text)) { |
||
5157 | results.push(this); |
||
5158 | return true; |
||
5159 | } |
||
5160 | else if (settings.fullTextSearch === true && module.fuzzySearch(searchTerm, text)) { |
||
5161 | results.push(this); |
||
5162 | return true; |
||
5163 | } |
||
5164 | } |
||
5165 | if(settings.match == 'both' || settings.match == 'value') { |
||
5166 | value = String(module.get.choiceValue($choice, text)); |
||
5167 | if(value.search(beginsWithRegExp) !== -1) { |
||
5168 | results.push(this); |
||
5169 | return true; |
||
5170 | } |
||
5171 | else if (settings.fullTextSearch === 'exact' && module.exactSearch(searchTerm, value)) { |
||
5172 | results.push(this); |
||
5173 | return true; |
||
5174 | } |
||
5175 | else if (settings.fullTextSearch === true && module.fuzzySearch(searchTerm, value)) { |
||
5176 | results.push(this); |
||
5177 | return true; |
||
5178 | } |
||
5179 | } |
||
5180 | }) |
||
5181 | ; |
||
5182 | } |
||
5183 | module.debug('Showing only matched items', searchTerm); |
||
5184 | module.remove.filteredItem(); |
||
5185 | if(results) { |
||
5186 | $item |
||
5187 | .not(results) |
||
5188 | .addClass(className.filtered) |
||
5189 | ; |
||
5190 | } |
||
5191 | }, |
||
5192 | |||
5193 | fuzzySearch: function(query, term) { |
||
5194 | var |
||
5195 | termLength = term.length, |
||
5196 | queryLength = query.length |
||
5197 | ; |
||
5198 | query = query.toLowerCase(); |
||
5199 | term = term.toLowerCase(); |
||
5200 | if(queryLength > termLength) { |
||
5201 | return false; |
||
5202 | } |
||
5203 | if(queryLength === termLength) { |
||
5204 | return (query === term); |
||
5205 | } |
||
5206 | search: for (var characterIndex = 0, nextCharacterIndex = 0; characterIndex < queryLength; characterIndex++) { |
||
5207 | var |
||
5208 | queryCharacter = query.charCodeAt(characterIndex) |
||
5209 | ; |
||
5210 | while(nextCharacterIndex < termLength) { |
||
5211 | if(term.charCodeAt(nextCharacterIndex++) === queryCharacter) { |
||
5212 | continue search; |
||
5213 | } |
||
5214 | } |
||
5215 | return false; |
||
5216 | } |
||
5217 | return true; |
||
5218 | }, |
||
5219 | exactSearch: function (query, term) { |
||
5220 | query = query.toLowerCase(); |
||
5221 | term = term.toLowerCase(); |
||
5222 | if(term.indexOf(query) > -1) { |
||
5223 | return true; |
||
5224 | } |
||
5225 | return false; |
||
5226 | }, |
||
5227 | filterActive: function() { |
||
5228 | if(settings.useLabels) { |
||
5229 | $item.filter('.' + className.active) |
||
5230 | .addClass(className.filtered) |
||
5231 | ; |
||
5232 | } |
||
5233 | }, |
||
5234 | |||
5235 | focusSearch: function(skipHandler) { |
||
5236 | if( module.has.search() && !module.is.focusedOnSearch() ) { |
||
5237 | if(skipHandler) { |
||
5238 | $module.off('focus' + eventNamespace, selector.search); |
||
5239 | $search.focus(); |
||
5240 | $module.on('focus' + eventNamespace, selector.search, module.event.search.focus); |
||
5241 | } |
||
5242 | else { |
||
5243 | $search.focus(); |
||
5244 | } |
||
5245 | } |
||
5246 | }, |
||
5247 | |||
5248 | forceSelection: function() { |
||
5249 | var |
||
5250 | $currentlySelected = $item.not(className.filtered).filter('.' + className.selected).eq(0), |
||
5251 | $activeItem = $item.not(className.filtered).filter('.' + className.active).eq(0), |
||
5252 | $selectedItem = ($currentlySelected.length > 0) |
||
5253 | ? $currentlySelected |
||
5254 | : $activeItem, |
||
5255 | hasSelected = ($selectedItem.length > 0) |
||
5256 | ; |
||
5257 | if(hasSelected && !module.is.multiple()) { |
||
5258 | module.debug('Forcing partial selection to selected item', $selectedItem); |
||
5259 | module.event.item.click.call($selectedItem, {}, true); |
||
5260 | return; |
||
5261 | } |
||
5262 | else { |
||
5263 | if(settings.allowAdditions) { |
||
5264 | module.set.selected(module.get.query()); |
||
5265 | module.remove.searchTerm(); |
||
5266 | } |
||
5267 | else { |
||
5268 | module.remove.searchTerm(); |
||
5269 | } |
||
5270 | } |
||
5271 | }, |
||
5272 | |||
5273 | event: { |
||
5274 | change: function() { |
||
5275 | if(!internalChange) { |
||
5276 | module.debug('Input changed, updating selection'); |
||
5277 | module.set.selected(); |
||
5278 | } |
||
5279 | }, |
||
5280 | focus: function() { |
||
5281 | if(settings.showOnFocus && !activated && module.is.hidden() && !pageLostFocus) { |
||
5282 | module.show(); |
||
5283 | } |
||
5284 | }, |
||
5285 | blur: function(event) { |
||
5286 | pageLostFocus = (document.activeElement === this); |
||
5287 | if(!activated && !pageLostFocus) { |
||
5288 | module.remove.activeLabel(); |
||
5289 | module.hide(); |
||
5290 | } |
||
5291 | }, |
||
5292 | mousedown: function() { |
||
5293 | if(module.is.searchSelection()) { |
||
5294 | // prevent menu hiding on immediate re-focus |
||
5295 | willRefocus = true; |
||
5296 | } |
||
5297 | else { |
||
5298 | // prevents focus callback from occurring on mousedown |
||
5299 | activated = true; |
||
5300 | } |
||
5301 | }, |
||
5302 | mouseup: function() { |
||
5303 | if(module.is.searchSelection()) { |
||
5304 | // prevent menu hiding on immediate re-focus |
||
5305 | willRefocus = false; |
||
5306 | } |
||
5307 | else { |
||
5308 | activated = false; |
||
5309 | } |
||
5310 | }, |
||
5311 | click: function(event) { |
||
5312 | var |
||
5313 | $target = $(event.target) |
||
5314 | ; |
||
5315 | // focus search |
||
5316 | if($target.is($module)) { |
||
5317 | if(!module.is.focusedOnSearch()) { |
||
5318 | module.focusSearch(); |
||
5319 | } |
||
5320 | else { |
||
5321 | module.show(); |
||
5322 | } |
||
5323 | } |
||
5324 | }, |
||
5325 | search: { |
||
5326 | focus: function() { |
||
5327 | activated = true; |
||
5328 | if(module.is.multiple()) { |
||
5329 | module.remove.activeLabel(); |
||
5330 | } |
||
5331 | if(settings.showOnFocus) { |
||
5332 | module.search(); |
||
5333 | } |
||
5334 | }, |
||
5335 | blur: function(event) { |
||
5336 | pageLostFocus = (document.activeElement === this); |
||
5337 | if(module.is.searchSelection() && !willRefocus) { |
||
5338 | if(!itemActivated && !pageLostFocus) { |
||
5339 | if(settings.forceSelection) { |
||
5340 | module.forceSelection(); |
||
5341 | } |
||
5342 | module.hide(); |
||
5343 | } |
||
5344 | } |
||
5345 | willRefocus = false; |
||
5346 | } |
||
5347 | }, |
||
5348 | icon: { |
||
5349 | click: function(event) { |
||
5350 | module.toggle(); |
||
5351 | } |
||
5352 | }, |
||
5353 | text: { |
||
5354 | focus: function(event) { |
||
5355 | activated = true; |
||
5356 | module.focusSearch(); |
||
5357 | } |
||
5358 | }, |
||
5359 | input: function(event) { |
||
5360 | if(module.is.multiple() || module.is.searchSelection()) { |
||
5361 | module.set.filtered(); |
||
5362 | } |
||
5363 | clearTimeout(module.timer); |
||
5364 | module.timer = setTimeout(module.search, settings.delay.search); |
||
5365 | }, |
||
5366 | label: { |
||
5367 | click: function(event) { |
||
5368 | var |
||
5369 | $label = $(this), |
||
5370 | $labels = $module.find(selector.label), |
||
5371 | $activeLabels = $labels.filter('.' + className.active), |
||
5372 | $nextActive = $label.nextAll('.' + className.active), |
||
5373 | $prevActive = $label.prevAll('.' + className.active), |
||
5374 | $range = ($nextActive.length > 0) |
||
5375 | ? $label.nextUntil($nextActive).add($activeLabels).add($label) |
||
5376 | : $label.prevUntil($prevActive).add($activeLabels).add($label) |
||
5377 | ; |
||
5378 | if(event.shiftKey) { |
||
5379 | $activeLabels.removeClass(className.active); |
||
5380 | $range.addClass(className.active); |
||
5381 | } |
||
5382 | else if(event.ctrlKey) { |
||
5383 | $label.toggleClass(className.active); |
||
5384 | } |
||
5385 | else { |
||
5386 | $activeLabels.removeClass(className.active); |
||
5387 | $label.addClass(className.active); |
||
5388 | } |
||
5389 | settings.onLabelSelect.apply(this, $labels.filter('.' + className.active)); |
||
5390 | } |
||
5391 | }, |
||
5392 | remove: { |
||
5393 | click: function() { |
||
5394 | var |
||
5395 | $label = $(this).parent() |
||
5396 | ; |
||
5397 | if( $label.hasClass(className.active) ) { |
||
5398 | // remove all selected labels |
||
5399 | module.remove.activeLabels(); |
||
5400 | } |
||
5401 | else { |
||
5402 | // remove this label only |
||
5403 | module.remove.activeLabels( $label ); |
||
5404 | } |
||
5405 | } |
||
5406 | }, |
||
5407 | test: { |
||
5408 | toggle: function(event) { |
||
5409 | var |
||
5410 | toggleBehavior = (module.is.multiple()) |
||
5411 | ? module.show |
||
5412 | : module.toggle |
||
5413 | ; |
||
5414 | if(module.is.bubbledLabelClick(event) || module.is.bubbledIconClick(event)) { |
||
5415 | return; |
||
5416 | } |
||
5417 | if( module.determine.eventOnElement(event, toggleBehavior) ) { |
||
5418 | event.preventDefault(); |
||
5419 | } |
||
5420 | }, |
||
5421 | touch: function(event) { |
||
5422 | module.determine.eventOnElement(event, function() { |
||
5423 | if(event.type == 'touchstart') { |
||
5424 | module.timer = setTimeout(function() { |
||
5425 | module.hide(); |
||
5426 | }, settings.delay.touch); |
||
5427 | } |
||
5428 | else if(event.type == 'touchmove') { |
||
5429 | clearTimeout(module.timer); |
||
5430 | } |
||
5431 | }); |
||
5432 | event.stopPropagation(); |
||
5433 | }, |
||
5434 | hide: function(event) { |
||
5435 | module.determine.eventInModule(event, module.hide); |
||
5436 | } |
||
5437 | }, |
||
5438 | select: { |
||
5439 | mutation: function(mutations) { |
||
5440 | module.debug('<select> modified, recreating menu'); |
||
5441 | module.setup.select(); |
||
5442 | } |
||
5443 | }, |
||
5444 | menu: { |
||
5445 | mutation: function(mutations) { |
||
5446 | var |
||
5447 | mutation = mutations[0], |
||
5448 | $addedNode = mutation.addedNodes |
||
5449 | ? $(mutation.addedNodes[0]) |
||
5450 | : $(false), |
||
5451 | $removedNode = mutation.removedNodes |
||
5452 | ? $(mutation.removedNodes[0]) |
||
5453 | : $(false), |
||
5454 | $changedNodes = $addedNode.add($removedNode), |
||
5455 | isUserAddition = $changedNodes.is(selector.addition) || $changedNodes.closest(selector.addition).length > 0, |
||
5456 | isMessage = $changedNodes.is(selector.message) || $changedNodes.closest(selector.message).length > 0 |
||
5457 | ; |
||
5458 | if(isUserAddition || isMessage) { |
||
5459 | module.debug('Updating item selector cache'); |
||
5460 | module.refreshItems(); |
||
5461 | } |
||
5462 | else { |
||
5463 | module.debug('Menu modified, updating selector cache'); |
||
5464 | module.refresh(); |
||
5465 | } |
||
5466 | }, |
||
5467 | mousedown: function() { |
||
5468 | itemActivated = true; |
||
5469 | }, |
||
5470 | mouseup: function() { |
||
5471 | itemActivated = false; |
||
5472 | } |
||
5473 | }, |
||
5474 | item: { |
||
5475 | mouseenter: function(event) { |
||
5476 | var |
||
5477 | $target = $(event.target), |
||
5478 | $item = $(this), |
||
5479 | $subMenu = $item.children(selector.menu), |
||
5480 | $otherMenus = $item.siblings(selector.item).children(selector.menu), |
||
5481 | hasSubMenu = ($subMenu.length > 0), |
||
5482 | isBubbledEvent = ($subMenu.find($target).length > 0) |
||
5483 | ; |
||
5484 | if( !isBubbledEvent && hasSubMenu ) { |
||
5485 | clearTimeout(module.itemTimer); |
||
5486 | module.itemTimer = setTimeout(function() { |
||
5487 | module.verbose('Showing sub-menu', $subMenu); |
||
5488 | $.each($otherMenus, function() { |
||
5489 | module.animate.hide(false, $(this)); |
||
5490 | }); |
||
5491 | module.animate.show(false, $subMenu); |
||
5492 | }, settings.delay.show); |
||
5493 | event.preventDefault(); |
||
5494 | } |
||
5495 | }, |
||
5496 | mouseleave: function(event) { |
||
5497 | var |
||
5498 | $subMenu = $(this).children(selector.menu) |
||
5499 | ; |
||
5500 | if($subMenu.length > 0) { |
||
5501 | clearTimeout(module.itemTimer); |
||
5502 | module.itemTimer = setTimeout(function() { |
||
5503 | module.verbose('Hiding sub-menu', $subMenu); |
||
5504 | module.animate.hide(false, $subMenu); |
||
5505 | }, settings.delay.hide); |
||
5506 | } |
||
5507 | }, |
||
5508 | click: function (event, skipRefocus) { |
||
5509 | var |
||
5510 | $choice = $(this), |
||
5511 | $target = (event) |
||
5512 | ? $(event.target) |
||
5513 | : $(''), |
||
5514 | $subMenu = $choice.find(selector.menu), |
||
5515 | text = module.get.choiceText($choice), |
||
5516 | value = module.get.choiceValue($choice, text), |
||
5517 | hasSubMenu = ($subMenu.length > 0), |
||
5518 | isBubbledEvent = ($subMenu.find($target).length > 0) |
||
5519 | ; |
||
5520 | // prevents IE11 bug where menu receives focus even though `tabindex=-1` |
||
5521 | if(module.has.menuSearch()) { |
||
5522 | $(document.activeElement).blur(); |
||
5523 | } |
||
5524 | if(!isBubbledEvent && (!hasSubMenu || settings.allowCategorySelection)) { |
||
5525 | if(module.is.searchSelection()) { |
||
5526 | if(settings.allowAdditions) { |
||
5527 | module.remove.userAddition(); |
||
5528 | } |
||
5529 | module.remove.searchTerm(); |
||
5530 | if(!module.is.focusedOnSearch() && !(skipRefocus == true)) { |
||
5531 | module.focusSearch(true); |
||
5532 | } |
||
5533 | } |
||
5534 | if(!settings.useLabels) { |
||
5535 | module.remove.filteredItem(); |
||
5536 | module.set.scrollPosition($choice); |
||
5537 | } |
||
5538 | module.determine.selectAction.call(this, text, value); |
||
5539 | } |
||
5540 | } |
||
5541 | }, |
||
5542 | |||
5543 | document: { |
||
5544 | // label selection should occur even when element has no focus |
||
5545 | keydown: function(event) { |
||
5546 | var |
||
5547 | pressedKey = event.which, |
||
5548 | isShortcutKey = module.is.inObject(pressedKey, keys) |
||
5549 | ; |
||
5550 | if(isShortcutKey) { |
||
5551 | var |
||
5552 | $label = $module.find(selector.label), |
||
5553 | $activeLabel = $label.filter('.' + className.active), |
||
5554 | activeValue = $activeLabel.data(metadata.value), |
||
5555 | labelIndex = $label.index($activeLabel), |
||
5556 | labelCount = $label.length, |
||
5557 | hasActiveLabel = ($activeLabel.length > 0), |
||
5558 | hasMultipleActive = ($activeLabel.length > 1), |
||
5559 | isFirstLabel = (labelIndex === 0), |
||
5560 | isLastLabel = (labelIndex + 1 == labelCount), |
||
5561 | isSearch = module.is.searchSelection(), |
||
5562 | isFocusedOnSearch = module.is.focusedOnSearch(), |
||
5563 | isFocused = module.is.focused(), |
||
5564 | caretAtStart = (isFocusedOnSearch && module.get.caretPosition() === 0), |
||
5565 | $nextLabel |
||
5566 | ; |
||
5567 | if(isSearch && !hasActiveLabel && !isFocusedOnSearch) { |
||
5568 | return; |
||
5569 | } |
||
5570 | |||
5571 | if(pressedKey == keys.leftArrow) { |
||
5572 | // activate previous label |
||
5573 | if((isFocused || caretAtStart) && !hasActiveLabel) { |
||
5574 | module.verbose('Selecting previous label'); |
||
5575 | $label.last().addClass(className.active); |
||
5576 | } |
||
5577 | else if(hasActiveLabel) { |
||
5578 | if(!event.shiftKey) { |
||
5579 | module.verbose('Selecting previous label'); |
||
5580 | $label.removeClass(className.active); |
||
5581 | } |
||
5582 | else { |
||
5583 | module.verbose('Adding previous label to selection'); |
||
5584 | } |
||
5585 | if(isFirstLabel && !hasMultipleActive) { |
||
5586 | $activeLabel.addClass(className.active); |
||
5587 | } |
||
5588 | else { |
||
5589 | $activeLabel.prev(selector.siblingLabel) |
||
5590 | .addClass(className.active) |
||
5591 | .end() |
||
5592 | ; |
||
5593 | } |
||
5594 | event.preventDefault(); |
||
5595 | } |
||
5596 | } |
||
5597 | else if(pressedKey == keys.rightArrow) { |
||
5598 | // activate first label |
||
5599 | if(isFocused && !hasActiveLabel) { |
||
5600 | $label.first().addClass(className.active); |
||
5601 | } |
||
5602 | // activate next label |
||
5603 | if(hasActiveLabel) { |
||
5604 | if(!event.shiftKey) { |
||
5605 | module.verbose('Selecting next label'); |
||
5606 | $label.removeClass(className.active); |
||
5607 | } |
||
5608 | else { |
||
5609 | module.verbose('Adding next label to selection'); |
||
5610 | } |
||
5611 | if(isLastLabel) { |
||
5612 | if(isSearch) { |
||
5613 | if(!isFocusedOnSearch) { |
||
5614 | module.focusSearch(); |
||
5615 | } |
||
5616 | else { |
||
5617 | $label.removeClass(className.active); |
||
5618 | } |
||
5619 | } |
||
5620 | else if(hasMultipleActive) { |
||
5621 | $activeLabel.next(selector.siblingLabel).addClass(className.active); |
||
5622 | } |
||
5623 | else { |
||
5624 | $activeLabel.addClass(className.active); |
||
5625 | } |
||
5626 | } |
||
5627 | else { |
||
5628 | $activeLabel.next(selector.siblingLabel).addClass(className.active); |
||
5629 | } |
||
5630 | event.preventDefault(); |
||
5631 | } |
||
5632 | } |
||
5633 | else if(pressedKey == keys.deleteKey || pressedKey == keys.backspace) { |
||
5634 | if(hasActiveLabel) { |
||
5635 | module.verbose('Removing active labels'); |
||
5636 | if(isLastLabel) { |
||
5637 | if(isSearch && !isFocusedOnSearch) { |
||
5638 | module.focusSearch(); |
||
5639 | } |
||
5640 | } |
||
5641 | $activeLabel.last().next(selector.siblingLabel).addClass(className.active); |
||
5642 | module.remove.activeLabels($activeLabel); |
||
5643 | event.preventDefault(); |
||
5644 | } |
||
5645 | else if(caretAtStart && !hasActiveLabel && pressedKey == keys.backspace) { |
||
5646 | module.verbose('Removing last label on input backspace'); |
||
5647 | $activeLabel = $label.last().addClass(className.active); |
||
5648 | module.remove.activeLabels($activeLabel); |
||
5649 | } |
||
5650 | } |
||
5651 | else { |
||
5652 | $activeLabel.removeClass(className.active); |
||
5653 | } |
||
5654 | } |
||
5655 | } |
||
5656 | }, |
||
5657 | |||
5658 | keydown: function(event) { |
||
5659 | var |
||
5660 | pressedKey = event.which, |
||
5661 | isShortcutKey = module.is.inObject(pressedKey, keys) |
||
5662 | ; |
||
5663 | if(isShortcutKey) { |
||
5664 | var |
||
5665 | $currentlySelected = $item.not(selector.unselectable).filter('.' + className.selected).eq(0), |
||
5666 | $activeItem = $menu.children('.' + className.active).eq(0), |
||
5667 | $selectedItem = ($currentlySelected.length > 0) |
||
5668 | ? $currentlySelected |
||
5669 | : $activeItem, |
||
5670 | $visibleItems = ($selectedItem.length > 0) |
||
5671 | ? $selectedItem.siblings(':not(.' + className.filtered +')').addBack() |
||
5672 | : $menu.children(':not(.' + className.filtered +')'), |
||
5673 | $subMenu = $selectedItem.children(selector.menu), |
||
5674 | $parentMenu = $selectedItem.closest(selector.menu), |
||
5675 | inVisibleMenu = ($parentMenu.hasClass(className.visible) || $parentMenu.hasClass(className.animating) || $parentMenu.parent(selector.menu).length > 0), |
||
5676 | hasSubMenu = ($subMenu.length> 0), |
||
5677 | hasSelectedItem = ($selectedItem.length > 0), |
||
5678 | selectedIsSelectable = ($selectedItem.not(selector.unselectable).length > 0), |
||
5679 | delimiterPressed = (pressedKey == keys.delimiter && settings.allowAdditions && module.is.multiple()), |
||
5680 | isAdditionWithoutMenu = (settings.allowAdditions && settings.hideAdditions && (pressedKey == keys.enter || delimiterPressed) && selectedIsSelectable), |
||
5681 | $nextItem, |
||
5682 | isSubMenuItem, |
||
5683 | newIndex |
||
5684 | ; |
||
5685 | // allow selection with menu closed |
||
5686 | if(isAdditionWithoutMenu) { |
||
5687 | module.verbose('Selecting item from keyboard shortcut', $selectedItem); |
||
5688 | module.event.item.click.call($selectedItem, event); |
||
5689 | if(module.is.searchSelection()) { |
||
5690 | module.remove.searchTerm(); |
||
5691 | } |
||
5692 | } |
||
5693 | |||
5694 | // visible menu keyboard shortcuts |
||
5695 | if( module.is.visible() ) { |
||
5696 | |||
5697 | // enter (select or open sub-menu) |
||
5698 | if(pressedKey == keys.enter || delimiterPressed) { |
||
5699 | if(pressedKey == keys.enter && hasSelectedItem && hasSubMenu && !settings.allowCategorySelection) { |
||
5700 | module.verbose('Pressed enter on unselectable category, opening sub menu'); |
||
5701 | pressedKey = keys.rightArrow; |
||
5702 | } |
||
5703 | else if(selectedIsSelectable) { |
||
5704 | module.verbose('Selecting item from keyboard shortcut', $selectedItem); |
||
5705 | module.event.item.click.call($selectedItem, event); |
||
5706 | if(module.is.searchSelection()) { |
||
5707 | module.remove.searchTerm(); |
||
5708 | } |
||
5709 | } |
||
5710 | event.preventDefault(); |
||
5711 | } |
||
5712 | |||
5713 | // sub-menu actions |
||
5714 | if(hasSelectedItem) { |
||
5715 | |||
5716 | if(pressedKey == keys.leftArrow) { |
||
5717 | |||
5718 | isSubMenuItem = ($parentMenu[0] !== $menu[0]); |
||
5719 | |||
5720 | if(isSubMenuItem) { |
||
5721 | module.verbose('Left key pressed, closing sub-menu'); |
||
5722 | module.animate.hide(false, $parentMenu); |
||
5723 | $selectedItem |
||
5724 | .removeClass(className.selected) |
||
5725 | ; |
||
5726 | $parentMenu |
||
5727 | .closest(selector.item) |
||
5728 | .addClass(className.selected) |
||
5729 | ; |
||
5730 | event.preventDefault(); |
||
5731 | } |
||
5732 | } |
||
5733 | |||
5734 | // right arrow (show sub-menu) |
||
5735 | if(pressedKey == keys.rightArrow) { |
||
5736 | if(hasSubMenu) { |
||
5737 | module.verbose('Right key pressed, opening sub-menu'); |
||
5738 | module.animate.show(false, $subMenu); |
||
5739 | $selectedItem |
||
5740 | .removeClass(className.selected) |
||
5741 | ; |
||
5742 | $subMenu |
||
5743 | .find(selector.item).eq(0) |
||
5744 | .addClass(className.selected) |
||
5745 | ; |
||
5746 | event.preventDefault(); |
||
5747 | } |
||
5748 | } |
||
5749 | } |
||
5750 | |||
5751 | // up arrow (traverse menu up) |
||
5752 | if(pressedKey == keys.upArrow) { |
||
5753 | $nextItem = (hasSelectedItem && inVisibleMenu) |
||
5754 | ? $selectedItem.prevAll(selector.item + ':not(' + selector.unselectable + ')').eq(0) |
||
5755 | : $item.eq(0) |
||
5756 | ; |
||
5757 | if($visibleItems.index( $nextItem ) < 0) { |
||
5758 | module.verbose('Up key pressed but reached top of current menu'); |
||
5759 | event.preventDefault(); |
||
5760 | return; |
||
5761 | } |
||
5762 | else { |
||
5763 | module.verbose('Up key pressed, changing active item'); |
||
5764 | $selectedItem |
||
5765 | .removeClass(className.selected) |
||
5766 | ; |
||
5767 | $nextItem |
||
5768 | .addClass(className.selected) |
||
5769 | ; |
||
5770 | module.set.scrollPosition($nextItem); |
||
5771 | if(settings.selectOnKeydown && module.is.single()) { |
||
5772 | module.set.selectedItem($nextItem); |
||
5773 | } |
||
5774 | } |
||
5775 | event.preventDefault(); |
||
5776 | } |
||
5777 | |||
5778 | // down arrow (traverse menu down) |
||
5779 | if(pressedKey == keys.downArrow) { |
||
5780 | $nextItem = (hasSelectedItem && inVisibleMenu) |
||
5781 | ? $nextItem = $selectedItem.nextAll(selector.item + ':not(' + selector.unselectable + ')').eq(0) |
||
5782 | : $item.eq(0) |
||
5783 | ; |
||
5784 | if($nextItem.length === 0) { |
||
5785 | module.verbose('Down key pressed but reached bottom of current menu'); |
||
5786 | event.preventDefault(); |
||
5787 | return; |
||
5788 | } |
||
5789 | else { |
||
5790 | module.verbose('Down key pressed, changing active item'); |
||
5791 | $item |
||
5792 | .removeClass(className.selected) |
||
5793 | ; |
||
5794 | $nextItem |
||
5795 | .addClass(className.selected) |
||
5796 | ; |
||
5797 | module.set.scrollPosition($nextItem); |
||
5798 | if(settings.selectOnKeydown && module.is.single()) { |
||
5799 | module.set.selectedItem($nextItem); |
||
5800 | } |
||
5801 | } |
||
5802 | event.preventDefault(); |
||
5803 | } |
||
5804 | |||
5805 | // page down (show next page) |
||
5806 | if(pressedKey == keys.pageUp) { |
||
5807 | module.scrollPage('up'); |
||
5808 | event.preventDefault(); |
||
5809 | } |
||
5810 | if(pressedKey == keys.pageDown) { |
||
5811 | module.scrollPage('down'); |
||
5812 | event.preventDefault(); |
||
5813 | } |
||
5814 | |||
5815 | // escape (close menu) |
||
5816 | if(pressedKey == keys.escape) { |
||
5817 | module.verbose('Escape key pressed, closing dropdown'); |
||
5818 | module.hide(); |
||
5819 | } |
||
5820 | |||
5821 | } |
||
5822 | else { |
||
5823 | // delimiter key |
||
5824 | if(delimiterPressed) { |
||
5825 | event.preventDefault(); |
||
5826 | } |
||
5827 | // down arrow (open menu) |
||
5828 | if(pressedKey == keys.downArrow && !module.is.visible()) { |
||
5829 | module.verbose('Down key pressed, showing dropdown'); |
||
5830 | module.show(); |
||
5831 | event.preventDefault(); |
||
5832 | } |
||
5833 | } |
||
5834 | } |
||
5835 | else { |
||
5836 | if( !module.has.search() ) { |
||
5837 | module.set.selectedLetter( String.fromCharCode(pressedKey) ); |
||
5838 | } |
||
5839 | } |
||
5840 | } |
||
5841 | }, |
||
5842 | |||
5843 | trigger: { |
||
5844 | change: function() { |
||
5845 | var |
||
5846 | events = document.createEvent('HTMLEvents'), |
||
5847 | inputElement = $input[0] |
||
5848 | ; |
||
5849 | if(inputElement) { |
||
5850 | module.verbose('Triggering native change event'); |
||
5851 | events.initEvent('change', true, false); |
||
5852 | inputElement.dispatchEvent(events); |
||
5853 | } |
||
5854 | } |
||
5855 | }, |
||
5856 | |||
5857 | determine: { |
||
5858 | selectAction: function(text, value) { |
||
5859 | module.verbose('Determining action', settings.action); |
||
5860 | if( $.isFunction( module.action[settings.action] ) ) { |
||
5861 | module.verbose('Triggering preset action', settings.action, text, value); |
||
5862 | module.action[ settings.action ].call(element, text, value, this); |
||
5863 | } |
||
5864 | else if( $.isFunction(settings.action) ) { |
||
5865 | module.verbose('Triggering user action', settings.action, text, value); |
||
5866 | settings.action.call(element, text, value, this); |
||
5867 | } |
||
5868 | else { |
||
5869 | module.error(error.action, settings.action); |
||
5870 | } |
||
5871 | }, |
||
5872 | eventInModule: function(event, callback) { |
||
5873 | var |
||
5874 | $target = $(event.target), |
||
5875 | inDocument = ($target.closest(document.documentElement).length > 0), |
||
5876 | inModule = ($target.closest($module).length > 0) |
||
5877 | ; |
||
5878 | callback = $.isFunction(callback) |
||
5879 | ? callback |
||
5880 | : function(){} |
||
5881 | ; |
||
5882 | if(inDocument && !inModule) { |
||
5883 | module.verbose('Triggering event', callback); |
||
5884 | callback(); |
||
5885 | return true; |
||
5886 | } |
||
5887 | else { |
||
5888 | module.verbose('Event occurred in dropdown, canceling callback'); |
||
5889 | return false; |
||
5890 | } |
||
5891 | }, |
||
5892 | eventOnElement: function(event, callback) { |
||
5893 | var |
||
5894 | $target = $(event.target), |
||
5895 | $label = $target.closest(selector.siblingLabel), |
||
5896 | inVisibleDOM = document.body.contains(event.target), |
||
5897 | notOnLabel = ($module.find($label).length === 0), |
||
5898 | notInMenu = ($target.closest($menu).length === 0) |
||
5899 | ; |
||
5900 | callback = $.isFunction(callback) |
||
5901 | ? callback |
||
5902 | : function(){} |
||
5903 | ; |
||
5904 | if(inVisibleDOM && notOnLabel && notInMenu) { |
||
5905 | module.verbose('Triggering event', callback); |
||
5906 | callback(); |
||
5907 | return true; |
||
5908 | } |
||
5909 | else { |
||
5910 | module.verbose('Event occurred in dropdown menu, canceling callback'); |
||
5911 | return false; |
||
5912 | } |
||
5913 | } |
||
5914 | }, |
||
5915 | |||
5916 | action: { |
||
5917 | |||
5918 | nothing: function() {}, |
||
5919 | |||
5920 | activate: function(text, value, element) { |
||
5921 | value = (value !== undefined) |
||
5922 | ? value |
||
5923 | : text |
||
5924 | ; |
||
5925 | if( module.can.activate( $(element) ) ) { |
||
5926 | module.set.selected(value, $(element)); |
||
5927 | if(module.is.multiple() && !module.is.allFiltered()) { |
||
5928 | return; |
||
5929 | } |
||
5930 | else { |
||
5931 | module.hideAndClear(); |
||
5932 | } |
||
5933 | } |
||
5934 | }, |
||
5935 | |||
5936 | select: function(text, value, element) { |
||
5937 | value = (value !== undefined) |
||
5938 | ? value |
||
5939 | : text |
||
5940 | ; |
||
5941 | if( module.can.activate( $(element) ) ) { |
||
5942 | module.set.value(value, $(element)); |
||
5943 | if(module.is.multiple() && !module.is.allFiltered()) { |
||
5944 | return; |
||
5945 | } |
||
5946 | else { |
||
5947 | module.hideAndClear(); |
||
5948 | } |
||
5949 | } |
||
5950 | }, |
||
5951 | |||
5952 | combo: function(text, value, element) { |
||
5953 | value = (value !== undefined) |
||
5954 | ? value |
||
5955 | : text |
||
5956 | ; |
||
5957 | module.set.selected(value, $(element)); |
||
5958 | module.hideAndClear(); |
||
5959 | }, |
||
5960 | |||
5961 | hide: function(text, value, element) { |
||
5962 | module.set.value(value, text); |
||
5963 | module.hideAndClear(); |
||
5964 | } |
||
5965 | |||
5966 | }, |
||
5967 | |||
5968 | get: { |
||
5969 | id: function() { |
||
5970 | return id; |
||
5971 | }, |
||
5972 | defaultText: function() { |
||
5973 | return $module.data(metadata.defaultText); |
||
5974 | }, |
||
5975 | defaultValue: function() { |
||
5976 | return $module.data(metadata.defaultValue); |
||
5977 | }, |
||
5978 | placeholderText: function() { |
||
5979 | return $module.data(metadata.placeholderText) || ''; |
||
5980 | }, |
||
5981 | text: function() { |
||
5982 | return $text.text(); |
||
5983 | }, |
||
5984 | query: function() { |
||
5985 | return $.trim($search.val()); |
||
5986 | }, |
||
5987 | searchWidth: function(value) { |
||
5988 | value = (value !== undefined) |
||
5989 | ? value |
||
5990 | : $search.val() |
||
5991 | ; |
||
5992 | $sizer.text(value); |
||
5993 | // prevent rounding issues |
||
5994 | return Math.ceil( $sizer.width() + 1); |
||
5995 | }, |
||
5996 | selectionCount: function() { |
||
5997 | var |
||
5998 | values = module.get.values(), |
||
5999 | count |
||
6000 | ; |
||
6001 | count = ( module.is.multiple() ) |
||
6002 | ? $.isArray(values) |
||
6003 | ? values.length |
||
6004 | : 0 |
||
6005 | : (module.get.value() !== '') |
||
6006 | ? 1 |
||
6007 | : 0 |
||
6008 | ; |
||
6009 | return count; |
||
6010 | }, |
||
6011 | transition: function($subMenu) { |
||
6012 | return (settings.transition == 'auto') |
||
6013 | ? module.is.upward($subMenu) |
||
6014 | ? 'slide up' |
||
6015 | : 'slide down' |
||
6016 | : settings.transition |
||
6017 | ; |
||
6018 | }, |
||
6019 | userValues: function() { |
||
6020 | var |
||
6021 | values = module.get.values() |
||
6022 | ; |
||
6023 | if(!values) { |
||
6024 | return false; |
||
6025 | } |
||
6026 | values = $.isArray(values) |
||
6027 | ? values |
||
6028 | : [values] |
||
6029 | ; |
||
6030 | return $.grep(values, function(value) { |
||
6031 | return (module.get.item(value) === false); |
||
6032 | }); |
||
6033 | }, |
||
6034 | uniqueArray: function(array) { |
||
6035 | return $.grep(array, function (value, index) { |
||
6036 | return $.inArray(value, array) === index; |
||
6037 | }); |
||
6038 | }, |
||
6039 | caretPosition: function() { |
||
6040 | var |
||
6041 | input = $search.get(0), |
||
6042 | range, |
||
6043 | rangeLength |
||
6044 | ; |
||
6045 | if('selectionStart' in input) { |
||
6046 | return input.selectionStart; |
||
6047 | } |
||
6048 | else if (document.selection) { |
||
6049 | input.focus(); |
||
6050 | range = document.selection.createRange(); |
||
6051 | rangeLength = range.text.length; |
||
6052 | range.moveStart('character', -input.value.length); |
||
6053 | return range.text.length - rangeLength; |
||
6054 | } |
||
6055 | }, |
||
6056 | value: function() { |
||
6057 | var |
||
6058 | value = ($input.length > 0) |
||
6059 | ? $input.val() |
||
6060 | : $module.data(metadata.value), |
||
6061 | isEmptyMultiselect = ($.isArray(value) && value.length === 1 && value[0] === '') |
||
6062 | ; |
||
6063 | // prevents placeholder element from being selected when multiple |
||
6064 | return (value === undefined || isEmptyMultiselect) |
||
6065 | ? '' |
||
6066 | : value |
||
6067 | ; |
||
6068 | }, |
||
6069 | values: function() { |
||
6070 | var |
||
6071 | value = module.get.value() |
||
6072 | ; |
||
6073 | if(value === '') { |
||
6074 | return ''; |
||
6075 | } |
||
6076 | return ( !module.has.selectInput() && module.is.multiple() ) |
||
6077 | ? (typeof value == 'string') // delimited string |
||
6078 | ? value.split(settings.delimiter) |
||
6079 | : '' |
||
6080 | : value |
||
6081 | ; |
||
6082 | }, |
||
6083 | remoteValues: function() { |
||
6084 | var |
||
6085 | values = module.get.values(), |
||
6086 | remoteValues = false |
||
6087 | ; |
||
6088 | if(values) { |
||
6089 | if(typeof values == 'string') { |
||
6090 | values = [values]; |
||
6091 | } |
||
6092 | $.each(values, function(index, value) { |
||
6093 | var |
||
6094 | name = module.read.remoteData(value) |
||
6095 | ; |
||
6096 | module.verbose('Restoring value from session data', name, value); |
||
6097 | if(name) { |
||
6098 | if(!remoteValues) { |
||
6099 | remoteValues = {}; |
||
6100 | } |
||
6101 | remoteValues[value] = name; |
||
6102 | } |
||
6103 | }); |
||
6104 | } |
||
6105 | return remoteValues; |
||
6106 | }, |
||
6107 | choiceText: function($choice, preserveHTML) { |
||
6108 | preserveHTML = (preserveHTML !== undefined) |
||
6109 | ? preserveHTML |
||
6110 | : settings.preserveHTML |
||
6111 | ; |
||
6112 | if($choice) { |
||
6113 | if($choice.find(selector.menu).length > 0) { |
||
6114 | module.verbose('Retrieving text of element with sub-menu'); |
||
6115 | $choice = $choice.clone(); |
||
6116 | $choice.find(selector.menu).remove(); |
||
6117 | $choice.find(selector.menuIcon).remove(); |
||
6118 | } |
||
6119 | return ($choice.data(metadata.text) !== undefined) |
||
6120 | ? $choice.data(metadata.text) |
||
6121 | : (preserveHTML) |
||
6122 | ? $.trim($choice.html()) |
||
6123 | : $.trim($choice.text()) |
||
6124 | ; |
||
6125 | } |
||
6126 | }, |
||
6127 | choiceValue: function($choice, choiceText) { |
||
6128 | choiceText = choiceText || module.get.choiceText($choice); |
||
6129 | if(!$choice) { |
||
6130 | return false; |
||
6131 | } |
||
6132 | return ($choice.data(metadata.value) !== undefined) |
||
6133 | ? String( $choice.data(metadata.value) ) |
||
6134 | : (typeof choiceText === 'string') |
||
6135 | ? $.trim(choiceText.toLowerCase()) |
||
6136 | : String(choiceText) |
||
6137 | ; |
||
6138 | }, |
||
6139 | inputEvent: function() { |
||
6140 | var |
||
6141 | input = $search[0] |
||
6142 | ; |
||
6143 | if(input) { |
||
6144 | return (input.oninput !== undefined) |
||
6145 | ? 'input' |
||
6146 | : (input.onpropertychange !== undefined) |
||
6147 | ? 'propertychange' |
||
6148 | : 'keyup' |
||
6149 | ; |
||
6150 | } |
||
6151 | return false; |
||
6152 | }, |
||
6153 | selectValues: function() { |
||
6154 | var |
||
6155 | select = {} |
||
6156 | ; |
||
6157 | select.values = []; |
||
6158 | $module |
||
6159 | .find('option') |
||
6160 | .each(function() { |
||
6161 | var |
||
6162 | $option = $(this), |
||
6163 | name = $option.html(), |
||
6164 | disabled = $option.attr('disabled'), |
||
6165 | value = ( $option.attr('value') !== undefined ) |
||
6166 | ? $option.attr('value') |
||
6167 | : name |
||
6168 | ; |
||
6169 | if(settings.placeholder === 'auto' && value === '') { |
||
6170 | select.placeholder = name; |
||
6171 | } |
||
6172 | else { |
||
6173 | select.values.push({ |
||
6174 | name : name, |
||
6175 | value : value, |
||
6176 | disabled : disabled |
||
6177 | }); |
||
6178 | } |
||
6179 | }) |
||
6180 | ; |
||
6181 | if(settings.placeholder && settings.placeholder !== 'auto') { |
||
6182 | module.debug('Setting placeholder value to', settings.placeholder); |
||
6183 | select.placeholder = settings.placeholder; |
||
6184 | } |
||
6185 | if(settings.sortSelect) { |
||
6186 | select.values.sort(function(a, b) { |
||
6187 | return (a.name > b.name) |
||
6188 | ? 1 |
||
6189 | : -1 |
||
6190 | ; |
||
6191 | }); |
||
6192 | module.debug('Retrieved and sorted values from select', select); |
||
6193 | } |
||
6194 | else { |
||
6195 | module.debug('Retrieved values from select', select); |
||
6196 | } |
||
6197 | return select; |
||
6198 | }, |
||
6199 | activeItem: function() { |
||
6200 | return $item.filter('.' + className.active); |
||
6201 | }, |
||
6202 | selectedItem: function() { |
||
6203 | var |
||
6204 | $selectedItem = $item.not(selector.unselectable).filter('.' + className.selected) |
||
6205 | ; |
||
6206 | return ($selectedItem.length > 0) |
||
6207 | ? $selectedItem |
||
6208 | : $item.eq(0) |
||
6209 | ; |
||
6210 | }, |
||
6211 | itemWithAdditions: function(value) { |
||
6212 | var |
||
6213 | $items = module.get.item(value), |
||
6214 | $userItems = module.create.userChoice(value), |
||
6215 | hasUserItems = ($userItems && $userItems.length > 0) |
||
6216 | ; |
||
6217 | if(hasUserItems) { |
||
6218 | $items = ($items.length > 0) |
||
6219 | ? $items.add($userItems) |
||
6220 | : $userItems |
||
6221 | ; |
||
6222 | } |
||
6223 | return $items; |
||
6224 | }, |
||
6225 | item: function(value, strict) { |
||
6226 | var |
||
6227 | $selectedItem = false, |
||
6228 | shouldSearch, |
||
6229 | isMultiple |
||
6230 | ; |
||
6231 | value = (value !== undefined) |
||
6232 | ? value |
||
6233 | : ( module.get.values() !== undefined) |
||
6234 | ? module.get.values() |
||
6235 | : module.get.text() |
||
6236 | ; |
||
6237 | shouldSearch = (isMultiple) |
||
6238 | ? (value.length > 0) |
||
6239 | : (value !== undefined && value !== null) |
||
6240 | ; |
||
6241 | isMultiple = (module.is.multiple() && $.isArray(value)); |
||
6242 | strict = (value === '' || value === 0) |
||
6243 | ? true |
||
6244 | : strict || false |
||
6245 | ; |
||
6246 | if(shouldSearch) { |
||
6247 | $item |
||
6248 | .each(function() { |
||
6249 | var |
||
6250 | $choice = $(this), |
||
6251 | optionText = module.get.choiceText($choice), |
||
6252 | optionValue = module.get.choiceValue($choice, optionText) |
||
6253 | ; |
||
6254 | // safe early exit |
||
6255 | if(optionValue === null || optionValue === undefined) { |
||
6256 | return; |
||
6257 | } |
||
6258 | if(isMultiple) { |
||
6259 | if($.inArray( String(optionValue), value) !== -1 || $.inArray(optionText, value) !== -1) { |
||
6260 | $selectedItem = ($selectedItem) |
||
6261 | ? $selectedItem.add($choice) |
||
6262 | : $choice |
||
6263 | ; |
||
6264 | } |
||
6265 | } |
||
6266 | else if(strict) { |
||
6267 | module.verbose('Ambiguous dropdown value using strict type check', $choice, value); |
||
6268 | if( optionValue === value || optionText === value) { |
||
6269 | $selectedItem = $choice; |
||
6270 | return true; |
||
6271 | } |
||
6272 | } |
||
6273 | else { |
||
6274 | if( String(optionValue) == String(value) || optionText == value) { |
||
6275 | module.verbose('Found select item by value', optionValue, value); |
||
6276 | $selectedItem = $choice; |
||
6277 | return true; |
||
6278 | } |
||
6279 | } |
||
6280 | }) |
||
6281 | ; |
||
6282 | } |
||
6283 | return $selectedItem; |
||
6284 | } |
||
6285 | }, |
||
6286 | |||
6287 | check: { |
||
6288 | maxSelections: function(selectionCount) { |
||
6289 | if(settings.maxSelections) { |
||
6290 | selectionCount = (selectionCount !== undefined) |
||
6291 | ? selectionCount |
||
6292 | : module.get.selectionCount() |
||
6293 | ; |
||
6294 | if(selectionCount >= settings.maxSelections) { |
||
6295 | module.debug('Maximum selection count reached'); |
||
6296 | if(settings.useLabels) { |
||
6297 | $item.addClass(className.filtered); |
||
6298 | module.add.message(message.maxSelections); |
||
6299 | } |
||
6300 | return true; |
||
6301 | } |
||
6302 | else { |
||
6303 | module.verbose('No longer at maximum selection count'); |
||
6304 | module.remove.message(); |
||
6305 | module.remove.filteredItem(); |
||
6306 | if(module.is.searchSelection()) { |
||
6307 | module.filterItems(); |
||
6308 | } |
||
6309 | return false; |
||
6310 | } |
||
6311 | } |
||
6312 | return true; |
||
6313 | } |
||
6314 | }, |
||
6315 | |||
6316 | restore: { |
||
6317 | defaults: function() { |
||
6318 | module.clear(); |
||
6319 | module.restore.defaultText(); |
||
6320 | module.restore.defaultValue(); |
||
6321 | }, |
||
6322 | defaultText: function() { |
||
6323 | var |
||
6324 | defaultText = module.get.defaultText(), |
||
6325 | placeholderText = module.get.placeholderText |
||
6326 | ; |
||
6327 | if(defaultText === placeholderText) { |
||
6328 | module.debug('Restoring default placeholder text', defaultText); |
||
6329 | module.set.placeholderText(defaultText); |
||
6330 | } |
||
6331 | else { |
||
6332 | module.debug('Restoring default text', defaultText); |
||
6333 | module.set.text(defaultText); |
||
6334 | } |
||
6335 | }, |
||
6336 | placeholderText: function() { |
||
6337 | module.set.placeholderText(); |
||
6338 | }, |
||
6339 | defaultValue: function() { |
||
6340 | var |
||
6341 | defaultValue = module.get.defaultValue() |
||
6342 | ; |
||
6343 | if(defaultValue !== undefined) { |
||
6344 | module.debug('Restoring default value', defaultValue); |
||
6345 | if(defaultValue !== '') { |
||
6346 | module.set.value(defaultValue); |
||
6347 | module.set.selected(); |
||
6348 | } |
||
6349 | else { |
||
6350 | module.remove.activeItem(); |
||
6351 | module.remove.selectedItem(); |
||
6352 | } |
||
6353 | } |
||
6354 | }, |
||
6355 | labels: function() { |
||
6356 | if(settings.allowAdditions) { |
||
6357 | if(!settings.useLabels) { |
||
6358 | module.error(error.labels); |
||
6359 | settings.useLabels = true; |
||
6360 | } |
||
6361 | module.debug('Restoring selected values'); |
||
6362 | module.create.userLabels(); |
||
6363 | } |
||
6364 | module.check.maxSelections(); |
||
6365 | }, |
||
6366 | selected: function() { |
||
6367 | module.restore.values(); |
||
6368 | if(module.is.multiple()) { |
||
6369 | module.debug('Restoring previously selected values and labels'); |
||
6370 | module.restore.labels(); |
||
6371 | } |
||
6372 | else { |
||
6373 | module.debug('Restoring previously selected values'); |
||
6374 | } |
||
6375 | }, |
||
6376 | values: function() { |
||
6377 | // prevents callbacks from occurring on initial load |
||
6378 | module.set.initialLoad(); |
||
6379 | if(settings.apiSettings && settings.saveRemoteData && module.get.remoteValues()) { |
||
6380 | module.restore.remoteValues(); |
||
6381 | } |
||
6382 | else { |
||
6383 | module.set.selected(); |
||
6384 | } |
||
6385 | module.remove.initialLoad(); |
||
6386 | }, |
||
6387 | remoteValues: function() { |
||
6388 | var |
||
6389 | values = module.get.remoteValues() |
||
6390 | ; |
||
6391 | module.debug('Recreating selected from session data', values); |
||
6392 | if(values) { |
||
6393 | if( module.is.single() ) { |
||
6394 | $.each(values, function(value, name) { |
||
6395 | module.set.text(name); |
||
6396 | }); |
||
6397 | } |
||
6398 | else { |
||
6399 | $.each(values, function(value, name) { |
||
6400 | module.add.label(value, name); |
||
6401 | }); |
||
6402 | } |
||
6403 | } |
||
6404 | } |
||
6405 | }, |
||
6406 | |||
6407 | read: { |
||
6408 | remoteData: function(value) { |
||
6409 | var |
||
6410 | name |
||
6411 | ; |
||
6412 | if(window.Storage === undefined) { |
||
6413 | module.error(error.noStorage); |
||
6414 | return; |
||
6415 | } |
||
6416 | name = sessionStorage.getItem(value); |
||
6417 | return (name !== undefined) |
||
6418 | ? name |
||
6419 | : false |
||
6420 | ; |
||
6421 | } |
||
6422 | }, |
||
6423 | |||
6424 | save: { |
||
6425 | defaults: function() { |
||
6426 | module.save.defaultText(); |
||
6427 | module.save.placeholderText(); |
||
6428 | module.save.defaultValue(); |
||
6429 | }, |
||
6430 | defaultValue: function() { |
||
6431 | var |
||
6432 | value = module.get.value() |
||
6433 | ; |
||
6434 | module.verbose('Saving default value as', value); |
||
6435 | $module.data(metadata.defaultValue, value); |
||
6436 | }, |
||
6437 | defaultText: function() { |
||
6438 | var |
||
6439 | text = module.get.text() |
||
6440 | ; |
||
6441 | module.verbose('Saving default text as', text); |
||
6442 | $module.data(metadata.defaultText, text); |
||
6443 | }, |
||
6444 | placeholderText: function() { |
||
6445 | var |
||
6446 | text |
||
6447 | ; |
||
6448 | if(settings.placeholder !== false && $text.hasClass(className.placeholder)) { |
||
6449 | text = module.get.text(); |
||
6450 | module.verbose('Saving placeholder text as', text); |
||
6451 | $module.data(metadata.placeholderText, text); |
||
6452 | } |
||
6453 | }, |
||
6454 | remoteData: function(name, value) { |
||
6455 | if(window.Storage === undefined) { |
||
6456 | module.error(error.noStorage); |
||
6457 | return; |
||
6458 | } |
||
6459 | module.verbose('Saving remote data to session storage', value, name); |
||
6460 | sessionStorage.setItem(value, name); |
||
6461 | } |
||
6462 | }, |
||
6463 | |||
6464 | clear: function() { |
||
6465 | if(module.is.multiple() && settings.useLabels) { |
||
6466 | module.remove.labels(); |
||
6467 | } |
||
6468 | else { |
||
6469 | module.remove.activeItem(); |
||
6470 | module.remove.selectedItem(); |
||
6471 | } |
||
6472 | module.set.placeholderText(); |
||
6473 | module.clearValue(); |
||
6474 | }, |
||
6475 | |||
6476 | clearValue: function() { |
||
6477 | module.set.value(''); |
||
6478 | }, |
||
6479 | |||
6480 | scrollPage: function(direction, $selectedItem) { |
||
6481 | var |
||
6482 | $currentItem = $selectedItem || module.get.selectedItem(), |
||
6483 | $menu = $currentItem.closest(selector.menu), |
||
6484 | menuHeight = $menu.outerHeight(), |
||
6485 | currentScroll = $menu.scrollTop(), |
||
6486 | itemHeight = $item.eq(0).outerHeight(), |
||
6487 | itemsPerPage = Math.floor(menuHeight / itemHeight), |
||
6488 | maxScroll = $menu.prop('scrollHeight'), |
||
6489 | newScroll = (direction == 'up') |
||
6490 | ? currentScroll - (itemHeight * itemsPerPage) |
||
6491 | : currentScroll + (itemHeight * itemsPerPage), |
||
6492 | $selectableItem = $item.not(selector.unselectable), |
||
6493 | isWithinRange, |
||
6494 | $nextSelectedItem, |
||
6495 | elementIndex |
||
6496 | ; |
||
6497 | elementIndex = (direction == 'up') |
||
6498 | ? $selectableItem.index($currentItem) - itemsPerPage |
||
6499 | : $selectableItem.index($currentItem) + itemsPerPage |
||
6500 | ; |
||
6501 | isWithinRange = (direction == 'up') |
||
6502 | ? (elementIndex >= 0) |
||
6503 | : (elementIndex < $selectableItem.length) |
||
6504 | ; |
||
6505 | $nextSelectedItem = (isWithinRange) |
||
6506 | ? $selectableItem.eq(elementIndex) |
||
6507 | : (direction == 'up') |
||
6508 | ? $selectableItem.first() |
||
6509 | : $selectableItem.last() |
||
6510 | ; |
||
6511 | if($nextSelectedItem.length > 0) { |
||
6512 | module.debug('Scrolling page', direction, $nextSelectedItem); |
||
6513 | $currentItem |
||
6514 | .removeClass(className.selected) |
||
6515 | ; |
||
6516 | $nextSelectedItem |
||
6517 | .addClass(className.selected) |
||
6518 | ; |
||
6519 | if(settings.selectOnKeydown && module.is.single()) { |
||
6520 | module.set.selectedItem($nextSelectedItem); |
||
6521 | } |
||
6522 | $menu |
||
6523 | .scrollTop(newScroll) |
||
6524 | ; |
||
6525 | } |
||
6526 | }, |
||
6527 | |||
6528 | set: { |
||
6529 | filtered: function() { |
||
6530 | var |
||
6531 | isMultiple = module.is.multiple(), |
||
6532 | isSearch = module.is.searchSelection(), |
||
6533 | isSearchMultiple = (isMultiple && isSearch), |
||
6534 | searchValue = (isSearch) |
||
6535 | ? module.get.query() |
||
6536 | : '', |
||
6537 | hasSearchValue = (typeof searchValue === 'string' && searchValue.length > 0), |
||
6538 | searchWidth = module.get.searchWidth(), |
||
6539 | valueIsSet = searchValue !== '' |
||
6540 | ; |
||
6541 | if(isMultiple && hasSearchValue) { |
||
6542 | module.verbose('Adjusting input width', searchWidth, settings.glyphWidth); |
||
6543 | $search.css('width', searchWidth); |
||
6544 | } |
||
6545 | if(hasSearchValue || (isSearchMultiple && valueIsSet)) { |
||
6546 | module.verbose('Hiding placeholder text'); |
||
6547 | $text.addClass(className.filtered); |
||
6548 | } |
||
6549 | else if(!isMultiple || (isSearchMultiple && !valueIsSet)) { |
||
6550 | module.verbose('Showing placeholder text'); |
||
6551 | $text.removeClass(className.filtered); |
||
6552 | } |
||
6553 | }, |
||
6554 | empty: function() { |
||
6555 | $module.addClass(className.empty); |
||
6556 | }, |
||
6557 | loading: function() { |
||
6558 | $module.addClass(className.loading); |
||
6559 | }, |
||
6560 | placeholderText: function(text) { |
||
6561 | text = text || module.get.placeholderText(); |
||
6562 | module.debug('Setting placeholder text', text); |
||
6563 | module.set.text(text); |
||
6564 | $text.addClass(className.placeholder); |
||
6565 | }, |
||
6566 | tabbable: function() { |
||
6567 | if( module.is.searchSelection() ) { |
||
6568 | module.debug('Added tabindex to searchable dropdown'); |
||
6569 | $search |
||
6570 | .val('') |
||
6571 | .attr('tabindex', 0) |
||
6572 | ; |
||
6573 | $menu |
||
6574 | .attr('tabindex', -1) |
||
6575 | ; |
||
6576 | } |
||
6577 | else { |
||
6578 | module.debug('Added tabindex to dropdown'); |
||
6579 | if( $module.attr('tabindex') === undefined) { |
||
6580 | $module |
||
6581 | .attr('tabindex', 0) |
||
6582 | ; |
||
6583 | $menu |
||
6584 | .attr('tabindex', -1) |
||
6585 | ; |
||
6586 | } |
||
6587 | } |
||
6588 | }, |
||
6589 | initialLoad: function() { |
||
6590 | module.verbose('Setting initial load'); |
||
6591 | initialLoad = true; |
||
6592 | }, |
||
6593 | activeItem: function($item) { |
||
6594 | if( settings.allowAdditions && $item.filter(selector.addition).length > 0 ) { |
||
6595 | $item.addClass(className.filtered); |
||
6596 | } |
||
6597 | else { |
||
6598 | $item.addClass(className.active); |
||
6599 | } |
||
6600 | }, |
||
6601 | partialSearch: function(text) { |
||
6602 | var |
||
6603 | length = module.get.query().length |
||
6604 | ; |
||
6605 | $search.val( text.substr(0 , length)); |
||
6606 | }, |
||
6607 | scrollPosition: function($item, forceScroll) { |
||
6608 | var |
||
6609 | edgeTolerance = 5, |
||
6610 | $menu, |
||
6611 | hasActive, |
||
6612 | offset, |
||
6613 | itemHeight, |
||
6614 | itemOffset, |
||
6615 | menuOffset, |
||
6616 | menuScroll, |
||
6617 | menuHeight, |
||
6618 | abovePage, |
||
6619 | belowPage |
||
6620 | ; |
||
6621 | |||
6622 | $item = $item || module.get.selectedItem(); |
||
6623 | $menu = $item.closest(selector.menu); |
||
6624 | hasActive = ($item && $item.length > 0); |
||
6625 | forceScroll = (forceScroll !== undefined) |
||
6626 | ? forceScroll |
||
6627 | : false |
||
6628 | ; |
||
6629 | if($item && $menu.length > 0 && hasActive) { |
||
6630 | itemOffset = $item.position().top; |
||
6631 | |||
6632 | $menu.addClass(className.loading); |
||
6633 | menuScroll = $menu.scrollTop(); |
||
6634 | menuOffset = $menu.offset().top; |
||
6635 | itemOffset = $item.offset().top; |
||
6636 | offset = menuScroll - menuOffset + itemOffset; |
||
6637 | if(!forceScroll) { |
||
6638 | menuHeight = $menu.height(); |
||
6639 | belowPage = menuScroll + menuHeight < (offset + edgeTolerance); |
||
6640 | abovePage = ((offset - edgeTolerance) < menuScroll); |
||
6641 | } |
||
6642 | module.debug('Scrolling to active item', offset); |
||
6643 | if(forceScroll || abovePage || belowPage) { |
||
6644 | $menu.scrollTop(offset); |
||
6645 | } |
||
6646 | $menu.removeClass(className.loading); |
||
6647 | } |
||
6648 | }, |
||
6649 | text: function(text) { |
||
6650 | if(settings.action !== 'select') { |
||
6651 | if(settings.action == 'combo') { |
||
6652 | module.debug('Changing combo button text', text, $combo); |
||
6653 | if(settings.preserveHTML) { |
||
6654 | $combo.html(text); |
||
6655 | } |
||
6656 | else { |
||
6657 | $combo.text(text); |
||
6658 | } |
||
6659 | } |
||
6660 | else { |
||
6661 | if(text !== module.get.placeholderText()) { |
||
6662 | $text.removeClass(className.placeholder); |
||
6663 | } |
||
6664 | module.debug('Changing text', text, $text); |
||
6665 | $text |
||
6666 | .removeClass(className.filtered) |
||
6667 | ; |
||
6668 | if(settings.preserveHTML) { |
||
6669 | $text.html(text); |
||
6670 | } |
||
6671 | else { |
||
6672 | $text.text(text); |
||
6673 | } |
||
6674 | } |
||
6675 | } |
||
6676 | }, |
||
6677 | selectedItem: function($item) { |
||
6678 | var |
||
6679 | value = module.get.choiceValue($item), |
||
6680 | searchText = module.get.choiceText($item, false), |
||
6681 | text = module.get.choiceText($item, true) |
||
6682 | ; |
||
6683 | module.debug('Setting user selection to item', $item); |
||
6684 | module.remove.activeItem(); |
||
6685 | module.set.partialSearch(searchText); |
||
6686 | module.set.activeItem($item); |
||
6687 | module.set.selected(value, $item); |
||
6688 | module.set.text(text); |
||
6689 | }, |
||
6690 | selectedLetter: function(letter) { |
||
6691 | var |
||
6692 | $selectedItem = $item.filter('.' + className.selected), |
||
6693 | alreadySelectedLetter = $selectedItem.length > 0 && module.has.firstLetter($selectedItem, letter), |
||
6694 | $nextValue = false, |
||
6695 | $nextItem |
||
6696 | ; |
||
6697 | // check next of same letter |
||
6698 | if(alreadySelectedLetter) { |
||
6699 | $nextItem = $selectedItem.nextAll($item).eq(0); |
||
6700 | if( module.has.firstLetter($nextItem, letter) ) { |
||
6701 | $nextValue = $nextItem; |
||
6702 | } |
||
6703 | } |
||
6704 | // check all values |
||
6705 | if(!$nextValue) { |
||
6706 | $item |
||
6707 | .each(function(){ |
||
6708 | if(module.has.firstLetter($(this), letter)) { |
||
6709 | $nextValue = $(this); |
||
6710 | return false; |
||
6711 | } |
||
6712 | }) |
||
6713 | ; |
||
6714 | } |
||
6715 | // set next value |
||
6716 | if($nextValue) { |
||
6717 | module.verbose('Scrolling to next value with letter', letter); |
||
6718 | module.set.scrollPosition($nextValue); |
||
6719 | $selectedItem.removeClass(className.selected); |
||
6720 | $nextValue.addClass(className.selected); |
||
6721 | if(settings.selectOnKeydown && module.is.single()) { |
||
6722 | module.set.selectedItem($nextValue); |
||
6723 | } |
||
6724 | } |
||
6725 | }, |
||
6726 | direction: function($menu) { |
||
6727 | if(settings.direction == 'auto') { |
||
6728 | // reset position |
||
6729 | module.remove.upward(); |
||
6730 | |||
6731 | if(module.can.openDownward($menu)) { |
||
6732 | module.remove.upward($menu); |
||
6733 | } |
||
6734 | else { |
||
6735 | module.set.upward($menu); |
||
6736 | } |
||
6737 | if(!module.is.leftward($menu) && !module.can.openRightward($menu)) { |
||
6738 | module.set.leftward($menu); |
||
6739 | } |
||
6740 | } |
||
6741 | else if(settings.direction == 'upward') { |
||
6742 | module.set.upward($menu); |
||
6743 | } |
||
6744 | }, |
||
6745 | upward: function($currentMenu) { |
||
6746 | var $element = $currentMenu || $module; |
||
6747 | $element.addClass(className.upward); |
||
6748 | }, |
||
6749 | leftward: function($currentMenu) { |
||
6750 | var $element = $currentMenu || $menu; |
||
6751 | $element.addClass(className.leftward); |
||
6752 | }, |
||
6753 | value: function(value, text, $selected) { |
||
6754 | var |
||
6755 | escapedValue = module.escape.value(value), |
||
6756 | hasInput = ($input.length > 0), |
||
6757 | isAddition = !module.has.value(value), |
||
6758 | currentValue = module.get.values(), |
||
6759 | stringValue = (value !== undefined) |
||
6760 | ? String(value) |
||
6761 | : value, |
||
6762 | newValue |
||
6763 | ; |
||
6764 | if(hasInput) { |
||
6765 | if(!settings.allowReselection && stringValue == currentValue) { |
||
6766 | module.verbose('Skipping value update already same value', value, currentValue); |
||
6767 | if(!module.is.initialLoad()) { |
||
6768 | return; |
||
6769 | } |
||
6770 | } |
||
6771 | |||
6772 | if( module.is.single() && module.has.selectInput() && module.can.extendSelect() ) { |
||
6773 | module.debug('Adding user option', value); |
||
6774 | module.add.optionValue(value); |
||
6775 | } |
||
6776 | module.debug('Updating input value', escapedValue, currentValue); |
||
6777 | internalChange = true; |
||
6778 | $input |
||
6779 | .val(escapedValue) |
||
6780 | ; |
||
6781 | if(settings.fireOnInit === false && module.is.initialLoad()) { |
||
6782 | module.debug('Input native change event ignored on initial load'); |
||
6783 | } |
||
6784 | else { |
||
6785 | module.trigger.change(); |
||
6786 | } |
||
6787 | internalChange = false; |
||
6788 | } |
||
6789 | else { |
||
6790 | module.verbose('Storing value in metadata', escapedValue, $input); |
||
6791 | if(escapedValue !== currentValue) { |
||
6792 | $module.data(metadata.value, stringValue); |
||
6793 | } |
||
6794 | } |
||
6795 | if(settings.fireOnInit === false && module.is.initialLoad()) { |
||
6796 | module.verbose('No callback on initial load', settings.onChange); |
||
6797 | } |
||
6798 | else { |
||
6799 | settings.onChange.call(element, value, text, $selected); |
||
6800 | } |
||
6801 | }, |
||
6802 | active: function() { |
||
6803 | $module |
||
6804 | .addClass(className.active) |
||
6805 | ; |
||
6806 | }, |
||
6807 | multiple: function() { |
||
6808 | $module.addClass(className.multiple); |
||
6809 | }, |
||
6810 | visible: function() { |
||
6811 | $module.addClass(className.visible); |
||
6812 | }, |
||
6813 | exactly: function(value, $selectedItem) { |
||
6814 | module.debug('Setting selected to exact values'); |
||
6815 | module.clear(); |
||
6816 | module.set.selected(value, $selectedItem); |
||
6817 | }, |
||
6818 | selected: function(value, $selectedItem) { |
||
6819 | var |
||
6820 | isMultiple = module.is.multiple(), |
||
6821 | $userSelectedItem |
||
6822 | ; |
||
6823 | $selectedItem = (settings.allowAdditions) |
||
6824 | ? $selectedItem || module.get.itemWithAdditions(value) |
||
6825 | : $selectedItem || module.get.item(value) |
||
6826 | ; |
||
6827 | if(!$selectedItem) { |
||
6828 | return; |
||
6829 | } |
||
6830 | module.debug('Setting selected menu item to', $selectedItem); |
||
6831 | if(module.is.multiple()) { |
||
6832 | module.remove.searchWidth(); |
||
6833 | } |
||
6834 | if(module.is.single()) { |
||
6835 | module.remove.activeItem(); |
||
6836 | module.remove.selectedItem(); |
||
6837 | } |
||
6838 | else if(settings.useLabels) { |
||
6839 | module.remove.selectedItem(); |
||
6840 | } |
||
6841 | // select each item |
||
6842 | $selectedItem |
||
6843 | .each(function() { |
||
6844 | var |
||
6845 | $selected = $(this), |
||
6846 | selectedText = module.get.choiceText($selected), |
||
6847 | selectedValue = module.get.choiceValue($selected, selectedText), |
||
6848 | |||
6849 | isFiltered = $selected.hasClass(className.filtered), |
||
6850 | isActive = $selected.hasClass(className.active), |
||
6851 | isUserValue = $selected.hasClass(className.addition), |
||
6852 | shouldAnimate = (isMultiple && $selectedItem.length == 1) |
||
6853 | ; |
||
6854 | if(isMultiple) { |
||
6855 | if(!isActive || isUserValue) { |
||
6856 | if(settings.apiSettings && settings.saveRemoteData) { |
||
6857 | module.save.remoteData(selectedText, selectedValue); |
||
6858 | } |
||
6859 | if(settings.useLabels) { |
||
6860 | module.add.value(selectedValue, selectedText, $selected); |
||
6861 | module.add.label(selectedValue, selectedText, shouldAnimate); |
||
6862 | module.set.activeItem($selected); |
||
6863 | module.filterActive(); |
||
6864 | module.select.nextAvailable($selectedItem); |
||
6865 | } |
||
6866 | else { |
||
6867 | module.add.value(selectedValue, selectedText, $selected); |
||
6868 | module.set.text(module.add.variables(message.count)); |
||
6869 | module.set.activeItem($selected); |
||
6870 | } |
||
6871 | } |
||
6872 | else if(!isFiltered) { |
||
6873 | module.debug('Selected active value, removing label'); |
||
6874 | module.remove.selected(selectedValue); |
||
6875 | } |
||
6876 | } |
||
6877 | else { |
||
6878 | if(settings.apiSettings && settings.saveRemoteData) { |
||
6879 | module.save.remoteData(selectedText, selectedValue); |
||
6880 | } |
||
6881 | module.set.text(selectedText); |
||
6882 | module.set.value(selectedValue, selectedText, $selected); |
||
6883 | $selected |
||
6884 | .addClass(className.active) |
||
6885 | .addClass(className.selected) |
||
6886 | ; |
||
6887 | } |
||
6888 | }) |
||
6889 | ; |
||
6890 | } |
||
6891 | }, |
||
6892 | |||
6893 | add: { |
||
6894 | label: function(value, text, shouldAnimate) { |
||
6895 | var |
||
6896 | $next = module.is.searchSelection() |
||
6897 | ? $search |
||
6898 | : $text, |
||
6899 | escapedValue = module.escape.value(value), |
||
6900 | $label |
||
6901 | ; |
||
6902 | $label = $('<a />') |
||
6903 | .addClass(className.label) |
||
6904 | .attr('data-' + metadata.value, escapedValue) |
||
6905 | .html(templates.label(escapedValue, text)) |
||
6906 | ; |
||
6907 | $label = settings.onLabelCreate.call($label, escapedValue, text); |
||
6908 | |||
6909 | if(module.has.label(value)) { |
||
6910 | module.debug('Label already exists, skipping', escapedValue); |
||
6911 | return; |
||
6912 | } |
||
6913 | if(settings.label.variation) { |
||
6914 | $label.addClass(settings.label.variation); |
||
6915 | } |
||
6916 | if(shouldAnimate === true) { |
||
6917 | module.debug('Animating in label', $label); |
||
6918 | $label |
||
6919 | .addClass(className.hidden) |
||
6920 | .insertBefore($next) |
||
6921 | .transition(settings.label.transition, settings.label.duration) |
||
6922 | ; |
||
6923 | } |
||
6924 | else { |
||
6925 | module.debug('Adding selection label', $label); |
||
6926 | $label |
||
6927 | .insertBefore($next) |
||
6928 | ; |
||
6929 | } |
||
6930 | }, |
||
6931 | message: function(message) { |
||
6932 | var |
||
6933 | $message = $menu.children(selector.message), |
||
6934 | html = settings.templates.message(module.add.variables(message)) |
||
6935 | ; |
||
6936 | if($message.length > 0) { |
||
6937 | $message |
||
6938 | .html(html) |
||
6939 | ; |
||
6940 | } |
||
6941 | else { |
||
6942 | $message = $('<div/>') |
||
6943 | .html(html) |
||
6944 | .addClass(className.message) |
||
6945 | .appendTo($menu) |
||
6946 | ; |
||
6947 | } |
||
6948 | }, |
||
6949 | optionValue: function(value) { |
||
6950 | var |
||
6951 | escapedValue = module.escape.value(value), |
||
6952 | $option = $input.find('option[value="' + module.escape.string(escapedValue) + '"]'), |
||
6953 | hasOption = ($option.length > 0) |
||
6954 | ; |
||
6955 | if(hasOption) { |
||
6956 | return; |
||
6957 | } |
||
6958 | // temporarily disconnect observer |
||
6959 | module.disconnect.selectObserver(); |
||
6960 | if( module.is.single() ) { |
||
6961 | module.verbose('Removing previous user addition'); |
||
6962 | $input.find('option.' + className.addition).remove(); |
||
6963 | } |
||
6964 | $('<option/>') |
||
6965 | .prop('value', escapedValue) |
||
6966 | .addClass(className.addition) |
||
6967 | .html(value) |
||
6968 | .appendTo($input) |
||
6969 | ; |
||
6970 | module.verbose('Adding user addition as an <option>', value); |
||
6971 | module.observe.select(); |
||
6972 | }, |
||
6973 | userSuggestion: function(value) { |
||
6974 | var |
||
6975 | $addition = $menu.children(selector.addition), |
||
6976 | $existingItem = module.get.item(value), |
||
6977 | alreadyHasValue = $existingItem && $existingItem.not(selector.addition).length, |
||
6978 | hasUserSuggestion = $addition.length > 0, |
||
6979 | html |
||
6980 | ; |
||
6981 | if(settings.useLabels && module.has.maxSelections()) { |
||
6982 | return; |
||
6983 | } |
||
6984 | if(value === '' || alreadyHasValue) { |
||
6985 | $addition.remove(); |
||
6986 | return; |
||
6987 | } |
||
6988 | if(hasUserSuggestion) { |
||
6989 | $addition |
||
6990 | .data(metadata.value, value) |
||
6991 | .data(metadata.text, value) |
||
6992 | .attr('data-' + metadata.value, value) |
||
6993 | .attr('data-' + metadata.text, value) |
||
6994 | .removeClass(className.filtered) |
||
6995 | ; |
||
6996 | if(!settings.hideAdditions) { |
||
6997 | html = settings.templates.addition( module.add.variables(message.addResult, value) ); |
||
6998 | $addition |
||
6999 | .html(html) |
||
7000 | ; |
||
7001 | } |
||
7002 | module.verbose('Replacing user suggestion with new value', $addition); |
||
7003 | } |
||
7004 | else { |
||
7005 | $addition = module.create.userChoice(value); |
||
7006 | $addition |
||
7007 | .prependTo($menu) |
||
7008 | ; |
||
7009 | module.verbose('Adding item choice to menu corresponding with user choice addition', $addition); |
||
7010 | } |
||
7011 | if(!settings.hideAdditions || module.is.allFiltered()) { |
||
7012 | $addition |
||
7013 | .addClass(className.selected) |
||
7014 | .siblings() |
||
7015 | .removeClass(className.selected) |
||
7016 | ; |
||
7017 | } |
||
7018 | module.refreshItems(); |
||
7019 | }, |
||
7020 | variables: function(message, term) { |
||
7021 | var |
||
7022 | hasCount = (message.search('{count}') !== -1), |
||
7023 | hasMaxCount = (message.search('{maxCount}') !== -1), |
||
7024 | hasTerm = (message.search('{term}') !== -1), |
||
7025 | values, |
||
7026 | count, |
||
7027 | query |
||
7028 | ; |
||
7029 | module.verbose('Adding templated variables to message', message); |
||
7030 | if(hasCount) { |
||
7031 | count = module.get.selectionCount(); |
||
7032 | message = message.replace('{count}', count); |
||
7033 | } |
||
7034 | if(hasMaxCount) { |
||
7035 | count = module.get.selectionCount(); |
||
7036 | message = message.replace('{maxCount}', settings.maxSelections); |
||
7037 | } |
||
7038 | if(hasTerm) { |
||
7039 | query = term || module.get.query(); |
||
7040 | message = message.replace('{term}', query); |
||
7041 | } |
||
7042 | return message; |
||
7043 | }, |
||
7044 | value: function(addedValue, addedText, $selectedItem) { |
||
7045 | var |
||
7046 | currentValue = module.get.values(), |
||
7047 | newValue |
||
7048 | ; |
||
7049 | if(addedValue === '') { |
||
7050 | module.debug('Cannot select blank values from multiselect'); |
||
7051 | return; |
||
7052 | } |
||
7053 | // extend current array |
||
7054 | if($.isArray(currentValue)) { |
||
7055 | newValue = currentValue.concat([addedValue]); |
||
7056 | newValue = module.get.uniqueArray(newValue); |
||
7057 | } |
||
7058 | else { |
||
7059 | newValue = [addedValue]; |
||
7060 | } |
||
7061 | // add values |
||
7062 | if( module.has.selectInput() ) { |
||
7063 | if(module.can.extendSelect()) { |
||
7064 | module.debug('Adding value to select', addedValue, newValue, $input); |
||
7065 | module.add.optionValue(addedValue); |
||
7066 | } |
||
7067 | } |
||
7068 | else { |
||
7069 | newValue = newValue.join(settings.delimiter); |
||
7070 | module.debug('Setting hidden input to delimited value', newValue, $input); |
||
7071 | } |
||
7072 | |||
7073 | if(settings.fireOnInit === false && module.is.initialLoad()) { |
||
7074 | module.verbose('Skipping onadd callback on initial load', settings.onAdd); |
||
7075 | } |
||
7076 | else { |
||
7077 | settings.onAdd.call(element, addedValue, addedText, $selectedItem); |
||
7078 | } |
||
7079 | module.set.value(newValue, addedValue, addedText, $selectedItem); |
||
7080 | module.check.maxSelections(); |
||
7081 | } |
||
7082 | }, |
||
7083 | |||
7084 | remove: { |
||
7085 | active: function() { |
||
7086 | $module.removeClass(className.active); |
||
7087 | }, |
||
7088 | activeLabel: function() { |
||
7089 | $module.find(selector.label).removeClass(className.active); |
||
7090 | }, |
||
7091 | empty: function() { |
||
7092 | $module.removeClass(className.empty); |
||
7093 | }, |
||
7094 | loading: function() { |
||
7095 | $module.removeClass(className.loading); |
||
7096 | }, |
||
7097 | initialLoad: function() { |
||
7098 | initialLoad = false; |
||
7099 | }, |
||
7100 | upward: function($currentMenu) { |
||
7101 | var $element = $currentMenu || $module; |
||
7102 | $element.removeClass(className.upward); |
||
7103 | }, |
||
7104 | leftward: function($currentMenu) { |
||
7105 | var $element = $currentMenu || $menu; |
||
7106 | $element.removeClass(className.leftward); |
||
7107 | }, |
||
7108 | visible: function() { |
||
7109 | $module.removeClass(className.visible); |
||
7110 | }, |
||
7111 | activeItem: function() { |
||
7112 | $item.removeClass(className.active); |
||
7113 | }, |
||
7114 | filteredItem: function() { |
||
7115 | if(settings.useLabels && module.has.maxSelections() ) { |
||
7116 | return; |
||
7117 | } |
||
7118 | if(settings.useLabels && module.is.multiple()) { |
||
7119 | $item.not('.' + className.active).removeClass(className.filtered); |
||
7120 | } |
||
7121 | else { |
||
7122 | $item.removeClass(className.filtered); |
||
7123 | } |
||
7124 | module.remove.empty(); |
||
7125 | }, |
||
7126 | optionValue: function(value) { |
||
7127 | var |
||
7128 | escapedValue = module.escape.value(value), |
||
7129 | $option = $input.find('option[value="' + module.escape.string(escapedValue) + '"]'), |
||
7130 | hasOption = ($option.length > 0) |
||
7131 | ; |
||
7132 | if(!hasOption || !$option.hasClass(className.addition)) { |
||
7133 | return; |
||
7134 | } |
||
7135 | // temporarily disconnect observer |
||
7136 | if(selectObserver) { |
||
7137 | selectObserver.disconnect(); |
||
7138 | module.verbose('Temporarily disconnecting mutation observer'); |
||
7139 | } |
||
7140 | $option.remove(); |
||
7141 | module.verbose('Removing user addition as an <option>', escapedValue); |
||
7142 | if(selectObserver) { |
||
7143 | selectObserver.observe($input[0], { |
||
7144 | childList : true, |
||
7145 | subtree : true |
||
7146 | }); |
||
7147 | } |
||
7148 | }, |
||
7149 | message: function() { |
||
7150 | $menu.children(selector.message).remove(); |
||
7151 | }, |
||
7152 | searchWidth: function() { |
||
7153 | $search.css('width', ''); |
||
7154 | }, |
||
7155 | searchTerm: function() { |
||
7156 | module.verbose('Cleared search term'); |
||
7157 | $search.val(''); |
||
7158 | module.set.filtered(); |
||
7159 | }, |
||
7160 | userAddition: function() { |
||
7161 | $item.filter(selector.addition).remove(); |
||
7162 | }, |
||
7163 | selected: function(value, $selectedItem) { |
||
7164 | $selectedItem = (settings.allowAdditions) |
||
7165 | ? $selectedItem || module.get.itemWithAdditions(value) |
||
7166 | : $selectedItem || module.get.item(value) |
||
7167 | ; |
||
7168 | |||
7169 | if(!$selectedItem) { |
||
7170 | return false; |
||
7171 | } |
||
7172 | |||
7173 | $selectedItem |
||
7174 | .each(function() { |
||
7175 | var |
||
7176 | $selected = $(this), |
||
7177 | selectedText = module.get.choiceText($selected), |
||
7178 | selectedValue = module.get.choiceValue($selected, selectedText) |
||
7179 | ; |
||
7180 | if(module.is.multiple()) { |
||
7181 | if(settings.useLabels) { |
||
7182 | module.remove.value(selectedValue, selectedText, $selected); |
||
7183 | module.remove.label(selectedValue); |
||
7184 | } |
||
7185 | else { |
||
7186 | module.remove.value(selectedValue, selectedText, $selected); |
||
7187 | if(module.get.selectionCount() === 0) { |
||
7188 | module.set.placeholderText(); |
||
7189 | } |
||
7190 | else { |
||
7191 | module.set.text(module.add.variables(message.count)); |
||
7192 | } |
||
7193 | } |
||
7194 | } |
||
7195 | else { |
||
7196 | module.remove.value(selectedValue, selectedText, $selected); |
||
7197 | } |
||
7198 | $selected |
||
7199 | .removeClass(className.filtered) |
||
7200 | .removeClass(className.active) |
||
7201 | ; |
||
7202 | if(settings.useLabels) { |
||
7203 | $selected.removeClass(className.selected); |
||
7204 | } |
||
7205 | }) |
||
7206 | ; |
||
7207 | }, |
||
7208 | selectedItem: function() { |
||
7209 | $item.removeClass(className.selected); |
||
7210 | }, |
||
7211 | value: function(removedValue, removedText, $removedItem) { |
||
7212 | var |
||
7213 | values = module.get.values(), |
||
7214 | newValue |
||
7215 | ; |
||
7216 | if( module.has.selectInput() ) { |
||
7217 | module.verbose('Input is <select> removing selected option', removedValue); |
||
7218 | newValue = module.remove.arrayValue(removedValue, values); |
||
7219 | module.remove.optionValue(removedValue); |
||
7220 | } |
||
7221 | else { |
||
7222 | module.verbose('Removing from delimited values', removedValue); |
||
7223 | newValue = module.remove.arrayValue(removedValue, values); |
||
7224 | newValue = newValue.join(settings.delimiter); |
||
7225 | } |
||
7226 | if(settings.fireOnInit === false && module.is.initialLoad()) { |
||
7227 | module.verbose('No callback on initial load', settings.onRemove); |
||
7228 | } |
||
7229 | else { |
||
7230 | settings.onRemove.call(element, removedValue, removedText, $removedItem); |
||
7231 | } |
||
7232 | module.set.value(newValue, removedText, $removedItem); |
||
7233 | module.check.maxSelections(); |
||
7234 | }, |
||
7235 | arrayValue: function(removedValue, values) { |
||
7236 | if( !$.isArray(values) ) { |
||
7237 | values = [values]; |
||
7238 | } |
||
7239 | values = $.grep(values, function(value){ |
||
7240 | return (removedValue != value); |
||
7241 | }); |
||
7242 | module.verbose('Removed value from delimited string', removedValue, values); |
||
7243 | return values; |
||
7244 | }, |
||
7245 | label: function(value, shouldAnimate) { |
||
7246 | var |
||
7247 | $labels = $module.find(selector.label), |
||
7248 | $removedLabel = $labels.filter('[data-' + metadata.value + '="' + module.escape.string(value) +'"]') |
||
7249 | ; |
||
7250 | module.verbose('Removing label', $removedLabel); |
||
7251 | $removedLabel.remove(); |
||
7252 | }, |
||
7253 | activeLabels: function($activeLabels) { |
||
7254 | $activeLabels = $activeLabels || $module.find(selector.label).filter('.' + className.active); |
||
7255 | module.verbose('Removing active label selections', $activeLabels); |
||
7256 | module.remove.labels($activeLabels); |
||
7257 | }, |
||
7258 | labels: function($labels) { |
||
7259 | $labels = $labels || $module.find(selector.label); |
||
7260 | module.verbose('Removing labels', $labels); |
||
7261 | $labels |
||
7262 | .each(function(){ |
||
7263 | var |
||
7264 | $label = $(this), |
||
7265 | value = $label.data(metadata.value), |
||
7266 | stringValue = (value !== undefined) |
||
7267 | ? String(value) |
||
7268 | : value, |
||
7269 | isUserValue = module.is.userValue(stringValue) |
||
7270 | ; |
||
7271 | if(settings.onLabelRemove.call($label, value) === false) { |
||
7272 | module.debug('Label remove callback cancelled removal'); |
||
7273 | return; |
||
7274 | } |
||
7275 | module.remove.message(); |
||
7276 | if(isUserValue) { |
||
7277 | module.remove.value(stringValue); |
||
7278 | module.remove.label(stringValue); |
||
7279 | } |
||
7280 | else { |
||
7281 | // selected will also remove label |
||
7282 | module.remove.selected(stringValue); |
||
7283 | } |
||
7284 | }) |
||
7285 | ; |
||
7286 | }, |
||
7287 | tabbable: function() { |
||
7288 | if( module.is.searchSelection() ) { |
||
7289 | module.debug('Searchable dropdown initialized'); |
||
7290 | $search |
||
7291 | .removeAttr('tabindex') |
||
7292 | ; |
||
7293 | $menu |
||
7294 | .removeAttr('tabindex') |
||
7295 | ; |
||
7296 | } |
||
7297 | else { |
||
7298 | module.debug('Simple selection dropdown initialized'); |
||
7299 | $module |
||
7300 | .removeAttr('tabindex') |
||
7301 | ; |
||
7302 | $menu |
||
7303 | .removeAttr('tabindex') |
||
7304 | ; |
||
7305 | } |
||
7306 | } |
||
7307 | }, |
||
7308 | |||
7309 | has: { |
||
7310 | menuSearch: function() { |
||
7311 | return (module.has.search() && $search.closest($menu).length > 0); |
||
7312 | }, |
||
7313 | search: function() { |
||
7314 | return ($search.length > 0); |
||
7315 | }, |
||
7316 | sizer: function() { |
||
7317 | return ($sizer.length > 0); |
||
7318 | }, |
||
7319 | selectInput: function() { |
||
7320 | return ( $input.is('select') ); |
||
7321 | }, |
||
7322 | minCharacters: function(searchTerm) { |
||
7323 | if(settings.minCharacters) { |
||
7324 | searchTerm = (searchTerm !== undefined) |
||
7325 | ? String(searchTerm) |
||
7326 | : String(module.get.query()) |
||
7327 | ; |
||
7328 | return (searchTerm.length >= settings.minCharacters); |
||
7329 | } |
||
7330 | return true; |
||
7331 | }, |
||
7332 | firstLetter: function($item, letter) { |
||
7333 | var |
||
7334 | text, |
||
7335 | firstLetter |
||
7336 | ; |
||
7337 | if(!$item || $item.length === 0 || typeof letter !== 'string') { |
||
7338 | return false; |
||
7339 | } |
||
7340 | text = module.get.choiceText($item, false); |
||
7341 | letter = letter.toLowerCase(); |
||
7342 | firstLetter = String(text).charAt(0).toLowerCase(); |
||
7343 | return (letter == firstLetter); |
||
7344 | }, |
||
7345 | input: function() { |
||
7346 | return ($input.length > 0); |
||
7347 | }, |
||
7348 | items: function() { |
||
7349 | return ($item.length > 0); |
||
7350 | }, |
||
7351 | menu: function() { |
||
7352 | return ($menu.length > 0); |
||
7353 | }, |
||
7354 | message: function() { |
||
7355 | return ($menu.children(selector.message).length !== 0); |
||
7356 | }, |
||
7357 | label: function(value) { |
||
7358 | var |
||
7359 | escapedValue = module.escape.value(value), |
||
7360 | $labels = $module.find(selector.label) |
||
7361 | ; |
||
7362 | return ($labels.filter('[data-' + metadata.value + '="' + module.escape.string(escapedValue) +'"]').length > 0); |
||
7363 | }, |
||
7364 | maxSelections: function() { |
||
7365 | return (settings.maxSelections && module.get.selectionCount() >= settings.maxSelections); |
||
7366 | }, |
||
7367 | allResultsFiltered: function() { |
||
7368 | var |
||
7369 | $normalResults = $item.not(selector.addition) |
||
7370 | ; |
||
7371 | return ($normalResults.filter(selector.unselectable).length === $normalResults.length); |
||
7372 | }, |
||
7373 | userSuggestion: function() { |
||
7374 | return ($menu.children(selector.addition).length > 0); |
||
7375 | }, |
||
7376 | query: function() { |
||
7377 | return (module.get.query() !== ''); |
||
7378 | }, |
||
7379 | value: function(value) { |
||
7380 | var |
||
7381 | values = module.get.values(), |
||
7382 | hasValue = $.isArray(values) |
||
7383 | ? values && ($.inArray(value, values) !== -1) |
||
7384 | : (values == value) |
||
7385 | ; |
||
7386 | return (hasValue) |
||
7387 | ? true |
||
7388 | : false |
||
7389 | ; |
||
7390 | } |
||
7391 | }, |
||
7392 | |||
7393 | is: { |
||
7394 | active: function() { |
||
7395 | return $module.hasClass(className.active); |
||
7396 | }, |
||
7397 | bubbledLabelClick: function(event) { |
||
7398 | return $(event.target).is('select, input') && $module.closest('label').length > 0; |
||
7399 | }, |
||
7400 | bubbledIconClick: function(event) { |
||
7401 | return $(event.target).closest($icon).length > 0; |
||
7402 | }, |
||
7403 | alreadySetup: function() { |
||
7404 | return ($module.is('select') && $module.parent(selector.dropdown).length > 0 && $module.prev().length === 0); |
||
7405 | }, |
||
7406 | animating: function($subMenu) { |
||
7407 | return ($subMenu) |
||
7408 | ? $subMenu.transition && $subMenu.transition('is animating') |
||
7409 | : $menu.transition && $menu.transition('is animating') |
||
7410 | ; |
||
7411 | }, |
||
7412 | leftward: function($subMenu) { |
||
7413 | var $selectedMenu = $subMenu || $menu; |
||
7414 | return $selectedMenu.hasClass(className.leftward); |
||
7415 | }, |
||
7416 | disabled: function() { |
||
7417 | return $module.hasClass(className.disabled); |
||
7418 | }, |
||
7419 | focused: function() { |
||
7420 | return (document.activeElement === $module[0]); |
||
7421 | }, |
||
7422 | focusedOnSearch: function() { |
||
7423 | return (document.activeElement === $search[0]); |
||
7424 | }, |
||
7425 | allFiltered: function() { |
||
7426 | return( (module.is.multiple() || module.has.search()) && !(settings.hideAdditions == false && module.has.userSuggestion()) && !module.has.message() && module.has.allResultsFiltered() ); |
||
7427 | }, |
||
7428 | hidden: function($subMenu) { |
||
7429 | return !module.is.visible($subMenu); |
||
7430 | }, |
||
7431 | initialLoad: function() { |
||
7432 | return initialLoad; |
||
7433 | }, |
||
7434 | inObject: function(needle, object) { |
||
7435 | var |
||
7436 | found = false |
||
7437 | ; |
||
7438 | $.each(object, function(index, property) { |
||
7439 | if(property == needle) { |
||
7440 | found = true; |
||
7441 | return true; |
||
7442 | } |
||
7443 | }); |
||
7444 | return found; |
||
7445 | }, |
||
7446 | multiple: function() { |
||
7447 | return $module.hasClass(className.multiple); |
||
7448 | }, |
||
7449 | remote: function() { |
||
7450 | return settings.apiSettings && module.can.useAPI(); |
||
7451 | }, |
||
7452 | single: function() { |
||
7453 | return !module.is.multiple(); |
||
7454 | }, |
||
7455 | selectMutation: function(mutations) { |
||
7456 | var |
||
7457 | selectChanged = false |
||
7458 | ; |
||
7459 | $.each(mutations, function(index, mutation) { |
||
7460 | if(mutation.target && $(mutation.target).is('select')) { |
||
7461 | selectChanged = true; |
||
7462 | return true; |
||
7463 | } |
||
7464 | }); |
||
7465 | return selectChanged; |
||
7466 | }, |
||
7467 | search: function() { |
||
7468 | return $module.hasClass(className.search); |
||
7469 | }, |
||
7470 | searchSelection: function() { |
||
7471 | return ( module.has.search() && $search.parent(selector.dropdown).length === 1 ); |
||
7472 | }, |
||
7473 | selection: function() { |
||
7474 | return $module.hasClass(className.selection); |
||
7475 | }, |
||
7476 | userValue: function(value) { |
||
7477 | return ($.inArray(value, module.get.userValues()) !== -1); |
||
7478 | }, |
||
7479 | upward: function($menu) { |
||
7480 | var $element = $menu || $module; |
||
7481 | return $element.hasClass(className.upward); |
||
7482 | }, |
||
7483 | visible: function($subMenu) { |
||
7484 | return ($subMenu) |
||
7485 | ? $subMenu.hasClass(className.visible) |
||
7486 | : $menu.hasClass(className.visible) |
||
7487 | ; |
||
7488 | }, |
||
7489 | verticallyScrollableContext: function() { |
||
7490 | var |
||
7491 | overflowY = ($context.get(0) !== window) |
||
7492 | ? $context.css('overflow-y') |
||
7493 | : false |
||
7494 | ; |
||
7495 | return (overflowY == 'auto' || overflowY == 'scroll'); |
||
7496 | }, |
||
7497 | horizontallyScrollableContext: function() { |
||
7498 | var |
||
7499 | overflowX = ($context.get(0) !== window) |
||
7500 | ? $context.css('overflow-X') |
||
7501 | : false |
||
7502 | ; |
||
7503 | return (overflowX == 'auto' || overflowX == 'scroll'); |
||
7504 | } |
||
7505 | }, |
||
7506 | |||
7507 | can: { |
||
7508 | activate: function($item) { |
||
7509 | if(settings.useLabels) { |
||
7510 | return true; |
||
7511 | } |
||
7512 | if(!module.has.maxSelections()) { |
||
7513 | return true; |
||
7514 | } |
||
7515 | if(module.has.maxSelections() && $item.hasClass(className.active)) { |
||
7516 | return true; |
||
7517 | } |
||
7518 | return false; |
||
7519 | }, |
||
7520 | openDownward: function($subMenu) { |
||
7521 | var |
||
7522 | $currentMenu = $subMenu || $menu, |
||
7523 | canOpenDownward = true, |
||
7524 | onScreen = {}, |
||
7525 | calculations |
||
7526 | ; |
||
7527 | $currentMenu |
||
7528 | .addClass(className.loading) |
||
7529 | ; |
||
7530 | calculations = { |
||
7531 | context: { |
||
7532 | scrollTop : $context.scrollTop(), |
||
7533 | height : $context.outerHeight() |
||
7534 | }, |
||
7535 | menu : { |
||
7536 | offset: $currentMenu.offset(), |
||
7537 | height: $currentMenu.outerHeight() |
||
7538 | } |
||
7539 | }; |
||
7540 | if(module.is.verticallyScrollableContext()) { |
||
7541 | calculations.menu.offset.top += calculations.context.scrollTop; |
||
7542 | } |
||
7543 | onScreen = { |
||
7544 | above : (calculations.context.scrollTop) <= calculations.menu.offset.top - calculations.menu.height, |
||
7545 | below : (calculations.context.scrollTop + calculations.context.height) >= calculations.menu.offset.top + calculations.menu.height |
||
7546 | }; |
||
7547 | if(onScreen.below) { |
||
7548 | module.verbose('Dropdown can fit in context downward', onScreen); |
||
7549 | canOpenDownward = true; |
||
7550 | } |
||
7551 | else if(!onScreen.below && !onScreen.above) { |
||
7552 | module.verbose('Dropdown cannot fit in either direction, favoring downward', onScreen); |
||
7553 | canOpenDownward = true; |
||
7554 | } |
||
7555 | else { |
||
7556 | module.verbose('Dropdown cannot fit below, opening upward', onScreen); |
||
7557 | canOpenDownward = false; |
||
7558 | } |
||
7559 | $currentMenu.removeClass(className.loading); |
||
7560 | return canOpenDownward; |
||
7561 | }, |
||
7562 | openRightward: function($subMenu) { |
||
7563 | var |
||
7564 | $currentMenu = $subMenu || $menu, |
||
7565 | canOpenRightward = true, |
||
7566 | isOffscreenRight = false, |
||
7567 | calculations |
||
7568 | ; |
||
7569 | $currentMenu |
||
7570 | .addClass(className.loading) |
||
7571 | ; |
||
7572 | calculations = { |
||
7573 | context: { |
||
7574 | scrollLeft : $context.scrollLeft(), |
||
7575 | width : $context.outerWidth() |
||
7576 | }, |
||
7577 | menu: { |
||
7578 | offset : $currentMenu.offset(), |
||
7579 | width : $currentMenu.outerWidth() |
||
7580 | } |
||
7581 | }; |
||
7582 | if(module.is.horizontallyScrollableContext()) { |
||
7583 | calculations.menu.offset.left += calculations.context.scrollLeft; |
||
7584 | } |
||
7585 | isOffscreenRight = (calculations.menu.offset.left + calculations.menu.width >= calculations.context.scrollLeft + calculations.context.width); |
||
7586 | if(isOffscreenRight) { |
||
7587 | module.verbose('Dropdown cannot fit in context rightward', isOffscreenRight); |
||
7588 | canOpenRightward = false; |
||
7589 | } |
||
7590 | $currentMenu.removeClass(className.loading); |
||
7591 | return canOpenRightward; |
||
7592 | }, |
||
7593 | click: function() { |
||
7594 | return (hasTouch || settings.on == 'click'); |
||
7595 | }, |
||
7596 | extendSelect: function() { |
||
7597 | return settings.allowAdditions || settings.apiSettings; |
||
7598 | }, |
||
7599 | show: function() { |
||
7600 | return !module.is.disabled() && (module.has.items() || module.has.message()); |
||
7601 | }, |
||
7602 | useAPI: function() { |
||
7603 | return $.fn.api !== undefined; |
||
7604 | } |
||
7605 | }, |
||
7606 | |||
7607 | animate: { |
||
7608 | show: function(callback, $subMenu) { |
||
7609 | var |
||
7610 | $currentMenu = $subMenu || $menu, |
||
7611 | start = ($subMenu) |
||
7612 | ? function() {} |
||
7613 | : function() { |
||
7614 | module.hideSubMenus(); |
||
7615 | module.hideOthers(); |
||
7616 | module.set.active(); |
||
7617 | }, |
||
7618 | transition |
||
7619 | ; |
||
7620 | callback = $.isFunction(callback) |
||
7621 | ? callback |
||
7622 | : function(){} |
||
7623 | ; |
||
7624 | module.verbose('Doing menu show animation', $currentMenu); |
||
7625 | module.set.direction($subMenu); |
||
7626 | transition = module.get.transition($subMenu); |
||
7627 | if( module.is.selection() ) { |
||
7628 | module.set.scrollPosition(module.get.selectedItem(), true); |
||
7629 | } |
||
7630 | if( module.is.hidden($currentMenu) || module.is.animating($currentMenu) ) { |
||
7631 | if(transition == 'none') { |
||
7632 | start(); |
||
7633 | $currentMenu.transition('show'); |
||
7634 | callback.call(element); |
||
7635 | } |
||
7636 | else if($.fn.transition !== undefined && $module.transition('is supported')) { |
||
7637 | $currentMenu |
||
7638 | .transition({ |
||
7639 | animation : transition + ' in', |
||
7640 | debug : settings.debug, |
||
7641 | verbose : settings.verbose, |
||
7642 | duration : settings.duration, |
||
7643 | queue : true, |
||
7644 | onStart : start, |
||
7645 | onComplete : function() { |
||
7646 | callback.call(element); |
||
7647 | } |
||
7648 | }) |
||
7649 | ; |
||
7650 | } |
||
7651 | else { |
||
7652 | module.error(error.noTransition, transition); |
||
7653 | } |
||
7654 | } |
||
7655 | }, |
||
7656 | hide: function(callback, $subMenu) { |
||
7657 | var |
||
7658 | $currentMenu = $subMenu || $menu, |
||
7659 | duration = ($subMenu) |
||
7660 | ? (settings.duration * 0.9) |
||
7661 | : settings.duration, |
||
7662 | start = ($subMenu) |
||
7663 | ? function() {} |
||
7664 | : function() { |
||
7665 | if( module.can.click() ) { |
||
7666 | module.unbind.intent(); |
||
7667 | } |
||
7668 | module.remove.active(); |
||
7669 | }, |
||
7670 | transition = module.get.transition($subMenu) |
||
7671 | ; |
||
7672 | callback = $.isFunction(callback) |
||
7673 | ? callback |
||
7674 | : function(){} |
||
7675 | ; |
||
7676 | if( module.is.visible($currentMenu) || module.is.animating($currentMenu) ) { |
||
7677 | module.verbose('Doing menu hide animation', $currentMenu); |
||
7678 | |||
7679 | if(transition == 'none') { |
||
7680 | start(); |
||
7681 | $currentMenu.transition('hide'); |
||
7682 | callback.call(element); |
||
7683 | } |
||
7684 | else if($.fn.transition !== undefined && $module.transition('is supported')) { |
||
7685 | $currentMenu |
||
7686 | .transition({ |
||
7687 | animation : transition + ' out', |
||
7688 | duration : settings.duration, |
||
7689 | debug : settings.debug, |
||
7690 | verbose : settings.verbose, |
||
7691 | queue : true, |
||
7692 | onStart : start, |
||
7693 | onComplete : function() { |
||
7694 | callback.call(element); |
||
7695 | } |
||
7696 | }) |
||
7697 | ; |
||
7698 | } |
||
7699 | else { |
||
7700 | module.error(error.transition); |
||
7701 | } |
||
7702 | } |
||
7703 | } |
||
7704 | }, |
||
7705 | |||
7706 | hideAndClear: function() { |
||
7707 | module.remove.searchTerm(); |
||
7708 | if( module.has.maxSelections() ) { |
||
7709 | return; |
||
7710 | } |
||
7711 | if(module.has.search()) { |
||
7712 | module.hide(function() { |
||
7713 | module.remove.filteredItem(); |
||
7714 | }); |
||
7715 | } |
||
7716 | else { |
||
7717 | module.hide(); |
||
7718 | } |
||
7719 | }, |
||
7720 | |||
7721 | delay: { |
||
7722 | show: function() { |
||
7723 | module.verbose('Delaying show event to ensure user intent'); |
||
7724 | clearTimeout(module.timer); |
||
7725 | module.timer = setTimeout(module.show, settings.delay.show); |
||
7726 | }, |
||
7727 | hide: function() { |
||
7728 | module.verbose('Delaying hide event to ensure user intent'); |
||
7729 | clearTimeout(module.timer); |
||
7730 | module.timer = setTimeout(module.hide, settings.delay.hide); |
||
7731 | } |
||
7732 | }, |
||
7733 | |||
7734 | escape: { |
||
7735 | value: function(value) { |
||
7736 | var |
||
7737 | multipleValues = $.isArray(value), |
||
7738 | stringValue = (typeof value === 'string'), |
||
7739 | isUnparsable = (!stringValue && !multipleValues), |
||
7740 | hasQuotes = (stringValue && value.search(regExp.quote) !== -1), |
||
7741 | values = [] |
||
7742 | ; |
||
7743 | if(isUnparsable || !hasQuotes) { |
||
7744 | return value; |
||
7745 | } |
||
7746 | module.debug('Encoding quote values for use in select', value); |
||
7747 | if(multipleValues) { |
||
7748 | $.each(value, function(index, value){ |
||
7749 | values.push(value.replace(regExp.quote, '"')); |
||
7750 | }); |
||
7751 | return values; |
||
7752 | } |
||
7753 | return value.replace(regExp.quote, '"'); |
||
7754 | }, |
||
7755 | string: function(text) { |
||
7756 | text = String(text); |
||
7757 | return text.replace(regExp.escape, '\\$&'); |
||
7758 | } |
||
7759 | }, |
||
7760 | |||
7761 | setting: function(name, value) { |
||
7762 | module.debug('Changing setting', name, value); |
||
7763 | if( $.isPlainObject(name) ) { |
||
7764 | $.extend(true, settings, name); |
||
7765 | } |
||
7766 | else if(value !== undefined) { |
||
7767 | if($.isPlainObject(settings[name])) { |
||
7768 | $.extend(true, settings[name], value); |
||
7769 | } |
||
7770 | else { |
||
7771 | settings[name] = value; |
||
7772 | } |
||
7773 | } |
||
7774 | else { |
||
7775 | return settings[name]; |
||
7776 | } |
||
7777 | }, |
||
7778 | internal: function(name, value) { |
||
7779 | if( $.isPlainObject(name) ) { |
||
7780 | $.extend(true, module, name); |
||
7781 | } |
||
7782 | else if(value !== undefined) { |
||
7783 | module[name] = value; |
||
7784 | } |
||
7785 | else { |
||
7786 | return module[name]; |
||
7787 | } |
||
7788 | }, |
||
7789 | debug: function() { |
||
7790 | if(!settings.silent && settings.debug) { |
||
7791 | if(settings.performance) { |
||
7792 | module.performance.log(arguments); |
||
7793 | } |
||
7794 | else { |
||
7795 | module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':'); |
||
7796 | module.debug.apply(console, arguments); |
||
7797 | } |
||
7798 | } |
||
7799 | }, |
||
7800 | verbose: function() { |
||
7801 | if(!settings.silent && settings.verbose && settings.debug) { |
||
7802 | if(settings.performance) { |
||
7803 | module.performance.log(arguments); |
||
7804 | } |
||
7805 | else { |
||
7806 | module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':'); |
||
7807 | module.verbose.apply(console, arguments); |
||
7808 | } |
||
7809 | } |
||
7810 | }, |
||
7811 | error: function() { |
||
7812 | if(!settings.silent) { |
||
7813 | module.error = Function.prototype.bind.call(console.error, console, settings.name + ':'); |
||
7814 | module.error.apply(console, arguments); |
||
7815 | } |
||
7816 | }, |
||
7817 | performance: { |
||
7818 | log: function(message) { |
||
7819 | var |
||
7820 | currentTime, |
||
7821 | executionTime, |
||
7822 | previousTime |
||
7823 | ; |
||
7824 | if(settings.performance) { |
||
7825 | currentTime = new Date().getTime(); |
||
7826 | previousTime = time || currentTime; |
||
7827 | executionTime = currentTime - previousTime; |
||
7828 | time = currentTime; |
||
7829 | performance.push({ |
||
7830 | 'Name' : message[0], |
||
7831 | 'Arguments' : [].slice.call(message, 1) || '', |
||
7832 | 'Element' : element, |
||
7833 | 'Execution Time' : executionTime |
||
7834 | }); |
||
7835 | } |
||
7836 | clearTimeout(module.performance.timer); |
||
7837 | module.performance.timer = setTimeout(module.performance.display, 500); |
||
7838 | }, |
||
7839 | display: function() { |
||
7840 | var |
||
7841 | title = settings.name + ':', |
||
7842 | totalTime = 0 |
||
7843 | ; |
||
7844 | time = false; |
||
7845 | clearTimeout(module.performance.timer); |
||
7846 | $.each(performance, function(index, data) { |
||
7847 | totalTime += data['Execution Time']; |
||
7848 | }); |
||
7849 | title += ' ' + totalTime + 'ms'; |
||
7850 | if(moduleSelector) { |
||
7851 | title += ' \'' + moduleSelector + '\''; |
||
7852 | } |
||
7853 | if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) { |
||
7854 | console.groupCollapsed(title); |
||
7855 | if(console.table) { |
||
7856 | console.table(performance); |
||
7857 | } |
||
7858 | else { |
||
7859 | $.each(performance, function(index, data) { |
||
7860 | console.log(data['Name'] + ': ' + data['Execution Time']+'ms'); |
||
7861 | }); |
||
7862 | } |
||
7863 | console.groupEnd(); |
||
7864 | } |
||
7865 | performance = []; |
||
7866 | } |
||
7867 | }, |
||
7868 | invoke: function(query, passedArguments, context) { |
||
7869 | var |
||
7870 | object = instance, |
||
7871 | maxDepth, |
||
7872 | found, |
||
7873 | response |
||
7874 | ; |
||
7875 | passedArguments = passedArguments || queryArguments; |
||
7876 | context = element || context; |
||
7877 | if(typeof query == 'string' && object !== undefined) { |
||
7878 | query = query.split(/[\. ]/); |
||
7879 | maxDepth = query.length - 1; |
||
7880 | $.each(query, function(depth, value) { |
||
7881 | var camelCaseValue = (depth != maxDepth) |
||
7882 | ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1) |
||
7883 | : query |
||
7884 | ; |
||
7885 | if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) { |
||
7886 | object = object[camelCaseValue]; |
||
7887 | } |
||
7888 | else if( object[camelCaseValue] !== undefined ) { |
||
7889 | found = object[camelCaseValue]; |
||
7890 | return false; |
||
7891 | } |
||
7892 | else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) { |
||
7893 | object = object[value]; |
||
7894 | } |
||
7895 | else if( object[value] !== undefined ) { |
||
7896 | found = object[value]; |
||
7897 | return false; |
||
7898 | } |
||
7899 | else { |
||
7900 | module.error(error.method, query); |
||
7901 | return false; |
||
7902 | } |
||
7903 | }); |
||
7904 | } |
||
7905 | if ( $.isFunction( found ) ) { |
||
7906 | response = found.apply(context, passedArguments); |
||
7907 | } |
||
7908 | else if(found !== undefined) { |
||
7909 | response = found; |
||
7910 | } |
||
7911 | if($.isArray(returnedValue)) { |
||
7912 | returnedValue.push(response); |
||
7913 | } |
||
7914 | else if(returnedValue !== undefined) { |
||
7915 | returnedValue = [returnedValue, response]; |
||
7916 | } |
||
7917 | else if(response !== undefined) { |
||
7918 | returnedValue = response; |
||
7919 | } |
||
7920 | return found; |
||
7921 | } |
||
7922 | }; |
||
7923 | |||
7924 | if(methodInvoked) { |
||
7925 | if(instance === undefined) { |
||
7926 | module.initialize(); |
||
7927 | } |
||
7928 | module.invoke(query); |
||
7929 | } |
||
7930 | else { |
||
7931 | if(instance !== undefined) { |
||
7932 | instance.invoke('destroy'); |
||
7933 | } |
||
7934 | module.initialize(); |
||
7935 | } |
||
7936 | }) |
||
7937 | ; |
||
7938 | return (returnedValue !== undefined) |
||
7939 | ? returnedValue |
||
7940 | : $allModules |
||
7941 | ; |
||
7942 | }; |
||
7943 | |||
7944 | $.fn.dropdown.settings = { |
||
7945 | |||
7946 | silent : false, |
||
7947 | debug : false, |
||
7948 | verbose : false, |
||
7949 | performance : true, |
||
7950 | |||
7951 | on : 'click', // what event should show menu action on item selection |
||
7952 | action : 'activate', // action on item selection (nothing, activate, select, combo, hide, function(){}) |
||
7953 | |||
7954 | |||
7955 | apiSettings : false, |
||
7956 | selectOnKeydown : true, // Whether selection should occur automatically when keyboard shortcuts used |
||
7957 | minCharacters : 0, // Minimum characters required to trigger API call |
||
7958 | |||
7959 | filterRemoteData : false, // Whether API results should be filtered after being returned for query term |
||
7960 | saveRemoteData : true, // Whether remote name/value pairs should be stored in sessionStorage to allow remote data to be restored on page refresh |
||
7961 | |||
7962 | throttle : 200, // How long to wait after last user input to search remotely |
||
7963 | |||
7964 | context : window, // Context to use when determining if on screen |
||
7965 | direction : 'auto', // Whether dropdown should always open in one direction |
||
7966 | keepOnScreen : true, // Whether dropdown should check whether it is on screen before showing |
||
7967 | |||
7968 | match : 'both', // what to match against with search selection (both, text, or label) |
||
7969 | fullTextSearch : false, // search anywhere in value (set to 'exact' to require exact matches) |
||
7970 | |||
7971 | placeholder : 'auto', // whether to convert blank <select> values to placeholder text |
||
7972 | preserveHTML : true, // preserve html when selecting value |
||
7973 | sortSelect : false, // sort selection on init |
||
7974 | |||
7975 | forceSelection : true, // force a choice on blur with search selection |
||
7976 | |||
7977 | allowAdditions : false, // whether multiple select should allow user added values |
||
7978 | hideAdditions : true, // whether or not to hide special message prompting a user they can enter a value |
||
7979 | |||
7980 | maxSelections : false, // When set to a number limits the number of selections to this count |
||
7981 | useLabels : true, // whether multiple select should filter currently active selections from choices |
||
7982 | delimiter : ',', // when multiselect uses normal <input> the values will be delimited with this character |
||
7983 | |||
7984 | showOnFocus : true, // show menu on focus |
||
7985 | allowReselection : false, // whether current value should trigger callbacks when reselected |
||
7986 | allowTab : true, // add tabindex to element |
||
7987 | allowCategorySelection : false, // allow elements with sub-menus to be selected |
||
7988 | |||
7989 | fireOnInit : false, // Whether callbacks should fire when initializing dropdown values |
||
7990 | |||
7991 | transition : 'auto', // auto transition will slide down or up based on direction |
||
7992 | duration : 200, // duration of transition |
||
7993 | |||
7994 | glyphWidth : 1.037, // widest glyph width in em (W is 1.037 em) used to calculate multiselect input width |
||
7995 | |||
7996 | // label settings on multi-select |
||
7997 | label: { |
||
7998 | transition : 'scale', |
||
7999 | duration : 200, |
||
8000 | variation : false |
||
8001 | }, |
||
8002 | |||
8003 | // delay before event |
||
8004 | delay : { |
||
8005 | hide : 300, |
||
8006 | show : 200, |
||
8007 | search : 20, |
||
8008 | touch : 50 |
||
8009 | }, |
||
8010 | |||
8011 | /* Callbacks */ |
||
8012 | onChange : function(value, text, $selected){}, |
||
8013 | onAdd : function(value, text, $selected){}, |
||
8014 | onRemove : function(value, text, $selected){}, |
||
8015 | |||
8016 | onLabelSelect : function($selectedLabels){}, |
||
8017 | onLabelCreate : function(value, text) { return $(this); }, |
||
8018 | onLabelRemove : function(value) { return true; }, |
||
8019 | onNoResults : function(searchTerm) { return true; }, |
||
8020 | onShow : function(){}, |
||
8021 | onHide : function(){}, |
||
8022 | |||
8023 | /* Component */ |
||
8024 | name : 'Dropdown', |
||
8025 | namespace : 'dropdown', |
||
8026 | |||
8027 | message: { |
||
8028 | addResult : 'Add <b>{term}</b>', |
||
8029 | count : '{count} selected', |
||
8030 | maxSelections : 'Max {maxCount} selections', |
||
8031 | noResults : 'No results found.', |
||
8032 | serverError : 'There was an error contacting the server' |
||
8033 | }, |
||
8034 | |||
8035 | error : { |
||
8036 | action : 'You called a dropdown action that was not defined', |
||
8037 | alreadySetup : 'Once a select has been initialized behaviors must be called on the created ui dropdown', |
||
8038 | labels : 'Allowing user additions currently requires the use of labels.', |
||
8039 | missingMultiple : '<select> requires multiple property to be set to correctly preserve multiple values', |
||
8040 | method : 'The method you called is not defined.', |
||
8041 | noAPI : 'The API module is required to load resources remotely', |
||
8042 | noStorage : 'Saving remote data requires session storage', |
||
8043 | noTransition : 'This module requires ui transitions <https://github.com/Semantic-Org/UI-Transition>' |
||
8044 | }, |
||
8045 | |||
8046 | regExp : { |
||
8047 | escape : /[-[\]{}()*+?.,\\^$|#\s]/g, |
||
8048 | quote : /"/g |
||
8049 | }, |
||
8050 | |||
8051 | metadata : { |
||
8052 | defaultText : 'defaultText', |
||
8053 | defaultValue : 'defaultValue', |
||
8054 | placeholderText : 'placeholder', |
||
8055 | text : 'text', |
||
8056 | value : 'value' |
||
8057 | }, |
||
8058 | |||
8059 | // property names for remote query |
||
8060 | fields: { |
||
8061 | remoteValues : 'results', // grouping for api results |
||
8062 | values : 'values', // grouping for all dropdown values |
||
8063 | disabled : 'disabled', // whether value should be disabled |
||
8064 | name : 'name', // displayed dropdown text |
||
8065 | value : 'value', // actual dropdown value |
||
8066 | text : 'text' // displayed text when selected |
||
8067 | }, |
||
8068 | |||
8069 | keys : { |
||
8070 | backspace : 8, |
||
8071 | delimiter : 188, // comma |
||
8072 | deleteKey : 46, |
||
8073 | enter : 13, |
||
8074 | escape : 27, |
||
8075 | pageUp : 33, |
||
8076 | pageDown : 34, |
||
8077 | leftArrow : 37, |
||
8078 | upArrow : 38, |
||
8079 | rightArrow : 39, |
||
8080 | downArrow : 40 |
||
8081 | }, |
||
8082 | |||
8083 | selector : { |
||
8084 | addition : '.addition', |
||
8085 | dropdown : '.ui.dropdown', |
||
8086 | hidden : '.hidden', |
||
8087 | icon : '> .dropdown.icon', |
||
8088 | input : '> input[type="hidden"], > select', |
||
8089 | item : '.item', |
||
8090 | label : '> .label', |
||
8091 | remove : '> .label > .delete.icon', |
||
8092 | siblingLabel : '.label', |
||
8093 | menu : '.menu', |
||
8094 | message : '.message', |
||
8095 | menuIcon : '.dropdown.icon', |
||
8096 | search : 'input.search, .menu > .search > input, .menu input.search', |
||
8097 | sizer : '> input.sizer', |
||
8098 | text : '> .text:not(.icon)', |
||
8099 | unselectable : '.disabled, .filtered' |
||
8100 | }, |
||
8101 | |||
8102 | className : { |
||
8103 | active : 'active', |
||
8104 | addition : 'addition', |
||
8105 | animating : 'animating', |
||
8106 | disabled : 'disabled', |
||
8107 | empty : 'empty', |
||
8108 | dropdown : 'ui dropdown', |
||
8109 | filtered : 'filtered', |
||
8110 | hidden : 'hidden transition', |
||
8111 | item : 'item', |
||
8112 | label : 'ui label', |
||
8113 | loading : 'loading', |
||
8114 | menu : 'menu', |
||
8115 | message : 'message', |
||
8116 | multiple : 'multiple', |
||
8117 | placeholder : 'default', |
||
8118 | sizer : 'sizer', |
||
8119 | search : 'search', |
||
8120 | selected : 'selected', |
||
8121 | selection : 'selection', |
||
8122 | upward : 'upward', |
||
8123 | leftward : 'left', |
||
8124 | visible : 'visible' |
||
8125 | } |
||
8126 | |||
8127 | }; |
||
8128 | |||
8129 | /* Templates */ |
||
8130 | $.fn.dropdown.settings.templates = { |
||
8131 | |||
8132 | // generates dropdown from select values |
||
8133 | dropdown: function(select) { |
||
8134 | var |
||
8135 | placeholder = select.placeholder || false, |
||
8136 | values = select.values || {}, |
||
8137 | html = '' |
||
8138 | ; |
||
8139 | html += '<i class="dropdown icon"></i>'; |
||
8140 | if(select.placeholder) { |
||
8141 | html += '<div class="default text">' + placeholder + '</div>'; |
||
8142 | } |
||
8143 | else { |
||
8144 | html += '<div class="text"></div>'; |
||
8145 | } |
||
8146 | html += '<div class="menu">'; |
||
8147 | $.each(select.values, function(index, option) { |
||
8148 | html += (option.disabled) |
||
8149 | ? '<div class="disabled item" data-value="' + option.value + '">' + option.name + '</div>' |
||
8150 | : '<div class="item" data-value="' + option.value + '">' + option.name + '</div>' |
||
8151 | ; |
||
8152 | }); |
||
8153 | html += '</div>'; |
||
8154 | return html; |
||
8155 | }, |
||
8156 | |||
8157 | // generates just menu from select |
||
8158 | menu: function(response, fields) { |
||
8159 | var |
||
8160 | values = response[fields.values] || {}, |
||
8161 | html = '' |
||
8162 | ; |
||
8163 | $.each(values, function(index, option) { |
||
8164 | var |
||
8165 | maybeText = (option[fields.text]) |
||
8166 | ? 'data-text="' + option[fields.text] + '"' |
||
8167 | : '', |
||
8168 | maybeDisabled = (option[fields.disabled]) |
||
8169 | ? 'disabled ' |
||
8170 | : '' |
||
8171 | ; |
||
8172 | html += '<div class="'+ maybeDisabled +'item" data-value="' + option[fields.value] + '"' + maybeText + '>' |
||
8173 | html += option[fields.name]; |
||
8174 | html += '</div>'; |
||
8175 | }); |
||
8176 | return html; |
||
8177 | }, |
||
8178 | |||
8179 | // generates label for multiselect |
||
8180 | label: function(value, text) { |
||
8181 | return text + '<i class="delete icon"></i>'; |
||
8182 | }, |
||
8183 | |||
8184 | |||
8185 | // generates messages like "No results" |
||
8186 | message: function(message) { |
||
8187 | return message; |
||
8188 | }, |
||
8189 | |||
8190 | // generates user addition to selection menu |
||
8191 | addition: function(choice) { |
||
8192 | return choice; |
||
8193 | } |
||
8194 | |||
8195 | }; |
||
8196 | |||
8197 | })( jQuery, window, document ); |
||
8198 | |||
8199 | /*! |
||
8200 | * # Semantic UI 2.2.11 - Embed |
||
8201 | * http://github.com/semantic-org/semantic-ui/ |
||
8202 | * |
||
8203 | * |
||
8204 | * Released under the MIT license |
||
8205 | * http://opensource.org/licenses/MIT |
||
8206 | * |
||
8207 | */ |
||
8208 | |||
8209 | View Code Duplication | ;(function ($, window, document, undefined) { |
|
8210 | |||
8211 | "use strict"; |
||
8212 | |||
8213 | window = (typeof window != 'undefined' && window.Math == Math) |
||
8214 | ? window |
||
8215 | : (typeof self != 'undefined' && self.Math == Math) |
||
8216 | ? self |
||
8217 | : Function('return this')() |
||
8218 | ; |
||
8219 | |||
8220 | $.fn.embed = function(parameters) { |
||
8221 | |||
8222 | var |
||
8223 | $allModules = $(this), |
||
8224 | |||
8225 | moduleSelector = $allModules.selector || '', |
||
8226 | |||
8227 | time = new Date().getTime(), |
||
8228 | performance = [], |
||
8229 | |||
8230 | query = arguments[0], |
||
8231 | methodInvoked = (typeof query == 'string'), |
||
8232 | queryArguments = [].slice.call(arguments, 1), |
||
8233 | |||
8234 | returnedValue |
||
8235 | ; |
||
8236 | |||
8237 | $allModules |
||
8238 | .each(function() { |
||
8239 | var |
||
8240 | settings = ( $.isPlainObject(parameters) ) |
||
8241 | ? $.extend(true, {}, $.fn.embed.settings, parameters) |
||
8242 | : $.extend({}, $.fn.embed.settings), |
||
8243 | |||
8244 | selector = settings.selector, |
||
8245 | className = settings.className, |
||
8246 | sources = settings.sources, |
||
8247 | error = settings.error, |
||
8248 | metadata = settings.metadata, |
||
8249 | namespace = settings.namespace, |
||
8250 | templates = settings.templates, |
||
8251 | |||
8252 | eventNamespace = '.' + namespace, |
||
8253 | moduleNamespace = 'module-' + namespace, |
||
8254 | |||
8255 | $window = $(window), |
||
8256 | $module = $(this), |
||
8257 | $placeholder = $module.find(selector.placeholder), |
||
8258 | $icon = $module.find(selector.icon), |
||
8259 | $embed = $module.find(selector.embed), |
||
8260 | |||
8261 | element = this, |
||
8262 | instance = $module.data(moduleNamespace), |
||
8263 | module |
||
8264 | ; |
||
8265 | |||
8266 | module = { |
||
8267 | |||
8268 | initialize: function() { |
||
8269 | module.debug('Initializing embed'); |
||
8270 | module.determine.autoplay(); |
||
8271 | module.create(); |
||
8272 | module.bind.events(); |
||
8273 | module.instantiate(); |
||
8274 | }, |
||
8275 | |||
8276 | instantiate: function() { |
||
8277 | module.verbose('Storing instance of module', module); |
||
8278 | instance = module; |
||
8279 | $module |
||
8280 | .data(moduleNamespace, module) |
||
8281 | ; |
||
8282 | }, |
||
8283 | |||
8284 | destroy: function() { |
||
8285 | module.verbose('Destroying previous instance of embed'); |
||
8286 | module.reset(); |
||
8287 | $module |
||
8288 | .removeData(moduleNamespace) |
||
8289 | .off(eventNamespace) |
||
8290 | ; |
||
8291 | }, |
||
8292 | |||
8293 | refresh: function() { |
||
8294 | module.verbose('Refreshing selector cache'); |
||
8295 | $placeholder = $module.find(selector.placeholder); |
||
8296 | $icon = $module.find(selector.icon); |
||
8297 | $embed = $module.find(selector.embed); |
||
8298 | }, |
||
8299 | |||
8300 | bind: { |
||
8301 | events: function() { |
||
8302 | if( module.has.placeholder() ) { |
||
8303 | module.debug('Adding placeholder events'); |
||
8304 | $module |
||
8305 | .on('click' + eventNamespace, selector.placeholder, module.createAndShow) |
||
8306 | .on('click' + eventNamespace, selector.icon, module.createAndShow) |
||
8307 | ; |
||
8308 | } |
||
8309 | } |
||
8310 | }, |
||
8311 | |||
8312 | create: function() { |
||
8313 | var |
||
8314 | placeholder = module.get.placeholder() |
||
8315 | ; |
||
8316 | if(placeholder) { |
||
8317 | module.createPlaceholder(); |
||
8318 | } |
||
8319 | else { |
||
8320 | module.createAndShow(); |
||
8321 | } |
||
8322 | }, |
||
8323 | |||
8324 | createPlaceholder: function(placeholder) { |
||
8325 | var |
||
8326 | icon = module.get.icon(), |
||
8327 | url = module.get.url(), |
||
8328 | embed = module.generate.embed(url) |
||
8329 | ; |
||
8330 | placeholder = placeholder || module.get.placeholder(); |
||
8331 | $module.html( templates.placeholder(placeholder, icon) ); |
||
8332 | module.debug('Creating placeholder for embed', placeholder, icon); |
||
8333 | }, |
||
8334 | |||
8335 | createEmbed: function(url) { |
||
8336 | module.refresh(); |
||
8337 | url = url || module.get.url(); |
||
8338 | $embed = $('<div/>') |
||
8339 | .addClass(className.embed) |
||
8340 | .html( module.generate.embed(url) ) |
||
8341 | .appendTo($module) |
||
8342 | ; |
||
8343 | settings.onCreate.call(element, url); |
||
8344 | module.debug('Creating embed object', $embed); |
||
8345 | }, |
||
8346 | |||
8347 | changeEmbed: function(url) { |
||
8348 | $embed |
||
8349 | .html( module.generate.embed(url) ) |
||
8350 | ; |
||
8351 | }, |
||
8352 | |||
8353 | createAndShow: function() { |
||
8354 | module.createEmbed(); |
||
8355 | module.show(); |
||
8356 | }, |
||
8357 | |||
8358 | // sets new embed |
||
8359 | change: function(source, id, url) { |
||
8360 | module.debug('Changing video to ', source, id, url); |
||
8361 | $module |
||
8362 | .data(metadata.source, source) |
||
8363 | .data(metadata.id, id) |
||
8364 | ; |
||
8365 | if(url) { |
||
8366 | $module.data(metadata.url, url); |
||
8367 | } |
||
8368 | else { |
||
8369 | $module.removeData(metadata.url); |
||
8370 | } |
||
8371 | if(module.has.embed()) { |
||
8372 | module.changeEmbed(); |
||
8373 | } |
||
8374 | else { |
||
8375 | module.create(); |
||
8376 | } |
||
8377 | }, |
||
8378 | |||
8379 | // clears embed |
||
8380 | reset: function() { |
||
8381 | module.debug('Clearing embed and showing placeholder'); |
||
8382 | module.remove.active(); |
||
8383 | module.remove.embed(); |
||
8384 | module.showPlaceholder(); |
||
8385 | settings.onReset.call(element); |
||
8386 | }, |
||
8387 | |||
8388 | // shows current embed |
||
8389 | show: function() { |
||
8390 | module.debug('Showing embed'); |
||
8391 | module.set.active(); |
||
8392 | settings.onDisplay.call(element); |
||
8393 | }, |
||
8394 | |||
8395 | hide: function() { |
||
8396 | module.debug('Hiding embed'); |
||
8397 | module.showPlaceholder(); |
||
8398 | }, |
||
8399 | |||
8400 | showPlaceholder: function() { |
||
8401 | module.debug('Showing placeholder image'); |
||
8402 | module.remove.active(); |
||
8403 | settings.onPlaceholderDisplay.call(element); |
||
8404 | }, |
||
8405 | |||
8406 | get: { |
||
8407 | id: function() { |
||
8408 | return settings.id || $module.data(metadata.id); |
||
8409 | }, |
||
8410 | placeholder: function() { |
||
8411 | return settings.placeholder || $module.data(metadata.placeholder); |
||
8412 | }, |
||
8413 | icon: function() { |
||
8414 | return (settings.icon) |
||
8415 | ? settings.icon |
||
8416 | : ($module.data(metadata.icon) !== undefined) |
||
8417 | ? $module.data(metadata.icon) |
||
8418 | : module.determine.icon() |
||
8419 | ; |
||
8420 | }, |
||
8421 | source: function(url) { |
||
8422 | return (settings.source) |
||
8423 | ? settings.source |
||
8424 | : ($module.data(metadata.source) !== undefined) |
||
8425 | ? $module.data(metadata.source) |
||
8426 | : module.determine.source() |
||
8427 | ; |
||
8428 | }, |
||
8429 | type: function() { |
||
8430 | var source = module.get.source(); |
||
8431 | return (sources[source] !== undefined) |
||
8432 | ? sources[source].type |
||
8433 | : false |
||
8434 | ; |
||
8435 | }, |
||
8436 | url: function() { |
||
8437 | return (settings.url) |
||
8438 | ? settings.url |
||
8439 | : ($module.data(metadata.url) !== undefined) |
||
8440 | ? $module.data(metadata.url) |
||
8441 | : module.determine.url() |
||
8442 | ; |
||
8443 | } |
||
8444 | }, |
||
8445 | |||
8446 | determine: { |
||
8447 | autoplay: function() { |
||
8448 | if(module.should.autoplay()) { |
||
8449 | settings.autoplay = true; |
||
8450 | } |
||
8451 | }, |
||
8452 | source: function(url) { |
||
8453 | var |
||
8454 | matchedSource = false |
||
8455 | ; |
||
8456 | url = url || module.get.url(); |
||
8457 | if(url) { |
||
8458 | $.each(sources, function(name, source) { |
||
8459 | if(url.search(source.domain) !== -1) { |
||
8460 | matchedSource = name; |
||
8461 | return false; |
||
8462 | } |
||
8463 | }); |
||
8464 | } |
||
8465 | return matchedSource; |
||
8466 | }, |
||
8467 | icon: function() { |
||
8468 | var |
||
8469 | source = module.get.source() |
||
8470 | ; |
||
8471 | return (sources[source] !== undefined) |
||
8472 | ? sources[source].icon |
||
8473 | : false |
||
8474 | ; |
||
8475 | }, |
||
8476 | url: function() { |
||
8477 | var |
||
8478 | id = settings.id || $module.data(metadata.id), |
||
8479 | source = settings.source || $module.data(metadata.source), |
||
8480 | url |
||
8481 | ; |
||
8482 | url = (sources[source] !== undefined) |
||
8483 | ? sources[source].url.replace('{id}', id) |
||
8484 | : false |
||
8485 | ; |
||
8486 | if(url) { |
||
8487 | $module.data(metadata.url, url); |
||
8488 | } |
||
8489 | return url; |
||
8490 | } |
||
8491 | }, |
||
8492 | |||
8493 | |||
8494 | set: { |
||
8495 | active: function() { |
||
8496 | $module.addClass(className.active); |
||
8497 | } |
||
8498 | }, |
||
8499 | |||
8500 | remove: { |
||
8501 | active: function() { |
||
8502 | $module.removeClass(className.active); |
||
8503 | }, |
||
8504 | embed: function() { |
||
8505 | $embed.empty(); |
||
8506 | } |
||
8507 | }, |
||
8508 | |||
8509 | encode: { |
||
8510 | parameters: function(parameters) { |
||
8511 | var |
||
8512 | urlString = [], |
||
8513 | index |
||
8514 | ; |
||
8515 | for (index in parameters) { |
||
8516 | urlString.push( encodeURIComponent(index) + '=' + encodeURIComponent( parameters[index] ) ); |
||
8517 | } |
||
8518 | return urlString.join('&'); |
||
8519 | } |
||
8520 | }, |
||
8521 | |||
8522 | generate: { |
||
8523 | embed: function(url) { |
||
8524 | module.debug('Generating embed html'); |
||
8525 | var |
||
8526 | source = module.get.source(), |
||
8527 | html, |
||
8528 | parameters |
||
8529 | ; |
||
8530 | url = module.get.url(url); |
||
8531 | if(url) { |
||
8532 | parameters = module.generate.parameters(source); |
||
8533 | html = templates.iframe(url, parameters); |
||
8534 | } |
||
8535 | else { |
||
8536 | module.error(error.noURL, $module); |
||
8537 | } |
||
8538 | return html; |
||
8539 | }, |
||
8540 | parameters: function(source, extraParameters) { |
||
8541 | var |
||
8542 | parameters = (sources[source] && sources[source].parameters !== undefined) |
||
8543 | ? sources[source].parameters(settings) |
||
8544 | : {} |
||
8545 | ; |
||
8546 | extraParameters = extraParameters || settings.parameters; |
||
8547 | if(extraParameters) { |
||
8548 | parameters = $.extend({}, parameters, extraParameters); |
||
8549 | } |
||
8550 | parameters = settings.onEmbed(parameters); |
||
8551 | return module.encode.parameters(parameters); |
||
8552 | } |
||
8553 | }, |
||
8554 | |||
8555 | has: { |
||
8556 | embed: function() { |
||
8557 | return ($embed.length > 0); |
||
8558 | }, |
||
8559 | placeholder: function() { |
||
8560 | return settings.placeholder || $module.data(metadata.placeholder); |
||
8561 | } |
||
8562 | }, |
||
8563 | |||
8564 | should: { |
||
8565 | autoplay: function() { |
||
8566 | return (settings.autoplay === 'auto') |
||
8567 | ? (settings.placeholder || $module.data(metadata.placeholder) !== undefined) |
||
8568 | : settings.autoplay |
||
8569 | ; |
||
8570 | } |
||
8571 | }, |
||
8572 | |||
8573 | is: { |
||
8574 | video: function() { |
||
8575 | return module.get.type() == 'video'; |
||
8576 | } |
||
8577 | }, |
||
8578 | |||
8579 | setting: function(name, value) { |
||
8580 | module.debug('Changing setting', name, value); |
||
8581 | if( $.isPlainObject(name) ) { |
||
8582 | $.extend(true, settings, name); |
||
8583 | } |
||
8584 | else if(value !== undefined) { |
||
8585 | if($.isPlainObject(settings[name])) { |
||
8586 | $.extend(true, settings[name], value); |
||
8587 | } |
||
8588 | else { |
||
8589 | settings[name] = value; |
||
8590 | } |
||
8591 | } |
||
8592 | else { |
||
8593 | return settings[name]; |
||
8594 | } |
||
8595 | }, |
||
8596 | internal: function(name, value) { |
||
8597 | if( $.isPlainObject(name) ) { |
||
8598 | $.extend(true, module, name); |
||
8599 | } |
||
8600 | else if(value !== undefined) { |
||
8601 | module[name] = value; |
||
8602 | } |
||
8603 | else { |
||
8604 | return module[name]; |
||
8605 | } |
||
8606 | }, |
||
8607 | debug: function() { |
||
8608 | if(!settings.silent && settings.debug) { |
||
8609 | if(settings.performance) { |
||
8610 | module.performance.log(arguments); |
||
8611 | } |
||
8612 | else { |
||
8613 | module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':'); |
||
8614 | module.debug.apply(console, arguments); |
||
8615 | } |
||
8616 | } |
||
8617 | }, |
||
8618 | verbose: function() { |
||
8619 | if(!settings.silent && settings.verbose && settings.debug) { |
||
8620 | if(settings.performance) { |
||
8621 | module.performance.log(arguments); |
||
8622 | } |
||
8623 | else { |
||
8624 | module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':'); |
||
8625 | module.verbose.apply(console, arguments); |
||
8626 | } |
||
8627 | } |
||
8628 | }, |
||
8629 | error: function() { |
||
8630 | if(!settings.silent) { |
||
8631 | module.error = Function.prototype.bind.call(console.error, console, settings.name + ':'); |
||
8632 | module.error.apply(console, arguments); |
||
8633 | } |
||
8634 | }, |
||
8635 | performance: { |
||
8636 | log: function(message) { |
||
8637 | var |
||
8638 | currentTime, |
||
8639 | executionTime, |
||
8640 | previousTime |
||
8641 | ; |
||
8642 | if(settings.performance) { |
||
8643 | currentTime = new Date().getTime(); |
||
8644 | previousTime = time || currentTime; |
||
8645 | executionTime = currentTime - previousTime; |
||
8646 | time = currentTime; |
||
8647 | performance.push({ |
||
8648 | 'Name' : message[0], |
||
8649 | 'Arguments' : [].slice.call(message, 1) || '', |
||
8650 | 'Element' : element, |
||
8651 | 'Execution Time' : executionTime |
||
8652 | }); |
||
8653 | } |
||
8654 | clearTimeout(module.performance.timer); |
||
8655 | module.performance.timer = setTimeout(module.performance.display, 500); |
||
8656 | }, |
||
8657 | display: function() { |
||
8658 | var |
||
8659 | title = settings.name + ':', |
||
8660 | totalTime = 0 |
||
8661 | ; |
||
8662 | time = false; |
||
8663 | clearTimeout(module.performance.timer); |
||
8664 | $.each(performance, function(index, data) { |
||
8665 | totalTime += data['Execution Time']; |
||
8666 | }); |
||
8667 | title += ' ' + totalTime + 'ms'; |
||
8668 | if(moduleSelector) { |
||
8669 | title += ' \'' + moduleSelector + '\''; |
||
8670 | } |
||
8671 | if($allModules.length > 1) { |
||
8672 | title += ' ' + '(' + $allModules.length + ')'; |
||
8673 | } |
||
8674 | if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) { |
||
8675 | console.groupCollapsed(title); |
||
8676 | if(console.table) { |
||
8677 | console.table(performance); |
||
8678 | } |
||
8679 | else { |
||
8680 | $.each(performance, function(index, data) { |
||
8681 | console.log(data['Name'] + ': ' + data['Execution Time']+'ms'); |
||
8682 | }); |
||
8683 | } |
||
8684 | console.groupEnd(); |
||
8685 | } |
||
8686 | performance = []; |
||
8687 | } |
||
8688 | }, |
||
8689 | invoke: function(query, passedArguments, context) { |
||
8690 | var |
||
8691 | object = instance, |
||
8692 | maxDepth, |
||
8693 | found, |
||
8694 | response |
||
8695 | ; |
||
8696 | passedArguments = passedArguments || queryArguments; |
||
8697 | context = element || context; |
||
8698 | if(typeof query == 'string' && object !== undefined) { |
||
8699 | query = query.split(/[\. ]/); |
||
8700 | maxDepth = query.length - 1; |
||
8701 | $.each(query, function(depth, value) { |
||
8702 | var camelCaseValue = (depth != maxDepth) |
||
8703 | ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1) |
||
8704 | : query |
||
8705 | ; |
||
8706 | if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) { |
||
8707 | object = object[camelCaseValue]; |
||
8708 | } |
||
8709 | else if( object[camelCaseValue] !== undefined ) { |
||
8710 | found = object[camelCaseValue]; |
||
8711 | return false; |
||
8712 | } |
||
8713 | else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) { |
||
8714 | object = object[value]; |
||
8715 | } |
||
8716 | else if( object[value] !== undefined ) { |
||
8717 | found = object[value]; |
||
8718 | return false; |
||
8719 | } |
||
8720 | else { |
||
8721 | module.error(error.method, query); |
||
8722 | return false; |
||
8723 | } |
||
8724 | }); |
||
8725 | } |
||
8726 | if ( $.isFunction( found ) ) { |
||
8727 | response = found.apply(context, passedArguments); |
||
8728 | } |
||
8729 | else if(found !== undefined) { |
||
8730 | response = found; |
||
8731 | } |
||
8732 | if($.isArray(returnedValue)) { |
||
8733 | returnedValue.push(response); |
||
8734 | } |
||
8735 | else if(returnedValue !== undefined) { |
||
8736 | returnedValue = [returnedValue, response]; |
||
8737 | } |
||
8738 | else if(response !== undefined) { |
||
8739 | returnedValue = response; |
||
8740 | } |
||
8741 | return found; |
||
8742 | } |
||
8743 | }; |
||
8744 | |||
8745 | if(methodInvoked) { |
||
8746 | if(instance === undefined) { |
||
8747 | module.initialize(); |
||
8748 | } |
||
8749 | module.invoke(query); |
||
8750 | } |
||
8751 | else { |
||
8752 | if(instance !== undefined) { |
||
8753 | instance.invoke('destroy'); |
||
8754 | } |
||
8755 | module.initialize(); |
||
8756 | } |
||
8757 | }) |
||
8758 | ; |
||
8759 | return (returnedValue !== undefined) |
||
8760 | ? returnedValue |
||
8761 | : this |
||
8762 | ; |
||
8763 | }; |
||
8764 | |||
8765 | $.fn.embed.settings = { |
||
8766 | |||
8767 | name : 'Embed', |
||
8768 | namespace : 'embed', |
||
8769 | |||
8770 | silent : false, |
||
8771 | debug : false, |
||
8772 | verbose : false, |
||
8773 | performance : true, |
||
8774 | |||
8775 | icon : false, |
||
8776 | source : false, |
||
8777 | url : false, |
||
8778 | id : false, |
||
8779 | |||
8780 | // standard video settings |
||
8781 | autoplay : 'auto', |
||
8782 | color : '#444444', |
||
8783 | hd : true, |
||
8784 | brandedUI : false, |
||
8785 | |||
8786 | // additional parameters to include with the embed |
||
8787 | parameters: false, |
||
8788 | |||
8789 | onDisplay : function() {}, |
||
8790 | onPlaceholderDisplay : function() {}, |
||
8791 | onReset : function() {}, |
||
8792 | onCreate : function(url) {}, |
||
8793 | onEmbed : function(parameters) { |
||
8794 | return parameters; |
||
8795 | }, |
||
8796 | |||
8797 | metadata : { |
||
8798 | id : 'id', |
||
8799 | icon : 'icon', |
||
8800 | placeholder : 'placeholder', |
||
8801 | source : 'source', |
||
8802 | url : 'url' |
||
8803 | }, |
||
8804 | |||
8805 | error : { |
||
8806 | noURL : 'No URL specified', |
||
8807 | method : 'The method you called is not defined' |
||
8808 | }, |
||
8809 | |||
8810 | className : { |
||
8811 | active : 'active', |
||
8812 | embed : 'embed' |
||
8813 | }, |
||
8814 | |||
8815 | selector : { |
||
8816 | embed : '.embed', |
||
8817 | placeholder : '.placeholder', |
||
8818 | icon : '.icon' |
||
8819 | }, |
||
8820 | |||
8821 | sources: { |
||
8822 | youtube: { |
||
8823 | name : 'youtube', |
||
8824 | type : 'video', |
||
8825 | icon : 'video play', |
||
8826 | domain : 'youtube.com', |
||
8827 | url : '//www.youtube.com/embed/{id}', |
||
8828 | parameters: function(settings) { |
||
8829 | return { |
||
8830 | autohide : !settings.brandedUI, |
||
8831 | autoplay : settings.autoplay, |
||
8832 | color : settings.color || undefined, |
||
8833 | hq : settings.hd, |
||
8834 | jsapi : settings.api, |
||
8835 | modestbranding : !settings.brandedUI |
||
8836 | }; |
||
8837 | } |
||
8838 | }, |
||
8839 | vimeo: { |
||
8840 | name : 'vimeo', |
||
8841 | type : 'video', |
||
8842 | icon : 'video play', |
||
8843 | domain : 'vimeo.com', |
||
8844 | url : '//player.vimeo.com/video/{id}', |
||
8845 | parameters: function(settings) { |
||
8846 | return { |
||
8847 | api : settings.api, |
||
8848 | autoplay : settings.autoplay, |
||
8849 | byline : settings.brandedUI, |
||
8850 | color : settings.color || undefined, |
||
8851 | portrait : settings.brandedUI, |
||
8852 | title : settings.brandedUI |
||
8853 | }; |
||
8854 | } |
||
8855 | } |
||
8856 | }, |
||
8857 | |||
8858 | templates: { |
||
8859 | iframe : function(url, parameters) { |
||
8860 | var src = url; |
||
8861 | if (parameters) { |
||
8862 | src += '?' + parameters; |
||
8863 | } |
||
8864 | return '' |
||
8865 | + '<iframe src="' + src + '"' |
||
8866 | + ' width="100%" height="100%"' |
||
8867 | + ' frameborder="0" scrolling="no" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>' |
||
8868 | ; |
||
8869 | }, |
||
8870 | placeholder : function(image, icon) { |
||
8871 | var |
||
8872 | html = '' |
||
8873 | ; |
||
8874 | if(icon) { |
||
8875 | html += '<i class="' + icon + ' icon"></i>'; |
||
8876 | } |
||
8877 | if(image) { |
||
8878 | html += '<img class="placeholder" src="' + image + '">'; |
||
8879 | } |
||
8880 | return html; |
||
8881 | } |
||
8882 | }, |
||
8883 | |||
8884 | // NOT YET IMPLEMENTED |
||
8885 | api : false, |
||
8886 | onPause : function() {}, |
||
8887 | onPlay : function() {}, |
||
8888 | onStop : function() {} |
||
8889 | |||
8890 | }; |
||
8891 | |||
8892 | |||
8893 | |||
8894 | })( jQuery, window, document ); |
||
8895 | |||
8896 | /*! |
||
8897 | * # Semantic UI 2.2.11 - Modal |
||
8898 | * http://github.com/semantic-org/semantic-ui/ |
||
8899 | * |
||
8900 | * |
||
8901 | * Released under the MIT license |
||
8902 | * http://opensource.org/licenses/MIT |
||
8903 | * |
||
8904 | */ |
||
8905 | |||
8906 | View Code Duplication | ;(function ($, window, document, undefined) { |
|
8907 | |||
8908 | "use strict"; |
||
8909 | |||
8910 | window = (typeof window != 'undefined' && window.Math == Math) |
||
8911 | ? window |
||
8912 | : (typeof self != 'undefined' && self.Math == Math) |
||
8913 | ? self |
||
8914 | : Function('return this')() |
||
8915 | ; |
||
8916 | |||
8917 | $.fn.modal = function(parameters) { |
||
8918 | var |
||
8919 | $allModules = $(this), |
||
8920 | $window = $(window), |
||
8921 | $document = $(document), |
||
8922 | $body = $('body'), |
||
8923 | |||
8924 | moduleSelector = $allModules.selector || '', |
||
8925 | |||
8926 | time = new Date().getTime(), |
||
8927 | performance = [], |
||
8928 | |||
8929 | query = arguments[0], |
||
8930 | methodInvoked = (typeof query == 'string'), |
||
8931 | queryArguments = [].slice.call(arguments, 1), |
||
8932 | |||
8933 | requestAnimationFrame = window.requestAnimationFrame |
||
8934 | || window.mozRequestAnimationFrame |
||
8935 | || window.webkitRequestAnimationFrame |
||
8936 | || window.msRequestAnimationFrame |
||
8937 | || function(callback) { setTimeout(callback, 0); }, |
||
8938 | |||
8939 | returnedValue |
||
8940 | ; |
||
8941 | |||
8942 | $allModules |
||
8943 | .each(function() { |
||
8944 | var |
||
8945 | settings = ( $.isPlainObject(parameters) ) |
||
8946 | ? $.extend(true, {}, $.fn.modal.settings, parameters) |
||
8947 | : $.extend({}, $.fn.modal.settings), |
||
8948 | |||
8949 | selector = settings.selector, |
||
8950 | className = settings.className, |
||
8951 | namespace = settings.namespace, |
||
8952 | error = settings.error, |
||
8953 | |||
8954 | eventNamespace = '.' + namespace, |
||
8955 | moduleNamespace = 'module-' + namespace, |
||
8956 | |||
8957 | $module = $(this), |
||
8958 | $context = $(settings.context), |
||
8959 | $close = $module.find(selector.close), |
||
8960 | |||
8961 | $allModals, |
||
8962 | $otherModals, |
||
8963 | $focusedElement, |
||
8964 | $dimmable, |
||
8965 | $dimmer, |
||
8966 | |||
8967 | element = this, |
||
8968 | instance = $module.data(moduleNamespace), |
||
8969 | |||
8970 | ignoreRepeatedEvents = false, |
||
8971 | |||
8972 | elementEventNamespace, |
||
8973 | id, |
||
8974 | observer, |
||
8975 | module |
||
8976 | ; |
||
8977 | module = { |
||
8978 | |||
8979 | initialize: function() { |
||
8980 | module.verbose('Initializing dimmer', $context); |
||
8981 | |||
8982 | module.create.id(); |
||
8983 | module.create.dimmer(); |
||
8984 | module.refreshModals(); |
||
8985 | |||
8986 | module.bind.events(); |
||
8987 | if(settings.observeChanges) { |
||
8988 | module.observeChanges(); |
||
8989 | } |
||
8990 | module.instantiate(); |
||
8991 | }, |
||
8992 | |||
8993 | instantiate: function() { |
||
8994 | module.verbose('Storing instance of modal'); |
||
8995 | instance = module; |
||
8996 | $module |
||
8997 | .data(moduleNamespace, instance) |
||
8998 | ; |
||
8999 | }, |
||
9000 | |||
9001 | create: { |
||
9002 | dimmer: function() { |
||
9003 | var |
||
9004 | defaultSettings = { |
||
9005 | debug : settings.debug, |
||
9006 | dimmerName : 'modals' |
||
9007 | }, |
||
9008 | dimmerSettings = $.extend(true, defaultSettings, settings.dimmerSettings) |
||
9009 | ; |
||
9010 | if($.fn.dimmer === undefined) { |
||
9011 | module.error(error.dimmer); |
||
9012 | return; |
||
9013 | } |
||
9014 | module.debug('Creating dimmer'); |
||
9015 | $dimmable = $context.dimmer(dimmerSettings); |
||
9016 | if(settings.detachable) { |
||
9017 | module.verbose('Modal is detachable, moving content into dimmer'); |
||
9018 | $dimmable.dimmer('add content', $module); |
||
9019 | } |
||
9020 | else { |
||
9021 | module.set.undetached(); |
||
9022 | } |
||
9023 | $dimmer = $dimmable.dimmer('get dimmer'); |
||
9024 | }, |
||
9025 | id: function() { |
||
9026 | id = (Math.random().toString(16) + '000000000').substr(2,8); |
||
9027 | elementEventNamespace = '.' + id; |
||
9028 | module.verbose('Creating unique id for element', id); |
||
9029 | } |
||
9030 | }, |
||
9031 | |||
9032 | destroy: function() { |
||
9033 | module.verbose('Destroying previous modal'); |
||
9034 | $module |
||
9035 | .removeData(moduleNamespace) |
||
9036 | .off(eventNamespace) |
||
9037 | ; |
||
9038 | $window.off(elementEventNamespace); |
||
9039 | $dimmer.off(elementEventNamespace); |
||
9040 | $close.off(eventNamespace); |
||
9041 | $context.dimmer('destroy'); |
||
9042 | }, |
||
9043 | |||
9044 | observeChanges: function() { |
||
9045 | if('MutationObserver' in window) { |
||
9046 | observer = new MutationObserver(function(mutations) { |
||
9047 | module.debug('DOM tree modified, refreshing'); |
||
9048 | module.refresh(); |
||
9049 | }); |
||
9050 | observer.observe(element, { |
||
9051 | childList : true, |
||
9052 | subtree : true |
||
9053 | }); |
||
9054 | module.debug('Setting up mutation observer', observer); |
||
9055 | } |
||
9056 | }, |
||
9057 | |||
9058 | refresh: function() { |
||
9059 | module.remove.scrolling(); |
||
9060 | module.cacheSizes(); |
||
9061 | module.set.screenHeight(); |
||
9062 | module.set.type(); |
||
9063 | module.set.position(); |
||
9064 | }, |
||
9065 | |||
9066 | refreshModals: function() { |
||
9067 | $otherModals = $module.siblings(selector.modal); |
||
9068 | $allModals = $otherModals.add($module); |
||
9069 | }, |
||
9070 | |||
9071 | attachEvents: function(selector, event) { |
||
9072 | var |
||
9073 | $toggle = $(selector) |
||
9074 | ; |
||
9075 | event = $.isFunction(module[event]) |
||
9076 | ? module[event] |
||
9077 | : module.toggle |
||
9078 | ; |
||
9079 | if($toggle.length > 0) { |
||
9080 | module.debug('Attaching modal events to element', selector, event); |
||
9081 | $toggle |
||
9082 | .off(eventNamespace) |
||
9083 | .on('click' + eventNamespace, event) |
||
9084 | ; |
||
9085 | } |
||
9086 | else { |
||
9087 | module.error(error.notFound, selector); |
||
9088 | } |
||
9089 | }, |
||
9090 | |||
9091 | bind: { |
||
9092 | events: function() { |
||
9093 | module.verbose('Attaching events'); |
||
9094 | $module |
||
9095 | .on('click' + eventNamespace, selector.close, module.event.close) |
||
9096 | .on('click' + eventNamespace, selector.approve, module.event.approve) |
||
9097 | .on('click' + eventNamespace, selector.deny, module.event.deny) |
||
9098 | ; |
||
9099 | $window |
||
9100 | .on('resize' + elementEventNamespace, module.event.resize) |
||
9101 | ; |
||
9102 | } |
||
9103 | }, |
||
9104 | |||
9105 | get: { |
||
9106 | id: function() { |
||
9107 | return (Math.random().toString(16) + '000000000').substr(2,8); |
||
9108 | } |
||
9109 | }, |
||
9110 | |||
9111 | event: { |
||
9112 | approve: function() { |
||
9113 | if(ignoreRepeatedEvents || settings.onApprove.call(element, $(this)) === false) { |
||
9114 | module.verbose('Approve callback returned false cancelling hide'); |
||
9115 | return; |
||
9116 | } |
||
9117 | ignoreRepeatedEvents = true; |
||
9118 | module.hide(function() { |
||
9119 | ignoreRepeatedEvents = false; |
||
9120 | }); |
||
9121 | }, |
||
9122 | deny: function() { |
||
9123 | if(ignoreRepeatedEvents || settings.onDeny.call(element, $(this)) === false) { |
||
9124 | module.verbose('Deny callback returned false cancelling hide'); |
||
9125 | return; |
||
9126 | } |
||
9127 | ignoreRepeatedEvents = true; |
||
9128 | module.hide(function() { |
||
9129 | ignoreRepeatedEvents = false; |
||
9130 | }); |
||
9131 | }, |
||
9132 | close: function() { |
||
9133 | module.hide(); |
||
9134 | }, |
||
9135 | click: function(event) { |
||
9136 | var |
||
9137 | $target = $(event.target), |
||
9138 | isInModal = ($target.closest(selector.modal).length > 0), |
||
9139 | isInDOM = $.contains(document.documentElement, event.target) |
||
9140 | ; |
||
9141 | if(!isInModal && isInDOM) { |
||
9142 | module.debug('Dimmer clicked, hiding all modals'); |
||
9143 | if( module.is.active() ) { |
||
9144 | module.remove.clickaway(); |
||
9145 | if(settings.allowMultiple) { |
||
9146 | module.hide(); |
||
9147 | } |
||
9148 | else { |
||
9149 | module.hideAll(); |
||
9150 | } |
||
9151 | } |
||
9152 | } |
||
9153 | }, |
||
9154 | debounce: function(method, delay) { |
||
9155 | clearTimeout(module.timer); |
||
9156 | module.timer = setTimeout(method, delay); |
||
9157 | }, |
||
9158 | keyboard: function(event) { |
||
9159 | var |
||
9160 | keyCode = event.which, |
||
9161 | escapeKey = 27 |
||
9162 | ; |
||
9163 | if(keyCode == escapeKey) { |
||
9164 | if(settings.closable) { |
||
9165 | module.debug('Escape key pressed hiding modal'); |
||
9166 | module.hide(); |
||
9167 | } |
||
9168 | else { |
||
9169 | module.debug('Escape key pressed, but closable is set to false'); |
||
9170 | } |
||
9171 | event.preventDefault(); |
||
9172 | } |
||
9173 | }, |
||
9174 | resize: function() { |
||
9175 | if( $dimmable.dimmer('is active') && ( module.is.animating() || module.is.active() ) ) { |
||
9176 | requestAnimationFrame(module.refresh); |
||
9177 | } |
||
9178 | } |
||
9179 | }, |
||
9180 | |||
9181 | toggle: function() { |
||
9182 | if( module.is.active() || module.is.animating() ) { |
||
9183 | module.hide(); |
||
9184 | } |
||
9185 | else { |
||
9186 | module.show(); |
||
9187 | } |
||
9188 | }, |
||
9189 | |||
9190 | show: function(callback) { |
||
9191 | callback = $.isFunction(callback) |
||
9192 | ? callback |
||
9193 | : function(){} |
||
9194 | ; |
||
9195 | module.refreshModals(); |
||
9196 | module.set.dimmerSettings(); |
||
9197 | module.showModal(callback); |
||
9198 | }, |
||
9199 | |||
9200 | hide: function(callback) { |
||
9201 | callback = $.isFunction(callback) |
||
9202 | ? callback |
||
9203 | : function(){} |
||
9204 | ; |
||
9205 | module.refreshModals(); |
||
9206 | module.hideModal(callback); |
||
9207 | }, |
||
9208 | |||
9209 | showModal: function(callback) { |
||
9210 | callback = $.isFunction(callback) |
||
9211 | ? callback |
||
9212 | : function(){} |
||
9213 | ; |
||
9214 | if( module.is.animating() || !module.is.active() ) { |
||
9215 | |||
9216 | module.showDimmer(); |
||
9217 | module.cacheSizes(); |
||
9218 | module.set.position(); |
||
9219 | module.set.screenHeight(); |
||
9220 | module.set.type(); |
||
9221 | module.set.clickaway(); |
||
9222 | |||
9223 | if( !settings.allowMultiple && module.others.active() ) { |
||
9224 | module.hideOthers(module.showModal); |
||
9225 | } |
||
9226 | else { |
||
9227 | settings.onShow.call(element); |
||
9228 | if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) { |
||
9229 | module.debug('Showing modal with css animations'); |
||
9230 | $module |
||
9231 | .transition({ |
||
9232 | debug : settings.debug, |
||
9233 | animation : settings.transition + ' in', |
||
9234 | queue : settings.queue, |
||
9235 | duration : settings.duration, |
||
9236 | useFailSafe : true, |
||
9237 | onComplete : function() { |
||
9238 | settings.onVisible.apply(element); |
||
9239 | if(settings.keyboardShortcuts) { |
||
9240 | module.add.keyboardShortcuts(); |
||
9241 | } |
||
9242 | module.save.focus(); |
||
9243 | module.set.active(); |
||
9244 | if(settings.autofocus) { |
||
9245 | module.set.autofocus(); |
||
9246 | } |
||
9247 | callback(); |
||
9248 | } |
||
9249 | }) |
||
9250 | ; |
||
9251 | } |
||
9252 | else { |
||
9253 | module.error(error.noTransition); |
||
9254 | } |
||
9255 | } |
||
9256 | } |
||
9257 | else { |
||
9258 | module.debug('Modal is already visible'); |
||
9259 | } |
||
9260 | }, |
||
9261 | |||
9262 | hideModal: function(callback, keepDimmed) { |
||
9263 | callback = $.isFunction(callback) |
||
9264 | ? callback |
||
9265 | : function(){} |
||
9266 | ; |
||
9267 | module.debug('Hiding modal'); |
||
9268 | if(settings.onHide.call(element, $(this)) === false) { |
||
9269 | module.verbose('Hide callback returned false cancelling hide'); |
||
9270 | return; |
||
9271 | } |
||
9272 | |||
9273 | if( module.is.animating() || module.is.active() ) { |
||
9274 | if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) { |
||
9275 | module.remove.active(); |
||
9276 | $module |
||
9277 | .transition({ |
||
9278 | debug : settings.debug, |
||
9279 | animation : settings.transition + ' out', |
||
9280 | queue : settings.queue, |
||
9281 | duration : settings.duration, |
||
9282 | useFailSafe : true, |
||
9283 | onStart : function() { |
||
9284 | if(!module.others.active() && !keepDimmed) { |
||
9285 | module.hideDimmer(); |
||
9286 | } |
||
9287 | if(settings.keyboardShortcuts) { |
||
9288 | module.remove.keyboardShortcuts(); |
||
9289 | } |
||
9290 | }, |
||
9291 | onComplete : function() { |
||
9292 | settings.onHidden.call(element); |
||
9293 | module.restore.focus(); |
||
9294 | callback(); |
||
9295 | } |
||
9296 | }) |
||
9297 | ; |
||
9298 | } |
||
9299 | else { |
||
9300 | module.error(error.noTransition); |
||
9301 | } |
||
9302 | } |
||
9303 | }, |
||
9304 | |||
9305 | showDimmer: function() { |
||
9306 | if($dimmable.dimmer('is animating') || !$dimmable.dimmer('is active') ) { |
||
9307 | module.debug('Showing dimmer'); |
||
9308 | $dimmable.dimmer('show'); |
||
9309 | } |
||
9310 | else { |
||
9311 | module.debug('Dimmer already visible'); |
||
9312 | } |
||
9313 | }, |
||
9314 | |||
9315 | hideDimmer: function() { |
||
9316 | if( $dimmable.dimmer('is animating') || ($dimmable.dimmer('is active')) ) { |
||
9317 | $dimmable.dimmer('hide', function() { |
||
9318 | module.remove.clickaway(); |
||
9319 | module.remove.screenHeight(); |
||
9320 | }); |
||
9321 | } |
||
9322 | else { |
||
9323 | module.debug('Dimmer is not visible cannot hide'); |
||
9324 | return; |
||
9325 | } |
||
9326 | }, |
||
9327 | |||
9328 | hideAll: function(callback) { |
||
9329 | var |
||
9330 | $visibleModals = $allModals.filter('.' + className.active + ', .' + className.animating) |
||
9331 | ; |
||
9332 | callback = $.isFunction(callback) |
||
9333 | ? callback |
||
9334 | : function(){} |
||
9335 | ; |
||
9336 | if( $visibleModals.length > 0 ) { |
||
9337 | module.debug('Hiding all visible modals'); |
||
9338 | module.hideDimmer(); |
||
9339 | $visibleModals |
||
9340 | .modal('hide modal', callback) |
||
9341 | ; |
||
9342 | } |
||
9343 | }, |
||
9344 | |||
9345 | hideOthers: function(callback) { |
||
9346 | var |
||
9347 | $visibleModals = $otherModals.filter('.' + className.active + ', .' + className.animating) |
||
9348 | ; |
||
9349 | callback = $.isFunction(callback) |
||
9350 | ? callback |
||
9351 | : function(){} |
||
9352 | ; |
||
9353 | if( $visibleModals.length > 0 ) { |
||
9354 | module.debug('Hiding other modals', $otherModals); |
||
9355 | $visibleModals |
||
9356 | .modal('hide modal', callback, true) |
||
9357 | ; |
||
9358 | } |
||
9359 | }, |
||
9360 | |||
9361 | others: { |
||
9362 | active: function() { |
||
9363 | return ($otherModals.filter('.' + className.active).length > 0); |
||
9364 | }, |
||
9365 | animating: function() { |
||
9366 | return ($otherModals.filter('.' + className.animating).length > 0); |
||
9367 | } |
||
9368 | }, |
||
9369 | |||
9370 | |||
9371 | add: { |
||
9372 | keyboardShortcuts: function() { |
||
9373 | module.verbose('Adding keyboard shortcuts'); |
||
9374 | $document |
||
9375 | .on('keyup' + eventNamespace, module.event.keyboard) |
||
9376 | ; |
||
9377 | } |
||
9378 | }, |
||
9379 | |||
9380 | save: { |
||
9381 | focus: function() { |
||
9382 | $focusedElement = $(document.activeElement).blur(); |
||
9383 | } |
||
9384 | }, |
||
9385 | |||
9386 | restore: { |
||
9387 | focus: function() { |
||
9388 | if($focusedElement && $focusedElement.length > 0) { |
||
9389 | $focusedElement.focus(); |
||
9390 | } |
||
9391 | } |
||
9392 | }, |
||
9393 | |||
9394 | remove: { |
||
9395 | active: function() { |
||
9396 | $module.removeClass(className.active); |
||
9397 | }, |
||
9398 | clickaway: function() { |
||
9399 | if(settings.closable) { |
||
9400 | $dimmer |
||
9401 | .off('click' + elementEventNamespace) |
||
9402 | ; |
||
9403 | } |
||
9404 | }, |
||
9405 | bodyStyle: function() { |
||
9406 | if($body.attr('style') === '') { |
||
9407 | module.verbose('Removing style attribute'); |
||
9408 | $body.removeAttr('style'); |
||
9409 | } |
||
9410 | }, |
||
9411 | screenHeight: function() { |
||
9412 | module.debug('Removing page height'); |
||
9413 | $body |
||
9414 | .css('height', '') |
||
9415 | ; |
||
9416 | }, |
||
9417 | keyboardShortcuts: function() { |
||
9418 | module.verbose('Removing keyboard shortcuts'); |
||
9419 | $document |
||
9420 | .off('keyup' + eventNamespace) |
||
9421 | ; |
||
9422 | }, |
||
9423 | scrolling: function() { |
||
9424 | $dimmable.removeClass(className.scrolling); |
||
9425 | $module.removeClass(className.scrolling); |
||
9426 | } |
||
9427 | }, |
||
9428 | |||
9429 | cacheSizes: function() { |
||
9430 | var |
||
9431 | modalHeight = $module.outerHeight() |
||
9432 | ; |
||
9433 | if(module.cache === undefined || modalHeight !== 0) { |
||
9434 | module.cache = { |
||
9435 | pageHeight : $(document).outerHeight(), |
||
9436 | height : modalHeight + settings.offset, |
||
9437 | contextHeight : (settings.context == 'body') |
||
9438 | ? $(window).height() |
||
9439 | : $dimmable.height() |
||
9440 | }; |
||
9441 | } |
||
9442 | module.debug('Caching modal and container sizes', module.cache); |
||
9443 | }, |
||
9444 | |||
9445 | can: { |
||
9446 | fit: function() { |
||
9447 | return ( ( module.cache.height + (settings.padding * 2) ) < module.cache.contextHeight); |
||
9448 | } |
||
9449 | }, |
||
9450 | |||
9451 | is: { |
||
9452 | active: function() { |
||
9453 | return $module.hasClass(className.active); |
||
9454 | }, |
||
9455 | animating: function() { |
||
9456 | return $module.transition('is supported') |
||
9457 | ? $module.transition('is animating') |
||
9458 | : $module.is(':visible') |
||
9459 | ; |
||
9460 | }, |
||
9461 | scrolling: function() { |
||
9462 | return $dimmable.hasClass(className.scrolling); |
||
9463 | }, |
||
9464 | modernBrowser: function() { |
||
9465 | // appName for IE11 reports 'Netscape' can no longer use |
||
9466 | return !(window.ActiveXObject || "ActiveXObject" in window); |
||
9467 | } |
||
9468 | }, |
||
9469 | |||
9470 | set: { |
||
9471 | autofocus: function() { |
||
9472 | var |
||
9473 | $inputs = $module.find('[tabindex], :input').filter(':visible'), |
||
9474 | $autofocus = $inputs.filter('[autofocus]'), |
||
9475 | $input = ($autofocus.length > 0) |
||
9476 | ? $autofocus.first() |
||
9477 | : $inputs.first() |
||
9478 | ; |
||
9479 | if($input.length > 0) { |
||
9480 | $input.focus(); |
||
9481 | } |
||
9482 | }, |
||
9483 | clickaway: function() { |
||
9484 | if(settings.closable) { |
||
9485 | $dimmer |
||
9486 | .on('click' + elementEventNamespace, module.event.click) |
||
9487 | ; |
||
9488 | } |
||
9489 | }, |
||
9490 | dimmerSettings: function() { |
||
9491 | if($.fn.dimmer === undefined) { |
||
9492 | module.error(error.dimmer); |
||
9493 | return; |
||
9494 | } |
||
9495 | var |
||
9496 | defaultSettings = { |
||
9497 | debug : settings.debug, |
||
9498 | dimmerName : 'modals', |
||
9499 | variation : false, |
||
9500 | closable : 'auto', |
||
9501 | duration : { |
||
9502 | show : settings.duration, |
||
9503 | hide : settings.duration |
||
9504 | } |
||
9505 | }, |
||
9506 | dimmerSettings = $.extend(true, defaultSettings, settings.dimmerSettings) |
||
9507 | ; |
||
9508 | if(settings.inverted) { |
||
9509 | dimmerSettings.variation = (dimmerSettings.variation !== undefined) |
||
9510 | ? dimmerSettings.variation + ' inverted' |
||
9511 | : 'inverted' |
||
9512 | ; |
||
9513 | $dimmer.addClass(className.inverted); |
||
9514 | } |
||
9515 | else { |
||
9516 | $dimmer.removeClass(className.inverted); |
||
9517 | } |
||
9518 | if(settings.blurring) { |
||
9519 | $dimmable.addClass(className.blurring); |
||
9520 | } |
||
9521 | else { |
||
9522 | $dimmable.removeClass(className.blurring); |
||
9523 | } |
||
9524 | $context.dimmer('setting', dimmerSettings); |
||
9525 | }, |
||
9526 | screenHeight: function() { |
||
9527 | if( module.can.fit() ) { |
||
9528 | $body.css('height', ''); |
||
9529 | } |
||
9530 | else { |
||
9531 | module.debug('Modal is taller than page content, resizing page height'); |
||
9532 | $body |
||
9533 | .css('height', module.cache.height + (settings.padding * 2) ) |
||
9534 | ; |
||
9535 | } |
||
9536 | }, |
||
9537 | active: function() { |
||
9538 | $module.addClass(className.active); |
||
9539 | }, |
||
9540 | scrolling: function() { |
||
9541 | $dimmable.addClass(className.scrolling); |
||
9542 | $module.addClass(className.scrolling); |
||
9543 | }, |
||
9544 | type: function() { |
||
9545 | if(module.can.fit()) { |
||
9546 | module.verbose('Modal fits on screen'); |
||
9547 | if(!module.others.active() && !module.others.animating()) { |
||
9548 | module.remove.scrolling(); |
||
9549 | } |
||
9550 | } |
||
9551 | else { |
||
9552 | module.verbose('Modal cannot fit on screen setting to scrolling'); |
||
9553 | module.set.scrolling(); |
||
9554 | } |
||
9555 | }, |
||
9556 | position: function() { |
||
9557 | module.verbose('Centering modal on page', module.cache); |
||
9558 | if(module.can.fit()) { |
||
9559 | $module |
||
9560 | .css({ |
||
9561 | top: '', |
||
9562 | marginTop: -(module.cache.height / 2) |
||
9563 | }) |
||
9564 | ; |
||
9565 | } |
||
9566 | else { |
||
9567 | $module |
||
9568 | .css({ |
||
9569 | marginTop : '', |
||
9570 | top : $document.scrollTop() |
||
9571 | }) |
||
9572 | ; |
||
9573 | } |
||
9574 | }, |
||
9575 | undetached: function() { |
||
9576 | $dimmable.addClass(className.undetached); |
||
9577 | } |
||
9578 | }, |
||
9579 | |||
9580 | setting: function(name, value) { |
||
9581 | module.debug('Changing setting', name, value); |
||
9582 | if( $.isPlainObject(name) ) { |
||
9583 | $.extend(true, settings, name); |
||
9584 | } |
||
9585 | else if(value !== undefined) { |
||
9586 | if($.isPlainObject(settings[name])) { |
||
9587 | $.extend(true, settings[name], value); |
||
9588 | } |
||
9589 | else { |
||
9590 | settings[name] = value; |
||
9591 | } |
||
9592 | } |
||
9593 | else { |
||
9594 | return settings[name]; |
||
9595 | } |
||
9596 | }, |
||
9597 | internal: function(name, value) { |
||
9598 | if( $.isPlainObject(name) ) { |
||
9599 | $.extend(true, module, name); |
||
9600 | } |
||
9601 | else if(value !== undefined) { |
||
9602 | module[name] = value; |
||
9603 | } |
||
9604 | else { |
||
9605 | return module[name]; |
||
9606 | } |
||
9607 | }, |
||
9608 | debug: function() { |
||
9609 | if(!settings.silent && settings.debug) { |
||
9610 | if(settings.performance) { |
||
9611 | module.performance.log(arguments); |
||
9612 | } |
||
9613 | else { |
||
9614 | module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':'); |
||
9615 | module.debug.apply(console, arguments); |
||
9616 | } |
||
9617 | } |
||
9618 | }, |
||
9619 | verbose: function() { |
||
9620 | if(!settings.silent && settings.verbose && settings.debug) { |
||
9621 | if(settings.performance) { |
||
9622 | module.performance.log(arguments); |
||
9623 | } |
||
9624 | else { |
||
9625 | module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':'); |
||
9626 | module.verbose.apply(console, arguments); |
||
9627 | } |
||
9628 | } |
||
9629 | }, |
||
9630 | error: function() { |
||
9631 | if(!settings.silent) { |
||
9632 | module.error = Function.prototype.bind.call(console.error, console, settings.name + ':'); |
||
9633 | module.error.apply(console, arguments); |
||
9634 | } |
||
9635 | }, |
||
9636 | performance: { |
||
9637 | log: function(message) { |
||
9638 | var |
||
9639 | currentTime, |
||
9640 | executionTime, |
||
9641 | previousTime |
||
9642 | ; |
||
9643 | if(settings.performance) { |
||
9644 | currentTime = new Date().getTime(); |
||
9645 | previousTime = time || currentTime; |
||
9646 | executionTime = currentTime - previousTime; |
||
9647 | time = currentTime; |
||
9648 | performance.push({ |
||
9649 | 'Name' : message[0], |
||
9650 | 'Arguments' : [].slice.call(message, 1) || '', |
||
9651 | 'Element' : element, |
||
9652 | 'Execution Time' : executionTime |
||
9653 | }); |
||
9654 | } |
||
9655 | clearTimeout(module.performance.timer); |
||
9656 | module.performance.timer = setTimeout(module.performance.display, 500); |
||
9657 | }, |
||
9658 | display: function() { |
||
9659 | var |
||
9660 | title = settings.name + ':', |
||
9661 | totalTime = 0 |
||
9662 | ; |
||
9663 | time = false; |
||
9664 | clearTimeout(module.performance.timer); |
||
9665 | $.each(performance, function(index, data) { |
||
9666 | totalTime += data['Execution Time']; |
||
9667 | }); |
||
9668 | title += ' ' + totalTime + 'ms'; |
||
9669 | if(moduleSelector) { |
||
9670 | title += ' \'' + moduleSelector + '\''; |
||
9671 | } |
||
9672 | if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) { |
||
9673 | console.groupCollapsed(title); |
||
9674 | if(console.table) { |
||
9675 | console.table(performance); |
||
9676 | } |
||
9677 | else { |
||
9678 | $.each(performance, function(index, data) { |
||
9679 | console.log(data['Name'] + ': ' + data['Execution Time']+'ms'); |
||
9680 | }); |
||
9681 | } |
||
9682 | console.groupEnd(); |
||
9683 | } |
||
9684 | performance = []; |
||
9685 | } |
||
9686 | }, |
||
9687 | invoke: function(query, passedArguments, context) { |
||
9688 | var |
||
9689 | object = instance, |
||
9690 | maxDepth, |
||
9691 | found, |
||
9692 | response |
||
9693 | ; |
||
9694 | passedArguments = passedArguments || queryArguments; |
||
9695 | context = element || context; |
||
9696 | if(typeof query == 'string' && object !== undefined) { |
||
9697 | query = query.split(/[\. ]/); |
||
9698 | maxDepth = query.length - 1; |
||
9699 | $.each(query, function(depth, value) { |
||
9700 | var camelCaseValue = (depth != maxDepth) |
||
9701 | ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1) |
||
9702 | : query |
||
9703 | ; |
||
9704 | if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) { |
||
9705 | object = object[camelCaseValue]; |
||
9706 | } |
||
9707 | else if( object[camelCaseValue] !== undefined ) { |
||
9708 | found = object[camelCaseValue]; |
||
9709 | return false; |
||
9710 | } |
||
9711 | else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) { |
||
9712 | object = object[value]; |
||
9713 | } |
||
9714 | else if( object[value] !== undefined ) { |
||
9715 | found = object[value]; |
||
9716 | return false; |
||
9717 | } |
||
9718 | else { |
||
9719 | return false; |
||
9720 | } |
||
9721 | }); |
||
9722 | } |
||
9723 | if ( $.isFunction( found ) ) { |
||
9724 | response = found.apply(context, passedArguments); |
||
9725 | } |
||
9726 | else if(found !== undefined) { |
||
9727 | response = found; |
||
9728 | } |
||
9729 | if($.isArray(returnedValue)) { |
||
9730 | returnedValue.push(response); |
||
9731 | } |
||
9732 | else if(returnedValue !== undefined) { |
||
9733 | returnedValue = [returnedValue, response]; |
||
9734 | } |
||
9735 | else if(response !== undefined) { |
||
9736 | returnedValue = response; |
||
9737 | } |
||
9738 | return found; |
||
9739 | } |
||
9740 | }; |
||
9741 | |||
9742 | if(methodInvoked) { |
||
9743 | if(instance === undefined) { |
||
9744 | module.initialize(); |
||
9745 | } |
||
9746 | module.invoke(query); |
||
9747 | } |
||
9748 | else { |
||
9749 | if(instance !== undefined) { |
||
9750 | instance.invoke('destroy'); |
||
9751 | } |
||
9752 | module.initialize(); |
||
9753 | } |
||
9754 | }) |
||
9755 | ; |
||
9756 | |||
9757 | return (returnedValue !== undefined) |
||
9758 | ? returnedValue |
||
9759 | : this |
||
9760 | ; |
||
9761 | }; |
||
9762 | |||
9763 | $.fn.modal.settings = { |
||
9764 | |||
9765 | name : 'Modal', |
||
9766 | namespace : 'modal', |
||
9767 | |||
9768 | silent : false, |
||
9769 | debug : false, |
||
9770 | verbose : false, |
||
9771 | performance : true, |
||
9772 | |||
9773 | observeChanges : false, |
||
9774 | |||
9775 | allowMultiple : false, |
||
9776 | detachable : true, |
||
9777 | closable : true, |
||
9778 | autofocus : true, |
||
9779 | |||
9780 | inverted : false, |
||
9781 | blurring : false, |
||
9782 | |||
9783 | dimmerSettings : { |
||
9784 | closable : false, |
||
9785 | useCSS : true |
||
9786 | }, |
||
9787 | |||
9788 | // whether to use keyboard shortcuts |
||
9789 | keyboardShortcuts: true, |
||
9790 | |||
9791 | context : 'body', |
||
9792 | |||
9793 | queue : false, |
||
9794 | duration : 500, |
||
9795 | offset : 0, |
||
9796 | transition : 'scale', |
||
9797 | |||
9798 | // padding with edge of page |
||
9799 | padding : 50, |
||
9800 | |||
9801 | // called before show animation |
||
9802 | onShow : function(){}, |
||
9803 | |||
9804 | // called after show animation |
||
9805 | onVisible : function(){}, |
||
9806 | |||
9807 | // called before hide animation |
||
9808 | onHide : function(){ return true; }, |
||
9809 | |||
9810 | // called after hide animation |
||
9811 | onHidden : function(){}, |
||
9812 | |||
9813 | // called after approve selector match |
||
9814 | onApprove : function(){ return true; }, |
||
9815 | |||
9816 | // called after deny selector match |
||
9817 | onDeny : function(){ return true; }, |
||
9818 | |||
9819 | selector : { |
||
9820 | close : '> .close', |
||
9821 | approve : '.actions .positive, .actions .approve, .actions .ok', |
||
9822 | deny : '.actions .negative, .actions .deny, .actions .cancel', |
||
9823 | modal : '.ui.modal' |
||
9824 | }, |
||
9825 | error : { |
||
9826 | dimmer : 'UI Dimmer, a required component is not included in this page', |
||
9827 | method : 'The method you called is not defined.', |
||
9828 | notFound : 'The element you specified could not be found' |
||
9829 | }, |
||
9830 | className : { |
||
9831 | active : 'active', |
||
9832 | animating : 'animating', |
||
9833 | blurring : 'blurring', |
||
9834 | inverted : 'inverted', |
||
9835 | scrolling : 'scrolling', |
||
9836 | undetached : 'undetached' |
||
9837 | } |
||
9838 | }; |
||
9839 | |||
9840 | |||
9841 | })( jQuery, window, document ); |
||
9842 | |||
9843 | /*! |
||
9844 | * # Semantic UI 2.2.11 - Nag |
||
9845 | * http://github.com/semantic-org/semantic-ui/ |
||
9846 | * |
||
9847 | * |
||
9848 | * Released under the MIT license |
||
9849 | * http://opensource.org/licenses/MIT |
||
9850 | * |
||
9851 | */ |
||
9852 | |||
9853 | View Code Duplication | ;(function ($, window, document, undefined) { |
|
9854 | |||
9855 | "use strict"; |
||
9856 | |||
9857 | window = (typeof window != 'undefined' && window.Math == Math) |
||
9858 | ? window |
||
9859 | : (typeof self != 'undefined' && self.Math == Math) |
||
9860 | ? self |
||
9861 | : Function('return this')() |
||
9862 | ; |
||
9863 | |||
9864 | $.fn.nag = function(parameters) { |
||
9865 | var |
||
9866 | $allModules = $(this), |
||
9867 | moduleSelector = $allModules.selector || '', |
||
9868 | |||
9869 | time = new Date().getTime(), |
||
9870 | performance = [], |
||
9871 | |||
9872 | query = arguments[0], |
||
9873 | methodInvoked = (typeof query == 'string'), |
||
9874 | queryArguments = [].slice.call(arguments, 1), |
||
9875 | returnedValue |
||
9876 | ; |
||
9877 | $allModules |
||
9878 | .each(function() { |
||
9879 | var |
||
9880 | settings = ( $.isPlainObject(parameters) ) |
||
9881 | ? $.extend(true, {}, $.fn.nag.settings, parameters) |
||
9882 | : $.extend({}, $.fn.nag.settings), |
||
9883 | |||
9884 | className = settings.className, |
||
9885 | selector = settings.selector, |
||
9886 | error = settings.error, |
||
9887 | namespace = settings.namespace, |
||
9888 | |||
9889 | eventNamespace = '.' + namespace, |
||
9890 | moduleNamespace = namespace + '-module', |
||
9891 | |||
9892 | $module = $(this), |
||
9893 | |||
9894 | $close = $module.find(selector.close), |
||
9895 | $context = (settings.context) |
||
9896 | ? $(settings.context) |
||
9897 | : $('body'), |
||
9898 | |||
9899 | element = this, |
||
9900 | instance = $module.data(moduleNamespace), |
||
9901 | |||
9902 | moduleOffset, |
||
9903 | moduleHeight, |
||
9904 | |||
9905 | contextWidth, |
||
9906 | contextHeight, |
||
9907 | contextOffset, |
||
9908 | |||
9909 | yOffset, |
||
9910 | yPosition, |
||
9911 | |||
9912 | timer, |
||
9913 | module, |
||
9914 | |||
9915 | requestAnimationFrame = window.requestAnimationFrame |
||
9916 | || window.mozRequestAnimationFrame |
||
9917 | || window.webkitRequestAnimationFrame |
||
9918 | || window.msRequestAnimationFrame |
||
9919 | || function(callback) { setTimeout(callback, 0); } |
||
9920 | ; |
||
9921 | module = { |
||
9922 | |||
9923 | initialize: function() { |
||
9924 | module.verbose('Initializing element'); |
||
9925 | |||
9926 | $module |
||
9927 | .on('click' + eventNamespace, selector.close, module.dismiss) |
||
9928 | .data(moduleNamespace, module) |
||
9929 | ; |
||
9930 | |||
9931 | if(settings.detachable && $module.parent()[0] !== $context[0]) { |
||
9932 | $module |
||
9933 | .detach() |
||
9934 | .prependTo($context) |
||
9935 | ; |
||
9936 | } |
||
9937 | |||
9938 | if(settings.displayTime > 0) { |
||
9939 | setTimeout(module.hide, settings.displayTime); |
||
9940 | } |
||
9941 | module.show(); |
||
9942 | }, |
||
9943 | |||
9944 | destroy: function() { |
||
9945 | module.verbose('Destroying instance'); |
||
9946 | $module |
||
9947 | .removeData(moduleNamespace) |
||
9948 | .off(eventNamespace) |
||
9949 | ; |
||
9950 | }, |
||
9951 | |||
9952 | show: function() { |
||
9953 | if( module.should.show() && !$module.is(':visible') ) { |
||
9954 | module.debug('Showing nag', settings.animation.show); |
||
9955 | if(settings.animation.show == 'fade') { |
||
9956 | $module |
||
9957 | .fadeIn(settings.duration, settings.easing) |
||
9958 | ; |
||
9959 | } |
||
9960 | else { |
||
9961 | $module |
||
9962 | .slideDown(settings.duration, settings.easing) |
||
9963 | ; |
||
9964 | } |
||
9965 | } |
||
9966 | }, |
||
9967 | |||
9968 | hide: function() { |
||
9969 | module.debug('Showing nag', settings.animation.hide); |
||
9970 | if(settings.animation.show == 'fade') { |
||
9971 | $module |
||
9972 | .fadeIn(settings.duration, settings.easing) |
||
9973 | ; |
||
9974 | } |
||
9975 | else { |
||
9976 | $module |
||
9977 | .slideUp(settings.duration, settings.easing) |
||
9978 | ; |
||
9979 | } |
||
9980 | }, |
||
9981 | |||
9982 | onHide: function() { |
||
9983 | module.debug('Removing nag', settings.animation.hide); |
||
9984 | $module.remove(); |
||
9985 | if (settings.onHide) { |
||
9986 | settings.onHide(); |
||
9987 | } |
||
9988 | }, |
||
9989 | |||
9990 | dismiss: function(event) { |
||
9991 | if(settings.storageMethod) { |
||
9992 | module.storage.set(settings.key, settings.value); |
||
9993 | } |
||
9994 | module.hide(); |
||
9995 | event.stopImmediatePropagation(); |
||
9996 | event.preventDefault(); |
||
9997 | }, |
||
9998 | |||
9999 | should: { |
||
10000 | show: function() { |
||
10001 | if(settings.persist) { |
||
10002 | module.debug('Persistent nag is set, can show nag'); |
||
10003 | return true; |
||
10004 | } |
||
10005 | if( module.storage.get(settings.key) != settings.value.toString() ) { |
||
10006 | module.debug('Stored value is not set, can show nag', module.storage.get(settings.key)); |
||
10007 | return true; |
||
10008 | } |
||
10009 | module.debug('Stored value is set, cannot show nag', module.storage.get(settings.key)); |
||
10010 | return false; |
||
10011 | } |
||
10012 | }, |
||
10013 | |||
10014 | get: { |
||
10015 | storageOptions: function() { |
||
10016 | var |
||
10017 | options = {} |
||
10018 | ; |
||
10019 | if(settings.expires) { |
||
10020 | options.expires = settings.expires; |
||
10021 | } |
||
10022 | if(settings.domain) { |
||
10023 | options.domain = settings.domain; |
||
10024 | } |
||
10025 | if(settings.path) { |
||
10026 | options.path = settings.path; |
||
10027 | } |
||
10028 | return options; |
||
10029 | } |
||
10030 | }, |
||
10031 | |||
10032 | clear: function() { |
||
10033 | module.storage.remove(settings.key); |
||
10034 | }, |
||
10035 | |||
10036 | storage: { |
||
10037 | set: function(key, value) { |
||
10038 | var |
||
10039 | options = module.get.storageOptions() |
||
10040 | ; |
||
10041 | if(settings.storageMethod == 'localstorage' && window.localStorage !== undefined) { |
||
10042 | window.localStorage.setItem(key, value); |
||
10043 | module.debug('Value stored using local storage', key, value); |
||
10044 | } |
||
10045 | else if(settings.storageMethod == 'sessionstorage' && window.sessionStorage !== undefined) { |
||
10046 | window.sessionStorage.setItem(key, value); |
||
10047 | module.debug('Value stored using session storage', key, value); |
||
10048 | } |
||
10049 | else if($.cookie !== undefined) { |
||
10050 | $.cookie(key, value, options); |
||
10051 | module.debug('Value stored using cookie', key, value, options); |
||
10052 | } |
||
10053 | else { |
||
10054 | module.error(error.noCookieStorage); |
||
10055 | return; |
||
10056 | } |
||
10057 | }, |
||
10058 | get: function(key, value) { |
||
10059 | var |
||
10060 | storedValue |
||
10061 | ; |
||
10062 | if(settings.storageMethod == 'localstorage' && window.localStorage !== undefined) { |
||
10063 | storedValue = window.localStorage.getItem(key); |
||
10064 | } |
||
10065 | else if(settings.storageMethod == 'sessionstorage' && window.sessionStorage !== undefined) { |
||
10066 | storedValue = window.sessionStorage.getItem(key); |
||
10067 | } |
||
10068 | // get by cookie |
||
10069 | else if($.cookie !== undefined) { |
||
10070 | storedValue = $.cookie(key); |
||
10071 | } |
||
10072 | else { |
||
10073 | module.error(error.noCookieStorage); |
||
10074 | } |
||
10075 | if(storedValue == 'undefined' || storedValue == 'null' || storedValue === undefined || storedValue === null) { |
||
10076 | storedValue = undefined; |
||
10077 | } |
||
10078 | return storedValue; |
||
10079 | }, |
||
10080 | remove: function(key) { |
||
10081 | var |
||
10082 | options = module.get.storageOptions() |
||
10083 | ; |
||
10084 | if(settings.storageMethod == 'localstorage' && window.localStorage !== undefined) { |
||
10085 | window.localStorage.removeItem(key); |
||
10086 | } |
||
10087 | else if(settings.storageMethod == 'sessionstorage' && window.sessionStorage !== undefined) { |
||
10088 | window.sessionStorage.removeItem(key); |
||
10089 | } |
||
10090 | // store by cookie |
||
10091 | else if($.cookie !== undefined) { |
||
10092 | $.removeCookie(key, options); |
||
10093 | } |
||
10094 | else { |
||
10095 | module.error(error.noStorage); |
||
10096 | } |
||
10097 | } |
||
10098 | }, |
||
10099 | |||
10100 | setting: function(name, value) { |
||
10101 | module.debug('Changing setting', name, value); |
||
10102 | if( $.isPlainObject(name) ) { |
||
10103 | $.extend(true, settings, name); |
||
10104 | } |
||
10105 | else if(value !== undefined) { |
||
10106 | if($.isPlainObject(settings[name])) { |
||
10107 | $.extend(true, settings[name], value); |
||
10108 | } |
||
10109 | else { |
||
10110 | settings[name] = value; |
||
10111 | } |
||
10112 | } |
||
10113 | else { |
||
10114 | return settings[name]; |
||
10115 | } |
||
10116 | }, |
||
10117 | internal: function(name, value) { |
||
10118 | if( $.isPlainObject(name) ) { |
||
10119 | $.extend(true, module, name); |
||
10120 | } |
||
10121 | else if(value !== undefined) { |
||
10122 | module[name] = value; |
||
10123 | } |
||
10124 | else { |
||
10125 | return module[name]; |
||
10126 | } |
||
10127 | }, |
||
10128 | debug: function() { |
||
10129 | if(!settings.silent && settings.debug) { |
||
10130 | if(settings.performance) { |
||
10131 | module.performance.log(arguments); |
||
10132 | } |
||
10133 | else { |
||
10134 | module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':'); |
||
10135 | module.debug.apply(console, arguments); |
||
10136 | } |
||
10137 | } |
||
10138 | }, |
||
10139 | verbose: function() { |
||
10140 | if(!settings.silent && settings.verbose && settings.debug) { |
||
10141 | if(settings.performance) { |
||
10142 | module.performance.log(arguments); |
||
10143 | } |
||
10144 | else { |
||
10145 | module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':'); |
||
10146 | module.verbose.apply(console, arguments); |
||
10147 | } |
||
10148 | } |
||
10149 | }, |
||
10150 | error: function() { |
||
10151 | if(!settings.silent) { |
||
10152 | module.error = Function.prototype.bind.call(console.error, console, settings.name + ':'); |
||
10153 | module.error.apply(console, arguments); |
||
10154 | } |
||
10155 | }, |
||
10156 | performance: { |
||
10157 | log: function(message) { |
||
10158 | var |
||
10159 | currentTime, |
||
10160 | executionTime, |
||
10161 | previousTime |
||
10162 | ; |
||
10163 | if(settings.performance) { |
||
10164 | currentTime = new Date().getTime(); |
||
10165 | previousTime = time || currentTime; |
||
10166 | executionTime = currentTime - previousTime; |
||
10167 | time = currentTime; |
||
10168 | performance.push({ |
||
10169 | 'Name' : message[0], |
||
10170 | 'Arguments' : [].slice.call(message, 1) || '', |
||
10171 | 'Element' : element, |
||
10172 | 'Execution Time' : executionTime |
||
10173 | }); |
||
10174 | } |
||
10175 | clearTimeout(module.performance.timer); |
||
10176 | module.performance.timer = setTimeout(module.performance.display, 500); |
||
10177 | }, |
||
10178 | display: function() { |
||
10179 | var |
||
10180 | title = settings.name + ':', |
||
10181 | totalTime = 0 |
||
10182 | ; |
||
10183 | time = false; |
||
10184 | clearTimeout(module.performance.timer); |
||
10185 | $.each(performance, function(index, data) { |
||
10186 | totalTime += data['Execution Time']; |
||
10187 | }); |
||
10188 | title += ' ' + totalTime + 'ms'; |
||
10189 | if(moduleSelector) { |
||
10190 | title += ' \'' + moduleSelector + '\''; |
||
10191 | } |
||
10192 | if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) { |
||
10193 | console.groupCollapsed(title); |
||
10194 | if(console.table) { |
||
10195 | console.table(performance); |
||
10196 | } |
||
10197 | else { |
||
10198 | $.each(performance, function(index, data) { |
||
10199 | console.log(data['Name'] + ': ' + data['Execution Time']+'ms'); |
||
10200 | }); |
||
10201 | } |
||
10202 | console.groupEnd(); |
||
10203 | } |
||
10204 | performance = []; |
||
10205 | } |
||
10206 | }, |
||
10207 | invoke: function(query, passedArguments, context) { |
||
10208 | var |
||
10209 | object = instance, |
||
10210 | maxDepth, |
||
10211 | found, |
||
10212 | response |
||
10213 | ; |
||
10214 | passedArguments = passedArguments || queryArguments; |
||
10215 | context = element || context; |
||
10216 | if(typeof query == 'string' && object !== undefined) { |
||
10217 | query = query.split(/[\. ]/); |
||
10218 | maxDepth = query.length - 1; |
||
10219 | $.each(query, function(depth, value) { |
||
10220 | var camelCaseValue = (depth != maxDepth) |
||
10221 | ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1) |
||
10222 | : query |
||
10223 | ; |
||
10224 | if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) { |
||
10225 | object = object[camelCaseValue]; |
||
10226 | } |
||
10227 | else if( object[camelCaseValue] !== undefined ) { |
||
10228 | found = object[camelCaseValue]; |
||
10229 | return false; |
||
10230 | } |
||
10231 | else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) { |
||
10232 | object = object[value]; |
||
10233 | } |
||
10234 | else if( object[value] !== undefined ) { |
||
10235 | found = object[value]; |
||
10236 | return false; |
||
10237 | } |
||
10238 | else { |
||
10239 | module.error(error.method, query); |
||
10240 | return false; |
||
10241 | } |
||
10242 | }); |
||
10243 | } |
||
10244 | if ( $.isFunction( found ) ) { |
||
10245 | response = found.apply(context, passedArguments); |
||
10246 | } |
||
10247 | else if(found !== undefined) { |
||
10248 | response = found; |
||
10249 | } |
||
10250 | if($.isArray(returnedValue)) { |
||
10251 | returnedValue.push(response); |
||
10252 | } |
||
10253 | else if(returnedValue !== undefined) { |
||
10254 | returnedValue = [returnedValue, response]; |
||
10255 | } |
||
10256 | else if(response !== undefined) { |
||
10257 | returnedValue = response; |
||
10258 | } |
||
10259 | return found; |
||
10260 | } |
||
10261 | }; |
||
10262 | |||
10263 | if(methodInvoked) { |
||
10264 | if(instance === undefined) { |
||
10265 | module.initialize(); |
||
10266 | } |
||
10267 | module.invoke(query); |
||
10268 | } |
||
10269 | else { |
||
10270 | if(instance !== undefined) { |
||
10271 | instance.invoke('destroy'); |
||
10272 | } |
||
10273 | module.initialize(); |
||
10274 | } |
||
10275 | }) |
||
10276 | ; |
||
10277 | |||
10278 | return (returnedValue !== undefined) |
||
10279 | ? returnedValue |
||
10280 | : this |
||
10281 | ; |
||
10282 | }; |
||
10283 | |||
10284 | $.fn.nag.settings = { |
||
10285 | |||
10286 | name : 'Nag', |
||
10287 | |||
10288 | silent : false, |
||
10289 | debug : false, |
||
10290 | verbose : false, |
||
10291 | performance : true, |
||
10292 | |||
10293 | namespace : 'Nag', |
||
10294 | |||
10295 | // allows cookie to be overridden |
||
10296 | persist : false, |
||
10297 | |||
10298 | // set to zero to require manually dismissal, otherwise hides on its own |
||
10299 | displayTime : 0, |
||
10300 | |||
10301 | animation : { |
||
10302 | show : 'slide', |
||
10303 | hide : 'slide' |
||
10304 | }, |
||
10305 | |||
10306 | context : false, |
||
10307 | detachable : false, |
||
10308 | |||
10309 | expires : 30, |
||
10310 | domain : false, |
||
10311 | path : '/', |
||
10312 | |||
10313 | // type of storage to use |
||
10314 | storageMethod : 'cookie', |
||
10315 | |||
10316 | // value to store in dismissed localstorage/cookie |
||
10317 | key : 'nag', |
||
10318 | value : 'dismiss', |
||
10319 | |||
10320 | error: { |
||
10321 | noCookieStorage : '$.cookie is not included. A storage solution is required.', |
||
10322 | noStorage : 'Neither $.cookie or store is defined. A storage solution is required for storing state', |
||
10323 | method : 'The method you called is not defined.' |
||
10324 | }, |
||
10325 | |||
10326 | className : { |
||
10327 | bottom : 'bottom', |
||
10328 | fixed : 'fixed' |
||
10329 | }, |
||
10330 | |||
10331 | selector : { |
||
10332 | close : '.close.icon' |
||
10333 | }, |
||
10334 | |||
10335 | speed : 500, |
||
10336 | easing : 'easeOutQuad', |
||
10337 | |||
10338 | onHide: function() {} |
||
10339 | |||
10340 | }; |
||
10341 | |||
10342 | // Adds easing |
||
10343 | $.extend( $.easing, { |
||
10344 | easeOutQuad: function (x, t, b, c, d) { |
||
10345 | return -c *(t/=d)*(t-2) + b; |
||
10346 | } |
||
10347 | }); |
||
10348 | |||
10349 | })( jQuery, window, document ); |
||
10350 | |||
10351 | /*! |
||
10352 | * # Semantic UI 2.2.11 - Popup |
||
10353 | * http://github.com/semantic-org/semantic-ui/ |
||
10354 | * |
||
10355 | * |
||
10356 | * Released under the MIT license |
||
10357 | * http://opensource.org/licenses/MIT |
||
10358 | * |
||
10359 | */ |
||
10360 | |||
10361 | View Code Duplication | ;(function ($, window, document, undefined) { |
|
10362 | |||
10363 | "use strict"; |
||
10364 | |||
10365 | window = (typeof window != 'undefined' && window.Math == Math) |
||
10366 | ? window |
||
10367 | : (typeof self != 'undefined' && self.Math == Math) |
||
10368 | ? self |
||
10369 | : Function('return this')() |
||
10370 | ; |
||
10371 | |||
10372 | $.fn.popup = function(parameters) { |
||
10373 | var |
||
10374 | $allModules = $(this), |
||
10375 | $document = $(document), |
||
10376 | $window = $(window), |
||
10377 | $body = $('body'), |
||
10378 | |||
10379 | moduleSelector = $allModules.selector || '', |
||
10380 | |||
10381 | hasTouch = (true), |
||
10382 | time = new Date().getTime(), |
||
10383 | performance = [], |
||
10384 | |||
10385 | query = arguments[0], |
||
10386 | methodInvoked = (typeof query == 'string'), |
||
10387 | queryArguments = [].slice.call(arguments, 1), |
||
10388 | |||
10389 | returnedValue |
||
10390 | ; |
||
10391 | $allModules |
||
10392 | .each(function() { |
||
10393 | var |
||
10394 | settings = ( $.isPlainObject(parameters) ) |
||
10395 | ? $.extend(true, {}, $.fn.popup.settings, parameters) |
||
10396 | : $.extend({}, $.fn.popup.settings), |
||
10397 | |||
10398 | selector = settings.selector, |
||
10399 | className = settings.className, |
||
10400 | error = settings.error, |
||
10401 | metadata = settings.metadata, |
||
10402 | namespace = settings.namespace, |
||
10403 | |||
10404 | eventNamespace = '.' + settings.namespace, |
||
10405 | moduleNamespace = 'module-' + namespace, |
||
10406 | |||
10407 | $module = $(this), |
||
10408 | $context = $(settings.context), |
||
10409 | $scrollContext = $(settings.scrollContext), |
||
10410 | $boundary = $(settings.boundary), |
||
10411 | $target = (settings.target) |
||
10412 | ? $(settings.target) |
||
10413 | : $module, |
||
10414 | |||
10415 | $popup, |
||
10416 | $offsetParent, |
||
10417 | |||
10418 | searchDepth = 0, |
||
10419 | triedPositions = false, |
||
10420 | openedWithTouch = false, |
||
10421 | |||
10422 | element = this, |
||
10423 | instance = $module.data(moduleNamespace), |
||
10424 | |||
10425 | documentObserver, |
||
10426 | elementNamespace, |
||
10427 | id, |
||
10428 | module |
||
10429 | ; |
||
10430 | |||
10431 | module = { |
||
10432 | |||
10433 | // binds events |
||
10434 | initialize: function() { |
||
10435 | module.debug('Initializing', $module); |
||
10436 | module.createID(); |
||
10437 | module.bind.events(); |
||
10438 | if(!module.exists() && settings.preserve) { |
||
10439 | module.create(); |
||
10440 | } |
||
10441 | if(settings.observeChanges) { |
||
10442 | module.observeChanges(); |
||
10443 | } |
||
10444 | module.instantiate(); |
||
10445 | }, |
||
10446 | |||
10447 | instantiate: function() { |
||
10448 | module.verbose('Storing instance', module); |
||
10449 | instance = module; |
||
10450 | $module |
||
10451 | .data(moduleNamespace, instance) |
||
10452 | ; |
||
10453 | }, |
||
10454 | |||
10455 | observeChanges: function() { |
||
10456 | if('MutationObserver' in window) { |
||
10457 | documentObserver = new MutationObserver(module.event.documentChanged); |
||
10458 | documentObserver.observe(document, { |
||
10459 | childList : true, |
||
10460 | subtree : true |
||
10461 | }); |
||
10462 | module.debug('Setting up mutation observer', documentObserver); |
||
10463 | } |
||
10464 | }, |
||
10465 | |||
10466 | refresh: function() { |
||
10467 | if(settings.popup) { |
||
10468 | $popup = $(settings.popup).eq(0); |
||
10469 | } |
||
10470 | else { |
||
10471 | if(settings.inline) { |
||
10472 | $popup = $target.nextAll(selector.popup).eq(0); |
||
10473 | settings.popup = $popup; |
||
10474 | } |
||
10475 | } |
||
10476 | if(settings.popup) { |
||
10477 | $popup.addClass(className.loading); |
||
10478 | $offsetParent = module.get.offsetParent($target); |
||
10479 | $popup.removeClass(className.loading); |
||
10480 | if(settings.movePopup && module.has.popup() && module.get.offsetParent($popup)[0] !== $offsetParent[0]) { |
||
10481 | module.debug('Moving popup to the same offset parent as target'); |
||
10482 | $popup |
||
10483 | .detach() |
||
10484 | .appendTo($offsetParent) |
||
10485 | ; |
||
10486 | } |
||
10487 | } |
||
10488 | else { |
||
10489 | $offsetParent = (settings.inline) |
||
10490 | ? module.get.offsetParent($target) |
||
10491 | : module.has.popup() |
||
10492 | ? module.get.offsetParent($target) |
||
10493 | : $body |
||
10494 | ; |
||
10495 | } |
||
10496 | if( $offsetParent.is('html') && $offsetParent[0] !== $body[0] ) { |
||
10497 | module.debug('Setting page as offset parent'); |
||
10498 | $offsetParent = $body; |
||
10499 | } |
||
10500 | if( module.get.variation() ) { |
||
10501 | module.set.variation(); |
||
10502 | } |
||
10503 | }, |
||
10504 | |||
10505 | reposition: function() { |
||
10506 | module.refresh(); |
||
10507 | module.set.position(); |
||
10508 | }, |
||
10509 | |||
10510 | destroy: function() { |
||
10511 | module.debug('Destroying previous module'); |
||
10512 | if(documentObserver) { |
||
10513 | documentObserver.disconnect(); |
||
10514 | } |
||
10515 | // remove element only if was created dynamically |
||
10516 | if($popup && !settings.preserve) { |
||
10517 | module.removePopup(); |
||
10518 | } |
||
10519 | // clear all timeouts |
||
10520 | clearTimeout(module.hideTimer); |
||
10521 | clearTimeout(module.showTimer); |
||
10522 | // remove events |
||
10523 | module.unbind.close(); |
||
10524 | module.unbind.events(); |
||
10525 | $module |
||
10526 | .removeData(moduleNamespace) |
||
10527 | ; |
||
10528 | }, |
||
10529 | |||
10530 | event: { |
||
10531 | start: function(event) { |
||
10532 | var |
||
10533 | delay = ($.isPlainObject(settings.delay)) |
||
10534 | ? settings.delay.show |
||
10535 | : settings.delay |
||
10536 | ; |
||
10537 | clearTimeout(module.hideTimer); |
||
10538 | if(!openedWithTouch) { |
||
10539 | module.showTimer = setTimeout(module.show, delay); |
||
10540 | } |
||
10541 | }, |
||
10542 | end: function() { |
||
10543 | var |
||
10544 | delay = ($.isPlainObject(settings.delay)) |
||
10545 | ? settings.delay.hide |
||
10546 | : settings.delay |
||
10547 | ; |
||
10548 | clearTimeout(module.showTimer); |
||
10549 | module.hideTimer = setTimeout(module.hide, delay); |
||
10550 | }, |
||
10551 | touchstart: function(event) { |
||
10552 | openedWithTouch = true; |
||
10553 | module.show(); |
||
10554 | }, |
||
10555 | resize: function() { |
||
10556 | if( module.is.visible() ) { |
||
10557 | module.set.position(); |
||
10558 | } |
||
10559 | }, |
||
10560 | documentChanged: function(mutations) { |
||
10561 | [].forEach.call(mutations, function(mutation) { |
||
10562 | if(mutation.removedNodes) { |
||
10563 | [].forEach.call(mutation.removedNodes, function(node) { |
||
10564 | if(node == element || $(node).find(element).length > 0) { |
||
10565 | module.debug('Element removed from DOM, tearing down events'); |
||
10566 | module.destroy(); |
||
10567 | } |
||
10568 | }); |
||
10569 | } |
||
10570 | }); |
||
10571 | }, |
||
10572 | hideGracefully: function(event) { |
||
10573 | var |
||
10574 | $target = $(event.target), |
||
10575 | isInDOM = $.contains(document.documentElement, event.target), |
||
10576 | inPopup = ($target.closest(selector.popup).length > 0) |
||
10577 | ; |
||
10578 | // don't close on clicks inside popup |
||
10579 | if(event && !inPopup && isInDOM) { |
||
10580 | module.debug('Click occurred outside popup hiding popup'); |
||
10581 | module.hide(); |
||
10582 | } |
||
10583 | else { |
||
10584 | module.debug('Click was inside popup, keeping popup open'); |
||
10585 | } |
||
10586 | } |
||
10587 | }, |
||
10588 | |||
10589 | // generates popup html from metadata |
||
10590 | create: function() { |
||
10591 | var |
||
10592 | html = module.get.html(), |
||
10593 | title = module.get.title(), |
||
10594 | content = module.get.content() |
||
10595 | ; |
||
10596 | |||
10597 | if(html || content || title) { |
||
10598 | module.debug('Creating pop-up html'); |
||
10599 | if(!html) { |
||
10600 | html = settings.templates.popup({ |
||
10601 | title : title, |
||
10602 | content : content |
||
10603 | }); |
||
10604 | } |
||
10605 | $popup = $('<div/>') |
||
10606 | .addClass(className.popup) |
||
10607 | .data(metadata.activator, $module) |
||
10608 | .html(html) |
||
10609 | ; |
||
10610 | if(settings.inline) { |
||
10611 | module.verbose('Inserting popup element inline', $popup); |
||
10612 | $popup |
||
10613 | .insertAfter($module) |
||
10614 | ; |
||
10615 | } |
||
10616 | else { |
||
10617 | module.verbose('Appending popup element to body', $popup); |
||
10618 | $popup |
||
10619 | .appendTo( $context ) |
||
10620 | ; |
||
10621 | } |
||
10622 | module.refresh(); |
||
10623 | module.set.variation(); |
||
10624 | |||
10625 | if(settings.hoverable) { |
||
10626 | module.bind.popup(); |
||
10627 | } |
||
10628 | settings.onCreate.call($popup, element); |
||
10629 | } |
||
10630 | else if($target.next(selector.popup).length !== 0) { |
||
10631 | module.verbose('Pre-existing popup found'); |
||
10632 | settings.inline = true; |
||
10633 | settings.popup = $target.next(selector.popup).data(metadata.activator, $module); |
||
10634 | module.refresh(); |
||
10635 | if(settings.hoverable) { |
||
10636 | module.bind.popup(); |
||
10637 | } |
||
10638 | } |
||
10639 | else if(settings.popup) { |
||
10640 | $(settings.popup).data(metadata.activator, $module); |
||
10641 | module.verbose('Used popup specified in settings'); |
||
10642 | module.refresh(); |
||
10643 | if(settings.hoverable) { |
||
10644 | module.bind.popup(); |
||
10645 | } |
||
10646 | } |
||
10647 | else { |
||
10648 | module.debug('No content specified skipping display', element); |
||
10649 | } |
||
10650 | }, |
||
10651 | |||
10652 | createID: function() { |
||
10653 | id = (Math.random().toString(16) + '000000000').substr(2, 8); |
||
10654 | elementNamespace = '.' + id; |
||
10655 | module.verbose('Creating unique id for element', id); |
||
10656 | }, |
||
10657 | |||
10658 | // determines popup state |
||
10659 | toggle: function() { |
||
10660 | module.debug('Toggling pop-up'); |
||
10661 | if( module.is.hidden() ) { |
||
10662 | module.debug('Popup is hidden, showing pop-up'); |
||
10663 | module.unbind.close(); |
||
10664 | module.show(); |
||
10665 | } |
||
10666 | else { |
||
10667 | module.debug('Popup is visible, hiding pop-up'); |
||
10668 | module.hide(); |
||
10669 | } |
||
10670 | }, |
||
10671 | |||
10672 | show: function(callback) { |
||
10673 | callback = callback || function(){}; |
||
10674 | module.debug('Showing pop-up', settings.transition); |
||
10675 | if(module.is.hidden() && !( module.is.active() && module.is.dropdown()) ) { |
||
10676 | if( !module.exists() ) { |
||
10677 | module.create(); |
||
10678 | } |
||
10679 | if(settings.onShow.call($popup, element) === false) { |
||
10680 | module.debug('onShow callback returned false, cancelling popup animation'); |
||
10681 | return; |
||
10682 | } |
||
10683 | else if(!settings.preserve && !settings.popup) { |
||
10684 | module.refresh(); |
||
10685 | } |
||
10686 | if( $popup && module.set.position() ) { |
||
10687 | module.save.conditions(); |
||
10688 | if(settings.exclusive) { |
||
10689 | module.hideAll(); |
||
10690 | } |
||
10691 | module.animate.show(callback); |
||
10692 | } |
||
10693 | } |
||
10694 | }, |
||
10695 | |||
10696 | |||
10697 | hide: function(callback) { |
||
10698 | callback = callback || function(){}; |
||
10699 | if( module.is.visible() || module.is.animating() ) { |
||
10700 | if(settings.onHide.call($popup, element) === false) { |
||
10701 | module.debug('onHide callback returned false, cancelling popup animation'); |
||
10702 | return; |
||
10703 | } |
||
10704 | module.remove.visible(); |
||
10705 | module.unbind.close(); |
||
10706 | module.restore.conditions(); |
||
10707 | module.animate.hide(callback); |
||
10708 | } |
||
10709 | }, |
||
10710 | |||
10711 | hideAll: function() { |
||
10712 | $(selector.popup) |
||
10713 | .filter('.' + className.popupVisible) |
||
10714 | .each(function() { |
||
10715 | $(this) |
||
10716 | .data(metadata.activator) |
||
10717 | .popup('hide') |
||
10718 | ; |
||
10719 | }) |
||
10720 | ; |
||
10721 | }, |
||
10722 | exists: function() { |
||
10723 | if(!$popup) { |
||
10724 | return false; |
||
10725 | } |
||
10726 | if(settings.inline || settings.popup) { |
||
10727 | return ( module.has.popup() ); |
||
10728 | } |
||
10729 | else { |
||
10730 | return ( $popup.closest($context).length >= 1 ) |
||
10731 | ? true |
||
10732 | : false |
||
10733 | ; |
||
10734 | } |
||
10735 | }, |
||
10736 | |||
10737 | removePopup: function() { |
||
10738 | if( module.has.popup() && !settings.popup) { |
||
10739 | module.debug('Removing popup', $popup); |
||
10740 | $popup.remove(); |
||
10741 | $popup = undefined; |
||
10742 | settings.onRemove.call($popup, element); |
||
10743 | } |
||
10744 | }, |
||
10745 | |||
10746 | save: { |
||
10747 | conditions: function() { |
||
10748 | module.cache = { |
||
10749 | title: $module.attr('title') |
||
10750 | }; |
||
10751 | if (module.cache.title) { |
||
10752 | $module.removeAttr('title'); |
||
10753 | } |
||
10754 | module.verbose('Saving original attributes', module.cache.title); |
||
10755 | } |
||
10756 | }, |
||
10757 | restore: { |
||
10758 | conditions: function() { |
||
10759 | if(module.cache && module.cache.title) { |
||
10760 | $module.attr('title', module.cache.title); |
||
10761 | module.verbose('Restoring original attributes', module.cache.title); |
||
10762 | } |
||
10763 | return true; |
||
10764 | } |
||
10765 | }, |
||
10766 | supports: { |
||
10767 | svg: function() { |
||
10768 | return (typeof SVGGraphicsElement === 'undefined'); |
||
10769 | } |
||
10770 | }, |
||
10771 | animate: { |
||
10772 | show: function(callback) { |
||
10773 | callback = $.isFunction(callback) ? callback : function(){}; |
||
10774 | if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) { |
||
10775 | module.set.visible(); |
||
10776 | $popup |
||
10777 | .transition({ |
||
10778 | animation : settings.transition + ' in', |
||
10779 | queue : false, |
||
10780 | debug : settings.debug, |
||
10781 | verbose : settings.verbose, |
||
10782 | duration : settings.duration, |
||
10783 | onComplete : function() { |
||
10784 | module.bind.close(); |
||
10785 | callback.call($popup, element); |
||
10786 | settings.onVisible.call($popup, element); |
||
10787 | } |
||
10788 | }) |
||
10789 | ; |
||
10790 | } |
||
10791 | else { |
||
10792 | module.error(error.noTransition); |
||
10793 | } |
||
10794 | }, |
||
10795 | hide: function(callback) { |
||
10796 | callback = $.isFunction(callback) ? callback : function(){}; |
||
10797 | module.debug('Hiding pop-up'); |
||
10798 | if(settings.onHide.call($popup, element) === false) { |
||
10799 | module.debug('onHide callback returned false, cancelling popup animation'); |
||
10800 | return; |
||
10801 | } |
||
10802 | if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) { |
||
10803 | $popup |
||
10804 | .transition({ |
||
10805 | animation : settings.transition + ' out', |
||
10806 | queue : false, |
||
10807 | duration : settings.duration, |
||
10808 | debug : settings.debug, |
||
10809 | verbose : settings.verbose, |
||
10810 | onComplete : function() { |
||
10811 | module.reset(); |
||
10812 | callback.call($popup, element); |
||
10813 | settings.onHidden.call($popup, element); |
||
10814 | } |
||
10815 | }) |
||
10816 | ; |
||
10817 | } |
||
10818 | else { |
||
10819 | module.error(error.noTransition); |
||
10820 | } |
||
10821 | } |
||
10822 | }, |
||
10823 | |||
10824 | change: { |
||
10825 | content: function(html) { |
||
10826 | $popup.html(html); |
||
10827 | } |
||
10828 | }, |
||
10829 | |||
10830 | get: { |
||
10831 | html: function() { |
||
10832 | $module.removeData(metadata.html); |
||
10833 | return $module.data(metadata.html) || settings.html; |
||
10834 | }, |
||
10835 | title: function() { |
||
10836 | $module.removeData(metadata.title); |
||
10837 | return $module.data(metadata.title) || settings.title; |
||
10838 | }, |
||
10839 | content: function() { |
||
10840 | $module.removeData(metadata.content); |
||
10841 | return $module.data(metadata.content) || $module.attr('title') || settings.content; |
||
10842 | }, |
||
10843 | variation: function() { |
||
10844 | $module.removeData(metadata.variation); |
||
10845 | return $module.data(metadata.variation) || settings.variation; |
||
10846 | }, |
||
10847 | popup: function() { |
||
10848 | return $popup; |
||
10849 | }, |
||
10850 | popupOffset: function() { |
||
10851 | return $popup.offset(); |
||
10852 | }, |
||
10853 | calculations: function() { |
||
10854 | var |
||
10855 | targetElement = $target[0], |
||
10856 | isWindow = ($boundary[0] == window), |
||
10857 | targetPosition = (settings.inline || (settings.popup && settings.movePopup)) |
||
10858 | ? $target.position() |
||
10859 | : $target.offset(), |
||
10860 | screenPosition = (isWindow) |
||
10861 | ? { top: 0, left: 0 } |
||
10862 | : $boundary.offset(), |
||
10863 | calculations = {}, |
||
10864 | scroll = (isWindow) |
||
10865 | ? { top: $window.scrollTop(), left: $window.scrollLeft() } |
||
10866 | : { top: 0, left: 0}, |
||
10867 | screen |
||
10868 | ; |
||
10869 | calculations = { |
||
10870 | // element which is launching popup |
||
10871 | target : { |
||
10872 | element : $target[0], |
||
10873 | width : $target.outerWidth(), |
||
10874 | height : $target.outerHeight(), |
||
10875 | top : targetPosition.top, |
||
10876 | left : targetPosition.left, |
||
10877 | margin : {} |
||
10878 | }, |
||
10879 | // popup itself |
||
10880 | popup : { |
||
10881 | width : $popup.outerWidth(), |
||
10882 | height : $popup.outerHeight() |
||
10883 | }, |
||
10884 | // offset container (or 3d context) |
||
10885 | parent : { |
||
10886 | width : $offsetParent.outerWidth(), |
||
10887 | height : $offsetParent.outerHeight() |
||
10888 | }, |
||
10889 | // screen boundaries |
||
10890 | screen : { |
||
10891 | top : screenPosition.top, |
||
10892 | left : screenPosition.left, |
||
10893 | scroll: { |
||
10894 | top : scroll.top, |
||
10895 | left : scroll.left |
||
10896 | }, |
||
10897 | width : $boundary.width(), |
||
10898 | height : $boundary.height() |
||
10899 | } |
||
10900 | }; |
||
10901 | |||
10902 | // add in container calcs if fluid |
||
10903 | if( settings.setFluidWidth && module.is.fluid() ) { |
||
10904 | calculations.container = { |
||
10905 | width: $popup.parent().outerWidth() |
||
10906 | }; |
||
10907 | calculations.popup.width = calculations.container.width; |
||
10908 | } |
||
10909 | |||
10910 | // add in margins if inline |
||
10911 | calculations.target.margin.top = (settings.inline) |
||
10912 | ? parseInt( window.getComputedStyle(targetElement).getPropertyValue('margin-top'), 10) |
||
10913 | : 0 |
||
10914 | ; |
||
10915 | calculations.target.margin.left = (settings.inline) |
||
10916 | ? module.is.rtl() |
||
10917 | ? parseInt( window.getComputedStyle(targetElement).getPropertyValue('margin-right'), 10) |
||
10918 | : parseInt( window.getComputedStyle(targetElement).getPropertyValue('margin-left'), 10) |
||
10919 | : 0 |
||
10920 | ; |
||
10921 | // calculate screen boundaries |
||
10922 | screen = calculations.screen; |
||
10923 | calculations.boundary = { |
||
10924 | top : screen.top + screen.scroll.top, |
||
10925 | bottom : screen.top + screen.scroll.top + screen.height, |
||
10926 | left : screen.left + screen.scroll.left, |
||
10927 | right : screen.left + screen.scroll.left + screen.width |
||
10928 | }; |
||
10929 | return calculations; |
||
10930 | }, |
||
10931 | id: function() { |
||
10932 | return id; |
||
10933 | }, |
||
10934 | startEvent: function() { |
||
10935 | if(settings.on == 'hover') { |
||
10936 | return 'mouseenter'; |
||
10937 | } |
||
10938 | else if(settings.on == 'focus') { |
||
10939 | return 'focus'; |
||
10940 | } |
||
10941 | return false; |
||
10942 | }, |
||
10943 | scrollEvent: function() { |
||
10944 | return 'scroll'; |
||
10945 | }, |
||
10946 | endEvent: function() { |
||
10947 | if(settings.on == 'hover') { |
||
10948 | return 'mouseleave'; |
||
10949 | } |
||
10950 | else if(settings.on == 'focus') { |
||
10951 | return 'blur'; |
||
10952 | } |
||
10953 | return false; |
||
10954 | }, |
||
10955 | distanceFromBoundary: function(offset, calculations) { |
||
10956 | var |
||
10957 | distanceFromBoundary = {}, |
||
10958 | popup, |
||
10959 | boundary |
||
10960 | ; |
||
10961 | calculations = calculations || module.get.calculations(); |
||
10962 | |||
10963 | // shorthand |
||
10964 | popup = calculations.popup; |
||
10965 | boundary = calculations.boundary; |
||
10966 | |||
10967 | if(offset) { |
||
10968 | distanceFromBoundary = { |
||
10969 | top : (offset.top - boundary.top), |
||
10970 | left : (offset.left - boundary.left), |
||
10971 | right : (boundary.right - (offset.left + popup.width) ), |
||
10972 | bottom : (boundary.bottom - (offset.top + popup.height) ) |
||
10973 | }; |
||
10974 | module.verbose('Distance from boundaries determined', offset, distanceFromBoundary); |
||
10975 | } |
||
10976 | return distanceFromBoundary; |
||
10977 | }, |
||
10978 | offsetParent: function($target) { |
||
10979 | var |
||
10980 | element = ($target !== undefined) |
||
10981 | ? $target[0] |
||
10982 | : $module[0], |
||
10983 | parentNode = element.parentNode, |
||
10984 | $node = $(parentNode) |
||
10985 | ; |
||
10986 | if(parentNode) { |
||
10987 | var |
||
10988 | is2D = ($node.css('transform') === 'none'), |
||
10989 | isStatic = ($node.css('position') === 'static'), |
||
10990 | isHTML = $node.is('html') |
||
10991 | ; |
||
10992 | while(parentNode && !isHTML && isStatic && is2D) { |
||
10993 | parentNode = parentNode.parentNode; |
||
10994 | $node = $(parentNode); |
||
10995 | is2D = ($node.css('transform') === 'none'); |
||
10996 | isStatic = ($node.css('position') === 'static'); |
||
10997 | isHTML = $node.is('html'); |
||
10998 | } |
||
10999 | } |
||
11000 | return ($node && $node.length > 0) |
||
11001 | ? $node |
||
11002 | : $() |
||
11003 | ; |
||
11004 | }, |
||
11005 | positions: function() { |
||
11006 | return { |
||
11007 | 'top left' : false, |
||
11008 | 'top center' : false, |
||
11009 | 'top right' : false, |
||
11010 | 'bottom left' : false, |
||
11011 | 'bottom center' : false, |
||
11012 | 'bottom right' : false, |
||
11013 | 'left center' : false, |
||
11014 | 'right center' : false |
||
11015 | }; |
||
11016 | }, |
||
11017 | nextPosition: function(position) { |
||
11018 | var |
||
11019 | positions = position.split(' '), |
||
11020 | verticalPosition = positions[0], |
||
11021 | horizontalPosition = positions[1], |
||
11022 | opposite = { |
||
11023 | top : 'bottom', |
||
11024 | bottom : 'top', |
||
11025 | left : 'right', |
||
11026 | right : 'left' |
||
11027 | }, |
||
11028 | adjacent = { |
||
11029 | left : 'center', |
||
11030 | center : 'right', |
||
11031 | right : 'left' |
||
11032 | }, |
||
11033 | backup = { |
||
11034 | 'top left' : 'top center', |
||
11035 | 'top center' : 'top right', |
||
11036 | 'top right' : 'right center', |
||
11037 | 'right center' : 'bottom right', |
||
11038 | 'bottom right' : 'bottom center', |
||
11039 | 'bottom center' : 'bottom left', |
||
11040 | 'bottom left' : 'left center', |
||
11041 | 'left center' : 'top left' |
||
11042 | }, |
||
11043 | adjacentsAvailable = (verticalPosition == 'top' || verticalPosition == 'bottom'), |
||
11044 | oppositeTried = false, |
||
11045 | adjacentTried = false, |
||
11046 | nextPosition = false |
||
11047 | ; |
||
11048 | if(!triedPositions) { |
||
11049 | module.verbose('All available positions available'); |
||
11050 | triedPositions = module.get.positions(); |
||
11051 | } |
||
11052 | |||
11053 | module.debug('Recording last position tried', position); |
||
11054 | triedPositions[position] = true; |
||
11055 | |||
11056 | if(settings.prefer === 'opposite') { |
||
11057 | nextPosition = [opposite[verticalPosition], horizontalPosition]; |
||
11058 | nextPosition = nextPosition.join(' '); |
||
11059 | oppositeTried = (triedPositions[nextPosition] === true); |
||
11060 | module.debug('Trying opposite strategy', nextPosition); |
||
11061 | } |
||
11062 | if((settings.prefer === 'adjacent') && adjacentsAvailable ) { |
||
11063 | nextPosition = [verticalPosition, adjacent[horizontalPosition]]; |
||
11064 | nextPosition = nextPosition.join(' '); |
||
11065 | adjacentTried = (triedPositions[nextPosition] === true); |
||
11066 | module.debug('Trying adjacent strategy', nextPosition); |
||
11067 | } |
||
11068 | if(adjacentTried || oppositeTried) { |
||
11069 | module.debug('Using backup position', nextPosition); |
||
11070 | nextPosition = backup[position]; |
||
11071 | } |
||
11072 | return nextPosition; |
||
11073 | } |
||
11074 | }, |
||
11075 | |||
11076 | set: { |
||
11077 | position: function(position, calculations) { |
||
11078 | |||
11079 | // exit conditions |
||
11080 | if($target.length === 0 || $popup.length === 0) { |
||
11081 | module.error(error.notFound); |
||
11082 | return; |
||
11083 | } |
||
11084 | var |
||
11085 | offset, |
||
11086 | distanceAway, |
||
11087 | target, |
||
11088 | popup, |
||
11089 | parent, |
||
11090 | positioning, |
||
11091 | popupOffset, |
||
11092 | distanceFromBoundary |
||
11093 | ; |
||
11094 | |||
11095 | calculations = calculations || module.get.calculations(); |
||
11096 | position = position || $module.data(metadata.position) || settings.position; |
||
11097 | |||
11098 | offset = $module.data(metadata.offset) || settings.offset; |
||
11099 | distanceAway = settings.distanceAway; |
||
11100 | |||
11101 | // shorthand |
||
11102 | target = calculations.target; |
||
11103 | popup = calculations.popup; |
||
11104 | parent = calculations.parent; |
||
11105 | |||
11106 | if(target.width === 0 && target.height === 0 && !module.is.svg(target.element)) { |
||
11107 | module.debug('Popup target is hidden, no action taken'); |
||
11108 | return false; |
||
11109 | } |
||
11110 | |||
11111 | if(settings.inline) { |
||
11112 | module.debug('Adding margin to calculation', target.margin); |
||
11113 | if(position == 'left center' || position == 'right center') { |
||
11114 | offset += target.margin.top; |
||
11115 | distanceAway += -target.margin.left; |
||
11116 | } |
||
11117 | else if (position == 'top left' || position == 'top center' || position == 'top right') { |
||
11118 | offset += target.margin.left; |
||
11119 | distanceAway -= target.margin.top; |
||
11120 | } |
||
11121 | else { |
||
11122 | offset += target.margin.left; |
||
11123 | distanceAway += target.margin.top; |
||
11124 | } |
||
11125 | } |
||
11126 | |||
11127 | module.debug('Determining popup position from calculations', position, calculations); |
||
11128 | |||
11129 | if (module.is.rtl()) { |
||
11130 | position = position.replace(/left|right/g, function (match) { |
||
11131 | return (match == 'left') |
||
11132 | ? 'right' |
||
11133 | : 'left' |
||
11134 | ; |
||
11135 | }); |
||
11136 | module.debug('RTL: Popup position updated', position); |
||
11137 | } |
||
11138 | |||
11139 | // if last attempt use specified last resort position |
||
11140 | if(searchDepth == settings.maxSearchDepth && typeof settings.lastResort === 'string') { |
||
11141 | position = settings.lastResort; |
||
11142 | } |
||
11143 | |||
11144 | switch (position) { |
||
11145 | case 'top left': |
||
11146 | positioning = { |
||
11147 | top : 'auto', |
||
11148 | bottom : parent.height - target.top + distanceAway, |
||
11149 | left : target.left + offset, |
||
11150 | right : 'auto' |
||
11151 | }; |
||
11152 | break; |
||
11153 | case 'top center': |
||
11154 | positioning = { |
||
11155 | bottom : parent.height - target.top + distanceAway, |
||
11156 | left : target.left + (target.width / 2) - (popup.width / 2) + offset, |
||
11157 | top : 'auto', |
||
11158 | right : 'auto' |
||
11159 | }; |
||
11160 | break; |
||
11161 | case 'top right': |
||
11162 | positioning = { |
||
11163 | bottom : parent.height - target.top + distanceAway, |
||
11164 | right : parent.width - target.left - target.width - offset, |
||
11165 | top : 'auto', |
||
11166 | left : 'auto' |
||
11167 | }; |
||
11168 | break; |
||
11169 | case 'left center': |
||
11170 | positioning = { |
||
11171 | top : target.top + (target.height / 2) - (popup.height / 2) + offset, |
||
11172 | right : parent.width - target.left + distanceAway, |
||
11173 | left : 'auto', |
||
11174 | bottom : 'auto' |
||
11175 | }; |
||
11176 | break; |
||
11177 | case 'right center': |
||
11178 | positioning = { |
||
11179 | top : target.top + (target.height / 2) - (popup.height / 2) + offset, |
||
11180 | left : target.left + target.width + distanceAway, |
||
11181 | bottom : 'auto', |
||
11182 | right : 'auto' |
||
11183 | }; |
||
11184 | break; |
||
11185 | case 'bottom left': |
||
11186 | positioning = { |
||
11187 | top : target.top + target.height + distanceAway, |
||
11188 | left : target.left + offset, |
||
11189 | bottom : 'auto', |
||
11190 | right : 'auto' |
||
11191 | }; |
||
11192 | break; |
||
11193 | case 'bottom center': |
||
11194 | positioning = { |
||
11195 | top : target.top + target.height + distanceAway, |
||
11196 | left : target.left + (target.width / 2) - (popup.width / 2) + offset, |
||
11197 | bottom : 'auto', |
||
11198 | right : 'auto' |
||
11199 | }; |
||
11200 | break; |
||
11201 | case 'bottom right': |
||
11202 | positioning = { |
||
11203 | top : target.top + target.height + distanceAway, |
||
11204 | right : parent.width - target.left - target.width - offset, |
||
11205 | left : 'auto', |
||
11206 | bottom : 'auto' |
||
11207 | }; |
||
11208 | break; |
||
11209 | } |
||
11210 | if(positioning === undefined) { |
||
11211 | module.error(error.invalidPosition, position); |
||
11212 | } |
||
11213 | |||
11214 | module.debug('Calculated popup positioning values', positioning); |
||
11215 | |||
11216 | // tentatively place on stage |
||
11217 | $popup |
||
11218 | .css(positioning) |
||
11219 | .removeClass(className.position) |
||
11220 | .addClass(position) |
||
11221 | .addClass(className.loading) |
||
11222 | ; |
||
11223 | |||
11224 | popupOffset = module.get.popupOffset(); |
||
11225 | |||
11226 | // see if any boundaries are surpassed with this tentative position |
||
11227 | distanceFromBoundary = module.get.distanceFromBoundary(popupOffset, calculations); |
||
11228 | |||
11229 | if( module.is.offstage(distanceFromBoundary, position) ) { |
||
11230 | module.debug('Position is outside viewport', position); |
||
11231 | if(searchDepth < settings.maxSearchDepth) { |
||
11232 | searchDepth++; |
||
11233 | position = module.get.nextPosition(position); |
||
11234 | module.debug('Trying new position', position); |
||
11235 | return ($popup) |
||
11236 | ? module.set.position(position, calculations) |
||
11237 | : false |
||
11238 | ; |
||
11239 | } |
||
11240 | else { |
||
11241 | if(settings.lastResort) { |
||
11242 | module.debug('No position found, showing with last position'); |
||
11243 | } |
||
11244 | else { |
||
11245 | module.debug('Popup could not find a position to display', $popup); |
||
11246 | module.error(error.cannotPlace, element); |
||
11247 | module.remove.attempts(); |
||
11248 | module.remove.loading(); |
||
11249 | module.reset(); |
||
11250 | settings.onUnplaceable.call($popup, element); |
||
11251 | return false; |
||
11252 | } |
||
11253 | } |
||
11254 | } |
||
11255 | module.debug('Position is on stage', position); |
||
11256 | module.remove.attempts(); |
||
11257 | module.remove.loading(); |
||
11258 | if( settings.setFluidWidth && module.is.fluid() ) { |
||
11259 | module.set.fluidWidth(calculations); |
||
11260 | } |
||
11261 | return true; |
||
11262 | }, |
||
11263 | |||
11264 | fluidWidth: function(calculations) { |
||
11265 | calculations = calculations || module.get.calculations(); |
||
11266 | module.debug('Automatically setting element width to parent width', calculations.parent.width); |
||
11267 | $popup.css('width', calculations.container.width); |
||
11268 | }, |
||
11269 | |||
11270 | variation: function(variation) { |
||
11271 | variation = variation || module.get.variation(); |
||
11272 | if(variation && module.has.popup() ) { |
||
11273 | module.verbose('Adding variation to popup', variation); |
||
11274 | $popup.addClass(variation); |
||
11275 | } |
||
11276 | }, |
||
11277 | |||
11278 | visible: function() { |
||
11279 | $module.addClass(className.visible); |
||
11280 | } |
||
11281 | }, |
||
11282 | |||
11283 | remove: { |
||
11284 | loading: function() { |
||
11285 | $popup.removeClass(className.loading); |
||
11286 | }, |
||
11287 | variation: function(variation) { |
||
11288 | variation = variation || module.get.variation(); |
||
11289 | if(variation) { |
||
11290 | module.verbose('Removing variation', variation); |
||
11291 | $popup.removeClass(variation); |
||
11292 | } |
||
11293 | }, |
||
11294 | visible: function() { |
||
11295 | $module.removeClass(className.visible); |
||
11296 | }, |
||
11297 | attempts: function() { |
||
11298 | module.verbose('Resetting all searched positions'); |
||
11299 | searchDepth = 0; |
||
11300 | triedPositions = false; |
||
11301 | } |
||
11302 | }, |
||
11303 | |||
11304 | bind: { |
||
11305 | events: function() { |
||
11306 | module.debug('Binding popup events to module'); |
||
11307 | if(settings.on == 'click') { |
||
11308 | $module |
||
11309 | .on('click' + eventNamespace, module.toggle) |
||
11310 | ; |
||
11311 | } |
||
11312 | if(settings.on == 'hover' && hasTouch) { |
||
11313 | $module |
||
11314 | .on('touchstart' + eventNamespace, module.event.touchstart) |
||
11315 | ; |
||
11316 | } |
||
11317 | if( module.get.startEvent() ) { |
||
11318 | $module |
||
11319 | .on(module.get.startEvent() + eventNamespace, module.event.start) |
||
11320 | .on(module.get.endEvent() + eventNamespace, module.event.end) |
||
11321 | ; |
||
11322 | } |
||
11323 | if(settings.target) { |
||
11324 | module.debug('Target set to element', $target); |
||
11325 | } |
||
11326 | $window.on('resize' + elementNamespace, module.event.resize); |
||
11327 | }, |
||
11328 | popup: function() { |
||
11329 | module.verbose('Allowing hover events on popup to prevent closing'); |
||
11330 | if( $popup && module.has.popup() ) { |
||
11331 | $popup |
||
11332 | .on('mouseenter' + eventNamespace, module.event.start) |
||
11333 | .on('mouseleave' + eventNamespace, module.event.end) |
||
11334 | ; |
||
11335 | } |
||
11336 | }, |
||
11337 | close: function() { |
||
11338 | if(settings.hideOnScroll === true || (settings.hideOnScroll == 'auto' && settings.on != 'click')) { |
||
11339 | module.bind.closeOnScroll(); |
||
11340 | } |
||
11341 | if(settings.on == 'hover' && openedWithTouch) { |
||
11342 | module.bind.touchClose(); |
||
11343 | } |
||
11344 | if(settings.on == 'click' && settings.closable) { |
||
11345 | module.bind.clickaway(); |
||
11346 | } |
||
11347 | }, |
||
11348 | closeOnScroll: function() { |
||
11349 | module.verbose('Binding scroll close event to document'); |
||
11350 | $scrollContext |
||
11351 | .one(module.get.scrollEvent() + elementNamespace, module.event.hideGracefully) |
||
11352 | ; |
||
11353 | }, |
||
11354 | touchClose: function() { |
||
11355 | module.verbose('Binding popup touchclose event to document'); |
||
11356 | $document |
||
11357 | .on('touchstart' + elementNamespace, function(event) { |
||
11358 | module.verbose('Touched away from popup'); |
||
11359 | module.event.hideGracefully.call(element, event); |
||
11360 | }) |
||
11361 | ; |
||
11362 | }, |
||
11363 | clickaway: function() { |
||
11364 | module.verbose('Binding popup close event to document'); |
||
11365 | $document |
||
11366 | .on('click' + elementNamespace, function(event) { |
||
11367 | module.verbose('Clicked away from popup'); |
||
11368 | module.event.hideGracefully.call(element, event); |
||
11369 | }) |
||
11370 | ; |
||
11371 | } |
||
11372 | }, |
||
11373 | |||
11374 | unbind: { |
||
11375 | events: function() { |
||
11376 | $window |
||
11377 | .off(elementNamespace) |
||
11378 | ; |
||
11379 | $module |
||
11380 | .off(eventNamespace) |
||
11381 | ; |
||
11382 | }, |
||
11383 | close: function() { |
||
11384 | $document |
||
11385 | .off(elementNamespace) |
||
11386 | ; |
||
11387 | $scrollContext |
||
11388 | .off(elementNamespace) |
||
11389 | ; |
||
11390 | }, |
||
11391 | }, |
||
11392 | |||
11393 | has: { |
||
11394 | popup: function() { |
||
11395 | return ($popup && $popup.length > 0); |
||
11396 | } |
||
11397 | }, |
||
11398 | |||
11399 | is: { |
||
11400 | offstage: function(distanceFromBoundary, position) { |
||
11401 | var |
||
11402 | offstage = [] |
||
11403 | ; |
||
11404 | // return boundaries that have been surpassed |
||
11405 | $.each(distanceFromBoundary, function(direction, distance) { |
||
11406 | if(distance < -settings.jitter) { |
||
11407 | module.debug('Position exceeds allowable distance from edge', direction, distance, position); |
||
11408 | offstage.push(direction); |
||
11409 | } |
||
11410 | }); |
||
11411 | if(offstage.length > 0) { |
||
11412 | return true; |
||
11413 | } |
||
11414 | else { |
||
11415 | return false; |
||
11416 | } |
||
11417 | }, |
||
11418 | svg: function(element) { |
||
11419 | return module.supports.svg() && (element instanceof SVGGraphicsElement); |
||
11420 | }, |
||
11421 | active: function() { |
||
11422 | return $module.hasClass(className.active); |
||
11423 | }, |
||
11424 | animating: function() { |
||
11425 | return ($popup !== undefined && $popup.hasClass(className.animating) ); |
||
11426 | }, |
||
11427 | fluid: function() { |
||
11428 | return ($popup !== undefined && $popup.hasClass(className.fluid)); |
||
11429 | }, |
||
11430 | visible: function() { |
||
11431 | return ($popup !== undefined && $popup.hasClass(className.popupVisible)); |
||
11432 | }, |
||
11433 | dropdown: function() { |
||
11434 | return $module.hasClass(className.dropdown); |
||
11435 | }, |
||
11436 | hidden: function() { |
||
11437 | return !module.is.visible(); |
||
11438 | }, |
||
11439 | rtl: function () { |
||
11440 | return $module.css('direction') == 'rtl'; |
||
11441 | } |
||
11442 | }, |
||
11443 | |||
11444 | reset: function() { |
||
11445 | module.remove.visible(); |
||
11446 | if(settings.preserve) { |
||
11447 | if($.fn.transition !== undefined) { |
||
11448 | $popup |
||
11449 | .transition('remove transition') |
||
11450 | ; |
||
11451 | } |
||
11452 | } |
||
11453 | else { |
||
11454 | module.removePopup(); |
||
11455 | } |
||
11456 | }, |
||
11457 | |||
11458 | setting: function(name, value) { |
||
11459 | if( $.isPlainObject(name) ) { |
||
11460 | $.extend(true, settings, name); |
||
11461 | } |
||
11462 | else if(value !== undefined) { |
||
11463 | settings[name] = value; |
||
11464 | } |
||
11465 | else { |
||
11466 | return settings[name]; |
||
11467 | } |
||
11468 | }, |
||
11469 | internal: function(name, value) { |
||
11470 | if( $.isPlainObject(name) ) { |
||
11471 | $.extend(true, module, name); |
||
11472 | } |
||
11473 | else if(value !== undefined) { |
||
11474 | module[name] = value; |
||
11475 | } |
||
11476 | else { |
||
11477 | return module[name]; |
||
11478 | } |
||
11479 | }, |
||
11480 | debug: function() { |
||
11481 | if(!settings.silent && settings.debug) { |
||
11482 | if(settings.performance) { |
||
11483 | module.performance.log(arguments); |
||
11484 | } |
||
11485 | else { |
||
11486 | module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':'); |
||
11487 | module.debug.apply(console, arguments); |
||
11488 | } |
||
11489 | } |
||
11490 | }, |
||
11491 | verbose: function() { |
||
11492 | if(!settings.silent && settings.verbose && settings.debug) { |
||
11493 | if(settings.performance) { |
||
11494 | module.performance.log(arguments); |
||
11495 | } |
||
11496 | else { |
||
11497 | module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':'); |
||
11498 | module.verbose.apply(console, arguments); |
||
11499 | } |
||
11500 | } |
||
11501 | }, |
||
11502 | error: function() { |
||
11503 | if(!settings.silent) { |
||
11504 | module.error = Function.prototype.bind.call(console.error, console, settings.name + ':'); |
||
11505 | module.error.apply(console, arguments); |
||
11506 | } |
||
11507 | }, |
||
11508 | performance: { |
||
11509 | log: function(message) { |
||
11510 | var |
||
11511 | currentTime, |
||
11512 | executionTime, |
||
11513 | previousTime |
||
11514 | ; |
||
11515 | if(settings.performance) { |
||
11516 | currentTime = new Date().getTime(); |
||
11517 | previousTime = time || currentTime; |
||
11518 | executionTime = currentTime - previousTime; |
||
11519 | time = currentTime; |
||
11520 | performance.push({ |
||
11521 | 'Name' : message[0], |
||
11522 | 'Arguments' : [].slice.call(message, 1) || '', |
||
11523 | 'Element' : element, |
||
11524 | 'Execution Time' : executionTime |
||
11525 | }); |
||
11526 | } |
||
11527 | clearTimeout(module.performance.timer); |
||
11528 | module.performance.timer = setTimeout(module.performance.display, 500); |
||
11529 | }, |
||
11530 | display: function() { |
||
11531 | var |
||
11532 | title = settings.name + ':', |
||
11533 | totalTime = 0 |
||
11534 | ; |
||
11535 | time = false; |
||
11536 | clearTimeout(module.performance.timer); |
||
11537 | $.each(performance, function(index, data) { |
||
11538 | totalTime += data['Execution Time']; |
||
11539 | }); |
||
11540 | title += ' ' + totalTime + 'ms'; |
||
11541 | if(moduleSelector) { |
||
11542 | title += ' \'' + moduleSelector + '\''; |
||
11543 | } |
||
11544 | if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) { |
||
11545 | console.groupCollapsed(title); |
||
11546 | if(console.table) { |
||
11547 | console.table(performance); |
||
11548 | } |
||
11549 | else { |
||
11550 | $.each(performance, function(index, data) { |
||
11551 | console.log(data['Name'] + ': ' + data['Execution Time']+'ms'); |
||
11552 | }); |
||
11553 | } |
||
11554 | console.groupEnd(); |
||
11555 | } |
||
11556 | performance = []; |
||
11557 | } |
||
11558 | }, |
||
11559 | invoke: function(query, passedArguments, context) { |
||
11560 | var |
||
11561 | object = instance, |
||
11562 | maxDepth, |
||
11563 | found, |
||
11564 | response |
||
11565 | ; |
||
11566 | passedArguments = passedArguments || queryArguments; |
||
11567 | context = element || context; |
||
11568 | if(typeof query == 'string' && object !== undefined) { |
||
11569 | query = query.split(/[\. ]/); |
||
11570 | maxDepth = query.length - 1; |
||
11571 | $.each(query, function(depth, value) { |
||
11572 | var camelCaseValue = (depth != maxDepth) |
||
11573 | ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1) |
||
11574 | : query |
||
11575 | ; |
||
11576 | if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) { |
||
11577 | object = object[camelCaseValue]; |
||
11578 | } |
||
11579 | else if( object[camelCaseValue] !== undefined ) { |
||
11580 | found = object[camelCaseValue]; |
||
11581 | return false; |
||
11582 | } |
||
11583 | else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) { |
||
11584 | object = object[value]; |
||
11585 | } |
||
11586 | else if( object[value] !== undefined ) { |
||
11587 | found = object[value]; |
||
11588 | return false; |
||
11589 | } |
||
11590 | else { |
||
11591 | return false; |
||
11592 | } |
||
11593 | }); |
||
11594 | } |
||
11595 | if ( $.isFunction( found ) ) { |
||
11596 | response = found.apply(context, passedArguments); |
||
11597 | } |
||
11598 | else if(found !== undefined) { |
||
11599 | response = found; |
||
11600 | } |
||
11601 | if($.isArray(returnedValue)) { |
||
11602 | returnedValue.push(response); |
||
11603 | } |
||
11604 | else if(returnedValue !== undefined) { |
||
11605 | returnedValue = [returnedValue, response]; |
||
11606 | } |
||
11607 | else if(response !== undefined) { |
||
11608 | returnedValue = response; |
||
11609 | } |
||
11610 | return found; |
||
11611 | } |
||
11612 | }; |
||
11613 | |||
11614 | if(methodInvoked) { |
||
11615 | if(instance === undefined) { |
||
11616 | module.initialize(); |
||
11617 | } |
||
11618 | module.invoke(query); |
||
11619 | } |
||
11620 | else { |
||
11621 | if(instance !== undefined) { |
||
11622 | instance.invoke('destroy'); |
||
11623 | } |
||
11624 | module.initialize(); |
||
11625 | } |
||
11626 | }) |
||
11627 | ; |
||
11628 | |||
11629 | return (returnedValue !== undefined) |
||
11630 | ? returnedValue |
||
11631 | : this |
||
11632 | ; |
||
11633 | }; |
||
11634 | |||
11635 | $.fn.popup.settings = { |
||
11636 | |||
11637 | name : 'Popup', |
||
11638 | |||
11639 | // module settings |
||
11640 | silent : false, |
||
11641 | debug : false, |
||
11642 | verbose : false, |
||
11643 | performance : true, |
||
11644 | namespace : 'popup', |
||
11645 | |||
11646 | // whether it should use dom mutation observers |
||
11647 | observeChanges : true, |
||
11648 | |||
11649 | // callback only when element added to dom |
||
11650 | onCreate : function(){}, |
||
11651 | |||
11652 | // callback before element removed from dom |
||
11653 | onRemove : function(){}, |
||
11654 | |||
11655 | // callback before show animation |
||
11656 | onShow : function(){}, |
||
11657 | |||
11658 | // callback after show animation |
||
11659 | onVisible : function(){}, |
||
11660 | |||
11661 | // callback before hide animation |
||
11662 | onHide : function(){}, |
||
11663 | |||
11664 | // callback when popup cannot be positioned in visible screen |
||
11665 | onUnplaceable : function(){}, |
||
11666 | |||
11667 | // callback after hide animation |
||
11668 | onHidden : function(){}, |
||
11669 | |||
11670 | // when to show popup |
||
11671 | on : 'hover', |
||
11672 | |||
11673 | // element to use to determine if popup is out of boundary |
||
11674 | boundary : window, |
||
11675 | |||
11676 | // whether to add touchstart events when using hover |
||
11677 | addTouchEvents : true, |
||
11678 | |||
11679 | // default position relative to element |
||
11680 | position : 'top left', |
||
11681 | |||
11682 | // name of variation to use |
||
11683 | variation : '', |
||
11684 | |||
11685 | // whether popup should be moved to context |
||
11686 | movePopup : true, |
||
11687 | |||
11688 | // element which popup should be relative to |
||
11689 | target : false, |
||
11690 | |||
11691 | // jq selector or element that should be used as popup |
||
11692 | popup : false, |
||
11693 | |||
11694 | // popup should remain inline next to activator |
||
11695 | inline : false, |
||
11696 | |||
11697 | // popup should be removed from page on hide |
||
11698 | preserve : false, |
||
11699 | |||
11700 | // popup should not close when being hovered on |
||
11701 | hoverable : false, |
||
11702 | |||
11703 | // explicitly set content |
||
11704 | content : false, |
||
11705 | |||
11706 | // explicitly set html |
||
11707 | html : false, |
||
11708 | |||
11709 | // explicitly set title |
||
11710 | title : false, |
||
11711 | |||
11712 | // whether automatically close on clickaway when on click |
||
11713 | closable : true, |
||
11714 | |||
11715 | // automatically hide on scroll |
||
11716 | hideOnScroll : 'auto', |
||
11717 | |||
11718 | // hide other popups on show |
||
11719 | exclusive : false, |
||
11720 | |||
11721 | // context to attach popups |
||
11722 | context : 'body', |
||
11723 | |||
11724 | // context for binding scroll events |
||
11725 | scrollContext : window, |
||
11726 | |||
11727 | // position to prefer when calculating new position |
||
11728 | prefer : 'opposite', |
||
11729 | |||
11730 | // specify position to appear even if it doesn't fit |
||
11731 | lastResort : false, |
||
11732 | |||
11733 | // delay used to prevent accidental refiring of animations due to user error |
||
11734 | delay : { |
||
11735 | show : 50, |
||
11736 | hide : 70 |
||
11737 | }, |
||
11738 | |||
11739 | // whether fluid variation should assign width explicitly |
||
11740 | setFluidWidth : true, |
||
11741 | |||
11742 | // transition settings |
||
11743 | duration : 200, |
||
11744 | transition : 'scale', |
||
11745 | |||
11746 | // distance away from activating element in px |
||
11747 | distanceAway : 0, |
||
11748 | |||
11749 | // number of pixels an element is allowed to be "offstage" for a position to be chosen (allows for rounding) |
||
11750 | jitter : 2, |
||
11751 | |||
11752 | // offset on aligning axis from calculated position |
||
11753 | offset : 0, |
||
11754 | |||
11755 | // maximum times to look for a position before failing (9 positions total) |
||
11756 | maxSearchDepth : 15, |
||
11757 | |||
11758 | error: { |
||
11759 | invalidPosition : 'The position you specified is not a valid position', |
||
11760 | cannotPlace : 'Popup does not fit within the boundaries of the viewport', |
||
11761 | method : 'The method you called is not defined.', |
||
11762 | noTransition : 'This module requires ui transitions <https://github.com/Semantic-Org/UI-Transition>', |
||
11763 | notFound : 'The target or popup you specified does not exist on the page' |
||
11764 | }, |
||
11765 | |||
11766 | metadata: { |
||
11767 | activator : 'activator', |
||
11768 | content : 'content', |
||
11769 | html : 'html', |
||
11770 | offset : 'offset', |
||
11771 | position : 'position', |
||
11772 | title : 'title', |
||
11773 | variation : 'variation' |
||
11774 | }, |
||
11775 | |||
11776 | className : { |
||
11777 | active : 'active', |
||
11778 | animating : 'animating', |
||
11779 | dropdown : 'dropdown', |
||
11780 | fluid : 'fluid', |
||
11781 | loading : 'loading', |
||
11782 | popup : 'ui popup', |
||
11783 | position : 'top left center bottom right', |
||
11784 | visible : 'visible', |
||
11785 | popupVisible : 'visible' |
||
11786 | }, |
||
11787 | |||
11788 | selector : { |
||
11789 | popup : '.ui.popup' |
||
11790 | }, |
||
11791 | |||
11792 | templates: { |
||
11793 | escape: function(string) { |
||
11794 | var |
||
11795 | badChars = /[&<>"'`]/g, |
||
11796 | shouldEscape = /[&<>"'`]/, |
||
11797 | escape = { |
||
11798 | "&": "&", |
||
11799 | "<": "<", |
||
11800 | ">": ">", |
||
11801 | '"': """, |
||
11802 | "'": "'", |
||
11803 | "`": "`" |
||
11804 | }, |
||
11805 | escapedChar = function(chr) { |
||
11806 | return escape[chr]; |
||
11807 | } |
||
11808 | ; |
||
11809 | if(shouldEscape.test(string)) { |
||
11810 | return string.replace(badChars, escapedChar); |
||
11811 | } |
||
11812 | return string; |
||
11813 | }, |
||
11814 | popup: function(text) { |
||
11815 | var |
||
11816 | html = '', |
||
11817 | escape = $.fn.popup.settings.templates.escape |
||
11818 | ; |
||
11819 | if(typeof text !== undefined) { |
||
11820 | if(typeof text.title !== undefined && text.title) { |
||
11821 | text.title = escape(text.title); |
||
11822 | html += '<div class="header">' + text.title + '</div>'; |
||
11823 | } |
||
11824 | if(typeof text.content !== undefined && text.content) { |
||
11825 | text.content = escape(text.content); |
||
11826 | html += '<div class="content">' + text.content + '</div>'; |
||
11827 | } |
||
11828 | } |
||
11829 | return html; |
||
11830 | } |
||
11831 | } |
||
11832 | |||
11833 | }; |
||
11834 | |||
11835 | |||
11836 | })( jQuery, window, document ); |
||
11837 | |||
11838 | /*! |
||
11839 | * # Semantic UI 2.2.11 - Progress |
||
11840 | * http://github.com/semantic-org/semantic-ui/ |
||
11841 | * |
||
11842 | * |
||
11843 | * Released under the MIT license |
||
11844 | * http://opensource.org/licenses/MIT |
||
11845 | * |
||
11846 | */ |
||
11847 | |||
11848 | View Code Duplication | ;(function ($, window, document, undefined) { |
|
11849 | |||
11850 | "use strict"; |
||
11851 | |||
11852 | window = (typeof window != 'undefined' && window.Math == Math) |
||
11853 | ? window |
||
11854 | : (typeof self != 'undefined' && self.Math == Math) |
||
11855 | ? self |
||
11856 | : Function('return this')() |
||
11857 | ; |
||
11858 | |||
11859 | var |
||
11860 | global = (typeof window != 'undefined' && window.Math == Math) |
||
11861 | ? window |
||
11862 | : (typeof self != 'undefined' && self.Math == Math) |
||
11863 | ? self |
||
11864 | : Function('return this')() |
||
11865 | ; |
||
11866 | |||
11867 | $.fn.progress = function(parameters) { |
||
11868 | var |
||
11869 | $allModules = $(this), |
||
11870 | |||
11871 | moduleSelector = $allModules.selector || '', |
||
11872 | |||
11873 | time = new Date().getTime(), |
||
11874 | performance = [], |
||
11875 | |||
11876 | query = arguments[0], |
||
11877 | methodInvoked = (typeof query == 'string'), |
||
11878 | queryArguments = [].slice.call(arguments, 1), |
||
11879 | |||
11880 | returnedValue |
||
11881 | ; |
||
11882 | |||
11883 | $allModules |
||
11884 | .each(function() { |
||
11885 | var |
||
11886 | settings = ( $.isPlainObject(parameters) ) |
||
11887 | ? $.extend(true, {}, $.fn.progress.settings, parameters) |
||
11888 | : $.extend({}, $.fn.progress.settings), |
||
11889 | |||
11890 | className = settings.className, |
||
11891 | metadata = settings.metadata, |
||
11892 | namespace = settings.namespace, |
||
11893 | selector = settings.selector, |
||
11894 | error = settings.error, |
||
11895 | |||
11896 | eventNamespace = '.' + namespace, |
||
11897 | moduleNamespace = 'module-' + namespace, |
||
11898 | |||
11899 | $module = $(this), |
||
11900 | $bar = $(this).find(selector.bar), |
||
11901 | $progress = $(this).find(selector.progress), |
||
11902 | $label = $(this).find(selector.label), |
||
11903 | |||
11904 | element = this, |
||
11905 | instance = $module.data(moduleNamespace), |
||
11906 | |||
11907 | animating = false, |
||
11908 | transitionEnd, |
||
11909 | module |
||
11910 | ; |
||
11911 | |||
11912 | module = { |
||
11913 | |||
11914 | initialize: function() { |
||
11915 | module.debug('Initializing progress bar', settings); |
||
11916 | |||
11917 | module.set.duration(); |
||
11918 | module.set.transitionEvent(); |
||
11919 | |||
11920 | module.read.metadata(); |
||
11921 | module.read.settings(); |
||
11922 | |||
11923 | module.instantiate(); |
||
11924 | }, |
||
11925 | |||
11926 | instantiate: function() { |
||
11927 | module.verbose('Storing instance of progress', module); |
||
11928 | instance = module; |
||
11929 | $module |
||
11930 | .data(moduleNamespace, module) |
||
11931 | ; |
||
11932 | }, |
||
11933 | destroy: function() { |
||
11934 | module.verbose('Destroying previous progress for', $module); |
||
11935 | clearInterval(instance.interval); |
||
11936 | module.remove.state(); |
||
11937 | $module.removeData(moduleNamespace); |
||
11938 | instance = undefined; |
||
11939 | }, |
||
11940 | |||
11941 | reset: function() { |
||
11942 | module.remove.nextValue(); |
||
11943 | module.update.progress(0); |
||
11944 | }, |
||
11945 | |||
11946 | complete: function() { |
||
11947 | if(module.percent === undefined || module.percent < 100) { |
||
11948 | module.remove.progressPoll(); |
||
11949 | module.set.percent(100); |
||
11950 | } |
||
11951 | }, |
||
11952 | |||
11953 | read: { |
||
11954 | metadata: function() { |
||
11955 | var |
||
11956 | data = { |
||
11957 | percent : $module.data(metadata.percent), |
||
11958 | total : $module.data(metadata.total), |
||
11959 | value : $module.data(metadata.value) |
||
11960 | } |
||
11961 | ; |
||
11962 | if(data.percent) { |
||
11963 | module.debug('Current percent value set from metadata', data.percent); |
||
11964 | module.set.percent(data.percent); |
||
11965 | } |
||
11966 | if(data.total) { |
||
11967 | module.debug('Total value set from metadata', data.total); |
||
11968 | module.set.total(data.total); |
||
11969 | } |
||
11970 | if(data.value) { |
||
11971 | module.debug('Current value set from metadata', data.value); |
||
11972 | module.set.value(data.value); |
||
11973 | module.set.progress(data.value); |
||
11974 | } |
||
11975 | }, |
||
11976 | settings: function() { |
||
11977 | if(settings.total !== false) { |
||
11978 | module.debug('Current total set in settings', settings.total); |
||
11979 | module.set.total(settings.total); |
||
11980 | } |
||
11981 | if(settings.value !== false) { |
||
11982 | module.debug('Current value set in settings', settings.value); |
||
11983 | module.set.value(settings.value); |
||
11984 | module.set.progress(module.value); |
||
11985 | } |
||
11986 | if(settings.percent !== false) { |
||
11987 | module.debug('Current percent set in settings', settings.percent); |
||
11988 | module.set.percent(settings.percent); |
||
11989 | } |
||
11990 | } |
||
11991 | }, |
||
11992 | |||
11993 | bind: { |
||
11994 | transitionEnd: function(callback) { |
||
11995 | var |
||
11996 | transitionEnd = module.get.transitionEnd() |
||
11997 | ; |
||
11998 | $bar |
||
11999 | .one(transitionEnd + eventNamespace, function(event) { |
||
12000 | clearTimeout(module.failSafeTimer); |
||
12001 | callback.call(this, event); |
||
12002 | }) |
||
12003 | ; |
||
12004 | module.failSafeTimer = setTimeout(function() { |
||
12005 | $bar.triggerHandler(transitionEnd); |
||
12006 | }, settings.duration + settings.failSafeDelay); |
||
12007 | module.verbose('Adding fail safe timer', module.timer); |
||
12008 | } |
||
12009 | }, |
||
12010 | |||
12011 | increment: function(incrementValue) { |
||
12012 | var |
||
12013 | maxValue, |
||
12014 | startValue, |
||
12015 | newValue |
||
12016 | ; |
||
12017 | if( module.has.total() ) { |
||
12018 | startValue = module.get.value(); |
||
12019 | incrementValue = incrementValue || 1; |
||
12020 | newValue = startValue + incrementValue; |
||
12021 | } |
||
12022 | else { |
||
12023 | startValue = module.get.percent(); |
||
12024 | incrementValue = incrementValue || module.get.randomValue(); |
||
12025 | |||
12026 | newValue = startValue + incrementValue; |
||
12027 | maxValue = 100; |
||
12028 | module.debug('Incrementing percentage by', startValue, newValue); |
||
12029 | } |
||
12030 | newValue = module.get.normalizedValue(newValue); |
||
12031 | module.set.progress(newValue); |
||
12032 | }, |
||
12033 | decrement: function(decrementValue) { |
||
12034 | var |
||
12035 | total = module.get.total(), |
||
12036 | startValue, |
||
12037 | newValue |
||
12038 | ; |
||
12039 | if(total) { |
||
12040 | startValue = module.get.value(); |
||
12041 | decrementValue = decrementValue || 1; |
||
12042 | newValue = startValue - decrementValue; |
||
12043 | module.debug('Decrementing value by', decrementValue, startValue); |
||
12044 | } |
||
12045 | else { |
||
12046 | startValue = module.get.percent(); |
||
12047 | decrementValue = decrementValue || module.get.randomValue(); |
||
12048 | newValue = startValue - decrementValue; |
||
12049 | module.debug('Decrementing percentage by', decrementValue, startValue); |
||
12050 | } |
||
12051 | newValue = module.get.normalizedValue(newValue); |
||
12052 | module.set.progress(newValue); |
||
12053 | }, |
||
12054 | |||
12055 | has: { |
||
12056 | progressPoll: function() { |
||
12057 | return module.progressPoll; |
||
12058 | }, |
||
12059 | total: function() { |
||
12060 | return (module.get.total() !== false); |
||
12061 | } |
||
12062 | }, |
||
12063 | |||
12064 | get: { |
||
12065 | text: function(templateText) { |
||
12066 | var |
||
12067 | value = module.value || 0, |
||
12068 | total = module.total || 0, |
||
12069 | percent = (animating) |
||
12070 | ? module.get.displayPercent() |
||
12071 | : module.percent || 0, |
||
12072 | left = (module.total > 0) |
||
12073 | ? (total - value) |
||
12074 | : (100 - percent) |
||
12075 | ; |
||
12076 | templateText = templateText || ''; |
||
12077 | templateText = templateText |
||
12078 | .replace('{value}', value) |
||
12079 | .replace('{total}', total) |
||
12080 | .replace('{left}', left) |
||
12081 | .replace('{percent}', percent) |
||
12082 | ; |
||
12083 | module.verbose('Adding variables to progress bar text', templateText); |
||
12084 | return templateText; |
||
12085 | }, |
||
12086 | |||
12087 | normalizedValue: function(value) { |
||
12088 | if(value < 0) { |
||
12089 | module.debug('Value cannot decrement below 0'); |
||
12090 | return 0; |
||
12091 | } |
||
12092 | if(module.has.total()) { |
||
12093 | if(value > module.total) { |
||
12094 | module.debug('Value cannot increment above total', module.total); |
||
12095 | return module.total; |
||
12096 | } |
||
12097 | } |
||
12098 | else if(value > 100 ) { |
||
12099 | module.debug('Value cannot increment above 100 percent'); |
||
12100 | return 100; |
||
12101 | } |
||
12102 | return value; |
||
12103 | }, |
||
12104 | |||
12105 | updateInterval: function() { |
||
12106 | if(settings.updateInterval == 'auto') { |
||
12107 | return settings.duration; |
||
12108 | } |
||
12109 | return settings.updateInterval; |
||
12110 | }, |
||
12111 | |||
12112 | randomValue: function() { |
||
12113 | module.debug('Generating random increment percentage'); |
||
12114 | return Math.floor((Math.random() * settings.random.max) + settings.random.min); |
||
12115 | }, |
||
12116 | |||
12117 | numericValue: function(value) { |
||
12118 | return (typeof value === 'string') |
||
12119 | ? (value.replace(/[^\d.]/g, '') !== '') |
||
12120 | ? +(value.replace(/[^\d.]/g, '')) |
||
12121 | : false |
||
12122 | : value |
||
12123 | ; |
||
12124 | }, |
||
12125 | |||
12126 | transitionEnd: function() { |
||
12127 | var |
||
12128 | element = document.createElement('element'), |
||
12129 | transitions = { |
||
12130 | 'transition' :'transitionend', |
||
12131 | 'OTransition' :'oTransitionEnd', |
||
12132 | 'MozTransition' :'transitionend', |
||
12133 | 'WebkitTransition' :'webkitTransitionEnd' |
||
12134 | }, |
||
12135 | transition |
||
12136 | ; |
||
12137 | for(transition in transitions){ |
||
12138 | if( element.style[transition] !== undefined ){ |
||
12139 | return transitions[transition]; |
||
12140 | } |
||
12141 | } |
||
12142 | }, |
||
12143 | |||
12144 | // gets current displayed percentage (if animating values this is the intermediary value) |
||
12145 | displayPercent: function() { |
||
12146 | var |
||
12147 | barWidth = $bar.width(), |
||
12148 | totalWidth = $module.width(), |
||
12149 | minDisplay = parseInt($bar.css('min-width'), 10), |
||
12150 | displayPercent = (barWidth > minDisplay) |
||
12151 | ? (barWidth / totalWidth * 100) |
||
12152 | : module.percent |
||
12153 | ; |
||
12154 | return (settings.precision > 0) |
||
12155 | ? Math.round(displayPercent * (10 * settings.precision)) / (10 * settings.precision) |
||
12156 | : Math.round(displayPercent) |
||
12157 | ; |
||
12158 | }, |
||
12159 | |||
12160 | percent: function() { |
||
12161 | return module.percent || 0; |
||
12162 | }, |
||
12163 | value: function() { |
||
12164 | return module.nextValue || module.value || 0; |
||
12165 | }, |
||
12166 | total: function() { |
||
12167 | return module.total || false; |
||
12168 | } |
||
12169 | }, |
||
12170 | |||
12171 | create: { |
||
12172 | progressPoll: function() { |
||
12173 | module.progressPoll = setTimeout(function() { |
||
12174 | module.update.toNextValue(); |
||
12175 | module.remove.progressPoll(); |
||
12176 | }, module.get.updateInterval()); |
||
12177 | }, |
||
12178 | }, |
||
12179 | |||
12180 | is: { |
||
12181 | complete: function() { |
||
12182 | return module.is.success() || module.is.warning() || module.is.error(); |
||
12183 | }, |
||
12184 | success: function() { |
||
12185 | return $module.hasClass(className.success); |
||
12186 | }, |
||
12187 | warning: function() { |
||
12188 | return $module.hasClass(className.warning); |
||
12189 | }, |
||
12190 | error: function() { |
||
12191 | return $module.hasClass(className.error); |
||
12192 | }, |
||
12193 | active: function() { |
||
12194 | return $module.hasClass(className.active); |
||
12195 | }, |
||
12196 | visible: function() { |
||
12197 | return $module.is(':visible'); |
||
12198 | } |
||
12199 | }, |
||
12200 | |||
12201 | remove: { |
||
12202 | progressPoll: function() { |
||
12203 | module.verbose('Removing progress poll timer'); |
||
12204 | if(module.progressPoll) { |
||
12205 | clearTimeout(module.progressPoll); |
||
12206 | delete module.progressPoll; |
||
12207 | } |
||
12208 | }, |
||
12209 | nextValue: function() { |
||
12210 | module.verbose('Removing progress value stored for next update'); |
||
12211 | delete module.nextValue; |
||
12212 | }, |
||
12213 | state: function() { |
||
12214 | module.verbose('Removing stored state'); |
||
12215 | delete module.total; |
||
12216 | delete module.percent; |
||
12217 | delete module.value; |
||
12218 | }, |
||
12219 | active: function() { |
||
12220 | module.verbose('Removing active state'); |
||
12221 | $module.removeClass(className.active); |
||
12222 | }, |
||
12223 | success: function() { |
||
12224 | module.verbose('Removing success state'); |
||
12225 | $module.removeClass(className.success); |
||
12226 | }, |
||
12227 | warning: function() { |
||
12228 | module.verbose('Removing warning state'); |
||
12229 | $module.removeClass(className.warning); |
||
12230 | }, |
||
12231 | error: function() { |
||
12232 | module.verbose('Removing error state'); |
||
12233 | $module.removeClass(className.error); |
||
12234 | } |
||
12235 | }, |
||
12236 | |||
12237 | set: { |
||
12238 | barWidth: function(value) { |
||
12239 | if(value > 100) { |
||
12240 | module.error(error.tooHigh, value); |
||
12241 | } |
||
12242 | else if (value < 0) { |
||
12243 | module.error(error.tooLow, value); |
||
12244 | } |
||
12245 | else { |
||
12246 | $bar |
||
12247 | .css('width', value + '%') |
||
12248 | ; |
||
12249 | $module |
||
12250 | .attr('data-percent', parseInt(value, 10)) |
||
12251 | ; |
||
12252 | } |
||
12253 | }, |
||
12254 | duration: function(duration) { |
||
12255 | duration = duration || settings.duration; |
||
12256 | duration = (typeof duration == 'number') |
||
12257 | ? duration + 'ms' |
||
12258 | : duration |
||
12259 | ; |
||
12260 | module.verbose('Setting progress bar transition duration', duration); |
||
12261 | $bar |
||
12262 | .css({ |
||
12263 | 'transition-duration': duration |
||
12264 | }) |
||
12265 | ; |
||
12266 | }, |
||
12267 | percent: function(percent) { |
||
12268 | percent = (typeof percent == 'string') |
||
12269 | ? +(percent.replace('%', '')) |
||
12270 | : percent |
||
12271 | ; |
||
12272 | // round display percentage |
||
12273 | percent = (settings.precision > 0) |
||
12274 | ? Math.round(percent * (10 * settings.precision)) / (10 * settings.precision) |
||
12275 | : Math.round(percent) |
||
12276 | ; |
||
12277 | module.percent = percent; |
||
12278 | if( !module.has.total() ) { |
||
12279 | module.value = (settings.precision > 0) |
||
12280 | ? Math.round( (percent / 100) * module.total * (10 * settings.precision)) / (10 * settings.precision) |
||
12281 | : Math.round( (percent / 100) * module.total * 10) / 10 |
||
12282 | ; |
||
12283 | if(settings.limitValues) { |
||
12284 | module.value = (module.value > 100) |
||
12285 | ? 100 |
||
12286 | : (module.value < 0) |
||
12287 | ? 0 |
||
12288 | : module.value |
||
12289 | ; |
||
12290 | } |
||
12291 | } |
||
12292 | module.set.barWidth(percent); |
||
12293 | module.set.labelInterval(); |
||
12294 | module.set.labels(); |
||
12295 | settings.onChange.call(element, percent, module.value, module.total); |
||
12296 | }, |
||
12297 | labelInterval: function() { |
||
12298 | var |
||
12299 | animationCallback = function() { |
||
12300 | module.verbose('Bar finished animating, removing continuous label updates'); |
||
12301 | clearInterval(module.interval); |
||
12302 | animating = false; |
||
12303 | module.set.labels(); |
||
12304 | } |
||
12305 | ; |
||
12306 | clearInterval(module.interval); |
||
12307 | module.bind.transitionEnd(animationCallback); |
||
12308 | animating = true; |
||
12309 | module.interval = setInterval(function() { |
||
12310 | var |
||
12311 | isInDOM = $.contains(document.documentElement, element) |
||
12312 | ; |
||
12313 | if(!isInDOM) { |
||
12314 | clearInterval(module.interval); |
||
12315 | animating = false; |
||
12316 | } |
||
12317 | module.set.labels(); |
||
12318 | }, settings.framerate); |
||
12319 | }, |
||
12320 | labels: function() { |
||
12321 | module.verbose('Setting both bar progress and outer label text'); |
||
12322 | module.set.barLabel(); |
||
12323 | module.set.state(); |
||
12324 | }, |
||
12325 | label: function(text) { |
||
12326 | text = text || ''; |
||
12327 | if(text) { |
||
12328 | text = module.get.text(text); |
||
12329 | module.verbose('Setting label to text', text); |
||
12330 | $label.text(text); |
||
12331 | } |
||
12332 | }, |
||
12333 | state: function(percent) { |
||
12334 | percent = (percent !== undefined) |
||
12335 | ? percent |
||
12336 | : module.percent |
||
12337 | ; |
||
12338 | if(percent === 100) { |
||
12339 | if(settings.autoSuccess && !(module.is.warning() || module.is.error() || module.is.success())) { |
||
12340 | module.set.success(); |
||
12341 | module.debug('Automatically triggering success at 100%'); |
||
12342 | } |
||
12343 | else { |
||
12344 | module.verbose('Reached 100% removing active state'); |
||
12345 | module.remove.active(); |
||
12346 | module.remove.progressPoll(); |
||
12347 | } |
||
12348 | } |
||
12349 | else if(percent > 0) { |
||
12350 | module.verbose('Adjusting active progress bar label', percent); |
||
12351 | module.set.active(); |
||
12352 | } |
||
12353 | else { |
||
12354 | module.remove.active(); |
||
12355 | module.set.label(settings.text.active); |
||
12356 | } |
||
12357 | }, |
||
12358 | barLabel: function(text) { |
||
12359 | if(text !== undefined) { |
||
12360 | $progress.text( module.get.text(text) ); |
||
12361 | } |
||
12362 | else if(settings.label == 'ratio' && module.total) { |
||
12363 | module.verbose('Adding ratio to bar label'); |
||
12364 | $progress.text( module.get.text(settings.text.ratio) ); |
||
12365 | } |
||
12366 | else if(settings.label == 'percent') { |
||
12367 | module.verbose('Adding percentage to bar label'); |
||
12368 | $progress.text( module.get.text(settings.text.percent) ); |
||
12369 | } |
||
12370 | }, |
||
12371 | active: function(text) { |
||
12372 | text = text || settings.text.active; |
||
12373 | module.debug('Setting active state'); |
||
12374 | if(settings.showActivity && !module.is.active() ) { |
||
12375 | $module.addClass(className.active); |
||
12376 | } |
||
12377 | module.remove.warning(); |
||
12378 | module.remove.error(); |
||
12379 | module.remove.success(); |
||
12380 | text = settings.onLabelUpdate('active', text, module.value, module.total); |
||
12381 | if(text) { |
||
12382 | module.set.label(text); |
||
12383 | } |
||
12384 | module.bind.transitionEnd(function() { |
||
12385 | settings.onActive.call(element, module.value, module.total); |
||
12386 | }); |
||
12387 | }, |
||
12388 | success : function(text) { |
||
12389 | text = text || settings.text.success || settings.text.active; |
||
12390 | module.debug('Setting success state'); |
||
12391 | $module.addClass(className.success); |
||
12392 | module.remove.active(); |
||
12393 | module.remove.warning(); |
||
12394 | module.remove.error(); |
||
12395 | module.complete(); |
||
12396 | if(settings.text.success) { |
||
12397 | text = settings.onLabelUpdate('success', text, module.value, module.total); |
||
12398 | module.set.label(text); |
||
12399 | } |
||
12400 | else { |
||
12401 | text = settings.onLabelUpdate('active', text, module.value, module.total); |
||
12402 | module.set.label(text); |
||
12403 | } |
||
12404 | module.bind.transitionEnd(function() { |
||
12405 | settings.onSuccess.call(element, module.total); |
||
12406 | }); |
||
12407 | }, |
||
12408 | warning : function(text) { |
||
12409 | text = text || settings.text.warning; |
||
12410 | module.debug('Setting warning state'); |
||
12411 | $module.addClass(className.warning); |
||
12412 | module.remove.active(); |
||
12413 | module.remove.success(); |
||
12414 | module.remove.error(); |
||
12415 | module.complete(); |
||
12416 | text = settings.onLabelUpdate('warning', text, module.value, module.total); |
||
12417 | if(text) { |
||
12418 | module.set.label(text); |
||
12419 | } |
||
12420 | module.bind.transitionEnd(function() { |
||
12421 | settings.onWarning.call(element, module.value, module.total); |
||
12422 | }); |
||
12423 | }, |
||
12424 | error : function(text) { |
||
12425 | text = text || settings.text.error; |
||
12426 | module.debug('Setting error state'); |
||
12427 | $module.addClass(className.error); |
||
12428 | module.remove.active(); |
||
12429 | module.remove.success(); |
||
12430 | module.remove.warning(); |
||
12431 | module.complete(); |
||
12432 | text = settings.onLabelUpdate('error', text, module.value, module.total); |
||
12433 | if(text) { |
||
12434 | module.set.label(text); |
||
12435 | } |
||
12436 | module.bind.transitionEnd(function() { |
||
12437 | settings.onError.call(element, module.value, module.total); |
||
12438 | }); |
||
12439 | }, |
||
12440 | transitionEvent: function() { |
||
12441 | transitionEnd = module.get.transitionEnd(); |
||
12442 | }, |
||
12443 | total: function(totalValue) { |
||
12444 | module.total = totalValue; |
||
12445 | }, |
||
12446 | value: function(value) { |
||
12447 | module.value = value; |
||
12448 | }, |
||
12449 | progress: function(value) { |
||
12450 | if(!module.has.progressPoll()) { |
||
12451 | module.debug('First update in progress update interval, immediately updating', value); |
||
12452 | module.update.progress(value); |
||
12453 | module.create.progressPoll(); |
||
12454 | } |
||
12455 | else { |
||
12456 | module.debug('Updated within interval, setting next update to use new value', value); |
||
12457 | module.set.nextValue(value); |
||
12458 | } |
||
12459 | }, |
||
12460 | nextValue: function(value) { |
||
12461 | module.nextValue = value; |
||
12462 | } |
||
12463 | }, |
||
12464 | |||
12465 | update: { |
||
12466 | toNextValue: function() { |
||
12467 | var |
||
12468 | nextValue = module.nextValue |
||
12469 | ; |
||
12470 | if(nextValue) { |
||
12471 | module.debug('Update interval complete using last updated value', nextValue); |
||
12472 | module.update.progress(nextValue); |
||
12473 | module.remove.nextValue(); |
||
12474 | } |
||
12475 | }, |
||
12476 | progress: function(value) { |
||
12477 | var |
||
12478 | percentComplete |
||
12479 | ; |
||
12480 | value = module.get.numericValue(value); |
||
12481 | if(value === false) { |
||
12482 | module.error(error.nonNumeric, value); |
||
12483 | } |
||
12484 | value = module.get.normalizedValue(value); |
||
12485 | if( module.has.total() ) { |
||
12486 | module.set.value(value); |
||
12487 | percentComplete = (value / module.total) * 100; |
||
12488 | module.debug('Calculating percent complete from total', percentComplete); |
||
12489 | module.set.percent( percentComplete ); |
||
12490 | } |
||
12491 | else { |
||
12492 | percentComplete = value; |
||
12493 | module.debug('Setting value to exact percentage value', percentComplete); |
||
12494 | module.set.percent( percentComplete ); |
||
12495 | } |
||
12496 | } |
||
12497 | }, |
||
12498 | |||
12499 | setting: function(name, value) { |
||
12500 | module.debug('Changing setting', name, value); |
||
12501 | if( $.isPlainObject(name) ) { |
||
12502 | $.extend(true, settings, name); |
||
12503 | } |
||
12504 | else if(value !== undefined) { |
||
12505 | if($.isPlainObject(settings[name])) { |
||
12506 | $.extend(true, settings[name], value); |
||
12507 | } |
||
12508 | else { |
||
12509 | settings[name] = value; |
||
12510 | } |
||
12511 | } |
||
12512 | else { |
||
12513 | return settings[name]; |
||
12514 | } |
||
12515 | }, |
||
12516 | internal: function(name, value) { |
||
12517 | if( $.isPlainObject(name) ) { |
||
12518 | $.extend(true, module, name); |
||
12519 | } |
||
12520 | else if(value !== undefined) { |
||
12521 | module[name] = value; |
||
12522 | } |
||
12523 | else { |
||
12524 | return module[name]; |
||
12525 | } |
||
12526 | }, |
||
12527 | debug: function() { |
||
12528 | if(!settings.silent && settings.debug) { |
||
12529 | if(settings.performance) { |
||
12530 | module.performance.log(arguments); |
||
12531 | } |
||
12532 | else { |
||
12533 | module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':'); |
||
12534 | module.debug.apply(console, arguments); |
||
12535 | } |
||
12536 | } |
||
12537 | }, |
||
12538 | verbose: function() { |
||
12539 | if(!settings.silent && settings.verbose && settings.debug) { |
||
12540 | if(settings.performance) { |
||
12541 | module.performance.log(arguments); |
||
12542 | } |
||
12543 | else { |
||
12544 | module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':'); |
||
12545 | module.verbose.apply(console, arguments); |
||
12546 | } |
||
12547 | } |
||
12548 | }, |
||
12549 | error: function() { |
||
12550 | if(!settings.silent) { |
||
12551 | module.error = Function.prototype.bind.call(console.error, console, settings.name + ':'); |
||
12552 | module.error.apply(console, arguments); |
||
12553 | } |
||
12554 | }, |
||
12555 | performance: { |
||
12556 | log: function(message) { |
||
12557 | var |
||
12558 | currentTime, |
||
12559 | executionTime, |
||
12560 | previousTime |
||
12561 | ; |
||
12562 | if(settings.performance) { |
||
12563 | currentTime = new Date().getTime(); |
||
12564 | previousTime = time || currentTime; |
||
12565 | executionTime = currentTime - previousTime; |
||
12566 | time = currentTime; |
||
12567 | performance.push({ |
||
12568 | 'Name' : message[0], |
||
12569 | 'Arguments' : [].slice.call(message, 1) || '', |
||
12570 | 'Element' : element, |
||
12571 | 'Execution Time' : executionTime |
||
12572 | }); |
||
12573 | } |
||
12574 | clearTimeout(module.performance.timer); |
||
12575 | module.performance.timer = setTimeout(module.performance.display, 500); |
||
12576 | }, |
||
12577 | display: function() { |
||
12578 | var |
||
12579 | title = settings.name + ':', |
||
12580 | totalTime = 0 |
||
12581 | ; |
||
12582 | time = false; |
||
12583 | clearTimeout(module.performance.timer); |
||
12584 | $.each(performance, function(index, data) { |
||
12585 | totalTime += data['Execution Time']; |
||
12586 | }); |
||
12587 | title += ' ' + totalTime + 'ms'; |
||
12588 | if(moduleSelector) { |
||
12589 | title += ' \'' + moduleSelector + '\''; |
||
12590 | } |
||
12591 | if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) { |
||
12592 | console.groupCollapsed(title); |
||
12593 | if(console.table) { |
||
12594 | console.table(performance); |
||
12595 | } |
||
12596 | else { |
||
12597 | $.each(performance, function(index, data) { |
||
12598 | console.log(data['Name'] + ': ' + data['Execution Time']+'ms'); |
||
12599 | }); |
||
12600 | } |
||
12601 | console.groupEnd(); |
||
12602 | } |
||
12603 | performance = []; |
||
12604 | } |
||
12605 | }, |
||
12606 | invoke: function(query, passedArguments, context) { |
||
12607 | var |
||
12608 | object = instance, |
||
12609 | maxDepth, |
||
12610 | found, |
||
12611 | response |
||
12612 | ; |
||
12613 | passedArguments = passedArguments || queryArguments; |
||
12614 | context = element || context; |
||
12615 | if(typeof query == 'string' && object !== undefined) { |
||
12616 | query = query.split(/[\. ]/); |
||
12617 | maxDepth = query.length - 1; |
||
12618 | $.each(query, function(depth, value) { |
||
12619 | var camelCaseValue = (depth != maxDepth) |
||
12620 | ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1) |
||
12621 | : query |
||
12622 | ; |
||
12623 | if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) { |
||
12624 | object = object[camelCaseValue]; |
||
12625 | } |
||
12626 | else if( object[camelCaseValue] !== undefined ) { |
||
12627 | found = object[camelCaseValue]; |
||
12628 | return false; |
||
12629 | } |
||
12630 | else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) { |
||
12631 | object = object[value]; |
||
12632 | } |
||
12633 | else if( object[value] !== undefined ) { |
||
12634 | found = object[value]; |
||
12635 | return false; |
||
12636 | } |
||
12637 | else { |
||
12638 | module.error(error.method, query); |
||
12639 | return false; |
||
12640 | } |
||
12641 | }); |
||
12642 | } |
||
12643 | if ( $.isFunction( found ) ) { |
||
12644 | response = found.apply(context, passedArguments); |
||
12645 | } |
||
12646 | else if(found !== undefined) { |
||
12647 | response = found; |
||
12648 | } |
||
12649 | if($.isArray(returnedValue)) { |
||
12650 | returnedValue.push(response); |
||
12651 | } |
||
12652 | else if(returnedValue !== undefined) { |
||
12653 | returnedValue = [returnedValue, response]; |
||
12654 | } |
||
12655 | else if(response !== undefined) { |
||
12656 | returnedValue = response; |
||
12657 | } |
||
12658 | return found; |
||
12659 | } |
||
12660 | }; |
||
12661 | |||
12662 | if(methodInvoked) { |
||
12663 | if(instance === undefined) { |
||
12664 | module.initialize(); |
||
12665 | } |
||
12666 | module.invoke(query); |
||
12667 | } |
||
12668 | else { |
||
12669 | if(instance !== undefined) { |
||
12670 | instance.invoke('destroy'); |
||
12671 | } |
||
12672 | module.initialize(); |
||
12673 | } |
||
12674 | }) |
||
12675 | ; |
||
12676 | |||
12677 | return (returnedValue !== undefined) |
||
12678 | ? returnedValue |
||
12679 | : this |
||
12680 | ; |
||
12681 | }; |
||
12682 | |||
12683 | $.fn.progress.settings = { |
||
12684 | |||
12685 | name : 'Progress', |
||
12686 | namespace : 'progress', |
||
12687 | |||
12688 | silent : false, |
||
12689 | debug : false, |
||
12690 | verbose : false, |
||
12691 | performance : true, |
||
12692 | |||
12693 | random : { |
||
12694 | min : 2, |
||
12695 | max : 5 |
||
12696 | }, |
||
12697 | |||
12698 | duration : 300, |
||
12699 | |||
12700 | updateInterval : 'auto', |
||
12701 | |||
12702 | autoSuccess : true, |
||
12703 | showActivity : true, |
||
12704 | limitValues : true, |
||
12705 | |||
12706 | label : 'percent', |
||
12707 | precision : 0, |
||
12708 | framerate : (1000 / 30), /// 30 fps |
||
12709 | |||
12710 | percent : false, |
||
12711 | total : false, |
||
12712 | value : false, |
||
12713 | |||
12714 | // delay in ms for fail safe animation callback |
||
12715 | failSafeDelay : 100, |
||
12716 | |||
12717 | onLabelUpdate : function(state, text, value, total){ |
||
12718 | return text; |
||
12719 | }, |
||
12720 | onChange : function(percent, value, total){}, |
||
12721 | onSuccess : function(total){}, |
||
12722 | onActive : function(value, total){}, |
||
12723 | onError : function(value, total){}, |
||
12724 | onWarning : function(value, total){}, |
||
12725 | |||
12726 | error : { |
||
12727 | method : 'The method you called is not defined.', |
||
12728 | nonNumeric : 'Progress value is non numeric', |
||
12729 | tooHigh : 'Value specified is above 100%', |
||
12730 | tooLow : 'Value specified is below 0%' |
||
12731 | }, |
||
12732 | |||
12733 | regExp: { |
||
12734 | variable: /\{\$*[A-z0-9]+\}/g |
||
12735 | }, |
||
12736 | |||
12737 | metadata: { |
||
12738 | percent : 'percent', |
||
12739 | total : 'total', |
||
12740 | value : 'value' |
||
12741 | }, |
||
12742 | |||
12743 | selector : { |
||
12744 | bar : '> .bar', |
||
12745 | label : '> .label', |
||
12746 | progress : '.bar > .progress' |
||
12747 | }, |
||
12748 | |||
12749 | text : { |
||
12750 | active : false, |
||
12751 | error : false, |
||
12752 | success : false, |
||
12753 | warning : false, |
||
12754 | percent : '{percent}%', |
||
12755 | ratio : '{value} of {total}' |
||
12756 | }, |
||
12757 | |||
12758 | className : { |
||
12759 | active : 'active', |
||
12760 | error : 'error', |
||
12761 | success : 'success', |
||
12762 | warning : 'warning' |
||
12763 | } |
||
12764 | |||
12765 | }; |
||
12766 | |||
12767 | |||
12768 | })( jQuery, window, document ); |
||
12769 | |||
12770 | /*! |
||
12771 | * # Semantic UI 2.2.11 - Rating |
||
12772 | * http://github.com/semantic-org/semantic-ui/ |
||
12773 | * |
||
12774 | * |
||
12775 | * Released under the MIT license |
||
12776 | * http://opensource.org/licenses/MIT |
||
12777 | * |
||
12778 | */ |
||
12779 | |||
12780 | View Code Duplication | ;(function ($, window, document, undefined) { |
|
12781 | |||
12782 | "use strict"; |
||
12783 | |||
12784 | window = (typeof window != 'undefined' && window.Math == Math) |
||
12785 | ? window |
||
12786 | : (typeof self != 'undefined' && self.Math == Math) |
||
12787 | ? self |
||
12788 | : Function('return this')() |
||
12789 | ; |
||
12790 | |||
12791 | $.fn.rating = function(parameters) { |
||
12792 | var |
||
12793 | $allModules = $(this), |
||
12794 | moduleSelector = $allModules.selector || '', |
||
12795 | |||
12796 | time = new Date().getTime(), |
||
12797 | performance = [], |
||
12798 | |||
12799 | query = arguments[0], |
||
12800 | methodInvoked = (typeof query == 'string'), |
||
12801 | queryArguments = [].slice.call(arguments, 1), |
||
12802 | returnedValue |
||
12803 | ; |
||
12804 | $allModules |
||
12805 | .each(function() { |
||
12806 | var |
||
12807 | settings = ( $.isPlainObject(parameters) ) |
||
12808 | ? $.extend(true, {}, $.fn.rating.settings, parameters) |
||
12809 | : $.extend({}, $.fn.rating.settings), |
||
12810 | |||
12811 | namespace = settings.namespace, |
||
12812 | className = settings.className, |
||
12813 | metadata = settings.metadata, |
||
12814 | selector = settings.selector, |
||
12815 | error = settings.error, |
||
12816 | |||
12817 | eventNamespace = '.' + namespace, |
||
12818 | moduleNamespace = 'module-' + namespace, |
||
12819 | |||
12820 | element = this, |
||
12821 | instance = $(this).data(moduleNamespace), |
||
12822 | |||
12823 | $module = $(this), |
||
12824 | $icon = $module.find(selector.icon), |
||
12825 | |||
12826 | initialLoad, |
||
12827 | module |
||
12828 | ; |
||
12829 | |||
12830 | module = { |
||
12831 | |||
12832 | initialize: function() { |
||
12833 | module.verbose('Initializing rating module', settings); |
||
12834 | |||
12835 | if($icon.length === 0) { |
||
12836 | module.setup.layout(); |
||
12837 | } |
||
12838 | |||
12839 | if(settings.interactive) { |
||
12840 | module.enable(); |
||
12841 | } |
||
12842 | else { |
||
12843 | module.disable(); |
||
12844 | } |
||
12845 | module.set.initialLoad(); |
||
12846 | module.set.rating( module.get.initialRating() ); |
||
12847 | module.remove.initialLoad(); |
||
12848 | module.instantiate(); |
||
12849 | }, |
||
12850 | |||
12851 | instantiate: function() { |
||
12852 | module.verbose('Instantiating module', settings); |
||
12853 | instance = module; |
||
12854 | $module |
||
12855 | .data(moduleNamespace, module) |
||
12856 | ; |
||
12857 | }, |
||
12858 | |||
12859 | destroy: function() { |
||
12860 | module.verbose('Destroying previous instance', instance); |
||
12861 | module.remove.events(); |
||
12862 | $module |
||
12863 | .removeData(moduleNamespace) |
||
12864 | ; |
||
12865 | }, |
||
12866 | |||
12867 | refresh: function() { |
||
12868 | $icon = $module.find(selector.icon); |
||
12869 | }, |
||
12870 | |||
12871 | setup: { |
||
12872 | layout: function() { |
||
12873 | var |
||
12874 | maxRating = module.get.maxRating(), |
||
12875 | html = $.fn.rating.settings.templates.icon(maxRating) |
||
12876 | ; |
||
12877 | module.debug('Generating icon html dynamically'); |
||
12878 | $module |
||
12879 | .html(html) |
||
12880 | ; |
||
12881 | module.refresh(); |
||
12882 | } |
||
12883 | }, |
||
12884 | |||
12885 | event: { |
||
12886 | mouseenter: function() { |
||
12887 | var |
||
12888 | $activeIcon = $(this) |
||
12889 | ; |
||
12890 | $activeIcon |
||
12891 | .nextAll() |
||
12892 | .removeClass(className.selected) |
||
12893 | ; |
||
12894 | $module |
||
12895 | .addClass(className.selected) |
||
12896 | ; |
||
12897 | $activeIcon |
||
12898 | .addClass(className.selected) |
||
12899 | .prevAll() |
||
12900 | .addClass(className.selected) |
||
12901 | ; |
||
12902 | }, |
||
12903 | mouseleave: function() { |
||
12904 | $module |
||
12905 | .removeClass(className.selected) |
||
12906 | ; |
||
12907 | $icon |
||
12908 | .removeClass(className.selected) |
||
12909 | ; |
||
12910 | }, |
||
12911 | click: function() { |
||
12912 | var |
||
12913 | $activeIcon = $(this), |
||
12914 | currentRating = module.get.rating(), |
||
12915 | rating = $icon.index($activeIcon) + 1, |
||
12916 | canClear = (settings.clearable == 'auto') |
||
12917 | ? ($icon.length === 1) |
||
12918 | : settings.clearable |
||
12919 | ; |
||
12920 | if(canClear && currentRating == rating) { |
||
12921 | module.clearRating(); |
||
12922 | } |
||
12923 | else { |
||
12924 | module.set.rating( rating ); |
||
12925 | } |
||
12926 | } |
||
12927 | }, |
||
12928 | |||
12929 | clearRating: function() { |
||
12930 | module.debug('Clearing current rating'); |
||
12931 | module.set.rating(0); |
||
12932 | }, |
||
12933 | |||
12934 | bind: { |
||
12935 | events: function() { |
||
12936 | module.verbose('Binding events'); |
||
12937 | $module |
||
12938 | .on('mouseenter' + eventNamespace, selector.icon, module.event.mouseenter) |
||
12939 | .on('mouseleave' + eventNamespace, selector.icon, module.event.mouseleave) |
||
12940 | .on('click' + eventNamespace, selector.icon, module.event.click) |
||
12941 | ; |
||
12942 | } |
||
12943 | }, |
||
12944 | |||
12945 | remove: { |
||
12946 | events: function() { |
||
12947 | module.verbose('Removing events'); |
||
12948 | $module |
||
12949 | .off(eventNamespace) |
||
12950 | ; |
||
12951 | }, |
||
12952 | initialLoad: function() { |
||
12953 | initialLoad = false; |
||
12954 | } |
||
12955 | }, |
||
12956 | |||
12957 | enable: function() { |
||
12958 | module.debug('Setting rating to interactive mode'); |
||
12959 | module.bind.events(); |
||
12960 | $module |
||
12961 | .removeClass(className.disabled) |
||
12962 | ; |
||
12963 | }, |
||
12964 | |||
12965 | disable: function() { |
||
12966 | module.debug('Setting rating to read-only mode'); |
||
12967 | module.remove.events(); |
||
12968 | $module |
||
12969 | .addClass(className.disabled) |
||
12970 | ; |
||
12971 | }, |
||
12972 | |||
12973 | is: { |
||
12974 | initialLoad: function() { |
||
12975 | return initialLoad; |
||
12976 | } |
||
12977 | }, |
||
12978 | |||
12979 | get: { |
||
12980 | initialRating: function() { |
||
12981 | if($module.data(metadata.rating) !== undefined) { |
||
12982 | $module.removeData(metadata.rating); |
||
12983 | return $module.data(metadata.rating); |
||
12984 | } |
||
12985 | return settings.initialRating; |
||
12986 | }, |
||
12987 | maxRating: function() { |
||
12988 | if($module.data(metadata.maxRating) !== undefined) { |
||
12989 | $module.removeData(metadata.maxRating); |
||
12990 | return $module.data(metadata.maxRating); |
||
12991 | } |
||
12992 | return settings.maxRating; |
||
12993 | }, |
||
12994 | rating: function() { |
||
12995 | var |
||
12996 | currentRating = $icon.filter('.' + className.active).length |
||
12997 | ; |
||
12998 | module.verbose('Current rating retrieved', currentRating); |
||
12999 | return currentRating; |
||
13000 | } |
||
13001 | }, |
||
13002 | |||
13003 | set: { |
||
13004 | rating: function(rating) { |
||
13005 | var |
||
13006 | ratingIndex = (rating - 1 >= 0) |
||
13007 | ? (rating - 1) |
||
13008 | : 0, |
||
13009 | $activeIcon = $icon.eq(ratingIndex) |
||
13010 | ; |
||
13011 | $module |
||
13012 | .removeClass(className.selected) |
||
13013 | ; |
||
13014 | $icon |
||
13015 | .removeClass(className.selected) |
||
13016 | .removeClass(className.active) |
||
13017 | ; |
||
13018 | if(rating > 0) { |
||
13019 | module.verbose('Setting current rating to', rating); |
||
13020 | $activeIcon |
||
13021 | .prevAll() |
||
13022 | .addBack() |
||
13023 | .addClass(className.active) |
||
13024 | ; |
||
13025 | } |
||
13026 | if(!module.is.initialLoad()) { |
||
13027 | settings.onRate.call(element, rating); |
||
13028 | } |
||
13029 | }, |
||
13030 | initialLoad: function() { |
||
13031 | initialLoad = true; |
||
13032 | } |
||
13033 | }, |
||
13034 | |||
13035 | setting: function(name, value) { |
||
13036 | module.debug('Changing setting', name, value); |
||
13037 | if( $.isPlainObject(name) ) { |
||
13038 | $.extend(true, settings, name); |
||
13039 | } |
||
13040 | else if(value !== undefined) { |
||
13041 | if($.isPlainObject(settings[name])) { |
||
13042 | $.extend(true, settings[name], value); |
||
13043 | } |
||
13044 | else { |
||
13045 | settings[name] = value; |
||
13046 | } |
||
13047 | } |
||
13048 | else { |
||
13049 | return settings[name]; |
||
13050 | } |
||
13051 | }, |
||
13052 | internal: function(name, value) { |
||
13053 | if( $.isPlainObject(name) ) { |
||
13054 | $.extend(true, module, name); |
||
13055 | } |
||
13056 | else if(value !== undefined) { |
||
13057 | module[name] = value; |
||
13058 | } |
||
13059 | else { |
||
13060 | return module[name]; |
||
13061 | } |
||
13062 | }, |
||
13063 | debug: function() { |
||
13064 | if(!settings.silent && settings.debug) { |
||
13065 | if(settings.performance) { |
||
13066 | module.performance.log(arguments); |
||
13067 | } |
||
13068 | else { |
||
13069 | module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':'); |
||
13070 | module.debug.apply(console, arguments); |
||
13071 | } |
||
13072 | } |
||
13073 | }, |
||
13074 | verbose: function() { |
||
13075 | if(!settings.silent && settings.verbose && settings.debug) { |
||
13076 | if(settings.performance) { |
||
13077 | module.performance.log(arguments); |
||
13078 | } |
||
13079 | else { |
||
13080 | module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':'); |
||
13081 | module.verbose.apply(console, arguments); |
||
13082 | } |
||
13083 | } |
||
13084 | }, |
||
13085 | error: function() { |
||
13086 | if(!settings.silent) { |
||
13087 | module.error = Function.prototype.bind.call(console.error, console, settings.name + ':'); |
||
13088 | module.error.apply(console, arguments); |
||
13089 | } |
||
13090 | }, |
||
13091 | performance: { |
||
13092 | log: function(message) { |
||
13093 | var |
||
13094 | currentTime, |
||
13095 | executionTime, |
||
13096 | previousTime |
||
13097 | ; |
||
13098 | if(settings.performance) { |
||
13099 | currentTime = new Date().getTime(); |
||
13100 | previousTime = time || currentTime; |
||
13101 | executionTime = currentTime - previousTime; |
||
13102 | time = currentTime; |
||
13103 | performance.push({ |
||
13104 | 'Name' : message[0], |
||
13105 | 'Arguments' : [].slice.call(message, 1) || '', |
||
13106 | 'Element' : element, |
||
13107 | 'Execution Time' : executionTime |
||
13108 | }); |
||
13109 | } |
||
13110 | clearTimeout(module.performance.timer); |
||
13111 | module.performance.timer = setTimeout(module.performance.display, 500); |
||
13112 | }, |
||
13113 | display: function() { |
||
13114 | var |
||
13115 | title = settings.name + ':', |
||
13116 | totalTime = 0 |
||
13117 | ; |
||
13118 | time = false; |
||
13119 | clearTimeout(module.performance.timer); |
||
13120 | $.each(performance, function(index, data) { |
||
13121 | totalTime += data['Execution Time']; |
||
13122 | }); |
||
13123 | title += ' ' + totalTime + 'ms'; |
||
13124 | if(moduleSelector) { |
||
13125 | title += ' \'' + moduleSelector + '\''; |
||
13126 | } |
||
13127 | if($allModules.length > 1) { |
||
13128 | title += ' ' + '(' + $allModules.length + ')'; |
||
13129 | } |
||
13130 | if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) { |
||
13131 | console.groupCollapsed(title); |
||
13132 | if(console.table) { |
||
13133 | console.table(performance); |
||
13134 | } |
||
13135 | else { |
||
13136 | $.each(performance, function(index, data) { |
||
13137 | console.log(data['Name'] + ': ' + data['Execution Time']+'ms'); |
||
13138 | }); |
||
13139 | } |
||
13140 | console.groupEnd(); |
||
13141 | } |
||
13142 | performance = []; |
||
13143 | } |
||
13144 | }, |
||
13145 | invoke: function(query, passedArguments, context) { |
||
13146 | var |
||
13147 | object = instance, |
||
13148 | maxDepth, |
||
13149 | found, |
||
13150 | response |
||
13151 | ; |
||
13152 | passedArguments = passedArguments || queryArguments; |
||
13153 | context = element || context; |
||
13154 | if(typeof query == 'string' && object !== undefined) { |
||
13155 | query = query.split(/[\. ]/); |
||
13156 | maxDepth = query.length - 1; |
||
13157 | $.each(query, function(depth, value) { |
||
13158 | var camelCaseValue = (depth != maxDepth) |
||
13159 | ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1) |
||
13160 | : query |
||
13161 | ; |
||
13162 | if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) { |
||
13163 | object = object[camelCaseValue]; |
||
13164 | } |
||
13165 | else if( object[camelCaseValue] !== undefined ) { |
||
13166 | found = object[camelCaseValue]; |
||
13167 | return false; |
||
13168 | } |
||
13169 | else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) { |
||
13170 | object = object[value]; |
||
13171 | } |
||
13172 | else if( object[value] !== undefined ) { |
||
13173 | found = object[value]; |
||
13174 | return false; |
||
13175 | } |
||
13176 | else { |
||
13177 | return false; |
||
13178 | } |
||
13179 | }); |
||
13180 | } |
||
13181 | if ( $.isFunction( found ) ) { |
||
13182 | response = found.apply(context, passedArguments); |
||
13183 | } |
||
13184 | else if(found !== undefined) { |
||
13185 | response = found; |
||
13186 | } |
||
13187 | if($.isArray(returnedValue)) { |
||
13188 | returnedValue.push(response); |
||
13189 | } |
||
13190 | else if(returnedValue !== undefined) { |
||
13191 | returnedValue = [returnedValue, response]; |
||
13192 | } |
||
13193 | else if(response !== undefined) { |
||
13194 | returnedValue = response; |
||
13195 | } |
||
13196 | return found; |
||
13197 | } |
||
13198 | }; |
||
13199 | if(methodInvoked) { |
||
13200 | if(instance === undefined) { |
||
13201 | module.initialize(); |
||
13202 | } |
||
13203 | module.invoke(query); |
||
13204 | } |
||
13205 | else { |
||
13206 | if(instance !== undefined) { |
||
13207 | instance.invoke('destroy'); |
||
13208 | } |
||
13209 | module.initialize(); |
||
13210 | } |
||
13211 | }) |
||
13212 | ; |
||
13213 | |||
13214 | return (returnedValue !== undefined) |
||
13215 | ? returnedValue |
||
13216 | : this |
||
13217 | ; |
||
13218 | }; |
||
13219 | |||
13220 | $.fn.rating.settings = { |
||
13221 | |||
13222 | name : 'Rating', |
||
13223 | namespace : 'rating', |
||
13224 | |||
13225 | slent : false, |
||
13226 | debug : false, |
||
13227 | verbose : false, |
||
13228 | performance : true, |
||
13229 | |||
13230 | initialRating : 0, |
||
13231 | interactive : true, |
||
13232 | maxRating : 4, |
||
13233 | clearable : 'auto', |
||
13234 | |||
13235 | fireOnInit : false, |
||
13236 | |||
13237 | onRate : function(rating){}, |
||
13238 | |||
13239 | error : { |
||
13240 | method : 'The method you called is not defined', |
||
13241 | noMaximum : 'No maximum rating specified. Cannot generate HTML automatically' |
||
13242 | }, |
||
13243 | |||
13244 | |||
13245 | metadata: { |
||
13246 | rating : 'rating', |
||
13247 | maxRating : 'maxRating' |
||
13248 | }, |
||
13249 | |||
13250 | className : { |
||
13251 | active : 'active', |
||
13252 | disabled : 'disabled', |
||
13253 | selected : 'selected', |
||
13254 | loading : 'loading' |
||
13255 | }, |
||
13256 | |||
13257 | selector : { |
||
13258 | icon : '.icon' |
||
13259 | }, |
||
13260 | |||
13261 | templates: { |
||
13262 | icon: function(maxRating) { |
||
13263 | var |
||
13264 | icon = 1, |
||
13265 | html = '' |
||
13266 | ; |
||
13267 | while(icon <= maxRating) { |
||
13268 | html += '<i class="icon"></i>'; |
||
13269 | icon++; |
||
13270 | } |
||
13271 | return html; |
||
13272 | } |
||
13273 | } |
||
13274 | |||
13275 | }; |
||
13276 | |||
13277 | })( jQuery, window, document ); |
||
13278 | |||
13279 | /*! |
||
13280 | * # Semantic UI 2.2.11 - Search |
||
13281 | * http://github.com/semantic-org/semantic-ui/ |
||
13282 | * |
||
13283 | * |
||
13284 | * Released under the MIT license |
||
13285 | * http://opensource.org/licenses/MIT |
||
13286 | * |
||
13287 | */ |
||
13288 | |||
13289 | View Code Duplication | ;(function ($, window, document, undefined) { |
|
13290 | |||
13291 | "use strict"; |
||
13292 | |||
13293 | window = (typeof window != 'undefined' && window.Math == Math) |
||
13294 | ? window |
||
13295 | : (typeof self != 'undefined' && self.Math == Math) |
||
13296 | ? self |
||
13297 | : Function('return this')() |
||
13298 | ; |
||
13299 | |||
13300 | $.fn.search = function(parameters) { |
||
13301 | var |
||
13302 | $allModules = $(this), |
||
13303 | moduleSelector = $allModules.selector || '', |
||
13304 | |||
13305 | time = new Date().getTime(), |
||
13306 | performance = [], |
||
13307 | |||
13308 | query = arguments[0], |
||
13309 | methodInvoked = (typeof query == 'string'), |
||
13310 | queryArguments = [].slice.call(arguments, 1), |
||
13311 | returnedValue |
||
13312 | ; |
||
13313 | $(this) |
||
13314 | .each(function() { |
||
13315 | var |
||
13316 | settings = ( $.isPlainObject(parameters) ) |
||
13317 | ? $.extend(true, {}, $.fn.search.settings, parameters) |
||
13318 | : $.extend({}, $.fn.search.settings), |
||
13319 | |||
13320 | className = settings.className, |
||
13321 | metadata = settings.metadata, |
||
13322 | regExp = settings.regExp, |
||
13323 | fields = settings.fields, |
||
13324 | selector = settings.selector, |
||
13325 | error = settings.error, |
||
13326 | namespace = settings.namespace, |
||
13327 | |||
13328 | eventNamespace = '.' + namespace, |
||
13329 | moduleNamespace = namespace + '-module', |
||
13330 | |||
13331 | $module = $(this), |
||
13332 | $prompt = $module.find(selector.prompt), |
||
13333 | $searchButton = $module.find(selector.searchButton), |
||
13334 | $results = $module.find(selector.results), |
||
13335 | $result = $module.find(selector.result), |
||
13336 | $category = $module.find(selector.category), |
||
13337 | |||
13338 | element = this, |
||
13339 | instance = $module.data(moduleNamespace), |
||
13340 | |||
13341 | disabledBubbled = false, |
||
13342 | resultsDismissed = false, |
||
13343 | |||
13344 | module |
||
13345 | ; |
||
13346 | |||
13347 | module = { |
||
13348 | |||
13349 | initialize: function() { |
||
13350 | module.verbose('Initializing module'); |
||
13351 | module.determine.searchFields(); |
||
13352 | module.bind.events(); |
||
13353 | module.set.type(); |
||
13354 | module.create.results(); |
||
13355 | module.instantiate(); |
||
13356 | }, |
||
13357 | instantiate: function() { |
||
13358 | module.verbose('Storing instance of module', module); |
||
13359 | instance = module; |
||
13360 | $module |
||
13361 | .data(moduleNamespace, module) |
||
13362 | ; |
||
13363 | }, |
||
13364 | destroy: function() { |
||
13365 | module.verbose('Destroying instance'); |
||
13366 | $module |
||
13367 | .off(eventNamespace) |
||
13368 | .removeData(moduleNamespace) |
||
13369 | ; |
||
13370 | }, |
||
13371 | |||
13372 | refresh: function() { |
||
13373 | module.debug('Refreshing selector cache'); |
||
13374 | $prompt = $module.find(selector.prompt); |
||
13375 | $searchButton = $module.find(selector.searchButton); |
||
13376 | $category = $module.find(selector.category); |
||
13377 | $results = $module.find(selector.results); |
||
13378 | $result = $module.find(selector.result); |
||
13379 | }, |
||
13380 | |||
13381 | refreshResults: function() { |
||
13382 | $results = $module.find(selector.results); |
||
13383 | $result = $module.find(selector.result); |
||
13384 | }, |
||
13385 | |||
13386 | bind: { |
||
13387 | events: function() { |
||
13388 | module.verbose('Binding events to search'); |
||
13389 | if(settings.automatic) { |
||
13390 | $module |
||
13391 | .on(module.get.inputEvent() + eventNamespace, selector.prompt, module.event.input) |
||
13392 | ; |
||
13393 | $prompt |
||
13394 | .attr('autocomplete', 'off') |
||
13395 | ; |
||
13396 | } |
||
13397 | $module |
||
13398 | // prompt |
||
13399 | .on('focus' + eventNamespace, selector.prompt, module.event.focus) |
||
13400 | .on('blur' + eventNamespace, selector.prompt, module.event.blur) |
||
13401 | .on('keydown' + eventNamespace, selector.prompt, module.handleKeyboard) |
||
13402 | // search button |
||
13403 | .on('click' + eventNamespace, selector.searchButton, module.query) |
||
13404 | // results |
||
13405 | .on('mousedown' + eventNamespace, selector.results, module.event.result.mousedown) |
||
13406 | .on('mouseup' + eventNamespace, selector.results, module.event.result.mouseup) |
||
13407 | .on('click' + eventNamespace, selector.result, module.event.result.click) |
||
13408 | ; |
||
13409 | } |
||
13410 | }, |
||
13411 | |||
13412 | determine: { |
||
13413 | searchFields: function() { |
||
13414 | // this makes sure $.extend does not add specified search fields to default fields |
||
13415 | // this is the only setting which should not extend defaults |
||
13416 | if(parameters && parameters.searchFields !== undefined) { |
||
13417 | settings.searchFields = parameters.searchFields; |
||
13418 | } |
||
13419 | } |
||
13420 | }, |
||
13421 | |||
13422 | event: { |
||
13423 | input: function() { |
||
13424 | if(settings.searchDelay) { |
||
13425 | clearTimeout(module.timer); |
||
13426 | module.timer = setTimeout(function() { |
||
13427 | if(module.is.focused()) { |
||
13428 | module.query(); |
||
13429 | } |
||
13430 | }, settings.searchDelay); |
||
13431 | } |
||
13432 | else { |
||
13433 | module.query(); |
||
13434 | } |
||
13435 | }, |
||
13436 | focus: function() { |
||
13437 | module.set.focus(); |
||
13438 | if(settings.searchOnFocus && module.has.minimumCharacters() ) { |
||
13439 | module.query(function() { |
||
13440 | if(module.can.show() ) { |
||
13441 | module.showResults(); |
||
13442 | } |
||
13443 | }); |
||
13444 | } |
||
13445 | }, |
||
13446 | blur: function(event) { |
||
13447 | var |
||
13448 | pageLostFocus = (document.activeElement === this), |
||
13449 | callback = function() { |
||
13450 | module.cancel.query(); |
||
13451 | module.remove.focus(); |
||
13452 | module.timer = setTimeout(module.hideResults, settings.hideDelay); |
||
13453 | } |
||
13454 | ; |
||
13455 | if(pageLostFocus) { |
||
13456 | return; |
||
13457 | } |
||
13458 | resultsDismissed = false; |
||
13459 | if(module.resultsClicked) { |
||
13460 | module.debug('Determining if user action caused search to close'); |
||
13461 | $module |
||
13462 | .one('click.close' + eventNamespace, selector.results, function(event) { |
||
13463 | if(module.is.inMessage(event) || disabledBubbled) { |
||
13464 | $prompt.focus(); |
||
13465 | return; |
||
13466 | } |
||
13467 | disabledBubbled = false; |
||
13468 | if( !module.is.animating() && !module.is.hidden()) { |
||
13469 | callback(); |
||
13470 | } |
||
13471 | }) |
||
13472 | ; |
||
13473 | } |
||
13474 | else { |
||
13475 | module.debug('Input blurred without user action, closing results'); |
||
13476 | callback(); |
||
13477 | } |
||
13478 | }, |
||
13479 | result: { |
||
13480 | mousedown: function() { |
||
13481 | module.resultsClicked = true; |
||
13482 | }, |
||
13483 | mouseup: function() { |
||
13484 | module.resultsClicked = false; |
||
13485 | }, |
||
13486 | click: function(event) { |
||
13487 | module.debug('Search result selected'); |
||
13488 | var |
||
13489 | $result = $(this), |
||
13490 | $title = $result.find(selector.title).eq(0), |
||
13491 | $link = $result.is('a[href]') |
||
13492 | ? $result |
||
13493 | : $result.find('a[href]').eq(0), |
||
13494 | href = $link.attr('href') || false, |
||
13495 | target = $link.attr('target') || false, |
||
13496 | title = $title.html(), |
||
13497 | // title is used for result lookup |
||
13498 | value = ($title.length > 0) |
||
13499 | ? $title.text() |
||
13500 | : false, |
||
13501 | results = module.get.results(), |
||
13502 | result = $result.data(metadata.result) || module.get.result(value, results), |
||
13503 | returnedValue |
||
13504 | ; |
||
13505 | if( $.isFunction(settings.onSelect) ) { |
||
13506 | if(settings.onSelect.call(element, result, results) === false) { |
||
13507 | module.debug('Custom onSelect callback cancelled default select action'); |
||
13508 | disabledBubbled = true; |
||
13509 | return; |
||
13510 | } |
||
13511 | } |
||
13512 | module.hideResults(); |
||
13513 | if(value) { |
||
13514 | module.set.value(value); |
||
13515 | } |
||
13516 | if(href) { |
||
13517 | module.verbose('Opening search link found in result', $link); |
||
13518 | if(target == '_blank' || event.ctrlKey) { |
||
13519 | window.open(href); |
||
13520 | } |
||
13521 | else { |
||
13522 | window.location.href = (href); |
||
13523 | } |
||
13524 | } |
||
13525 | } |
||
13526 | } |
||
13527 | }, |
||
13528 | handleKeyboard: function(event) { |
||
13529 | var |
||
13530 | // force selector refresh |
||
13531 | $result = $module.find(selector.result), |
||
13532 | $category = $module.find(selector.category), |
||
13533 | $activeResult = $result.filter('.' + className.active), |
||
13534 | currentIndex = $result.index( $activeResult ), |
||
13535 | resultSize = $result.length, |
||
13536 | hasActiveResult = $activeResult.length > 0, |
||
13537 | |||
13538 | keyCode = event.which, |
||
13539 | keys = { |
||
13540 | backspace : 8, |
||
13541 | enter : 13, |
||
13542 | escape : 27, |
||
13543 | upArrow : 38, |
||
13544 | downArrow : 40 |
||
13545 | }, |
||
13546 | newIndex |
||
13547 | ; |
||
13548 | // search shortcuts |
||
13549 | if(keyCode == keys.escape) { |
||
13550 | module.verbose('Escape key pressed, blurring search field'); |
||
13551 | module.hideResults(); |
||
13552 | resultsDismissed = true; |
||
13553 | } |
||
13554 | if( module.is.visible() ) { |
||
13555 | if(keyCode == keys.enter) { |
||
13556 | module.verbose('Enter key pressed, selecting active result'); |
||
13557 | if( $result.filter('.' + className.active).length > 0 ) { |
||
13558 | module.event.result.click.call($result.filter('.' + className.active), event); |
||
13559 | event.preventDefault(); |
||
13560 | return false; |
||
13561 | } |
||
13562 | } |
||
13563 | else if(keyCode == keys.upArrow && hasActiveResult) { |
||
13564 | module.verbose('Up key pressed, changing active result'); |
||
13565 | newIndex = (currentIndex - 1 < 0) |
||
13566 | ? currentIndex |
||
13567 | : currentIndex - 1 |
||
13568 | ; |
||
13569 | $category |
||
13570 | .removeClass(className.active) |
||
13571 | ; |
||
13572 | $result |
||
13573 | .removeClass(className.active) |
||
13574 | .eq(newIndex) |
||
13575 | .addClass(className.active) |
||
13576 | .closest($category) |
||
13577 | .addClass(className.active) |
||
13578 | ; |
||
13579 | event.preventDefault(); |
||
13580 | } |
||
13581 | else if(keyCode == keys.downArrow) { |
||
13582 | module.verbose('Down key pressed, changing active result'); |
||
13583 | newIndex = (currentIndex + 1 >= resultSize) |
||
13584 | ? currentIndex |
||
13585 | : currentIndex + 1 |
||
13586 | ; |
||
13587 | $category |
||
13588 | .removeClass(className.active) |
||
13589 | ; |
||
13590 | $result |
||
13591 | .removeClass(className.active) |
||
13592 | .eq(newIndex) |
||
13593 | .addClass(className.active) |
||
13594 | .closest($category) |
||
13595 | .addClass(className.active) |
||
13596 | ; |
||
13597 | event.preventDefault(); |
||
13598 | } |
||
13599 | } |
||
13600 | else { |
||
13601 | // query shortcuts |
||
13602 | if(keyCode == keys.enter) { |
||
13603 | module.verbose('Enter key pressed, executing query'); |
||
13604 | module.query(); |
||
13605 | module.set.buttonPressed(); |
||
13606 | $prompt.one('keyup', module.remove.buttonFocus); |
||
13607 | } |
||
13608 | } |
||
13609 | }, |
||
13610 | |||
13611 | setup: { |
||
13612 | api: function(searchTerm, callback) { |
||
13613 | var |
||
13614 | apiSettings = { |
||
13615 | debug : settings.debug, |
||
13616 | on : false, |
||
13617 | cache : true, |
||
13618 | action : 'search', |
||
13619 | urlData : { |
||
13620 | query : searchTerm |
||
13621 | }, |
||
13622 | onSuccess : function(response) { |
||
13623 | module.parse.response.call(element, response, searchTerm); |
||
13624 | callback(); |
||
13625 | }, |
||
13626 | onFailure : function() { |
||
13627 | module.displayMessage(error.serverError); |
||
13628 | callback(); |
||
13629 | }, |
||
13630 | onAbort : function(response) { |
||
13631 | }, |
||
13632 | onError : module.error |
||
13633 | }, |
||
13634 | searchHTML |
||
13635 | ; |
||
13636 | $.extend(true, apiSettings, settings.apiSettings); |
||
13637 | module.verbose('Setting up API request', apiSettings); |
||
13638 | $module.api(apiSettings); |
||
13639 | } |
||
13640 | }, |
||
13641 | |||
13642 | can: { |
||
13643 | useAPI: function() { |
||
13644 | return $.fn.api !== undefined; |
||
13645 | }, |
||
13646 | show: function() { |
||
13647 | return module.is.focused() && !module.is.visible() && !module.is.empty(); |
||
13648 | }, |
||
13649 | transition: function() { |
||
13650 | return settings.transition && $.fn.transition !== undefined && $module.transition('is supported'); |
||
13651 | } |
||
13652 | }, |
||
13653 | |||
13654 | is: { |
||
13655 | animating: function() { |
||
13656 | return $results.hasClass(className.animating); |
||
13657 | }, |
||
13658 | hidden: function() { |
||
13659 | return $results.hasClass(className.hidden); |
||
13660 | }, |
||
13661 | inMessage: function(event) { |
||
13662 | if(!event.target) { |
||
13663 | return; |
||
13664 | } |
||
13665 | var |
||
13666 | $target = $(event.target), |
||
13667 | isInDOM = $.contains(document.documentElement, event.target) |
||
13668 | ; |
||
13669 | return (isInDOM && $target.closest(selector.message).length > 0); |
||
13670 | }, |
||
13671 | empty: function() { |
||
13672 | return ($results.html() === ''); |
||
13673 | }, |
||
13674 | visible: function() { |
||
13675 | return ($results.filter(':visible').length > 0); |
||
13676 | }, |
||
13677 | focused: function() { |
||
13678 | return ($prompt.filter(':focus').length > 0); |
||
13679 | } |
||
13680 | }, |
||
13681 | |||
13682 | get: { |
||
13683 | inputEvent: function() { |
||
13684 | var |
||
13685 | prompt = $prompt[0], |
||
13686 | inputEvent = (prompt !== undefined && prompt.oninput !== undefined) |
||
13687 | ? 'input' |
||
13688 | : (prompt !== undefined && prompt.onpropertychange !== undefined) |
||
13689 | ? 'propertychange' |
||
13690 | : 'keyup' |
||
13691 | ; |
||
13692 | return inputEvent; |
||
13693 | }, |
||
13694 | value: function() { |
||
13695 | return $prompt.val(); |
||
13696 | }, |
||
13697 | results: function() { |
||
13698 | var |
||
13699 | results = $module.data(metadata.results) |
||
13700 | ; |
||
13701 | return results; |
||
13702 | }, |
||
13703 | result: function(value, results) { |
||
13704 | var |
||
13705 | lookupFields = ['title', 'id'], |
||
13706 | result = false |
||
13707 | ; |
||
13708 | value = (value !== undefined) |
||
13709 | ? value |
||
13710 | : module.get.value() |
||
13711 | ; |
||
13712 | results = (results !== undefined) |
||
13713 | ? results |
||
13714 | : module.get.results() |
||
13715 | ; |
||
13716 | if(settings.type === 'category') { |
||
13717 | module.debug('Finding result that matches', value); |
||
13718 | $.each(results, function(index, category) { |
||
13719 | if($.isArray(category.results)) { |
||
13720 | result = module.search.object(value, category.results, lookupFields)[0]; |
||
13721 | // don't continue searching if a result is found |
||
13722 | if(result) { |
||
13723 | return false; |
||
13724 | } |
||
13725 | } |
||
13726 | }); |
||
13727 | } |
||
13728 | else { |
||
13729 | module.debug('Finding result in results object', value); |
||
13730 | result = module.search.object(value, results, lookupFields)[0]; |
||
13731 | } |
||
13732 | return result || false; |
||
13733 | }, |
||
13734 | }, |
||
13735 | |||
13736 | select: { |
||
13737 | firstResult: function() { |
||
13738 | module.verbose('Selecting first result'); |
||
13739 | $result.first().addClass(className.active); |
||
13740 | } |
||
13741 | }, |
||
13742 | |||
13743 | set: { |
||
13744 | focus: function() { |
||
13745 | $module.addClass(className.focus); |
||
13746 | }, |
||
13747 | loading: function() { |
||
13748 | $module.addClass(className.loading); |
||
13749 | }, |
||
13750 | value: function(value) { |
||
13751 | module.verbose('Setting search input value', value); |
||
13752 | $prompt |
||
13753 | .val(value) |
||
13754 | ; |
||
13755 | }, |
||
13756 | type: function(type) { |
||
13757 | type = type || settings.type; |
||
13758 | if(settings.type == 'category') { |
||
13759 | $module.addClass(settings.type); |
||
13760 | } |
||
13761 | }, |
||
13762 | buttonPressed: function() { |
||
13763 | $searchButton.addClass(className.pressed); |
||
13764 | } |
||
13765 | }, |
||
13766 | |||
13767 | remove: { |
||
13768 | loading: function() { |
||
13769 | $module.removeClass(className.loading); |
||
13770 | }, |
||
13771 | focus: function() { |
||
13772 | $module.removeClass(className.focus); |
||
13773 | }, |
||
13774 | buttonPressed: function() { |
||
13775 | $searchButton.removeClass(className.pressed); |
||
13776 | } |
||
13777 | }, |
||
13778 | |||
13779 | query: function(callback) { |
||
13780 | callback = $.isFunction(callback) |
||
13781 | ? callback |
||
13782 | : function(){} |
||
13783 | ; |
||
13784 | var |
||
13785 | searchTerm = module.get.value(), |
||
13786 | cache = module.read.cache(searchTerm) |
||
13787 | ; |
||
13788 | callback = callback || function() {}; |
||
13789 | if( module.has.minimumCharacters() ) { |
||
13790 | if(cache) { |
||
13791 | module.debug('Reading result from cache', searchTerm); |
||
13792 | module.save.results(cache.results); |
||
13793 | module.addResults(cache.html); |
||
13794 | module.inject.id(cache.results); |
||
13795 | callback(); |
||
13796 | } |
||
13797 | else { |
||
13798 | module.debug('Querying for', searchTerm); |
||
13799 | if($.isPlainObject(settings.source) || $.isArray(settings.source)) { |
||
13800 | module.search.local(searchTerm); |
||
13801 | callback(); |
||
13802 | } |
||
13803 | else if( module.can.useAPI() ) { |
||
13804 | module.search.remote(searchTerm, callback); |
||
13805 | } |
||
13806 | else { |
||
13807 | module.error(error.source); |
||
13808 | callback(); |
||
13809 | } |
||
13810 | } |
||
13811 | settings.onSearchQuery.call(element, searchTerm); |
||
13812 | } |
||
13813 | else { |
||
13814 | module.hideResults(); |
||
13815 | } |
||
13816 | }, |
||
13817 | |||
13818 | search: { |
||
13819 | local: function(searchTerm) { |
||
13820 | var |
||
13821 | results = module.search.object(searchTerm, settings.content), |
||
13822 | searchHTML |
||
13823 | ; |
||
13824 | module.set.loading(); |
||
13825 | module.save.results(results); |
||
13826 | module.debug('Returned local search results', results); |
||
13827 | |||
13828 | searchHTML = module.generateResults({ |
||
13829 | results: results |
||
13830 | }); |
||
13831 | module.remove.loading(); |
||
13832 | module.addResults(searchHTML); |
||
13833 | module.inject.id(results); |
||
13834 | module.write.cache(searchTerm, { |
||
13835 | html : searchHTML, |
||
13836 | results : results |
||
13837 | }); |
||
13838 | }, |
||
13839 | remote: function(searchTerm, callback) { |
||
13840 | callback = $.isFunction(callback) |
||
13841 | ? callback |
||
13842 | : function(){} |
||
13843 | ; |
||
13844 | if($module.api('is loading')) { |
||
13845 | $module.api('abort'); |
||
13846 | } |
||
13847 | module.setup.api(searchTerm, callback); |
||
13848 | $module |
||
13849 | .api('query') |
||
13850 | ; |
||
13851 | }, |
||
13852 | object: function(searchTerm, source, searchFields) { |
||
13853 | var |
||
13854 | results = [], |
||
13855 | fuzzyResults = [], |
||
13856 | searchExp = searchTerm.toString().replace(regExp.escape, '\\$&'), |
||
13857 | matchRegExp = new RegExp(regExp.beginsWith + searchExp, 'i'), |
||
13858 | |||
13859 | // avoid duplicates when pushing results |
||
13860 | addResult = function(array, result) { |
||
13861 | var |
||
13862 | notResult = ($.inArray(result, results) == -1), |
||
13863 | notFuzzyResult = ($.inArray(result, fuzzyResults) == -1) |
||
13864 | ; |
||
13865 | if(notResult && notFuzzyResult) { |
||
13866 | array.push(result); |
||
13867 | } |
||
13868 | } |
||
13869 | ; |
||
13870 | source = source || settings.source; |
||
13871 | searchFields = (searchFields !== undefined) |
||
13872 | ? searchFields |
||
13873 | : settings.searchFields |
||
13874 | ; |
||
13875 | |||
13876 | // search fields should be array to loop correctly |
||
13877 | if(!$.isArray(searchFields)) { |
||
13878 | searchFields = [searchFields]; |
||
13879 | } |
||
13880 | |||
13881 | // exit conditions if no source |
||
13882 | if(source === undefined || source === false) { |
||
13883 | module.error(error.source); |
||
13884 | return []; |
||
13885 | } |
||
13886 | |||
13887 | // iterate through search fields looking for matches |
||
13888 | $.each(searchFields, function(index, field) { |
||
13889 | $.each(source, function(label, content) { |
||
13890 | var |
||
13891 | fieldExists = (typeof content[field] == 'string') |
||
13892 | ; |
||
13893 | if(fieldExists) { |
||
13894 | if( content[field].search(matchRegExp) !== -1) { |
||
13895 | // content starts with value (first in results) |
||
13896 | addResult(results, content); |
||
13897 | } |
||
13898 | else if(settings.searchFullText && module.fuzzySearch(searchTerm, content[field]) ) { |
||
13899 | // content fuzzy matches (last in results) |
||
13900 | addResult(fuzzyResults, content); |
||
13901 | } |
||
13902 | } |
||
13903 | }); |
||
13904 | }); |
||
13905 | return $.merge(results, fuzzyResults); |
||
13906 | } |
||
13907 | }, |
||
13908 | |||
13909 | fuzzySearch: function(query, term) { |
||
13910 | var |
||
13911 | termLength = term.length, |
||
13912 | queryLength = query.length |
||
13913 | ; |
||
13914 | if(typeof query !== 'string') { |
||
13915 | return false; |
||
13916 | } |
||
13917 | query = query.toLowerCase(); |
||
13918 | term = term.toLowerCase(); |
||
13919 | if(queryLength > termLength) { |
||
13920 | return false; |
||
13921 | } |
||
13922 | if(queryLength === termLength) { |
||
13923 | return (query === term); |
||
13924 | } |
||
13925 | search: for (var characterIndex = 0, nextCharacterIndex = 0; characterIndex < queryLength; characterIndex++) { |
||
13926 | var |
||
13927 | queryCharacter = query.charCodeAt(characterIndex) |
||
13928 | ; |
||
13929 | while(nextCharacterIndex < termLength) { |
||
13930 | if(term.charCodeAt(nextCharacterIndex++) === queryCharacter) { |
||
13931 | continue search; |
||
13932 | } |
||
13933 | } |
||
13934 | return false; |
||
13935 | } |
||
13936 | return true; |
||
13937 | }, |
||
13938 | |||
13939 | parse: { |
||
13940 | response: function(response, searchTerm) { |
||
13941 | var |
||
13942 | searchHTML = module.generateResults(response) |
||
13943 | ; |
||
13944 | module.verbose('Parsing server response', response); |
||
13945 | if(response !== undefined) { |
||
13946 | if(searchTerm !== undefined && response[fields.results] !== undefined) { |
||
13947 | module.addResults(searchHTML); |
||
13948 | module.inject.id(response[fields.results]); |
||
13949 | module.write.cache(searchTerm, { |
||
13950 | html : searchHTML, |
||
13951 | results : response[fields.results] |
||
13952 | }); |
||
13953 | module.save.results(response[fields.results]); |
||
13954 | } |
||
13955 | } |
||
13956 | } |
||
13957 | }, |
||
13958 | |||
13959 | cancel: { |
||
13960 | query: function() { |
||
13961 | if( module.can.useAPI() ) { |
||
13962 | $module.api('abort'); |
||
13963 | } |
||
13964 | } |
||
13965 | }, |
||
13966 | |||
13967 | has: { |
||
13968 | minimumCharacters: function() { |
||
13969 | var |
||
13970 | searchTerm = module.get.value(), |
||
13971 | numCharacters = searchTerm.length |
||
13972 | ; |
||
13973 | return (numCharacters >= settings.minCharacters); |
||
13974 | }, |
||
13975 | results: function() { |
||
13976 | if($results.length === 0) { |
||
13977 | return false; |
||
13978 | } |
||
13979 | var |
||
13980 | html = $results.html() |
||
13981 | ; |
||
13982 | return html != ''; |
||
13983 | } |
||
13984 | }, |
||
13985 | |||
13986 | clear: { |
||
13987 | cache: function(value) { |
||
13988 | var |
||
13989 | cache = $module.data(metadata.cache) |
||
13990 | ; |
||
13991 | if(!value) { |
||
13992 | module.debug('Clearing cache', value); |
||
13993 | $module.removeData(metadata.cache); |
||
13994 | } |
||
13995 | else if(value && cache && cache[value]) { |
||
13996 | module.debug('Removing value from cache', value); |
||
13997 | delete cache[value]; |
||
13998 | $module.data(metadata.cache, cache); |
||
13999 | } |
||
14000 | } |
||
14001 | }, |
||
14002 | |||
14003 | read: { |
||
14004 | cache: function(name) { |
||
14005 | var |
||
14006 | cache = $module.data(metadata.cache) |
||
14007 | ; |
||
14008 | if(settings.cache) { |
||
14009 | module.verbose('Checking cache for generated html for query', name); |
||
14010 | return (typeof cache == 'object') && (cache[name] !== undefined) |
||
14011 | ? cache[name] |
||
14012 | : false |
||
14013 | ; |
||
14014 | } |
||
14015 | return false; |
||
14016 | } |
||
14017 | }, |
||
14018 | |||
14019 | create: { |
||
14020 | id: function(resultIndex, categoryIndex) { |
||
14021 | var |
||
14022 | resultID = (resultIndex + 1), // not zero indexed |
||
14023 | categoryID = (categoryIndex + 1), |
||
14024 | firstCharCode, |
||
14025 | letterID, |
||
14026 | id |
||
14027 | ; |
||
14028 | if(categoryIndex !== undefined) { |
||
14029 | // start char code for "A" |
||
14030 | letterID = String.fromCharCode(97 + categoryIndex); |
||
14031 | id = letterID + resultID; |
||
14032 | module.verbose('Creating category result id', id); |
||
14033 | } |
||
14034 | else { |
||
14035 | id = resultID; |
||
14036 | module.verbose('Creating result id', id); |
||
14037 | } |
||
14038 | return id; |
||
14039 | }, |
||
14040 | results: function() { |
||
14041 | if($results.length === 0) { |
||
14042 | $results = $('<div />') |
||
14043 | .addClass(className.results) |
||
14044 | .appendTo($module) |
||
14045 | ; |
||
14046 | } |
||
14047 | } |
||
14048 | }, |
||
14049 | |||
14050 | inject: { |
||
14051 | result: function(result, resultIndex, categoryIndex) { |
||
14052 | module.verbose('Injecting result into results'); |
||
14053 | var |
||
14054 | $selectedResult = (categoryIndex !== undefined) |
||
14055 | ? $results |
||
14056 | .children().eq(categoryIndex) |
||
14057 | .children(selector.result).eq(resultIndex) |
||
14058 | : $results |
||
14059 | .children(selector.result).eq(resultIndex) |
||
14060 | ; |
||
14061 | module.verbose('Injecting results metadata', $selectedResult); |
||
14062 | $selectedResult |
||
14063 | .data(metadata.result, result) |
||
14064 | ; |
||
14065 | }, |
||
14066 | id: function(results) { |
||
14067 | module.debug('Injecting unique ids into results'); |
||
14068 | var |
||
14069 | // since results may be object, we must use counters |
||
14070 | categoryIndex = 0, |
||
14071 | resultIndex = 0 |
||
14072 | ; |
||
14073 | if(settings.type === 'category') { |
||
14074 | // iterate through each category result |
||
14075 | $.each(results, function(index, category) { |
||
14076 | resultIndex = 0; |
||
14077 | $.each(category.results, function(index, value) { |
||
14078 | var |
||
14079 | result = category.results[index] |
||
14080 | ; |
||
14081 | if(result.id === undefined) { |
||
14082 | result.id = module.create.id(resultIndex, categoryIndex); |
||
14083 | } |
||
14084 | module.inject.result(result, resultIndex, categoryIndex); |
||
14085 | resultIndex++; |
||
14086 | }); |
||
14087 | categoryIndex++; |
||
14088 | }); |
||
14089 | } |
||
14090 | else { |
||
14091 | // top level |
||
14092 | $.each(results, function(index, value) { |
||
14093 | var |
||
14094 | result = results[index] |
||
14095 | ; |
||
14096 | if(result.id === undefined) { |
||
14097 | result.id = module.create.id(resultIndex); |
||
14098 | } |
||
14099 | module.inject.result(result, resultIndex); |
||
14100 | resultIndex++; |
||
14101 | }); |
||
14102 | } |
||
14103 | return results; |
||
14104 | } |
||
14105 | }, |
||
14106 | |||
14107 | save: { |
||
14108 | results: function(results) { |
||
14109 | module.verbose('Saving current search results to metadata', results); |
||
14110 | $module.data(metadata.results, results); |
||
14111 | } |
||
14112 | }, |
||
14113 | |||
14114 | write: { |
||
14115 | cache: function(name, value) { |
||
14116 | var |
||
14117 | cache = ($module.data(metadata.cache) !== undefined) |
||
14118 | ? $module.data(metadata.cache) |
||
14119 | : {} |
||
14120 | ; |
||
14121 | if(settings.cache) { |
||
14122 | module.verbose('Writing generated html to cache', name, value); |
||
14123 | cache[name] = value; |
||
14124 | $module |
||
14125 | .data(metadata.cache, cache) |
||
14126 | ; |
||
14127 | } |
||
14128 | } |
||
14129 | }, |
||
14130 | |||
14131 | addResults: function(html) { |
||
14132 | if( $.isFunction(settings.onResultsAdd) ) { |
||
14133 | if( settings.onResultsAdd.call($results, html) === false ) { |
||
14134 | module.debug('onResultsAdd callback cancelled default action'); |
||
14135 | return false; |
||
14136 | } |
||
14137 | } |
||
14138 | if(html) { |
||
14139 | $results |
||
14140 | .html(html) |
||
14141 | ; |
||
14142 | module.refreshResults(); |
||
14143 | if(settings.selectFirstResult) { |
||
14144 | module.select.firstResult(); |
||
14145 | } |
||
14146 | module.showResults(); |
||
14147 | } |
||
14148 | else { |
||
14149 | module.hideResults(function() { |
||
14150 | $results.empty(); |
||
14151 | }); |
||
14152 | } |
||
14153 | }, |
||
14154 | |||
14155 | showResults: function(callback) { |
||
14156 | callback = $.isFunction(callback) |
||
14157 | ? callback |
||
14158 | : function(){} |
||
14159 | ; |
||
14160 | if(resultsDismissed) { |
||
14161 | return; |
||
14162 | } |
||
14163 | if(!module.is.visible() && module.has.results()) { |
||
14164 | if( module.can.transition() ) { |
||
14165 | module.debug('Showing results with css animations'); |
||
14166 | $results |
||
14167 | .transition({ |
||
14168 | animation : settings.transition + ' in', |
||
14169 | debug : settings.debug, |
||
14170 | verbose : settings.verbose, |
||
14171 | duration : settings.duration, |
||
14172 | onComplete : function() { |
||
14173 | callback(); |
||
14174 | }, |
||
14175 | queue : true |
||
14176 | }) |
||
14177 | ; |
||
14178 | } |
||
14179 | else { |
||
14180 | module.debug('Showing results with javascript'); |
||
14181 | $results |
||
14182 | .stop() |
||
14183 | .fadeIn(settings.duration, settings.easing) |
||
14184 | ; |
||
14185 | } |
||
14186 | settings.onResultsOpen.call($results); |
||
14187 | } |
||
14188 | }, |
||
14189 | hideResults: function(callback) { |
||
14190 | callback = $.isFunction(callback) |
||
14191 | ? callback |
||
14192 | : function(){} |
||
14193 | ; |
||
14194 | if( module.is.visible() ) { |
||
14195 | if( module.can.transition() ) { |
||
14196 | module.debug('Hiding results with css animations'); |
||
14197 | $results |
||
14198 | .transition({ |
||
14199 | animation : settings.transition + ' out', |
||
14200 | debug : settings.debug, |
||
14201 | verbose : settings.verbose, |
||
14202 | duration : settings.duration, |
||
14203 | onComplete : function() { |
||
14204 | callback(); |
||
14205 | }, |
||
14206 | queue : true |
||
14207 | }) |
||
14208 | ; |
||
14209 | } |
||
14210 | else { |
||
14211 | module.debug('Hiding results with javascript'); |
||
14212 | $results |
||
14213 | .stop() |
||
14214 | .fadeOut(settings.duration, settings.easing) |
||
14215 | ; |
||
14216 | } |
||
14217 | settings.onResultsClose.call($results); |
||
14218 | } |
||
14219 | }, |
||
14220 | |||
14221 | generateResults: function(response) { |
||
14222 | module.debug('Generating html from response', response); |
||
14223 | var |
||
14224 | template = settings.templates[settings.type], |
||
14225 | isProperObject = ($.isPlainObject(response[fields.results]) && !$.isEmptyObject(response[fields.results])), |
||
14226 | isProperArray = ($.isArray(response[fields.results]) && response[fields.results].length > 0), |
||
14227 | html = '' |
||
14228 | ; |
||
14229 | if(isProperObject || isProperArray ) { |
||
14230 | if(settings.maxResults > 0) { |
||
14231 | if(isProperObject) { |
||
14232 | if(settings.type == 'standard') { |
||
14233 | module.error(error.maxResults); |
||
14234 | } |
||
14235 | } |
||
14236 | else { |
||
14237 | response[fields.results] = response[fields.results].slice(0, settings.maxResults); |
||
14238 | } |
||
14239 | } |
||
14240 | if($.isFunction(template)) { |
||
14241 | html = template(response, fields); |
||
14242 | } |
||
14243 | else { |
||
14244 | module.error(error.noTemplate, false); |
||
14245 | } |
||
14246 | } |
||
14247 | else if(settings.showNoResults) { |
||
14248 | html = module.displayMessage(error.noResults, 'empty'); |
||
14249 | } |
||
14250 | settings.onResults.call(element, response); |
||
14251 | return html; |
||
14252 | }, |
||
14253 | |||
14254 | displayMessage: function(text, type) { |
||
14255 | type = type || 'standard'; |
||
14256 | module.debug('Displaying message', text, type); |
||
14257 | module.addResults( settings.templates.message(text, type) ); |
||
14258 | return settings.templates.message(text, type); |
||
14259 | }, |
||
14260 | |||
14261 | setting: function(name, value) { |
||
14262 | if( $.isPlainObject(name) ) { |
||
14263 | $.extend(true, settings, name); |
||
14264 | } |
||
14265 | else if(value !== undefined) { |
||
14266 | settings[name] = value; |
||
14267 | } |
||
14268 | else { |
||
14269 | return settings[name]; |
||
14270 | } |
||
14271 | }, |
||
14272 | internal: function(name, value) { |
||
14273 | if( $.isPlainObject(name) ) { |
||
14274 | $.extend(true, module, name); |
||
14275 | } |
||
14276 | else if(value !== undefined) { |
||
14277 | module[name] = value; |
||
14278 | } |
||
14279 | else { |
||
14280 | return module[name]; |
||
14281 | } |
||
14282 | }, |
||
14283 | debug: function() { |
||
14284 | if(!settings.silent && settings.debug) { |
||
14285 | if(settings.performance) { |
||
14286 | module.performance.log(arguments); |
||
14287 | } |
||
14288 | else { |
||
14289 | module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':'); |
||
14290 | module.debug.apply(console, arguments); |
||
14291 | } |
||
14292 | } |
||
14293 | }, |
||
14294 | verbose: function() { |
||
14295 | if(!settings.silent && settings.verbose && settings.debug) { |
||
14296 | if(settings.performance) { |
||
14297 | module.performance.log(arguments); |
||
14298 | } |
||
14299 | else { |
||
14300 | module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':'); |
||
14301 | module.verbose.apply(console, arguments); |
||
14302 | } |
||
14303 | } |
||
14304 | }, |
||
14305 | error: function() { |
||
14306 | if(!settings.silent) { |
||
14307 | module.error = Function.prototype.bind.call(console.error, console, settings.name + ':'); |
||
14308 | module.error.apply(console, arguments); |
||
14309 | } |
||
14310 | }, |
||
14311 | performance: { |
||
14312 | log: function(message) { |
||
14313 | var |
||
14314 | currentTime, |
||
14315 | executionTime, |
||
14316 | previousTime |
||
14317 | ; |
||
14318 | if(settings.performance) { |
||
14319 | currentTime = new Date().getTime(); |
||
14320 | previousTime = time || currentTime; |
||
14321 | executionTime = currentTime - previousTime; |
||
14322 | time = currentTime; |
||
14323 | performance.push({ |
||
14324 | 'Name' : message[0], |
||
14325 | 'Arguments' : [].slice.call(message, 1) || '', |
||
14326 | 'Element' : element, |
||
14327 | 'Execution Time' : executionTime |
||
14328 | }); |
||
14329 | } |
||
14330 | clearTimeout(module.performance.timer); |
||
14331 | module.performance.timer = setTimeout(module.performance.display, 500); |
||
14332 | }, |
||
14333 | display: function() { |
||
14334 | var |
||
14335 | title = settings.name + ':', |
||
14336 | totalTime = 0 |
||
14337 | ; |
||
14338 | time = false; |
||
14339 | clearTimeout(module.performance.timer); |
||
14340 | $.each(performance, function(index, data) { |
||
14341 | totalTime += data['Execution Time']; |
||
14342 | }); |
||
14343 | title += ' ' + totalTime + 'ms'; |
||
14344 | if(moduleSelector) { |
||
14345 | title += ' \'' + moduleSelector + '\''; |
||
14346 | } |
||
14347 | if($allModules.length > 1) { |
||
14348 | title += ' ' + '(' + $allModules.length + ')'; |
||
14349 | } |
||
14350 | if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) { |
||
14351 | console.groupCollapsed(title); |
||
14352 | if(console.table) { |
||
14353 | console.table(performance); |
||
14354 | } |
||
14355 | else { |
||
14356 | $.each(performance, function(index, data) { |
||
14357 | console.log(data['Name'] + ': ' + data['Execution Time']+'ms'); |
||
14358 | }); |
||
14359 | } |
||
14360 | console.groupEnd(); |
||
14361 | } |
||
14362 | performance = []; |
||
14363 | } |
||
14364 | }, |
||
14365 | invoke: function(query, passedArguments, context) { |
||
14366 | var |
||
14367 | object = instance, |
||
14368 | maxDepth, |
||
14369 | found, |
||
14370 | response |
||
14371 | ; |
||
14372 | passedArguments = passedArguments || queryArguments; |
||
14373 | context = element || context; |
||
14374 | if(typeof query == 'string' && object !== undefined) { |
||
14375 | query = query.split(/[\. ]/); |
||
14376 | maxDepth = query.length - 1; |
||
14377 | $.each(query, function(depth, value) { |
||
14378 | var camelCaseValue = (depth != maxDepth) |
||
14379 | ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1) |
||
14380 | : query |
||
14381 | ; |
||
14382 | if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) { |
||
14383 | object = object[camelCaseValue]; |
||
14384 | } |
||
14385 | else if( object[camelCaseValue] !== undefined ) { |
||
14386 | found = object[camelCaseValue]; |
||
14387 | return false; |
||
14388 | } |
||
14389 | else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) { |
||
14390 | object = object[value]; |
||
14391 | } |
||
14392 | else if( object[value] !== undefined ) { |
||
14393 | found = object[value]; |
||
14394 | return false; |
||
14395 | } |
||
14396 | else { |
||
14397 | return false; |
||
14398 | } |
||
14399 | }); |
||
14400 | } |
||
14401 | if( $.isFunction( found ) ) { |
||
14402 | response = found.apply(context, passedArguments); |
||
14403 | } |
||
14404 | else if(found !== undefined) { |
||
14405 | response = found; |
||
14406 | } |
||
14407 | if($.isArray(returnedValue)) { |
||
14408 | returnedValue.push(response); |
||
14409 | } |
||
14410 | else if(returnedValue !== undefined) { |
||
14411 | returnedValue = [returnedValue, response]; |
||
14412 | } |
||
14413 | else if(response !== undefined) { |
||
14414 | returnedValue = response; |
||
14415 | } |
||
14416 | return found; |
||
14417 | } |
||
14418 | }; |
||
14419 | if(methodInvoked) { |
||
14420 | if(instance === undefined) { |
||
14421 | module.initialize(); |
||
14422 | } |
||
14423 | module.invoke(query); |
||
14424 | } |
||
14425 | else { |
||
14426 | if(instance !== undefined) { |
||
14427 | instance.invoke('destroy'); |
||
14428 | } |
||
14429 | module.initialize(); |
||
14430 | } |
||
14431 | |||
14432 | }) |
||
14433 | ; |
||
14434 | |||
14435 | return (returnedValue !== undefined) |
||
14436 | ? returnedValue |
||
14437 | : this |
||
14438 | ; |
||
14439 | }; |
||
14440 | |||
14441 | $.fn.search.settings = { |
||
14442 | |||
14443 | name : 'Search', |
||
14444 | namespace : 'search', |
||
14445 | |||
14446 | silent : false, |
||
14447 | debug : false, |
||
14448 | verbose : false, |
||
14449 | performance : true, |
||
14450 | |||
14451 | // template to use (specified in settings.templates) |
||
14452 | type : 'standard', |
||
14453 | |||
14454 | // minimum characters required to search |
||
14455 | minCharacters : 1, |
||
14456 | |||
14457 | // whether to select first result after searching automatically |
||
14458 | selectFirstResult : false, |
||
14459 | |||
14460 | // API config |
||
14461 | apiSettings : false, |
||
14462 | |||
14463 | // object to search |
||
14464 | source : false, |
||
14465 | |||
14466 | // Whether search should query current term on focus |
||
14467 | searchOnFocus : true, |
||
14468 | |||
14469 | // fields to search |
||
14470 | searchFields : [ |
||
14471 | 'title', |
||
14472 | 'description' |
||
14473 | ], |
||
14474 | |||
14475 | // field to display in standard results template |
||
14476 | displayField : '', |
||
14477 | |||
14478 | // whether to include fuzzy results in local search |
||
14479 | searchFullText : true, |
||
14480 | |||
14481 | // whether to add events to prompt automatically |
||
14482 | automatic : true, |
||
14483 | |||
14484 | // delay before hiding menu after blur |
||
14485 | hideDelay : 0, |
||
14486 | |||
14487 | // delay before searching |
||
14488 | searchDelay : 200, |
||
14489 | |||
14490 | // maximum results returned from local |
||
14491 | maxResults : 7, |
||
14492 | |||
14493 | // whether to store lookups in local cache |
||
14494 | cache : true, |
||
14495 | |||
14496 | // whether no results errors should be shown |
||
14497 | showNoResults : true, |
||
14498 | |||
14499 | // transition settings |
||
14500 | transition : 'scale', |
||
14501 | duration : 200, |
||
14502 | easing : 'easeOutExpo', |
||
14503 | |||
14504 | // callbacks |
||
14505 | onSelect : false, |
||
14506 | onResultsAdd : false, |
||
14507 | |||
14508 | onSearchQuery : function(query){}, |
||
14509 | onResults : function(response){}, |
||
14510 | |||
14511 | onResultsOpen : function(){}, |
||
14512 | onResultsClose : function(){}, |
||
14513 | |||
14514 | className: { |
||
14515 | animating : 'animating', |
||
14516 | active : 'active', |
||
14517 | empty : 'empty', |
||
14518 | focus : 'focus', |
||
14519 | hidden : 'hidden', |
||
14520 | loading : 'loading', |
||
14521 | results : 'results', |
||
14522 | pressed : 'down' |
||
14523 | }, |
||
14524 | |||
14525 | error : { |
||
14526 | source : 'Cannot search. No source used, and Semantic API module was not included', |
||
14527 | noResults : 'Your search returned no results', |
||
14528 | logging : 'Error in debug logging, exiting.', |
||
14529 | noEndpoint : 'No search endpoint was specified', |
||
14530 | noTemplate : 'A valid template name was not specified.', |
||
14531 | serverError : 'There was an issue querying the server.', |
||
14532 | maxResults : 'Results must be an array to use maxResults setting', |
||
14533 | method : 'The method you called is not defined.' |
||
14534 | }, |
||
14535 | |||
14536 | metadata: { |
||
14537 | cache : 'cache', |
||
14538 | results : 'results', |
||
14539 | result : 'result' |
||
14540 | }, |
||
14541 | |||
14542 | regExp: { |
||
14543 | escape : /[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, |
||
14544 | beginsWith : '(?:\s|^)' |
||
14545 | }, |
||
14546 | |||
14547 | // maps api response attributes to internal representation |
||
14548 | fields: { |
||
14549 | categories : 'results', // array of categories (category view) |
||
14550 | categoryName : 'name', // name of category (category view) |
||
14551 | categoryResults : 'results', // array of results (category view) |
||
14552 | description : 'description', // result description |
||
14553 | image : 'image', // result image |
||
14554 | price : 'price', // result price |
||
14555 | results : 'results', // array of results (standard) |
||
14556 | title : 'title', // result title |
||
14557 | url : 'url', // result url |
||
14558 | action : 'action', // "view more" object name |
||
14559 | actionText : 'text', // "view more" text |
||
14560 | actionURL : 'url' // "view more" url |
||
14561 | }, |
||
14562 | |||
14563 | selector : { |
||
14564 | prompt : '.prompt', |
||
14565 | searchButton : '.search.button', |
||
14566 | results : '.results', |
||
14567 | message : '.results > .message', |
||
14568 | category : '.category', |
||
14569 | result : '.result', |
||
14570 | title : '.title, .name' |
||
14571 | }, |
||
14572 | |||
14573 | templates: { |
||
14574 | escape: function(string) { |
||
14575 | var |
||
14576 | badChars = /[&<>"'`]/g, |
||
14577 | shouldEscape = /[&<>"'`]/, |
||
14578 | escape = { |
||
14579 | "&": "&", |
||
14580 | "<": "<", |
||
14581 | ">": ">", |
||
14582 | '"': """, |
||
14583 | "'": "'", |
||
14584 | "`": "`" |
||
14585 | }, |
||
14586 | escapedChar = function(chr) { |
||
14587 | return escape[chr]; |
||
14588 | } |
||
14589 | ; |
||
14590 | if(shouldEscape.test(string)) { |
||
14591 | return string.replace(badChars, escapedChar); |
||
14592 | } |
||
14593 | return string; |
||
14594 | }, |
||
14595 | message: function(message, type) { |
||
14596 | var |
||
14597 | html = '' |
||
14598 | ; |
||
14599 | if(message !== undefined && type !== undefined) { |
||
14600 | html += '' |
||
14601 | + '<div class="message ' + type + '">' |
||
14602 | ; |
||
14603 | // message type |
||
14604 | if(type == 'empty') { |
||
14605 | html += '' |
||
14606 | + '<div class="header">No Results</div class="header">' |
||
14607 | + '<div class="description">' + message + '</div class="description">' |
||
14608 | ; |
||
14609 | } |
||
14610 | else { |
||
14611 | html += ' <div class="description">' + message + '</div>'; |
||
14612 | } |
||
14613 | html += '</div>'; |
||
14614 | } |
||
14615 | return html; |
||
14616 | }, |
||
14617 | category: function(response, fields) { |
||
14618 | var |
||
14619 | html = '', |
||
14620 | escape = $.fn.search.settings.templates.escape |
||
14621 | ; |
||
14622 | if(response[fields.categoryResults] !== undefined) { |
||
14623 | |||
14624 | // each category |
||
14625 | $.each(response[fields.categoryResults], function(index, category) { |
||
14626 | if(category[fields.results] !== undefined && category.results.length > 0) { |
||
14627 | |||
14628 | html += '<div class="category">'; |
||
14629 | |||
14630 | if(category[fields.categoryName] !== undefined) { |
||
14631 | html += '<div class="name">' + category[fields.categoryName] + '</div>'; |
||
14632 | } |
||
14633 | |||
14634 | // each item inside category |
||
14635 | $.each(category.results, function(index, result) { |
||
14636 | if(result[fields.url]) { |
||
14637 | html += '<a class="result" href="' + result[fields.url] + '">'; |
||
14638 | } |
||
14639 | else { |
||
14640 | html += '<a class="result">'; |
||
14641 | } |
||
14642 | if(result[fields.image] !== undefined) { |
||
14643 | html += '' |
||
14644 | + '<div class="image">' |
||
14645 | + ' <img src="' + result[fields.image] + '">' |
||
14646 | + '</div>' |
||
14647 | ; |
||
14648 | } |
||
14649 | html += '<div class="content">'; |
||
14650 | if(result[fields.price] !== undefined) { |
||
14651 | html += '<div class="price">' + result[fields.price] + '</div>'; |
||
14652 | } |
||
14653 | if(result[fields.title] !== undefined) { |
||
14654 | html += '<div class="title">' + result[fields.title] + '</div>'; |
||
14655 | } |
||
14656 | if(result[fields.description] !== undefined) { |
||
14657 | html += '<div class="description">' + result[fields.description] + '</div>'; |
||
14658 | } |
||
14659 | html += '' |
||
14660 | + '</div>' |
||
14661 | ; |
||
14662 | html += '</a>'; |
||
14663 | }); |
||
14664 | html += '' |
||
14665 | + '</div>' |
||
14666 | ; |
||
14667 | } |
||
14668 | }); |
||
14669 | if(response[fields.action]) { |
||
14670 | html += '' |
||
14671 | + '<a href="' + response[fields.action][fields.actionURL] + '" class="action">' |
||
14672 | + response[fields.action][fields.actionText] |
||
14673 | + '</a>'; |
||
14674 | } |
||
14675 | return html; |
||
14676 | } |
||
14677 | return false; |
||
14678 | }, |
||
14679 | standard: function(response, fields) { |
||
14680 | var |
||
14681 | html = '' |
||
14682 | ; |
||
14683 | if(response[fields.results] !== undefined) { |
||
14684 | |||
14685 | // each result |
||
14686 | $.each(response[fields.results], function(index, result) { |
||
14687 | if(result[fields.url]) { |
||
14688 | html += '<a class="result" href="' + result[fields.url] + '">'; |
||
14689 | } |
||
14690 | else { |
||
14691 | html += '<a class="result">'; |
||
14692 | } |
||
14693 | if(result[fields.image] !== undefined) { |
||
14694 | html += '' |
||
14695 | + '<div class="image">' |
||
14696 | + ' <img src="' + result[fields.image] + '">' |
||
14697 | + '</div>' |
||
14698 | ; |
||
14699 | } |
||
14700 | html += '<div class="content">'; |
||
14701 | if(result[fields.price] !== undefined) { |
||
14702 | html += '<div class="price">' + result[fields.price] + '</div>'; |
||
14703 | } |
||
14704 | if(result[fields.title] !== undefined) { |
||
14705 | html += '<div class="title">' + result[fields.title] + '</div>'; |
||
14706 | } |
||
14707 | if(result[fields.description] !== undefined) { |
||
14708 | html += '<div class="description">' + result[fields.description] + '</div>'; |
||
14709 | } |
||
14710 | html += '' |
||
14711 | + '</div>' |
||
14712 | ; |
||
14713 | html += '</a>'; |
||
14714 | }); |
||
14715 | |||
14716 | if(response[fields.action]) { |
||
14717 | html += '' |
||
14718 | + '<a href="' + response[fields.action][fields.actionURL] + '" class="action">' |
||
14719 | + response[fields.action][fields.actionText] |
||
14720 | + '</a>'; |
||
14721 | } |
||
14722 | return html; |
||
14723 | } |
||
14724 | return false; |
||
14725 | } |
||
14726 | } |
||
14727 | }; |
||
14728 | |||
14729 | })( jQuery, window, document ); |
||
14730 | |||
14731 | /*! |
||
14732 | * # Semantic UI 2.2.11 - Shape |
||
14733 | * http://github.com/semantic-org/semantic-ui/ |
||
14734 | * |
||
14735 | * |
||
14736 | * Released under the MIT license |
||
14737 | * http://opensource.org/licenses/MIT |
||
14738 | * |
||
14739 | */ |
||
14740 | |||
14741 | View Code Duplication | ;(function ($, window, document, undefined) { |
|
14742 | |||
14743 | "use strict"; |
||
14744 | |||
14745 | window = (typeof window != 'undefined' && window.Math == Math) |
||
14746 | ? window |
||
14747 | : (typeof self != 'undefined' && self.Math == Math) |
||
14748 | ? self |
||
14749 | : Function('return this')() |
||
14750 | ; |
||
14751 | |||
14752 | $.fn.shape = function(parameters) { |
||
14753 | var |
||
14754 | $allModules = $(this), |
||
14755 | $body = $('body'), |
||
14756 | |||
14757 | time = new Date().getTime(), |
||
14758 | performance = [], |
||
14759 | |||
14760 | query = arguments[0], |
||
14761 | methodInvoked = (typeof query == 'string'), |
||
14762 | queryArguments = [].slice.call(arguments, 1), |
||
14763 | |||
14764 | requestAnimationFrame = window.requestAnimationFrame |
||
14765 | || window.mozRequestAnimationFrame |
||
14766 | || window.webkitRequestAnimationFrame |
||
14767 | || window.msRequestAnimationFrame |
||
14768 | || function(callback) { setTimeout(callback, 0); }, |
||
14769 | |||
14770 | returnedValue |
||
14771 | ; |
||
14772 | |||
14773 | $allModules |
||
14774 | .each(function() { |
||
14775 | var |
||
14776 | moduleSelector = $allModules.selector || '', |
||
14777 | settings = ( $.isPlainObject(parameters) ) |
||
14778 | ? $.extend(true, {}, $.fn.shape.settings, parameters) |
||
14779 | : $.extend({}, $.fn.shape.settings), |
||
14780 | |||
14781 | // internal aliases |
||
14782 | namespace = settings.namespace, |
||
14783 | selector = settings.selector, |
||
14784 | error = settings.error, |
||
14785 | className = settings.className, |
||
14786 | |||
14787 | // define namespaces for modules |
||
14788 | eventNamespace = '.' + namespace, |
||
14789 | moduleNamespace = 'module-' + namespace, |
||
14790 | |||
14791 | // selector cache |
||
14792 | $module = $(this), |
||
14793 | $sides = $module.find(selector.sides), |
||
14794 | $side = $module.find(selector.side), |
||
14795 | |||
14796 | // private variables |
||
14797 | nextIndex = false, |
||
14798 | $activeSide, |
||
14799 | $nextSide, |
||
14800 | |||
14801 | // standard module |
||
14802 | element = this, |
||
14803 | instance = $module.data(moduleNamespace), |
||
14804 | module |
||
14805 | ; |
||
14806 | |||
14807 | module = { |
||
14808 | |||
14809 | initialize: function() { |
||
14810 | module.verbose('Initializing module for', element); |
||
14811 | module.set.defaultSide(); |
||
14812 | module.instantiate(); |
||
14813 | }, |
||
14814 | |||
14815 | instantiate: function() { |
||
14816 | module.verbose('Storing instance of module', module); |
||
14817 | instance = module; |
||
14818 | $module |
||
14819 | .data(moduleNamespace, instance) |
||
14820 | ; |
||
14821 | }, |
||
14822 | |||
14823 | destroy: function() { |
||
14824 | module.verbose('Destroying previous module for', element); |
||
14825 | $module |
||
14826 | .removeData(moduleNamespace) |
||
14827 | .off(eventNamespace) |
||
14828 | ; |
||
14829 | }, |
||
14830 | |||
14831 | refresh: function() { |
||
14832 | module.verbose('Refreshing selector cache for', element); |
||
14833 | $module = $(element); |
||
14834 | $sides = $(this).find(selector.shape); |
||
14835 | $side = $(this).find(selector.side); |
||
14836 | }, |
||
14837 | |||
14838 | repaint: function() { |
||
14839 | module.verbose('Forcing repaint event'); |
||
14840 | var |
||
14841 | shape = $sides[0] || document.createElement('div'), |
||
14842 | fakeAssignment = shape.offsetWidth |
||
14843 | ; |
||
14844 | }, |
||
14845 | |||
14846 | animate: function(propertyObject, callback) { |
||
14847 | module.verbose('Animating box with properties', propertyObject); |
||
14848 | callback = callback || function(event) { |
||
14849 | module.verbose('Executing animation callback'); |
||
14850 | if(event !== undefined) { |
||
14851 | event.stopPropagation(); |
||
14852 | } |
||
14853 | module.reset(); |
||
14854 | module.set.active(); |
||
14855 | }; |
||
14856 | settings.beforeChange.call($nextSide[0]); |
||
14857 | if(module.get.transitionEvent()) { |
||
14858 | module.verbose('Starting CSS animation'); |
||
14859 | $module |
||
14860 | .addClass(className.animating) |
||
14861 | ; |
||
14862 | $sides |
||
14863 | .css(propertyObject) |
||
14864 | .one(module.get.transitionEvent(), callback) |
||
14865 | ; |
||
14866 | module.set.duration(settings.duration); |
||
14867 | requestAnimationFrame(function() { |
||
14868 | $module |
||
14869 | .addClass(className.animating) |
||
14870 | ; |
||
14871 | $activeSide |
||
14872 | .addClass(className.hidden) |
||
14873 | ; |
||
14874 | }); |
||
14875 | } |
||
14876 | else { |
||
14877 | callback(); |
||
14878 | } |
||
14879 | }, |
||
14880 | |||
14881 | queue: function(method) { |
||
14882 | module.debug('Queueing animation of', method); |
||
14883 | $sides |
||
14884 | .one(module.get.transitionEvent(), function() { |
||
14885 | module.debug('Executing queued animation'); |
||
14886 | setTimeout(function(){ |
||
14887 | $module.shape(method); |
||
14888 | }, 0); |
||
14889 | }) |
||
14890 | ; |
||
14891 | }, |
||
14892 | |||
14893 | reset: function() { |
||
14894 | module.verbose('Animating states reset'); |
||
14895 | $module |
||
14896 | .removeClass(className.animating) |
||
14897 | .attr('style', '') |
||
14898 | .removeAttr('style') |
||
14899 | ; |
||
14900 | // removeAttr style does not consistently work in safari |
||
14901 | $sides |
||
14902 | .attr('style', '') |
||
14903 | .removeAttr('style') |
||
14904 | ; |
||
14905 | $side |
||
14906 | .attr('style', '') |
||
14907 | .removeAttr('style') |
||
14908 | .removeClass(className.hidden) |
||
14909 | ; |
||
14910 | $nextSide |
||
14911 | .removeClass(className.animating) |
||
14912 | .attr('style', '') |
||
14913 | .removeAttr('style') |
||
14914 | ; |
||
14915 | }, |
||
14916 | |||
14917 | is: { |
||
14918 | complete: function() { |
||
14919 | return ($side.filter('.' + className.active)[0] == $nextSide[0]); |
||
14920 | }, |
||
14921 | animating: function() { |
||
14922 | return $module.hasClass(className.animating); |
||
14923 | } |
||
14924 | }, |
||
14925 | |||
14926 | set: { |
||
14927 | |||
14928 | defaultSide: function() { |
||
14929 | $activeSide = $module.find('.' + settings.className.active); |
||
14930 | $nextSide = ( $activeSide.next(selector.side).length > 0 ) |
||
14931 | ? $activeSide.next(selector.side) |
||
14932 | : $module.find(selector.side).first() |
||
14933 | ; |
||
14934 | nextIndex = false; |
||
14935 | module.verbose('Active side set to', $activeSide); |
||
14936 | module.verbose('Next side set to', $nextSide); |
||
14937 | }, |
||
14938 | |||
14939 | duration: function(duration) { |
||
14940 | duration = duration || settings.duration; |
||
14941 | duration = (typeof duration == 'number') |
||
14942 | ? duration + 'ms' |
||
14943 | : duration |
||
14944 | ; |
||
14945 | module.verbose('Setting animation duration', duration); |
||
14946 | if(settings.duration || settings.duration === 0) { |
||
14947 | $sides.add($side) |
||
14948 | .css({ |
||
14949 | '-webkit-transition-duration': duration, |
||
14950 | '-moz-transition-duration': duration, |
||
14951 | '-ms-transition-duration': duration, |
||
14952 | '-o-transition-duration': duration, |
||
14953 | 'transition-duration': duration |
||
14954 | }) |
||
14955 | ; |
||
14956 | } |
||
14957 | }, |
||
14958 | |||
14959 | currentStageSize: function() { |
||
14960 | var |
||
14961 | $activeSide = $module.find('.' + settings.className.active), |
||
14962 | width = $activeSide.outerWidth(true), |
||
14963 | height = $activeSide.outerHeight(true) |
||
14964 | ; |
||
14965 | $module |
||
14966 | .css({ |
||
14967 | width: width, |
||
14968 | height: height |
||
14969 | }) |
||
14970 | ; |
||
14971 | }, |
||
14972 | |||
14973 | stageSize: function() { |
||
14974 | var |
||
14975 | $clone = $module.clone().addClass(className.loading), |
||
14976 | $activeSide = $clone.find('.' + settings.className.active), |
||
14977 | $nextSide = (nextIndex) |
||
14978 | ? $clone.find(selector.side).eq(nextIndex) |
||
14979 | : ( $activeSide.next(selector.side).length > 0 ) |
||
14980 | ? $activeSide.next(selector.side) |
||
14981 | : $clone.find(selector.side).first(), |
||
14982 | newWidth = (settings.width == 'next') |
||
14983 | ? $nextSide.outerWidth(true) |
||
14984 | : (settings.width == 'initial') |
||
14985 | ? $module.width() |
||
14986 | : settings.width, |
||
14987 | newHeight = (settings.height == 'next') |
||
14988 | ? $nextSide.outerHeight(true) |
||
14989 | : (settings.height == 'initial') |
||
14990 | ? $module.height() |
||
14991 | : settings.height |
||
14992 | ; |
||
14993 | $activeSide.removeClass(className.active); |
||
14994 | $nextSide.addClass(className.active); |
||
14995 | $clone.insertAfter($module); |
||
14996 | $clone.remove(); |
||
14997 | if(settings.width != 'auto') { |
||
14998 | $module.css('width', newWidth + settings.jitter); |
||
14999 | module.verbose('Specifying width during animation', newWidth); |
||
15000 | } |
||
15001 | if(settings.height != 'auto') { |
||
15002 | $module.css('height', newHeight + settings.jitter); |
||
15003 | module.verbose('Specifying height during animation', newHeight); |
||
15004 | } |
||
15005 | }, |
||
15006 | |||
15007 | nextSide: function(selector) { |
||
15008 | nextIndex = selector; |
||
15009 | $nextSide = $side.filter(selector); |
||
15010 | nextIndex = $side.index($nextSide); |
||
15011 | if($nextSide.length === 0) { |
||
15012 | module.set.defaultSide(); |
||
15013 | module.error(error.side); |
||
15014 | } |
||
15015 | module.verbose('Next side manually set to', $nextSide); |
||
15016 | }, |
||
15017 | |||
15018 | active: function() { |
||
15019 | module.verbose('Setting new side to active', $nextSide); |
||
15020 | $side |
||
15021 | .removeClass(className.active) |
||
15022 | ; |
||
15023 | $nextSide |
||
15024 | .addClass(className.active) |
||
15025 | ; |
||
15026 | settings.onChange.call($nextSide[0]); |
||
15027 | module.set.defaultSide(); |
||
15028 | } |
||
15029 | }, |
||
15030 | |||
15031 | flip: { |
||
15032 | |||
15033 | up: function() { |
||
15034 | if(module.is.complete() && !module.is.animating() && !settings.allowRepeats) { |
||
15035 | module.debug('Side already visible', $nextSide); |
||
15036 | return; |
||
15037 | } |
||
15038 | if( !module.is.animating()) { |
||
15039 | module.debug('Flipping up', $nextSide); |
||
15040 | var |
||
15041 | transform = module.get.transform.up() |
||
15042 | ; |
||
15043 | module.set.stageSize(); |
||
15044 | module.stage.above(); |
||
15045 | module.animate(transform); |
||
15046 | } |
||
15047 | else { |
||
15048 | module.queue('flip up'); |
||
15049 | } |
||
15050 | }, |
||
15051 | |||
15052 | down: function() { |
||
15053 | if(module.is.complete() && !module.is.animating() && !settings.allowRepeats) { |
||
15054 | module.debug('Side already visible', $nextSide); |
||
15055 | return; |
||
15056 | } |
||
15057 | if( !module.is.animating()) { |
||
15058 | module.debug('Flipping down', $nextSide); |
||
15059 | var |
||
15060 | transform = module.get.transform.down() |
||
15061 | ; |
||
15062 | module.set.stageSize(); |
||
15063 | module.stage.below(); |
||
15064 | module.animate(transform); |
||
15065 | } |
||
15066 | else { |
||
15067 | module.queue('flip down'); |
||
15068 | } |
||
15069 | }, |
||
15070 | |||
15071 | left: function() { |
||
15072 | if(module.is.complete() && !module.is.animating() && !settings.allowRepeats) { |
||
15073 | module.debug('Side already visible', $nextSide); |
||
15074 | return; |
||
15075 | } |
||
15076 | if( !module.is.animating()) { |
||
15077 | module.debug('Flipping left', $nextSide); |
||
15078 | var |
||
15079 | transform = module.get.transform.left() |
||
15080 | ; |
||
15081 | module.set.stageSize(); |
||
15082 | module.stage.left(); |
||
15083 | module.animate(transform); |
||
15084 | } |
||
15085 | else { |
||
15086 | module.queue('flip left'); |
||
15087 | } |
||
15088 | }, |
||
15089 | |||
15090 | right: function() { |
||
15091 | if(module.is.complete() && !module.is.animating() && !settings.allowRepeats) { |
||
15092 | module.debug('Side already visible', $nextSide); |
||
15093 | return; |
||
15094 | } |
||
15095 | if( !module.is.animating()) { |
||
15096 | module.debug('Flipping right', $nextSide); |
||
15097 | var |
||
15098 | transform = module.get.transform.right() |
||
15099 | ; |
||
15100 | module.set.stageSize(); |
||
15101 | module.stage.right(); |
||
15102 | module.animate(transform); |
||
15103 | } |
||
15104 | else { |
||
15105 | module.queue('flip right'); |
||
15106 | } |
||
15107 | }, |
||
15108 | |||
15109 | over: function() { |
||
15110 | if(module.is.complete() && !module.is.animating() && !settings.allowRepeats) { |
||
15111 | module.debug('Side already visible', $nextSide); |
||
15112 | return; |
||
15113 | } |
||
15114 | if( !module.is.animating()) { |
||
15115 | module.debug('Flipping over', $nextSide); |
||
15116 | module.set.stageSize(); |
||
15117 | module.stage.behind(); |
||
15118 | module.animate(module.get.transform.over() ); |
||
15119 | } |
||
15120 | else { |
||
15121 | module.queue('flip over'); |
||
15122 | } |
||
15123 | }, |
||
15124 | |||
15125 | back: function() { |
||
15126 | if(module.is.complete() && !module.is.animating() && !settings.allowRepeats) { |
||
15127 | module.debug('Side already visible', $nextSide); |
||
15128 | return; |
||
15129 | } |
||
15130 | if( !module.is.animating()) { |
||
15131 | module.debug('Flipping back', $nextSide); |
||
15132 | module.set.stageSize(); |
||
15133 | module.stage.behind(); |
||
15134 | module.animate(module.get.transform.back() ); |
||
15135 | } |
||
15136 | else { |
||
15137 | module.queue('flip back'); |
||
15138 | } |
||
15139 | } |
||
15140 | |||
15141 | }, |
||
15142 | |||
15143 | get: { |
||
15144 | |||
15145 | transform: { |
||
15146 | up: function() { |
||
15147 | var |
||
15148 | translate = { |
||
15149 | y: -(($activeSide.outerHeight(true) - $nextSide.outerHeight(true)) / 2), |
||
15150 | z: -($activeSide.outerHeight(true) / 2) |
||
15151 | } |
||
15152 | ; |
||
15153 | return { |
||
15154 | transform: 'translateY(' + translate.y + 'px) translateZ('+ translate.z + 'px) rotateX(-90deg)' |
||
15155 | }; |
||
15156 | }, |
||
15157 | |||
15158 | down: function() { |
||
15159 | var |
||
15160 | translate = { |
||
15161 | y: -(($activeSide.outerHeight(true) - $nextSide.outerHeight(true)) / 2), |
||
15162 | z: -($activeSide.outerHeight(true) / 2) |
||
15163 | } |
||
15164 | ; |
||
15165 | return { |
||
15166 | transform: 'translateY(' + translate.y + 'px) translateZ('+ translate.z + 'px) rotateX(90deg)' |
||
15167 | }; |
||
15168 | }, |
||
15169 | |||
15170 | left: function() { |
||
15171 | var |
||
15172 | translate = { |
||
15173 | x : -(($activeSide.outerWidth(true) - $nextSide.outerWidth(true)) / 2), |
||
15174 | z : -($activeSide.outerWidth(true) / 2) |
||
15175 | } |
||
15176 | ; |
||
15177 | return { |
||
15178 | transform: 'translateX(' + translate.x + 'px) translateZ(' + translate.z + 'px) rotateY(90deg)' |
||
15179 | }; |
||
15180 | }, |
||
15181 | |||
15182 | right: function() { |
||
15183 | var |
||
15184 | translate = { |
||
15185 | x : -(($activeSide.outerWidth(true) - $nextSide.outerWidth(true)) / 2), |
||
15186 | z : -($activeSide.outerWidth(true) / 2) |
||
15187 | } |
||
15188 | ; |
||
15189 | return { |
||
15190 | transform: 'translateX(' + translate.x + 'px) translateZ(' + translate.z + 'px) rotateY(-90deg)' |
||
15191 | }; |
||
15192 | }, |
||
15193 | |||
15194 | over: function() { |
||
15195 | var |
||
15196 | translate = { |
||
15197 | x : -(($activeSide.outerWidth(true) - $nextSide.outerWidth(true)) / 2) |
||
15198 | } |
||
15199 | ; |
||
15200 | return { |
||
15201 | transform: 'translateX(' + translate.x + 'px) rotateY(180deg)' |
||
15202 | }; |
||
15203 | }, |
||
15204 | |||
15205 | back: function() { |
||
15206 | var |
||
15207 | translate = { |
||
15208 | x : -(($activeSide.outerWidth(true) - $nextSide.outerWidth(true)) / 2) |
||
15209 | } |
||
15210 | ; |
||
15211 | return { |
||
15212 | transform: 'translateX(' + translate.x + 'px) rotateY(-180deg)' |
||
15213 | }; |
||
15214 | } |
||
15215 | }, |
||
15216 | |||
15217 | transitionEvent: function() { |
||
15218 | var |
||
15219 | element = document.createElement('element'), |
||
15220 | transitions = { |
||
15221 | 'transition' :'transitionend', |
||
15222 | 'OTransition' :'oTransitionEnd', |
||
15223 | 'MozTransition' :'transitionend', |
||
15224 | 'WebkitTransition' :'webkitTransitionEnd' |
||
15225 | }, |
||
15226 | transition |
||
15227 | ; |
||
15228 | for(transition in transitions){ |
||
15229 | if( element.style[transition] !== undefined ){ |
||
15230 | return transitions[transition]; |
||
15231 | } |
||
15232 | } |
||
15233 | }, |
||
15234 | |||
15235 | nextSide: function() { |
||
15236 | return ( $activeSide.next(selector.side).length > 0 ) |
||
15237 | ? $activeSide.next(selector.side) |
||
15238 | : $module.find(selector.side).first() |
||
15239 | ; |
||
15240 | } |
||
15241 | |||
15242 | }, |
||
15243 | |||
15244 | stage: { |
||
15245 | |||
15246 | above: function() { |
||
15247 | var |
||
15248 | box = { |
||
15249 | origin : (($activeSide.outerHeight(true) - $nextSide.outerHeight(true)) / 2), |
||
15250 | depth : { |
||
15251 | active : ($nextSide.outerHeight(true) / 2), |
||
15252 | next : ($activeSide.outerHeight(true) / 2) |
||
15253 | } |
||
15254 | } |
||
15255 | ; |
||
15256 | module.verbose('Setting the initial animation position as above', $nextSide, box); |
||
15257 | $sides |
||
15258 | .css({ |
||
15259 | 'transform' : 'translateZ(-' + box.depth.active + 'px)' |
||
15260 | }) |
||
15261 | ; |
||
15262 | $activeSide |
||
15263 | .css({ |
||
15264 | 'transform' : 'rotateY(0deg) translateZ(' + box.depth.active + 'px)' |
||
15265 | }) |
||
15266 | ; |
||
15267 | $nextSide |
||
15268 | .addClass(className.animating) |
||
15269 | .css({ |
||
15270 | 'top' : box.origin + 'px', |
||
15271 | 'transform' : 'rotateX(90deg) translateZ(' + box.depth.next + 'px)' |
||
15272 | }) |
||
15273 | ; |
||
15274 | }, |
||
15275 | |||
15276 | below: function() { |
||
15277 | var |
||
15278 | box = { |
||
15279 | origin : (($activeSide.outerHeight(true) - $nextSide.outerHeight(true)) / 2), |
||
15280 | depth : { |
||
15281 | active : ($nextSide.outerHeight(true) / 2), |
||
15282 | next : ($activeSide.outerHeight(true) / 2) |
||
15283 | } |
||
15284 | } |
||
15285 | ; |
||
15286 | module.verbose('Setting the initial animation position as below', $nextSide, box); |
||
15287 | $sides |
||
15288 | .css({ |
||
15289 | 'transform' : 'translateZ(-' + box.depth.active + 'px)' |
||
15290 | }) |
||
15291 | ; |
||
15292 | $activeSide |
||
15293 | .css({ |
||
15294 | 'transform' : 'rotateY(0deg) translateZ(' + box.depth.active + 'px)' |
||
15295 | }) |
||
15296 | ; |
||
15297 | $nextSide |
||
15298 | .addClass(className.animating) |
||
15299 | .css({ |
||
15300 | 'top' : box.origin + 'px', |
||
15301 | 'transform' : 'rotateX(-90deg) translateZ(' + box.depth.next + 'px)' |
||
15302 | }) |
||
15303 | ; |
||
15304 | }, |
||
15305 | |||
15306 | left: function() { |
||
15307 | var |
||
15308 | height = { |
||
15309 | active : $activeSide.outerWidth(true), |
||
15310 | next : $nextSide.outerWidth(true) |
||
15311 | }, |
||
15312 | box = { |
||
15313 | origin : ( ( height.active - height.next ) / 2), |
||
15314 | depth : { |
||
15315 | active : (height.next / 2), |
||
15316 | next : (height.active / 2) |
||
15317 | } |
||
15318 | } |
||
15319 | ; |
||
15320 | module.verbose('Setting the initial animation position as left', $nextSide, box); |
||
15321 | $sides |
||
15322 | .css({ |
||
15323 | 'transform' : 'translateZ(-' + box.depth.active + 'px)' |
||
15324 | }) |
||
15325 | ; |
||
15326 | $activeSide |
||
15327 | .css({ |
||
15328 | 'transform' : 'rotateY(0deg) translateZ(' + box.depth.active + 'px)' |
||
15329 | }) |
||
15330 | ; |
||
15331 | $nextSide |
||
15332 | .addClass(className.animating) |
||
15333 | .css({ |
||
15334 | 'left' : box.origin + 'px', |
||
15335 | 'transform' : 'rotateY(-90deg) translateZ(' + box.depth.next + 'px)' |
||
15336 | }) |
||
15337 | ; |
||
15338 | }, |
||
15339 | |||
15340 | right: function() { |
||
15341 | var |
||
15342 | height = { |
||
15343 | active : $activeSide.outerWidth(true), |
||
15344 | next : $nextSide.outerWidth(true) |
||
15345 | }, |
||
15346 | box = { |
||
15347 | origin : ( ( height.active - height.next ) / 2), |
||
15348 | depth : { |
||
15349 | active : (height.next / 2), |
||
15350 | next : (height.active / 2) |
||
15351 | } |
||
15352 | } |
||
15353 | ; |
||
15354 | module.verbose('Setting the initial animation position as left', $nextSide, box); |
||
15355 | $sides |
||
15356 | .css({ |
||
15357 | 'transform' : 'translateZ(-' + box.depth.active + 'px)' |
||
15358 | }) |
||
15359 | ; |
||
15360 | $activeSide |
||
15361 | .css({ |
||
15362 | 'transform' : 'rotateY(0deg) translateZ(' + box.depth.active + 'px)' |
||
15363 | }) |
||
15364 | ; |
||
15365 | $nextSide |
||
15366 | .addClass(className.animating) |
||
15367 | .css({ |
||
15368 | 'left' : box.origin + 'px', |
||
15369 | 'transform' : 'rotateY(90deg) translateZ(' + box.depth.next + 'px)' |
||
15370 | }) |
||
15371 | ; |
||
15372 | }, |
||
15373 | |||
15374 | behind: function() { |
||
15375 | var |
||
15376 | height = { |
||
15377 | active : $activeSide.outerWidth(true), |
||
15378 | next : $nextSide.outerWidth(true) |
||
15379 | }, |
||
15380 | box = { |
||
15381 | origin : ( ( height.active - height.next ) / 2), |
||
15382 | depth : { |
||
15383 | active : (height.next / 2), |
||
15384 | next : (height.active / 2) |
||
15385 | } |
||
15386 | } |
||
15387 | ; |
||
15388 | module.verbose('Setting the initial animation position as behind', $nextSide, box); |
||
15389 | $activeSide |
||
15390 | .css({ |
||
15391 | 'transform' : 'rotateY(0deg)' |
||
15392 | }) |
||
15393 | ; |
||
15394 | $nextSide |
||
15395 | .addClass(className.animating) |
||
15396 | .css({ |
||
15397 | 'left' : box.origin + 'px', |
||
15398 | 'transform' : 'rotateY(-180deg)' |
||
15399 | }) |
||
15400 | ; |
||
15401 | } |
||
15402 | }, |
||
15403 | setting: function(name, value) { |
||
15404 | module.debug('Changing setting', name, value); |
||
15405 | if( $.isPlainObject(name) ) { |
||
15406 | $.extend(true, settings, name); |
||
15407 | } |
||
15408 | else if(value !== undefined) { |
||
15409 | if($.isPlainObject(settings[name])) { |
||
15410 | $.extend(true, settings[name], value); |
||
15411 | } |
||
15412 | else { |
||
15413 | settings[name] = value; |
||
15414 | } |
||
15415 | } |
||
15416 | else { |
||
15417 | return settings[name]; |
||
15418 | } |
||
15419 | }, |
||
15420 | internal: function(name, value) { |
||
15421 | if( $.isPlainObject(name) ) { |
||
15422 | $.extend(true, module, name); |
||
15423 | } |
||
15424 | else if(value !== undefined) { |
||
15425 | module[name] = value; |
||
15426 | } |
||
15427 | else { |
||
15428 | return module[name]; |
||
15429 | } |
||
15430 | }, |
||
15431 | debug: function() { |
||
15432 | if(!settings.silent && settings.debug) { |
||
15433 | if(settings.performance) { |
||
15434 | module.performance.log(arguments); |
||
15435 | } |
||
15436 | else { |
||
15437 | module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':'); |
||
15438 | module.debug.apply(console, arguments); |
||
15439 | } |
||
15440 | } |
||
15441 | }, |
||
15442 | verbose: function() { |
||
15443 | if(!settings.silent && settings.verbose && settings.debug) { |
||
15444 | if(settings.performance) { |
||
15445 | module.performance.log(arguments); |
||
15446 | } |
||
15447 | else { |
||
15448 | module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':'); |
||
15449 | module.verbose.apply(console, arguments); |
||
15450 | } |
||
15451 | } |
||
15452 | }, |
||
15453 | error: function() { |
||
15454 | if(!settings.silent) { |
||
15455 | module.error = Function.prototype.bind.call(console.error, console, settings.name + ':'); |
||
15456 | module.error.apply(console, arguments); |
||
15457 | } |
||
15458 | }, |
||
15459 | performance: { |
||
15460 | log: function(message) { |
||
15461 | var |
||
15462 | currentTime, |
||
15463 | executionTime, |
||
15464 | previousTime |
||
15465 | ; |
||
15466 | if(settings.performance) { |
||
15467 | currentTime = new Date().getTime(); |
||
15468 | previousTime = time || currentTime; |
||
15469 | executionTime = currentTime - previousTime; |
||
15470 | time = currentTime; |
||
15471 | performance.push({ |
||
15472 | 'Name' : message[0], |
||
15473 | 'Arguments' : [].slice.call(message, 1) || '', |
||
15474 | 'Element' : element, |
||
15475 | 'Execution Time' : executionTime |
||
15476 | }); |
||
15477 | } |
||
15478 | clearTimeout(module.performance.timer); |
||
15479 | module.performance.timer = setTimeout(module.performance.display, 500); |
||
15480 | }, |
||
15481 | display: function() { |
||
15482 | var |
||
15483 | title = settings.name + ':', |
||
15484 | totalTime = 0 |
||
15485 | ; |
||
15486 | time = false; |
||
15487 | clearTimeout(module.performance.timer); |
||
15488 | $.each(performance, function(index, data) { |
||
15489 | totalTime += data['Execution Time']; |
||
15490 | }); |
||
15491 | title += ' ' + totalTime + 'ms'; |
||
15492 | if(moduleSelector) { |
||
15493 | title += ' \'' + moduleSelector + '\''; |
||
15494 | } |
||
15495 | if($allModules.length > 1) { |
||
15496 | title += ' ' + '(' + $allModules.length + ')'; |
||
15497 | } |
||
15498 | if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) { |
||
15499 | console.groupCollapsed(title); |
||
15500 | if(console.table) { |
||
15501 | console.table(performance); |
||
15502 | } |
||
15503 | else { |
||
15504 | $.each(performance, function(index, data) { |
||
15505 | console.log(data['Name'] + ': ' + data['Execution Time']+'ms'); |
||
15506 | }); |
||
15507 | } |
||
15508 | console.groupEnd(); |
||
15509 | } |
||
15510 | performance = []; |
||
15511 | } |
||
15512 | }, |
||
15513 | invoke: function(query, passedArguments, context) { |
||
15514 | var |
||
15515 | object = instance, |
||
15516 | maxDepth, |
||
15517 | found, |
||
15518 | response |
||
15519 | ; |
||
15520 | passedArguments = passedArguments || queryArguments; |
||
15521 | context = element || context; |
||
15522 | if(typeof query == 'string' && object !== undefined) { |
||
15523 | query = query.split(/[\. ]/); |
||
15524 | maxDepth = query.length - 1; |
||
15525 | $.each(query, function(depth, value) { |
||
15526 | var camelCaseValue = (depth != maxDepth) |
||
15527 | ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1) |
||
15528 | : query |
||
15529 | ; |
||
15530 | if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) { |
||
15531 | object = object[camelCaseValue]; |
||
15532 | } |
||
15533 | else if( object[camelCaseValue] !== undefined ) { |
||
15534 | found = object[camelCaseValue]; |
||
15535 | return false; |
||
15536 | } |
||
15537 | else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) { |
||
15538 | object = object[value]; |
||
15539 | } |
||
15540 | else if( object[value] !== undefined ) { |
||
15541 | found = object[value]; |
||
15542 | return false; |
||
15543 | } |
||
15544 | else { |
||
15545 | return false; |
||
15546 | } |
||
15547 | }); |
||
15548 | } |
||
15549 | if ( $.isFunction( found ) ) { |
||
15550 | response = found.apply(context, passedArguments); |
||
15551 | } |
||
15552 | else if(found !== undefined) { |
||
15553 | response = found; |
||
15554 | } |
||
15555 | if($.isArray(returnedValue)) { |
||
15556 | returnedValue.push(response); |
||
15557 | } |
||
15558 | else if(returnedValue !== undefined) { |
||
15559 | returnedValue = [returnedValue, response]; |
||
15560 | } |
||
15561 | else if(response !== undefined) { |
||
15562 | returnedValue = response; |
||
15563 | } |
||
15564 | return found; |
||
15565 | } |
||
15566 | }; |
||
15567 | |||
15568 | if(methodInvoked) { |
||
15569 | if(instance === undefined) { |
||
15570 | module.initialize(); |
||
15571 | } |
||
15572 | module.invoke(query); |
||
15573 | } |
||
15574 | else { |
||
15575 | if(instance !== undefined) { |
||
15576 | instance.invoke('destroy'); |
||
15577 | } |
||
15578 | module.initialize(); |
||
15579 | } |
||
15580 | }) |
||
15581 | ; |
||
15582 | |||
15583 | return (returnedValue !== undefined) |
||
15584 | ? returnedValue |
||
15585 | : this |
||
15586 | ; |
||
15587 | }; |
||
15588 | |||
15589 | $.fn.shape.settings = { |
||
15590 | |||
15591 | // module info |
||
15592 | name : 'Shape', |
||
15593 | |||
15594 | // hide all debug content |
||
15595 | silent : false, |
||
15596 | |||
15597 | // debug content outputted to console |
||
15598 | debug : false, |
||
15599 | |||
15600 | // verbose debug output |
||
15601 | verbose : false, |
||
15602 | |||
15603 | // fudge factor in pixels when swapping from 2d to 3d (can be useful to correct rounding errors) |
||
15604 | jitter : 0, |
||
15605 | |||
15606 | // performance data output |
||
15607 | performance: true, |
||
15608 | |||
15609 | // event namespace |
||
15610 | namespace : 'shape', |
||
15611 | |||
15612 | // width during animation, can be set to 'auto', initial', 'next' or pixel amount |
||
15613 | width: 'initial', |
||
15614 | |||
15615 | // height during animation, can be set to 'auto', 'initial', 'next' or pixel amount |
||
15616 | height: 'initial', |
||
15617 | |||
15618 | // callback occurs on side change |
||
15619 | beforeChange : function() {}, |
||
15620 | onChange : function() {}, |
||
15621 | |||
15622 | // allow animation to same side |
||
15623 | allowRepeats: false, |
||
15624 | |||
15625 | // animation duration |
||
15626 | duration : false, |
||
15627 | |||
15628 | // possible errors |
||
15629 | error: { |
||
15630 | side : 'You tried to switch to a side that does not exist.', |
||
15631 | method : 'The method you called is not defined' |
||
15632 | }, |
||
15633 | |||
15634 | // classnames used |
||
15635 | className : { |
||
15636 | animating : 'animating', |
||
15637 | hidden : 'hidden', |
||
15638 | loading : 'loading', |
||
15639 | active : 'active' |
||
15640 | }, |
||
15641 | |||
15642 | // selectors used |
||
15643 | selector : { |
||
15644 | sides : '.sides', |
||
15645 | side : '.side' |
||
15646 | } |
||
15647 | |||
15648 | }; |
||
15649 | |||
15650 | |||
15651 | })( jQuery, window, document ); |
||
15652 | |||
15653 | /*! |
||
15654 | * # Semantic UI 2.2.11 - Sidebar |
||
15655 | * http://github.com/semantic-org/semantic-ui/ |
||
15656 | * |
||
15657 | * |
||
15658 | * Released under the MIT license |
||
15659 | * http://opensource.org/licenses/MIT |
||
15660 | * |
||
15661 | */ |
||
15662 | |||
15663 | View Code Duplication | ;(function ($, window, document, undefined) { |
|
15664 | |||
15665 | "use strict"; |
||
15666 | |||
15667 | window = (typeof window != 'undefined' && window.Math == Math) |
||
15668 | ? window |
||
15669 | : (typeof self != 'undefined' && self.Math == Math) |
||
15670 | ? self |
||
15671 | : Function('return this')() |
||
15672 | ; |
||
15673 | |||
15674 | $.fn.sidebar = function(parameters) { |
||
15675 | var |
||
15676 | $allModules = $(this), |
||
15677 | $window = $(window), |
||
15678 | $document = $(document), |
||
15679 | $html = $('html'), |
||
15680 | $head = $('head'), |
||
15681 | |||
15682 | moduleSelector = $allModules.selector || '', |
||
15683 | |||
15684 | time = new Date().getTime(), |
||
15685 | performance = [], |
||
15686 | |||
15687 | query = arguments[0], |
||
15688 | methodInvoked = (typeof query == 'string'), |
||
15689 | queryArguments = [].slice.call(arguments, 1), |
||
15690 | |||
15691 | requestAnimationFrame = window.requestAnimationFrame |
||
15692 | || window.mozRequestAnimationFrame |
||
15693 | || window.webkitRequestAnimationFrame |
||
15694 | || window.msRequestAnimationFrame |
||
15695 | || function(callback) { setTimeout(callback, 0); }, |
||
15696 | |||
15697 | returnedValue |
||
15698 | ; |
||
15699 | |||
15700 | $allModules |
||
15701 | .each(function() { |
||
15702 | var |
||
15703 | settings = ( $.isPlainObject(parameters) ) |
||
15704 | ? $.extend(true, {}, $.fn.sidebar.settings, parameters) |
||
15705 | : $.extend({}, $.fn.sidebar.settings), |
||
15706 | |||
15707 | selector = settings.selector, |
||
15708 | className = settings.className, |
||
15709 | namespace = settings.namespace, |
||
15710 | regExp = settings.regExp, |
||
15711 | error = settings.error, |
||
15712 | |||
15713 | eventNamespace = '.' + namespace, |
||
15714 | moduleNamespace = 'module-' + namespace, |
||
15715 | |||
15716 | $module = $(this), |
||
15717 | $context = $(settings.context), |
||
15718 | |||
15719 | $sidebars = $module.children(selector.sidebar), |
||
15720 | $fixed = $context.children(selector.fixed), |
||
15721 | $pusher = $context.children(selector.pusher), |
||
15722 | $style, |
||
15723 | |||
15724 | element = this, |
||
15725 | instance = $module.data(moduleNamespace), |
||
15726 | |||
15727 | elementNamespace, |
||
15728 | id, |
||
15729 | currentScroll, |
||
15730 | transitionEvent, |
||
15731 | |||
15732 | module |
||
15733 | ; |
||
15734 | |||
15735 | module = { |
||
15736 | |||
15737 | initialize: function() { |
||
15738 | module.debug('Initializing sidebar', parameters); |
||
15739 | |||
15740 | module.create.id(); |
||
15741 | |||
15742 | transitionEvent = module.get.transitionEvent(); |
||
15743 | |||
15744 | // avoids locking rendering if initialized in onReady |
||
15745 | if(settings.delaySetup) { |
||
15746 | requestAnimationFrame(module.setup.layout); |
||
15747 | } |
||
15748 | else { |
||
15749 | module.setup.layout(); |
||
15750 | } |
||
15751 | |||
15752 | requestAnimationFrame(function() { |
||
15753 | module.setup.cache(); |
||
15754 | }); |
||
15755 | |||
15756 | module.instantiate(); |
||
15757 | }, |
||
15758 | |||
15759 | instantiate: function() { |
||
15760 | module.verbose('Storing instance of module', module); |
||
15761 | instance = module; |
||
15762 | $module |
||
15763 | .data(moduleNamespace, module) |
||
15764 | ; |
||
15765 | }, |
||
15766 | |||
15767 | create: { |
||
15768 | id: function() { |
||
15769 | id = (Math.random().toString(16) + '000000000').substr(2,8); |
||
15770 | elementNamespace = '.' + id; |
||
15771 | module.verbose('Creating unique id for element', id); |
||
15772 | } |
||
15773 | }, |
||
15774 | |||
15775 | destroy: function() { |
||
15776 | module.verbose('Destroying previous module for', $module); |
||
15777 | $module |
||
15778 | .off(eventNamespace) |
||
15779 | .removeData(moduleNamespace) |
||
15780 | ; |
||
15781 | if(module.is.ios()) { |
||
15782 | module.remove.ios(); |
||
15783 | } |
||
15784 | // bound by uuid |
||
15785 | $context.off(elementNamespace); |
||
15786 | $window.off(elementNamespace); |
||
15787 | $document.off(elementNamespace); |
||
15788 | }, |
||
15789 | |||
15790 | event: { |
||
15791 | clickaway: function(event) { |
||
15792 | var |
||
15793 | clickedInPusher = ($pusher.find(event.target).length > 0 || $pusher.is(event.target)), |
||
15794 | clickedContext = ($context.is(event.target)) |
||
15795 | ; |
||
15796 | if(clickedInPusher) { |
||
15797 | module.verbose('User clicked on dimmed page'); |
||
15798 | module.hide(); |
||
15799 | } |
||
15800 | if(clickedContext) { |
||
15801 | module.verbose('User clicked on dimmable context (scaled out page)'); |
||
15802 | module.hide(); |
||
15803 | } |
||
15804 | }, |
||
15805 | touch: function(event) { |
||
15806 | //event.stopPropagation(); |
||
15807 | }, |
||
15808 | containScroll: function(event) { |
||
15809 | if(element.scrollTop <= 0) { |
||
15810 | element.scrollTop = 1; |
||
15811 | } |
||
15812 | if((element.scrollTop + element.offsetHeight) >= element.scrollHeight) { |
||
15813 | element.scrollTop = element.scrollHeight - element.offsetHeight - 1; |
||
15814 | } |
||
15815 | }, |
||
15816 | scroll: function(event) { |
||
15817 | if( $(event.target).closest(selector.sidebar).length === 0 ) { |
||
15818 | event.preventDefault(); |
||
15819 | } |
||
15820 | } |
||
15821 | }, |
||
15822 | |||
15823 | bind: { |
||
15824 | clickaway: function() { |
||
15825 | module.verbose('Adding clickaway events to context', $context); |
||
15826 | if(settings.closable) { |
||
15827 | $context |
||
15828 | .on('click' + elementNamespace, module.event.clickaway) |
||
15829 | .on('touchend' + elementNamespace, module.event.clickaway) |
||
15830 | ; |
||
15831 | } |
||
15832 | }, |
||
15833 | scrollLock: function() { |
||
15834 | if(settings.scrollLock) { |
||
15835 | module.debug('Disabling page scroll'); |
||
15836 | $window |
||
15837 | .on('DOMMouseScroll' + elementNamespace, module.event.scroll) |
||
15838 | ; |
||
15839 | } |
||
15840 | module.verbose('Adding events to contain sidebar scroll'); |
||
15841 | $document |
||
15842 | .on('touchmove' + elementNamespace, module.event.touch) |
||
15843 | ; |
||
15844 | $module |
||
15845 | .on('scroll' + eventNamespace, module.event.containScroll) |
||
15846 | ; |
||
15847 | } |
||
15848 | }, |
||
15849 | unbind: { |
||
15850 | clickaway: function() { |
||
15851 | module.verbose('Removing clickaway events from context', $context); |
||
15852 | $context.off(elementNamespace); |
||
15853 | }, |
||
15854 | scrollLock: function() { |
||
15855 | module.verbose('Removing scroll lock from page'); |
||
15856 | $document.off(elementNamespace); |
||
15857 | $window.off(elementNamespace); |
||
15858 | $module.off('scroll' + eventNamespace); |
||
15859 | } |
||
15860 | }, |
||
15861 | |||
15862 | add: { |
||
15863 | inlineCSS: function() { |
||
15864 | var |
||
15865 | width = module.cache.width || $module.outerWidth(), |
||
15866 | height = module.cache.height || $module.outerHeight(), |
||
15867 | isRTL = module.is.rtl(), |
||
15868 | direction = module.get.direction(), |
||
15869 | distance = { |
||
15870 | left : width, |
||
15871 | right : -width, |
||
15872 | top : height, |
||
15873 | bottom : -height |
||
15874 | }, |
||
15875 | style |
||
15876 | ; |
||
15877 | |||
15878 | if(isRTL){ |
||
15879 | module.verbose('RTL detected, flipping widths'); |
||
15880 | distance.left = -width; |
||
15881 | distance.right = width; |
||
15882 | } |
||
15883 | |||
15884 | style = '<style>'; |
||
15885 | |||
15886 | if(direction === 'left' || direction === 'right') { |
||
15887 | module.debug('Adding CSS rules for animation distance', width); |
||
15888 | style += '' |
||
15889 | + ' .ui.visible.' + direction + '.sidebar ~ .fixed,' |
||
15890 | + ' .ui.visible.' + direction + '.sidebar ~ .pusher {' |
||
15891 | + ' -webkit-transform: translate3d('+ distance[direction] + 'px, 0, 0);' |
||
15892 | + ' transform: translate3d('+ distance[direction] + 'px, 0, 0);' |
||
15893 | + ' }' |
||
15894 | ; |
||
15895 | } |
||
15896 | else if(direction === 'top' || direction == 'bottom') { |
||
15897 | style += '' |
||
15898 | + ' .ui.visible.' + direction + '.sidebar ~ .fixed,' |
||
15899 | + ' .ui.visible.' + direction + '.sidebar ~ .pusher {' |
||
15900 | + ' -webkit-transform: translate3d(0, ' + distance[direction] + 'px, 0);' |
||
15901 | + ' transform: translate3d(0, ' + distance[direction] + 'px, 0);' |
||
15902 | + ' }' |
||
15903 | ; |
||
15904 | } |
||
15905 | |||
15906 | /* IE is only browser not to create context with transforms */ |
||
15907 | /* https://www.w3.org/Bugs/Public/show_bug.cgi?id=16328 */ |
||
15908 | if( module.is.ie() ) { |
||
15909 | if(direction === 'left' || direction === 'right') { |
||
15910 | module.debug('Adding CSS rules for animation distance', width); |
||
15911 | style += '' |
||
15912 | + ' body.pushable > .ui.visible.' + direction + '.sidebar ~ .pusher:after {' |
||
15913 | + ' -webkit-transform: translate3d('+ distance[direction] + 'px, 0, 0);' |
||
15914 | + ' transform: translate3d('+ distance[direction] + 'px, 0, 0);' |
||
15915 | + ' }' |
||
15916 | ; |
||
15917 | } |
||
15918 | else if(direction === 'top' || direction == 'bottom') { |
||
15919 | style += '' |
||
15920 | + ' body.pushable > .ui.visible.' + direction + '.sidebar ~ .pusher:after {' |
||
15921 | + ' -webkit-transform: translate3d(0, ' + distance[direction] + 'px, 0);' |
||
15922 | + ' transform: translate3d(0, ' + distance[direction] + 'px, 0);' |
||
15923 | + ' }' |
||
15924 | ; |
||
15925 | } |
||
15926 | /* opposite sides visible forces content overlay */ |
||
15927 | style += '' |
||
15928 | + ' body.pushable > .ui.visible.left.sidebar ~ .ui.visible.right.sidebar ~ .pusher:after,' |
||
15929 | + ' body.pushable > .ui.visible.right.sidebar ~ .ui.visible.left.sidebar ~ .pusher:after {' |
||
15930 | + ' -webkit-transform: translate3d(0px, 0, 0);' |
||
15931 | + ' transform: translate3d(0px, 0, 0);' |
||
15932 | + ' }' |
||
15933 | ; |
||
15934 | } |
||
15935 | style += '</style>'; |
||
15936 | $style = $(style) |
||
15937 | .appendTo($head) |
||
15938 | ; |
||
15939 | module.debug('Adding sizing css to head', $style); |
||
15940 | } |
||
15941 | }, |
||
15942 | |||
15943 | refresh: function() { |
||
15944 | module.verbose('Refreshing selector cache'); |
||
15945 | $context = $(settings.context); |
||
15946 | $sidebars = $context.children(selector.sidebar); |
||
15947 | $pusher = $context.children(selector.pusher); |
||
15948 | $fixed = $context.children(selector.fixed); |
||
15949 | module.clear.cache(); |
||
15950 | }, |
||
15951 | |||
15952 | refreshSidebars: function() { |
||
15953 | module.verbose('Refreshing other sidebars'); |
||
15954 | $sidebars = $context.children(selector.sidebar); |
||
15955 | }, |
||
15956 | |||
15957 | repaint: function() { |
||
15958 | module.verbose('Forcing repaint event'); |
||
15959 | element.style.display = 'none'; |
||
15960 | var ignored = element.offsetHeight; |
||
15961 | element.scrollTop = element.scrollTop; |
||
15962 | element.style.display = ''; |
||
15963 | }, |
||
15964 | |||
15965 | setup: { |
||
15966 | cache: function() { |
||
15967 | module.cache = { |
||
15968 | width : $module.outerWidth(), |
||
15969 | height : $module.outerHeight(), |
||
15970 | rtl : ($module.css('direction') == 'rtl') |
||
15971 | }; |
||
15972 | }, |
||
15973 | layout: function() { |
||
15974 | if( $context.children(selector.pusher).length === 0 ) { |
||
15975 | module.debug('Adding wrapper element for sidebar'); |
||
15976 | module.error(error.pusher); |
||
15977 | $pusher = $('<div class="pusher" />'); |
||
15978 | $context |
||
15979 | .children() |
||
15980 | .not(selector.omitted) |
||
15981 | .not($sidebars) |
||
15982 | .wrapAll($pusher) |
||
15983 | ; |
||
15984 | module.refresh(); |
||
15985 | } |
||
15986 | if($module.nextAll(selector.pusher).length === 0 || $module.nextAll(selector.pusher)[0] !== $pusher[0]) { |
||
15987 | module.debug('Moved sidebar to correct parent element'); |
||
15988 | module.error(error.movedSidebar, element); |
||
15989 | $module.detach().prependTo($context); |
||
15990 | module.refresh(); |
||
15991 | } |
||
15992 | module.clear.cache(); |
||
15993 | module.set.pushable(); |
||
15994 | module.set.direction(); |
||
15995 | } |
||
15996 | }, |
||
15997 | |||
15998 | attachEvents: function(selector, event) { |
||
15999 | var |
||
16000 | $toggle = $(selector) |
||
16001 | ; |
||
16002 | event = $.isFunction(module[event]) |
||
16003 | ? module[event] |
||
16004 | : module.toggle |
||
16005 | ; |
||
16006 | if($toggle.length > 0) { |
||
16007 | module.debug('Attaching sidebar events to element', selector, event); |
||
16008 | $toggle |
||
16009 | .on('click' + eventNamespace, event) |
||
16010 | ; |
||
16011 | } |
||
16012 | else { |
||
16013 | module.error(error.notFound, selector); |
||
16014 | } |
||
16015 | }, |
||
16016 | |||
16017 | show: function(callback) { |
||
16018 | callback = $.isFunction(callback) |
||
16019 | ? callback |
||
16020 | : function(){} |
||
16021 | ; |
||
16022 | if(module.is.hidden()) { |
||
16023 | module.refreshSidebars(); |
||
16024 | if(settings.overlay) { |
||
16025 | module.error(error.overlay); |
||
16026 | settings.transition = 'overlay'; |
||
16027 | } |
||
16028 | module.refresh(); |
||
16029 | if(module.othersActive()) { |
||
16030 | module.debug('Other sidebars currently visible'); |
||
16031 | if(settings.exclusive) { |
||
16032 | // if not overlay queue animation after hide |
||
16033 | if(settings.transition != 'overlay') { |
||
16034 | module.hideOthers(module.show); |
||
16035 | return; |
||
16036 | } |
||
16037 | else { |
||
16038 | module.hideOthers(); |
||
16039 | } |
||
16040 | } |
||
16041 | else { |
||
16042 | settings.transition = 'overlay'; |
||
16043 | } |
||
16044 | } |
||
16045 | module.pushPage(function() { |
||
16046 | callback.call(element); |
||
16047 | settings.onShow.call(element); |
||
16048 | }); |
||
16049 | settings.onChange.call(element); |
||
16050 | settings.onVisible.call(element); |
||
16051 | } |
||
16052 | else { |
||
16053 | module.debug('Sidebar is already visible'); |
||
16054 | } |
||
16055 | }, |
||
16056 | |||
16057 | hide: function(callback) { |
||
16058 | callback = $.isFunction(callback) |
||
16059 | ? callback |
||
16060 | : function(){} |
||
16061 | ; |
||
16062 | if(module.is.visible() || module.is.animating()) { |
||
16063 | module.debug('Hiding sidebar', callback); |
||
16064 | module.refreshSidebars(); |
||
16065 | module.pullPage(function() { |
||
16066 | callback.call(element); |
||
16067 | settings.onHidden.call(element); |
||
16068 | }); |
||
16069 | settings.onChange.call(element); |
||
16070 | settings.onHide.call(element); |
||
16071 | } |
||
16072 | }, |
||
16073 | |||
16074 | othersAnimating: function() { |
||
16075 | return ($sidebars.not($module).filter('.' + className.animating).length > 0); |
||
16076 | }, |
||
16077 | othersVisible: function() { |
||
16078 | return ($sidebars.not($module).filter('.' + className.visible).length > 0); |
||
16079 | }, |
||
16080 | othersActive: function() { |
||
16081 | return(module.othersVisible() || module.othersAnimating()); |
||
16082 | }, |
||
16083 | |||
16084 | hideOthers: function(callback) { |
||
16085 | var |
||
16086 | $otherSidebars = $sidebars.not($module).filter('.' + className.visible), |
||
16087 | sidebarCount = $otherSidebars.length, |
||
16088 | callbackCount = 0 |
||
16089 | ; |
||
16090 | callback = callback || function(){}; |
||
16091 | $otherSidebars |
||
16092 | .sidebar('hide', function() { |
||
16093 | callbackCount++; |
||
16094 | if(callbackCount == sidebarCount) { |
||
16095 | callback(); |
||
16096 | } |
||
16097 | }) |
||
16098 | ; |
||
16099 | }, |
||
16100 | |||
16101 | toggle: function() { |
||
16102 | module.verbose('Determining toggled direction'); |
||
16103 | if(module.is.hidden()) { |
||
16104 | module.show(); |
||
16105 | } |
||
16106 | else { |
||
16107 | module.hide(); |
||
16108 | } |
||
16109 | }, |
||
16110 | |||
16111 | pushPage: function(callback) { |
||
16112 | var |
||
16113 | transition = module.get.transition(), |
||
16114 | $transition = (transition === 'overlay' || module.othersActive()) |
||
16115 | ? $module |
||
16116 | : $pusher, |
||
16117 | animate, |
||
16118 | dim, |
||
16119 | transitionEnd |
||
16120 | ; |
||
16121 | callback = $.isFunction(callback) |
||
16122 | ? callback |
||
16123 | : function(){} |
||
16124 | ; |
||
16125 | if(settings.transition == 'scale down') { |
||
16126 | module.scrollToTop(); |
||
16127 | } |
||
16128 | module.set.transition(transition); |
||
16129 | module.repaint(); |
||
16130 | animate = function() { |
||
16131 | module.bind.clickaway(); |
||
16132 | module.add.inlineCSS(); |
||
16133 | module.set.animating(); |
||
16134 | module.set.visible(); |
||
16135 | }; |
||
16136 | dim = function() { |
||
16137 | module.set.dimmed(); |
||
16138 | }; |
||
16139 | transitionEnd = function(event) { |
||
16140 | if( event.target == $transition[0] ) { |
||
16141 | $transition.off(transitionEvent + elementNamespace, transitionEnd); |
||
16142 | module.remove.animating(); |
||
16143 | module.bind.scrollLock(); |
||
16144 | callback.call(element); |
||
16145 | } |
||
16146 | }; |
||
16147 | $transition.off(transitionEvent + elementNamespace); |
||
16148 | $transition.on(transitionEvent + elementNamespace, transitionEnd); |
||
16149 | requestAnimationFrame(animate); |
||
16150 | if(settings.dimPage && !module.othersVisible()) { |
||
16151 | requestAnimationFrame(dim); |
||
16152 | } |
||
16153 | }, |
||
16154 | |||
16155 | pullPage: function(callback) { |
||
16156 | var |
||
16157 | transition = module.get.transition(), |
||
16158 | $transition = (transition == 'overlay' || module.othersActive()) |
||
16159 | ? $module |
||
16160 | : $pusher, |
||
16161 | animate, |
||
16162 | transitionEnd |
||
16163 | ; |
||
16164 | callback = $.isFunction(callback) |
||
16165 | ? callback |
||
16166 | : function(){} |
||
16167 | ; |
||
16168 | module.verbose('Removing context push state', module.get.direction()); |
||
16169 | |||
16170 | module.unbind.clickaway(); |
||
16171 | module.unbind.scrollLock(); |
||
16172 | |||
16173 | animate = function() { |
||
16174 | module.set.transition(transition); |
||
16175 | module.set.animating(); |
||
16176 | module.remove.visible(); |
||
16177 | if(settings.dimPage && !module.othersVisible()) { |
||
16178 | $pusher.removeClass(className.dimmed); |
||
16179 | } |
||
16180 | }; |
||
16181 | transitionEnd = function(event) { |
||
16182 | if( event.target == $transition[0] ) { |
||
16183 | $transition.off(transitionEvent + elementNamespace, transitionEnd); |
||
16184 | module.remove.animating(); |
||
16185 | module.remove.transition(); |
||
16186 | module.remove.inlineCSS(); |
||
16187 | if(transition == 'scale down' || (settings.returnScroll && module.is.mobile()) ) { |
||
16188 | module.scrollBack(); |
||
16189 | } |
||
16190 | callback.call(element); |
||
16191 | } |
||
16192 | }; |
||
16193 | $transition.off(transitionEvent + elementNamespace); |
||
16194 | $transition.on(transitionEvent + elementNamespace, transitionEnd); |
||
16195 | requestAnimationFrame(animate); |
||
16196 | }, |
||
16197 | |||
16198 | scrollToTop: function() { |
||
16199 | module.verbose('Scrolling to top of page to avoid animation issues'); |
||
16200 | currentScroll = $(window).scrollTop(); |
||
16201 | $module.scrollTop(0); |
||
16202 | window.scrollTo(0, 0); |
||
16203 | }, |
||
16204 | |||
16205 | scrollBack: function() { |
||
16206 | module.verbose('Scrolling back to original page position'); |
||
16207 | window.scrollTo(0, currentScroll); |
||
16208 | }, |
||
16209 | |||
16210 | clear: { |
||
16211 | cache: function() { |
||
16212 | module.verbose('Clearing cached dimensions'); |
||
16213 | module.cache = {}; |
||
16214 | } |
||
16215 | }, |
||
16216 | |||
16217 | set: { |
||
16218 | |||
16219 | // ios only (scroll on html not document). This prevent auto-resize canvas/scroll in ios |
||
16220 | // (This is no longer necessary in latest iOS) |
||
16221 | ios: function() { |
||
16222 | $html.addClass(className.ios); |
||
16223 | }, |
||
16224 | |||
16225 | // container |
||
16226 | pushed: function() { |
||
16227 | $context.addClass(className.pushed); |
||
16228 | }, |
||
16229 | pushable: function() { |
||
16230 | $context.addClass(className.pushable); |
||
16231 | }, |
||
16232 | |||
16233 | // pusher |
||
16234 | dimmed: function() { |
||
16235 | $pusher.addClass(className.dimmed); |
||
16236 | }, |
||
16237 | |||
16238 | // sidebar |
||
16239 | active: function() { |
||
16240 | $module.addClass(className.active); |
||
16241 | }, |
||
16242 | animating: function() { |
||
16243 | $module.addClass(className.animating); |
||
16244 | }, |
||
16245 | transition: function(transition) { |
||
16246 | transition = transition || module.get.transition(); |
||
16247 | $module.addClass(transition); |
||
16248 | }, |
||
16249 | direction: function(direction) { |
||
16250 | direction = direction || module.get.direction(); |
||
16251 | $module.addClass(className[direction]); |
||
16252 | }, |
||
16253 | visible: function() { |
||
16254 | $module.addClass(className.visible); |
||
16255 | }, |
||
16256 | overlay: function() { |
||
16257 | $module.addClass(className.overlay); |
||
16258 | } |
||
16259 | }, |
||
16260 | remove: { |
||
16261 | |||
16262 | inlineCSS: function() { |
||
16263 | module.debug('Removing inline css styles', $style); |
||
16264 | if($style && $style.length > 0) { |
||
16265 | $style.remove(); |
||
16266 | } |
||
16267 | }, |
||
16268 | |||
16269 | // ios scroll on html not document |
||
16270 | ios: function() { |
||
16271 | $html.removeClass(className.ios); |
||
16272 | }, |
||
16273 | |||
16274 | // context |
||
16275 | pushed: function() { |
||
16276 | $context.removeClass(className.pushed); |
||
16277 | }, |
||
16278 | pushable: function() { |
||
16279 | $context.removeClass(className.pushable); |
||
16280 | }, |
||
16281 | |||
16282 | // sidebar |
||
16283 | active: function() { |
||
16284 | $module.removeClass(className.active); |
||
16285 | }, |
||
16286 | animating: function() { |
||
16287 | $module.removeClass(className.animating); |
||
16288 | }, |
||
16289 | transition: function(transition) { |
||
16290 | transition = transition || module.get.transition(); |
||
16291 | $module.removeClass(transition); |
||
16292 | }, |
||
16293 | direction: function(direction) { |
||
16294 | direction = direction || module.get.direction(); |
||
16295 | $module.removeClass(className[direction]); |
||
16296 | }, |
||
16297 | visible: function() { |
||
16298 | $module.removeClass(className.visible); |
||
16299 | }, |
||
16300 | overlay: function() { |
||
16301 | $module.removeClass(className.overlay); |
||
16302 | } |
||
16303 | }, |
||
16304 | |||
16305 | get: { |
||
16306 | direction: function() { |
||
16307 | if($module.hasClass(className.top)) { |
||
16308 | return className.top; |
||
16309 | } |
||
16310 | else if($module.hasClass(className.right)) { |
||
16311 | return className.right; |
||
16312 | } |
||
16313 | else if($module.hasClass(className.bottom)) { |
||
16314 | return className.bottom; |
||
16315 | } |
||
16316 | return className.left; |
||
16317 | }, |
||
16318 | transition: function() { |
||
16319 | var |
||
16320 | direction = module.get.direction(), |
||
16321 | transition |
||
16322 | ; |
||
16323 | transition = ( module.is.mobile() ) |
||
16324 | ? (settings.mobileTransition == 'auto') |
||
16325 | ? settings.defaultTransition.mobile[direction] |
||
16326 | : settings.mobileTransition |
||
16327 | : (settings.transition == 'auto') |
||
16328 | ? settings.defaultTransition.computer[direction] |
||
16329 | : settings.transition |
||
16330 | ; |
||
16331 | module.verbose('Determined transition', transition); |
||
16332 | return transition; |
||
16333 | }, |
||
16334 | transitionEvent: function() { |
||
16335 | var |
||
16336 | element = document.createElement('element'), |
||
16337 | transitions = { |
||
16338 | 'transition' :'transitionend', |
||
16339 | 'OTransition' :'oTransitionEnd', |
||
16340 | 'MozTransition' :'transitionend', |
||
16341 | 'WebkitTransition' :'webkitTransitionEnd' |
||
16342 | }, |
||
16343 | transition |
||
16344 | ; |
||
16345 | for(transition in transitions){ |
||
16346 | if( element.style[transition] !== undefined ){ |
||
16347 | return transitions[transition]; |
||
16348 | } |
||
16349 | } |
||
16350 | } |
||
16351 | }, |
||
16352 | |||
16353 | is: { |
||
16354 | |||
16355 | ie: function() { |
||
16356 | var |
||
16357 | isIE11 = (!(window.ActiveXObject) && 'ActiveXObject' in window), |
||
16358 | isIE = ('ActiveXObject' in window) |
||
16359 | ; |
||
16360 | return (isIE11 || isIE); |
||
16361 | }, |
||
16362 | |||
16363 | ios: function() { |
||
16364 | var |
||
16365 | userAgent = navigator.userAgent, |
||
16366 | isIOS = userAgent.match(regExp.ios), |
||
16367 | isMobileChrome = userAgent.match(regExp.mobileChrome) |
||
16368 | ; |
||
16369 | if(isIOS && !isMobileChrome) { |
||
16370 | module.verbose('Browser was found to be iOS', userAgent); |
||
16371 | return true; |
||
16372 | } |
||
16373 | else { |
||
16374 | return false; |
||
16375 | } |
||
16376 | }, |
||
16377 | mobile: function() { |
||
16378 | var |
||
16379 | userAgent = navigator.userAgent, |
||
16380 | isMobile = userAgent.match(regExp.mobile) |
||
16381 | ; |
||
16382 | if(isMobile) { |
||
16383 | module.verbose('Browser was found to be mobile', userAgent); |
||
16384 | return true; |
||
16385 | } |
||
16386 | else { |
||
16387 | module.verbose('Browser is not mobile, using regular transition', userAgent); |
||
16388 | return false; |
||
16389 | } |
||
16390 | }, |
||
16391 | hidden: function() { |
||
16392 | return !module.is.visible(); |
||
16393 | }, |
||
16394 | visible: function() { |
||
16395 | return $module.hasClass(className.visible); |
||
16396 | }, |
||
16397 | // alias |
||
16398 | open: function() { |
||
16399 | return module.is.visible(); |
||
16400 | }, |
||
16401 | closed: function() { |
||
16402 | return module.is.hidden(); |
||
16403 | }, |
||
16404 | vertical: function() { |
||
16405 | return $module.hasClass(className.top); |
||
16406 | }, |
||
16407 | animating: function() { |
||
16408 | return $context.hasClass(className.animating); |
||
16409 | }, |
||
16410 | rtl: function () { |
||
16411 | if(module.cache.rtl === undefined) { |
||
16412 | module.cache.rtl = ($module.css('direction') == 'rtl'); |
||
16413 | } |
||
16414 | return module.cache.rtl; |
||
16415 | } |
||
16416 | }, |
||
16417 | |||
16418 | setting: function(name, value) { |
||
16419 | module.debug('Changing setting', name, value); |
||
16420 | if( $.isPlainObject(name) ) { |
||
16421 | $.extend(true, settings, name); |
||
16422 | } |
||
16423 | else if(value !== undefined) { |
||
16424 | if($.isPlainObject(settings[name])) { |
||
16425 | $.extend(true, settings[name], value); |
||
16426 | } |
||
16427 | else { |
||
16428 | settings[name] = value; |
||
16429 | } |
||
16430 | } |
||
16431 | else { |
||
16432 | return settings[name]; |
||
16433 | } |
||
16434 | }, |
||
16435 | internal: function(name, value) { |
||
16436 | if( $.isPlainObject(name) ) { |
||
16437 | $.extend(true, module, name); |
||
16438 | } |
||
16439 | else if(value !== undefined) { |
||
16440 | module[name] = value; |
||
16441 | } |
||
16442 | else { |
||
16443 | return module[name]; |
||
16444 | } |
||
16445 | }, |
||
16446 | debug: function() { |
||
16447 | if(!settings.silent && settings.debug) { |
||
16448 | if(settings.performance) { |
||
16449 | module.performance.log(arguments); |
||
16450 | } |
||
16451 | else { |
||
16452 | module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':'); |
||
16453 | module.debug.apply(console, arguments); |
||
16454 | } |
||
16455 | } |
||
16456 | }, |
||
16457 | verbose: function() { |
||
16458 | if(!settings.silent && settings.verbose && settings.debug) { |
||
16459 | if(settings.performance) { |
||
16460 | module.performance.log(arguments); |
||
16461 | } |
||
16462 | else { |
||
16463 | module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':'); |
||
16464 | module.verbose.apply(console, arguments); |
||
16465 | } |
||
16466 | } |
||
16467 | }, |
||
16468 | error: function() { |
||
16469 | if(!settings.silent) { |
||
16470 | module.error = Function.prototype.bind.call(console.error, console, settings.name + ':'); |
||
16471 | module.error.apply(console, arguments); |
||
16472 | } |
||
16473 | }, |
||
16474 | performance: { |
||
16475 | log: function(message) { |
||
16476 | var |
||
16477 | currentTime, |
||
16478 | executionTime, |
||
16479 | previousTime |
||
16480 | ; |
||
16481 | if(settings.performance) { |
||
16482 | currentTime = new Date().getTime(); |
||
16483 | previousTime = time || currentTime; |
||
16484 | executionTime = currentTime - previousTime; |
||
16485 | time = currentTime; |
||
16486 | performance.push({ |
||
16487 | 'Name' : message[0], |
||
16488 | 'Arguments' : [].slice.call(message, 1) || '', |
||
16489 | 'Element' : element, |
||
16490 | 'Execution Time' : executionTime |
||
16491 | }); |
||
16492 | } |
||
16493 | clearTimeout(module.performance.timer); |
||
16494 | module.performance.timer = setTimeout(module.performance.display, 500); |
||
16495 | }, |
||
16496 | display: function() { |
||
16497 | var |
||
16498 | title = settings.name + ':', |
||
16499 | totalTime = 0 |
||
16500 | ; |
||
16501 | time = false; |
||
16502 | clearTimeout(module.performance.timer); |
||
16503 | $.each(performance, function(index, data) { |
||
16504 | totalTime += data['Execution Time']; |
||
16505 | }); |
||
16506 | title += ' ' + totalTime + 'ms'; |
||
16507 | if(moduleSelector) { |
||
16508 | title += ' \'' + moduleSelector + '\''; |
||
16509 | } |
||
16510 | if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) { |
||
16511 | console.groupCollapsed(title); |
||
16512 | if(console.table) { |
||
16513 | console.table(performance); |
||
16514 | } |
||
16515 | else { |
||
16516 | $.each(performance, function(index, data) { |
||
16517 | console.log(data['Name'] + ': ' + data['Execution Time']+'ms'); |
||
16518 | }); |
||
16519 | } |
||
16520 | console.groupEnd(); |
||
16521 | } |
||
16522 | performance = []; |
||
16523 | } |
||
16524 | }, |
||
16525 | invoke: function(query, passedArguments, context) { |
||
16526 | var |
||
16527 | object = instance, |
||
16528 | maxDepth, |
||
16529 | found, |
||
16530 | response |
||
16531 | ; |
||
16532 | passedArguments = passedArguments || queryArguments; |
||
16533 | context = element || context; |
||
16534 | if(typeof query == 'string' && object !== undefined) { |
||
16535 | query = query.split(/[\. ]/); |
||
16536 | maxDepth = query.length - 1; |
||
16537 | $.each(query, function(depth, value) { |
||
16538 | var camelCaseValue = (depth != maxDepth) |
||
16539 | ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1) |
||
16540 | : query |
||
16541 | ; |
||
16542 | if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) { |
||
16543 | object = object[camelCaseValue]; |
||
16544 | } |
||
16545 | else if( object[camelCaseValue] !== undefined ) { |
||
16546 | found = object[camelCaseValue]; |
||
16547 | return false; |
||
16548 | } |
||
16549 | else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) { |
||
16550 | object = object[value]; |
||
16551 | } |
||
16552 | else if( object[value] !== undefined ) { |
||
16553 | found = object[value]; |
||
16554 | return false; |
||
16555 | } |
||
16556 | else { |
||
16557 | module.error(error.method, query); |
||
16558 | return false; |
||
16559 | } |
||
16560 | }); |
||
16561 | } |
||
16562 | if ( $.isFunction( found ) ) { |
||
16563 | response = found.apply(context, passedArguments); |
||
16564 | } |
||
16565 | else if(found !== undefined) { |
||
16566 | response = found; |
||
16567 | } |
||
16568 | if($.isArray(returnedValue)) { |
||
16569 | returnedValue.push(response); |
||
16570 | } |
||
16571 | else if(returnedValue !== undefined) { |
||
16572 | returnedValue = [returnedValue, response]; |
||
16573 | } |
||
16574 | else if(response !== undefined) { |
||
16575 | returnedValue = response; |
||
16576 | } |
||
16577 | return found; |
||
16578 | } |
||
16579 | } |
||
16580 | ; |
||
16581 | |||
16582 | if(methodInvoked) { |
||
16583 | if(instance === undefined) { |
||
16584 | module.initialize(); |
||
16585 | } |
||
16586 | module.invoke(query); |
||
16587 | } |
||
16588 | else { |
||
16589 | if(instance !== undefined) { |
||
16590 | module.invoke('destroy'); |
||
16591 | } |
||
16592 | module.initialize(); |
||
16593 | } |
||
16594 | }); |
||
16595 | |||
16596 | return (returnedValue !== undefined) |
||
16597 | ? returnedValue |
||
16598 | : this |
||
16599 | ; |
||
16600 | }; |
||
16601 | |||
16602 | $.fn.sidebar.settings = { |
||
16603 | |||
16604 | name : 'Sidebar', |
||
16605 | namespace : 'sidebar', |
||
16606 | |||
16607 | silent : false, |
||
16608 | debug : false, |
||
16609 | verbose : false, |
||
16610 | performance : true, |
||
16611 | |||
16612 | transition : 'auto', |
||
16613 | mobileTransition : 'auto', |
||
16614 | |||
16615 | defaultTransition : { |
||
16616 | computer: { |
||
16617 | left : 'uncover', |
||
16618 | right : 'uncover', |
||
16619 | top : 'overlay', |
||
16620 | bottom : 'overlay' |
||
16621 | }, |
||
16622 | mobile: { |
||
16623 | left : 'uncover', |
||
16624 | right : 'uncover', |
||
16625 | top : 'overlay', |
||
16626 | bottom : 'overlay' |
||
16627 | } |
||
16628 | }, |
||
16629 | |||
16630 | context : 'body', |
||
16631 | exclusive : false, |
||
16632 | closable : true, |
||
16633 | dimPage : true, |
||
16634 | scrollLock : false, |
||
16635 | returnScroll : false, |
||
16636 | delaySetup : false, |
||
16637 | |||
16638 | duration : 500, |
||
16639 | |||
16640 | onChange : function(){}, |
||
16641 | onShow : function(){}, |
||
16642 | onHide : function(){}, |
||
16643 | |||
16644 | onHidden : function(){}, |
||
16645 | onVisible : function(){}, |
||
16646 | |||
16647 | className : { |
||
16648 | active : 'active', |
||
16649 | animating : 'animating', |
||
16650 | dimmed : 'dimmed', |
||
16651 | ios : 'ios', |
||
16652 | pushable : 'pushable', |
||
16653 | pushed : 'pushed', |
||
16654 | right : 'right', |
||
16655 | top : 'top', |
||
16656 | left : 'left', |
||
16657 | bottom : 'bottom', |
||
16658 | visible : 'visible' |
||
16659 | }, |
||
16660 | |||
16661 | selector: { |
||
16662 | fixed : '.fixed', |
||
16663 | omitted : 'script, link, style, .ui.modal, .ui.dimmer, .ui.nag, .ui.fixed', |
||
16664 | pusher : '.pusher', |
||
16665 | sidebar : '.ui.sidebar' |
||
16666 | }, |
||
16667 | |||
16668 | regExp: { |
||
16669 | ios : /(iPad|iPhone|iPod)/g, |
||
16670 | mobileChrome : /(CriOS)/g, |
||
16671 | 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 |
||
16672 | }, |
||
16673 | |||
16674 | error : { |
||
16675 | method : 'The method you called is not defined.', |
||
16676 | pusher : 'Had to add pusher element. For optimal performance make sure body content is inside a pusher element', |
||
16677 | movedSidebar : 'Had to move sidebar. For optimal performance make sure sidebar and pusher are direct children of your body tag', |
||
16678 | overlay : 'The overlay setting is no longer supported, use animation: overlay', |
||
16679 | notFound : 'There were no elements that matched the specified selector' |
||
16680 | } |
||
16681 | |||
16682 | }; |
||
16683 | |||
16684 | |||
16685 | })( jQuery, window, document ); |
||
16686 | |||
16687 | /*! |
||
16688 | * # Semantic UI 2.2.11 - Sticky |
||
16689 | * http://github.com/semantic-org/semantic-ui/ |
||
16690 | * |
||
16691 | * |
||
16692 | * Released under the MIT license |
||
16693 | * http://opensource.org/licenses/MIT |
||
16694 | * |
||
16695 | */ |
||
16696 | |||
16697 | View Code Duplication | ;(function ($, window, document, undefined) { |
|
16698 | |||
16699 | "use strict"; |
||
16700 | |||
16701 | window = (typeof window != 'undefined' && window.Math == Math) |
||
16702 | ? window |
||
16703 | : (typeof self != 'undefined' && self.Math == Math) |
||
16704 | ? self |
||
16705 | : Function('return this')() |
||
16706 | ; |
||
16707 | |||
16708 | $.fn.sticky = function(parameters) { |
||
16709 | var |
||
16710 | $allModules = $(this), |
||
16711 | moduleSelector = $allModules.selector || '', |
||
16712 | |||
16713 | time = new Date().getTime(), |
||
16714 | performance = [], |
||
16715 | |||
16716 | query = arguments[0], |
||
16717 | methodInvoked = (typeof query == 'string'), |
||
16718 | queryArguments = [].slice.call(arguments, 1), |
||
16719 | returnedValue |
||
16720 | ; |
||
16721 | |||
16722 | $allModules |
||
16723 | .each(function() { |
||
16724 | var |
||
16725 | settings = ( $.isPlainObject(parameters) ) |
||
16726 | ? $.extend(true, {}, $.fn.sticky.settings, parameters) |
||
16727 | : $.extend({}, $.fn.sticky.settings), |
||
16728 | |||
16729 | className = settings.className, |
||
16730 | namespace = settings.namespace, |
||
16731 | error = settings.error, |
||
16732 | |||
16733 | eventNamespace = '.' + namespace, |
||
16734 | moduleNamespace = 'module-' + namespace, |
||
16735 | |||
16736 | $module = $(this), |
||
16737 | $window = $(window), |
||
16738 | $scroll = $(settings.scrollContext), |
||
16739 | $container, |
||
16740 | $context, |
||
16741 | |||
16742 | selector = $module.selector || '', |
||
16743 | instance = $module.data(moduleNamespace), |
||
16744 | |||
16745 | requestAnimationFrame = window.requestAnimationFrame |
||
16746 | || window.mozRequestAnimationFrame |
||
16747 | || window.webkitRequestAnimationFrame |
||
16748 | || window.msRequestAnimationFrame |
||
16749 | || function(callback) { setTimeout(callback, 0); }, |
||
16750 | |||
16751 | element = this, |
||
16752 | |||
16753 | documentObserver, |
||
16754 | observer, |
||
16755 | module |
||
16756 | ; |
||
16757 | |||
16758 | module = { |
||
16759 | |||
16760 | initialize: function() { |
||
16761 | |||
16762 | module.determineContainer(); |
||
16763 | module.determineContext(); |
||
16764 | module.verbose('Initializing sticky', settings, $container); |
||
16765 | |||
16766 | module.save.positions(); |
||
16767 | module.checkErrors(); |
||
16768 | module.bind.events(); |
||
16769 | |||
16770 | if(settings.observeChanges) { |
||
16771 | module.observeChanges(); |
||
16772 | } |
||
16773 | module.instantiate(); |
||
16774 | }, |
||
16775 | |||
16776 | instantiate: function() { |
||
16777 | module.verbose('Storing instance of module', module); |
||
16778 | instance = module; |
||
16779 | $module |
||
16780 | .data(moduleNamespace, module) |
||
16781 | ; |
||
16782 | }, |
||
16783 | |||
16784 | destroy: function() { |
||
16785 | module.verbose('Destroying previous instance'); |
||
16786 | module.reset(); |
||
16787 | if(documentObserver) { |
||
16788 | documentObserver.disconnect(); |
||
16789 | } |
||
16790 | if(observer) { |
||
16791 | observer.disconnect(); |
||
16792 | } |
||
16793 | $window |
||
16794 | .off('load' + eventNamespace, module.event.load) |
||
16795 | .off('resize' + eventNamespace, module.event.resize) |
||
16796 | ; |
||
16797 | $scroll |
||
16798 | .off('scrollchange' + eventNamespace, module.event.scrollchange) |
||
16799 | ; |
||
16800 | $module.removeData(moduleNamespace); |
||
16801 | }, |
||
16802 | |||
16803 | observeChanges: function() { |
||
16804 | if('MutationObserver' in window) { |
||
16805 | documentObserver = new MutationObserver(module.event.documentChanged); |
||
16806 | observer = new MutationObserver(module.event.changed); |
||
16807 | documentObserver.observe(document, { |
||
16808 | childList : true, |
||
16809 | subtree : true |
||
16810 | }); |
||
16811 | observer.observe(element, { |
||
16812 | childList : true, |
||
16813 | subtree : true |
||
16814 | }); |
||
16815 | observer.observe($context[0], { |
||
16816 | childList : true, |
||
16817 | subtree : true |
||
16818 | }); |
||
16819 | module.debug('Setting up mutation observer', observer); |
||
16820 | } |
||
16821 | }, |
||
16822 | |||
16823 | determineContainer: function() { |
||
16824 | if(settings.container) { |
||
16825 | $container = $(settings.container); |
||
16826 | } |
||
16827 | else { |
||
16828 | $container = $module.offsetParent(); |
||
16829 | } |
||
16830 | }, |
||
16831 | |||
16832 | determineContext: function() { |
||
16833 | if(settings.context) { |
||
16834 | $context = $(settings.context); |
||
16835 | } |
||
16836 | else { |
||
16837 | $context = $container; |
||
16838 | } |
||
16839 | if($context.length === 0) { |
||
16840 | module.error(error.invalidContext, settings.context, $module); |
||
16841 | return; |
||
16842 | } |
||
16843 | }, |
||
16844 | |||
16845 | checkErrors: function() { |
||
16846 | if( module.is.hidden() ) { |
||
16847 | module.error(error.visible, $module); |
||
16848 | } |
||
16849 | if(module.cache.element.height > module.cache.context.height) { |
||
16850 | module.reset(); |
||
16851 | module.error(error.elementSize, $module); |
||
16852 | return; |
||
16853 | } |
||
16854 | }, |
||
16855 | |||
16856 | bind: { |
||
16857 | events: function() { |
||
16858 | $window |
||
16859 | .on('load' + eventNamespace, module.event.load) |
||
16860 | .on('resize' + eventNamespace, module.event.resize) |
||
16861 | ; |
||
16862 | // pub/sub pattern |
||
16863 | $scroll |
||
16864 | .off('scroll' + eventNamespace) |
||
16865 | .on('scroll' + eventNamespace, module.event.scroll) |
||
16866 | .on('scrollchange' + eventNamespace, module.event.scrollchange) |
||
16867 | ; |
||
16868 | } |
||
16869 | }, |
||
16870 | |||
16871 | event: { |
||
16872 | changed: function(mutations) { |
||
16873 | clearTimeout(module.timer); |
||
16874 | module.timer = setTimeout(function() { |
||
16875 | module.verbose('DOM tree modified, updating sticky menu', mutations); |
||
16876 | module.refresh(); |
||
16877 | }, 100); |
||
16878 | }, |
||
16879 | documentChanged: function(mutations) { |
||
16880 | [].forEach.call(mutations, function(mutation) { |
||
16881 | if(mutation.removedNodes) { |
||
16882 | [].forEach.call(mutation.removedNodes, function(node) { |
||
16883 | if(node == element || $(node).find(element).length > 0) { |
||
16884 | module.debug('Element removed from DOM, tearing down events'); |
||
16885 | module.destroy(); |
||
16886 | } |
||
16887 | }); |
||
16888 | } |
||
16889 | }); |
||
16890 | }, |
||
16891 | load: function() { |
||
16892 | module.verbose('Page contents finished loading'); |
||
16893 | requestAnimationFrame(module.refresh); |
||
16894 | }, |
||
16895 | resize: function() { |
||
16896 | module.verbose('Window resized'); |
||
16897 | requestAnimationFrame(module.refresh); |
||
16898 | }, |
||
16899 | scroll: function() { |
||
16900 | requestAnimationFrame(function() { |
||
16901 | $scroll.triggerHandler('scrollchange' + eventNamespace, $scroll.scrollTop() ); |
||
16902 | }); |
||
16903 | }, |
||
16904 | scrollchange: function(event, scrollPosition) { |
||
16905 | module.stick(scrollPosition); |
||
16906 | settings.onScroll.call(element); |
||
16907 | } |
||
16908 | }, |
||
16909 | |||
16910 | refresh: function(hardRefresh) { |
||
16911 | module.reset(); |
||
16912 | if(!settings.context) { |
||
16913 | module.determineContext(); |
||
16914 | } |
||
16915 | if(hardRefresh) { |
||
16916 | module.determineContainer(); |
||
16917 | } |
||
16918 | module.save.positions(); |
||
16919 | module.stick(); |
||
16920 | settings.onReposition.call(element); |
||
16921 | }, |
||
16922 | |||
16923 | supports: { |
||
16924 | sticky: function() { |
||
16925 | var |
||
16926 | $element = $('<div/>'), |
||
16927 | element = $element[0] |
||
16928 | ; |
||
16929 | $element.addClass(className.supported); |
||
16930 | return($element.css('position').match('sticky')); |
||
16931 | } |
||
16932 | }, |
||
16933 | |||
16934 | save: { |
||
16935 | lastScroll: function(scroll) { |
||
16936 | module.lastScroll = scroll; |
||
16937 | }, |
||
16938 | elementScroll: function(scroll) { |
||
16939 | module.elementScroll = scroll; |
||
16940 | }, |
||
16941 | positions: function() { |
||
16942 | var |
||
16943 | scrollContext = { |
||
16944 | height : $scroll.height() |
||
16945 | }, |
||
16946 | element = { |
||
16947 | margin: { |
||
16948 | top : parseInt($module.css('margin-top'), 10), |
||
16949 | bottom : parseInt($module.css('margin-bottom'), 10), |
||
16950 | }, |
||
16951 | offset : $module.offset(), |
||
16952 | width : $module.outerWidth(), |
||
16953 | height : $module.outerHeight() |
||
16954 | }, |
||
16955 | context = { |
||
16956 | offset : $context.offset(), |
||
16957 | height : $context.outerHeight() |
||
16958 | }, |
||
16959 | container = { |
||
16960 | height: $container.outerHeight() |
||
16961 | } |
||
16962 | ; |
||
16963 | if( !module.is.standardScroll() ) { |
||
16964 | module.debug('Non-standard scroll. Removing scroll offset from element offset'); |
||
16965 | |||
16966 | scrollContext.top = $scroll.scrollTop(); |
||
16967 | scrollContext.left = $scroll.scrollLeft(); |
||
16968 | |||
16969 | element.offset.top += scrollContext.top; |
||
16970 | context.offset.top += scrollContext.top; |
||
16971 | element.offset.left += scrollContext.left; |
||
16972 | context.offset.left += scrollContext.left; |
||
16973 | } |
||
16974 | module.cache = { |
||
16975 | fits : ( (element.height + settings.offset) <= scrollContext.height), |
||
16976 | sameHeight : (element.height == context.height), |
||
16977 | scrollContext : { |
||
16978 | height : scrollContext.height |
||
16979 | }, |
||
16980 | element: { |
||
16981 | margin : element.margin, |
||
16982 | top : element.offset.top - element.margin.top, |
||
16983 | left : element.offset.left, |
||
16984 | width : element.width, |
||
16985 | height : element.height, |
||
16986 | bottom : element.offset.top + element.height |
||
16987 | }, |
||
16988 | context: { |
||
16989 | top : context.offset.top, |
||
16990 | height : context.height, |
||
16991 | bottom : context.offset.top + context.height |
||
16992 | } |
||
16993 | }; |
||
16994 | module.set.containerSize(); |
||
16995 | |||
16996 | module.stick(); |
||
16997 | module.debug('Caching element positions', module.cache); |
||
16998 | } |
||
16999 | }, |
||
17000 | |||
17001 | get: { |
||
17002 | direction: function(scroll) { |
||
17003 | var |
||
17004 | direction = 'down' |
||
17005 | ; |
||
17006 | scroll = scroll || $scroll.scrollTop(); |
||
17007 | if(module.lastScroll !== undefined) { |
||
17008 | if(module.lastScroll < scroll) { |
||
17009 | direction = 'down'; |
||
17010 | } |
||
17011 | else if(module.lastScroll > scroll) { |
||
17012 | direction = 'up'; |
||
17013 | } |
||
17014 | } |
||
17015 | return direction; |
||
17016 | }, |
||
17017 | scrollChange: function(scroll) { |
||
17018 | scroll = scroll || $scroll.scrollTop(); |
||
17019 | return (module.lastScroll) |
||
17020 | ? (scroll - module.lastScroll) |
||
17021 | : 0 |
||
17022 | ; |
||
17023 | }, |
||
17024 | currentElementScroll: function() { |
||
17025 | if(module.elementScroll) { |
||
17026 | return module.elementScroll; |
||
17027 | } |
||
17028 | return ( module.is.top() ) |
||
17029 | ? Math.abs(parseInt($module.css('top'), 10)) || 0 |
||
17030 | : Math.abs(parseInt($module.css('bottom'), 10)) || 0 |
||
17031 | ; |
||
17032 | }, |
||
17033 | |||
17034 | elementScroll: function(scroll) { |
||
17035 | scroll = scroll || $scroll.scrollTop(); |
||
17036 | var |
||
17037 | element = module.cache.element, |
||
17038 | scrollContext = module.cache.scrollContext, |
||
17039 | delta = module.get.scrollChange(scroll), |
||
17040 | maxScroll = (element.height - scrollContext.height + settings.offset), |
||
17041 | elementScroll = module.get.currentElementScroll(), |
||
17042 | possibleScroll = (elementScroll + delta) |
||
17043 | ; |
||
17044 | if(module.cache.fits || possibleScroll < 0) { |
||
17045 | elementScroll = 0; |
||
17046 | } |
||
17047 | else if(possibleScroll > maxScroll ) { |
||
17048 | elementScroll = maxScroll; |
||
17049 | } |
||
17050 | else { |
||
17051 | elementScroll = possibleScroll; |
||
17052 | } |
||
17053 | return elementScroll; |
||
17054 | } |
||
17055 | }, |
||
17056 | |||
17057 | remove: { |
||
17058 | lastScroll: function() { |
||
17059 | delete module.lastScroll; |
||
17060 | }, |
||
17061 | elementScroll: function(scroll) { |
||
17062 | delete module.elementScroll; |
||
17063 | }, |
||
17064 | minimumSize: function() { |
||
17065 | $container |
||
17066 | .css('min-height', '') |
||
17067 | ; |
||
17068 | }, |
||
17069 | offset: function() { |
||
17070 | $module.css('margin-top', ''); |
||
17071 | } |
||
17072 | }, |
||
17073 | |||
17074 | set: { |
||
17075 | offset: function() { |
||
17076 | module.verbose('Setting offset on element', settings.offset); |
||
17077 | $module |
||
17078 | .css('margin-top', settings.offset) |
||
17079 | ; |
||
17080 | }, |
||
17081 | containerSize: function() { |
||
17082 | var |
||
17083 | tagName = $container.get(0).tagName |
||
17084 | ; |
||
17085 | if(tagName === 'HTML' || tagName == 'body') { |
||
17086 | // this can trigger for too many reasons |
||
17087 | //module.error(error.container, tagName, $module); |
||
17088 | module.determineContainer(); |
||
17089 | } |
||
17090 | else { |
||
17091 | if( Math.abs($container.outerHeight() - module.cache.context.height) > settings.jitter) { |
||
17092 | module.debug('Context has padding, specifying exact height for container', module.cache.context.height); |
||
17093 | $container.css({ |
||
17094 | height: module.cache.context.height |
||
17095 | }); |
||
17096 | } |
||
17097 | } |
||
17098 | }, |
||
17099 | minimumSize: function() { |
||
17100 | var |
||
17101 | element = module.cache.element |
||
17102 | ; |
||
17103 | $container |
||
17104 | .css('min-height', element.height) |
||
17105 | ; |
||
17106 | }, |
||
17107 | scroll: function(scroll) { |
||
17108 | module.debug('Setting scroll on element', scroll); |
||
17109 | if(module.elementScroll == scroll) { |
||
17110 | return; |
||
17111 | } |
||
17112 | if( module.is.top() ) { |
||
17113 | $module |
||
17114 | .css('bottom', '') |
||
17115 | .css('top', -scroll) |
||
17116 | ; |
||
17117 | } |
||
17118 | if( module.is.bottom() ) { |
||
17119 | $module |
||
17120 | .css('top', '') |
||
17121 | .css('bottom', scroll) |
||
17122 | ; |
||
17123 | } |
||
17124 | }, |
||
17125 | size: function() { |
||
17126 | if(module.cache.element.height !== 0 && module.cache.element.width !== 0) { |
||
17127 | element.style.setProperty('width', module.cache.element.width + 'px', 'important'); |
||
17128 | element.style.setProperty('height', module.cache.element.height + 'px', 'important'); |
||
17129 | } |
||
17130 | } |
||
17131 | }, |
||
17132 | |||
17133 | is: { |
||
17134 | standardScroll: function() { |
||
17135 | return ($scroll[0] == window); |
||
17136 | }, |
||
17137 | top: function() { |
||
17138 | return $module.hasClass(className.top); |
||
17139 | }, |
||
17140 | bottom: function() { |
||
17141 | return $module.hasClass(className.bottom); |
||
17142 | }, |
||
17143 | initialPosition: function() { |
||
17144 | return (!module.is.fixed() && !module.is.bound()); |
||
17145 | }, |
||
17146 | hidden: function() { |
||
17147 | return (!$module.is(':visible')); |
||
17148 | }, |
||
17149 | bound: function() { |
||
17150 | return $module.hasClass(className.bound); |
||
17151 | }, |
||
17152 | fixed: function() { |
||
17153 | return $module.hasClass(className.fixed); |
||
17154 | } |
||
17155 | }, |
||
17156 | |||
17157 | stick: function(scroll) { |
||
17158 | var |
||
17159 | cachedPosition = scroll || $scroll.scrollTop(), |
||
17160 | cache = module.cache, |
||
17161 | fits = cache.fits, |
||
17162 | sameHeight = cache.sameHeight, |
||
17163 | element = cache.element, |
||
17164 | scrollContext = cache.scrollContext, |
||
17165 | context = cache.context, |
||
17166 | offset = (module.is.bottom() && settings.pushing) |
||
17167 | ? settings.bottomOffset |
||
17168 | : settings.offset, |
||
17169 | scroll = { |
||
17170 | top : cachedPosition + offset, |
||
17171 | bottom : cachedPosition + offset + scrollContext.height |
||
17172 | }, |
||
17173 | direction = module.get.direction(scroll.top), |
||
17174 | elementScroll = (fits) |
||
17175 | ? 0 |
||
17176 | : module.get.elementScroll(scroll.top), |
||
17177 | |||
17178 | // shorthand |
||
17179 | doesntFit = !fits, |
||
17180 | elementVisible = (element.height !== 0) |
||
17181 | ; |
||
17182 | if(elementVisible && !sameHeight) { |
||
17183 | |||
17184 | if( module.is.initialPosition() ) { |
||
17185 | if(scroll.top >= context.bottom) { |
||
17186 | module.debug('Initial element position is bottom of container'); |
||
17187 | module.bindBottom(); |
||
17188 | } |
||
17189 | else if(scroll.top > element.top) { |
||
17190 | if( (element.height + scroll.top - elementScroll) >= context.bottom ) { |
||
17191 | module.debug('Initial element position is bottom of container'); |
||
17192 | module.bindBottom(); |
||
17193 | } |
||
17194 | else { |
||
17195 | module.debug('Initial element position is fixed'); |
||
17196 | module.fixTop(); |
||
17197 | } |
||
17198 | } |
||
17199 | |||
17200 | } |
||
17201 | else if( module.is.fixed() ) { |
||
17202 | |||
17203 | // currently fixed top |
||
17204 | if( module.is.top() ) { |
||
17205 | if( scroll.top <= element.top ) { |
||
17206 | module.debug('Fixed element reached top of container'); |
||
17207 | module.setInitialPosition(); |
||
17208 | } |
||
17209 | else if( (element.height + scroll.top - elementScroll) >= context.bottom ) { |
||
17210 | module.debug('Fixed element reached bottom of container'); |
||
17211 | module.bindBottom(); |
||
17212 | } |
||
17213 | // scroll element if larger than screen |
||
17214 | else if(doesntFit) { |
||
17215 | module.set.scroll(elementScroll); |
||
17216 | module.save.lastScroll(scroll.top); |
||
17217 | module.save.elementScroll(elementScroll); |
||
17218 | } |
||
17219 | } |
||
17220 | |||
17221 | // currently fixed bottom |
||
17222 | else if(module.is.bottom() ) { |
||
17223 | |||
17224 | // top edge |
||
17225 | if( (scroll.bottom - element.height) <= element.top) { |
||
17226 | module.debug('Bottom fixed rail has reached top of container'); |
||
17227 | module.setInitialPosition(); |
||
17228 | } |
||
17229 | // bottom edge |
||
17230 | else if(scroll.bottom >= context.bottom) { |
||
17231 | module.debug('Bottom fixed rail has reached bottom of container'); |
||
17232 | module.bindBottom(); |
||
17233 | } |
||
17234 | // scroll element if larger than screen |
||
17235 | else if(doesntFit) { |
||
17236 | module.set.scroll(elementScroll); |
||
17237 | module.save.lastScroll(scroll.top); |
||
17238 | module.save.elementScroll(elementScroll); |
||
17239 | } |
||
17240 | |||
17241 | } |
||
17242 | } |
||
17243 | else if( module.is.bottom() ) { |
||
17244 | if( scroll.top <= element.top ) { |
||
17245 | module.debug('Jumped from bottom fixed to top fixed, most likely used home/end button'); |
||
17246 | module.setInitialPosition(); |
||
17247 | } |
||
17248 | else { |
||
17249 | if(settings.pushing) { |
||
17250 | if(module.is.bound() && scroll.bottom <= context.bottom ) { |
||
17251 | module.debug('Fixing bottom attached element to bottom of browser.'); |
||
17252 | module.fixBottom(); |
||
17253 | } |
||
17254 | } |
||
17255 | else { |
||
17256 | if(module.is.bound() && (scroll.top <= context.bottom - element.height) ) { |
||
17257 | module.debug('Fixing bottom attached element to top of browser.'); |
||
17258 | module.fixTop(); |
||
17259 | } |
||
17260 | } |
||
17261 | } |
||
17262 | } |
||
17263 | } |
||
17264 | }, |
||
17265 | |||
17266 | bindTop: function() { |
||
17267 | module.debug('Binding element to top of parent container'); |
||
17268 | module.remove.offset(); |
||
17269 | $module |
||
17270 | .css({ |
||
17271 | left : '', |
||
17272 | top : '', |
||
17273 | marginBottom : '' |
||
17274 | }) |
||
17275 | .removeClass(className.fixed) |
||
17276 | .removeClass(className.bottom) |
||
17277 | .addClass(className.bound) |
||
17278 | .addClass(className.top) |
||
17279 | ; |
||
17280 | settings.onTop.call(element); |
||
17281 | settings.onUnstick.call(element); |
||
17282 | }, |
||
17283 | bindBottom: function() { |
||
17284 | module.debug('Binding element to bottom of parent container'); |
||
17285 | module.remove.offset(); |
||
17286 | $module |
||
17287 | .css({ |
||
17288 | left : '', |
||
17289 | top : '' |
||
17290 | }) |
||
17291 | .removeClass(className.fixed) |
||
17292 | .removeClass(className.top) |
||
17293 | .addClass(className.bound) |
||
17294 | .addClass(className.bottom) |
||
17295 | ; |
||
17296 | settings.onBottom.call(element); |
||
17297 | settings.onUnstick.call(element); |
||
17298 | }, |
||
17299 | |||
17300 | setInitialPosition: function() { |
||
17301 | module.debug('Returning to initial position'); |
||
17302 | module.unfix(); |
||
17303 | module.unbind(); |
||
17304 | }, |
||
17305 | |||
17306 | |||
17307 | fixTop: function() { |
||
17308 | module.debug('Fixing element to top of page'); |
||
17309 | if(settings.setSize) { |
||
17310 | module.set.size(); |
||
17311 | } |
||
17312 | module.set.minimumSize(); |
||
17313 | module.set.offset(); |
||
17314 | $module |
||
17315 | .css({ |
||
17316 | left : module.cache.element.left, |
||
17317 | bottom : '', |
||
17318 | marginBottom : '' |
||
17319 | }) |
||
17320 | .removeClass(className.bound) |
||
17321 | .removeClass(className.bottom) |
||
17322 | .addClass(className.fixed) |
||
17323 | .addClass(className.top) |
||
17324 | ; |
||
17325 | settings.onStick.call(element); |
||
17326 | }, |
||
17327 | |||
17328 | fixBottom: function() { |
||
17329 | module.debug('Sticking element to bottom of page'); |
||
17330 | if(settings.setSize) { |
||
17331 | module.set.size(); |
||
17332 | } |
||
17333 | module.set.minimumSize(); |
||
17334 | module.set.offset(); |
||
17335 | $module |
||
17336 | .css({ |
||
17337 | left : module.cache.element.left, |
||
17338 | bottom : '', |
||
17339 | marginBottom : '' |
||
17340 | }) |
||
17341 | .removeClass(className.bound) |
||
17342 | .removeClass(className.top) |
||
17343 | .addClass(className.fixed) |
||
17344 | .addClass(className.bottom) |
||
17345 | ; |
||
17346 | settings.onStick.call(element); |
||
17347 | }, |
||
17348 | |||
17349 | unbind: function() { |
||
17350 | if( module.is.bound() ) { |
||
17351 | module.debug('Removing container bound position on element'); |
||
17352 | module.remove.offset(); |
||
17353 | $module |
||
17354 | .removeClass(className.bound) |
||
17355 | .removeClass(className.top) |
||
17356 | .removeClass(className.bottom) |
||
17357 | ; |
||
17358 | } |
||
17359 | }, |
||
17360 | |||
17361 | unfix: function() { |
||
17362 | if( module.is.fixed() ) { |
||
17363 | module.debug('Removing fixed position on element'); |
||
17364 | module.remove.minimumSize(); |
||
17365 | module.remove.offset(); |
||
17366 | $module |
||
17367 | .removeClass(className.fixed) |
||
17368 | .removeClass(className.top) |
||
17369 | .removeClass(className.bottom) |
||
17370 | ; |
||
17371 | settings.onUnstick.call(element); |
||
17372 | } |
||
17373 | }, |
||
17374 | |||
17375 | reset: function() { |
||
17376 | module.debug('Resetting elements position'); |
||
17377 | module.unbind(); |
||
17378 | module.unfix(); |
||
17379 | module.resetCSS(); |
||
17380 | module.remove.offset(); |
||
17381 | module.remove.lastScroll(); |
||
17382 | }, |
||
17383 | |||
17384 | resetCSS: function() { |
||
17385 | $module |
||
17386 | .css({ |
||
17387 | width : '', |
||
17388 | height : '' |
||
17389 | }) |
||
17390 | ; |
||
17391 | $container |
||
17392 | .css({ |
||
17393 | height: '' |
||
17394 | }) |
||
17395 | ; |
||
17396 | }, |
||
17397 | |||
17398 | setting: function(name, value) { |
||
17399 | if( $.isPlainObject(name) ) { |
||
17400 | $.extend(true, settings, name); |
||
17401 | } |
||
17402 | else if(value !== undefined) { |
||
17403 | settings[name] = value; |
||
17404 | } |
||
17405 | else { |
||
17406 | return settings[name]; |
||
17407 | } |
||
17408 | }, |
||
17409 | internal: function(name, value) { |
||
17410 | if( $.isPlainObject(name) ) { |
||
17411 | $.extend(true, module, name); |
||
17412 | } |
||
17413 | else if(value !== undefined) { |
||
17414 | module[name] = value; |
||
17415 | } |
||
17416 | else { |
||
17417 | return module[name]; |
||
17418 | } |
||
17419 | }, |
||
17420 | debug: function() { |
||
17421 | if(!settings.silent && settings.debug) { |
||
17422 | if(settings.performance) { |
||
17423 | module.performance.log(arguments); |
||
17424 | } |
||
17425 | else { |
||
17426 | module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':'); |
||
17427 | module.debug.apply(console, arguments); |
||
17428 | } |
||
17429 | } |
||
17430 | }, |
||
17431 | verbose: function() { |
||
17432 | if(!settings.silent && settings.verbose && settings.debug) { |
||
17433 | if(settings.performance) { |
||
17434 | module.performance.log(arguments); |
||
17435 | } |
||
17436 | else { |
||
17437 | module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':'); |
||
17438 | module.verbose.apply(console, arguments); |
||
17439 | } |
||
17440 | } |
||
17441 | }, |
||
17442 | error: function() { |
||
17443 | if(!settings.silent) { |
||
17444 | module.error = Function.prototype.bind.call(console.error, console, settings.name + ':'); |
||
17445 | module.error.apply(console, arguments); |
||
17446 | } |
||
17447 | }, |
||
17448 | performance: { |
||
17449 | log: function(message) { |
||
17450 | var |
||
17451 | currentTime, |
||
17452 | executionTime, |
||
17453 | previousTime |
||
17454 | ; |
||
17455 | if(settings.performance) { |
||
17456 | currentTime = new Date().getTime(); |
||
17457 | previousTime = time || currentTime; |
||
17458 | executionTime = currentTime - previousTime; |
||
17459 | time = currentTime; |
||
17460 | performance.push({ |
||
17461 | 'Name' : message[0], |
||
17462 | 'Arguments' : [].slice.call(message, 1) || '', |
||
17463 | 'Element' : element, |
||
17464 | 'Execution Time' : executionTime |
||
17465 | }); |
||
17466 | } |
||
17467 | clearTimeout(module.performance.timer); |
||
17468 | module.performance.timer = setTimeout(module.performance.display, 0); |
||
17469 | }, |
||
17470 | display: function() { |
||
17471 | var |
||
17472 | title = settings.name + ':', |
||
17473 | totalTime = 0 |
||
17474 | ; |
||
17475 | time = false; |
||
17476 | clearTimeout(module.performance.timer); |
||
17477 | $.each(performance, function(index, data) { |
||
17478 | totalTime += data['Execution Time']; |
||
17479 | }); |
||
17480 | title += ' ' + totalTime + 'ms'; |
||
17481 | if(moduleSelector) { |
||
17482 | title += ' \'' + moduleSelector + '\''; |
||
17483 | } |
||
17484 | if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) { |
||
17485 | console.groupCollapsed(title); |
||
17486 | if(console.table) { |
||
17487 | console.table(performance); |
||
17488 | } |
||
17489 | else { |
||
17490 | $.each(performance, function(index, data) { |
||
17491 | console.log(data['Name'] + ': ' + data['Execution Time']+'ms'); |
||
17492 | }); |
||
17493 | } |
||
17494 | console.groupEnd(); |
||
17495 | } |
||
17496 | performance = []; |
||
17497 | } |
||
17498 | }, |
||
17499 | invoke: function(query, passedArguments, context) { |
||
17500 | var |
||
17501 | object = instance, |
||
17502 | maxDepth, |
||
17503 | found, |
||
17504 | response |
||
17505 | ; |
||
17506 | passedArguments = passedArguments || queryArguments; |
||
17507 | context = element || context; |
||
17508 | if(typeof query == 'string' && object !== undefined) { |
||
17509 | query = query.split(/[\. ]/); |
||
17510 | maxDepth = query.length - 1; |
||
17511 | $.each(query, function(depth, value) { |
||
17512 | var camelCaseValue = (depth != maxDepth) |
||
17513 | ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1) |
||
17514 | : query |
||
17515 | ; |
||
17516 | if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) { |
||
17517 | object = object[camelCaseValue]; |
||
17518 | } |
||
17519 | else if( object[camelCaseValue] !== undefined ) { |
||
17520 | found = object[camelCaseValue]; |
||
17521 | return false; |
||
17522 | } |
||
17523 | else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) { |
||
17524 | object = object[value]; |
||
17525 | } |
||
17526 | else if( object[value] !== undefined ) { |
||
17527 | found = object[value]; |
||
17528 | return false; |
||
17529 | } |
||
17530 | else { |
||
17531 | return false; |
||
17532 | } |
||
17533 | }); |
||
17534 | } |
||
17535 | if ( $.isFunction( found ) ) { |
||
17536 | response = found.apply(context, passedArguments); |
||
17537 | } |
||
17538 | else if(found !== undefined) { |
||
17539 | response = found; |
||
17540 | } |
||
17541 | if($.isArray(returnedValue)) { |
||
17542 | returnedValue.push(response); |
||
17543 | } |
||
17544 | else if(returnedValue !== undefined) { |
||
17545 | returnedValue = [returnedValue, response]; |
||
17546 | } |
||
17547 | else if(response !== undefined) { |
||
17548 | returnedValue = response; |
||
17549 | } |
||
17550 | return found; |
||
17551 | } |
||
17552 | }; |
||
17553 | |||
17554 | if(methodInvoked) { |
||
17555 | if(instance === undefined) { |
||
17556 | module.initialize(); |
||
17557 | } |
||
17558 | module.invoke(query); |
||
17559 | } |
||
17560 | else { |
||
17561 | if(instance !== undefined) { |
||
17562 | instance.invoke('destroy'); |
||
17563 | } |
||
17564 | module.initialize(); |
||
17565 | } |
||
17566 | }) |
||
17567 | ; |
||
17568 | |||
17569 | return (returnedValue !== undefined) |
||
17570 | ? returnedValue |
||
17571 | : this |
||
17572 | ; |
||
17573 | }; |
||
17574 | |||
17575 | $.fn.sticky.settings = { |
||
17576 | |||
17577 | name : 'Sticky', |
||
17578 | namespace : 'sticky', |
||
17579 | |||
17580 | silent : false, |
||
17581 | debug : false, |
||
17582 | verbose : true, |
||
17583 | performance : true, |
||
17584 | |||
17585 | // whether to stick in the opposite direction on scroll up |
||
17586 | pushing : false, |
||
17587 | |||
17588 | context : false, |
||
17589 | container : false, |
||
17590 | |||
17591 | // Context to watch scroll events |
||
17592 | scrollContext : window, |
||
17593 | |||
17594 | // Offset to adjust scroll |
||
17595 | offset : 0, |
||
17596 | |||
17597 | // Offset to adjust scroll when attached to bottom of screen |
||
17598 | bottomOffset : 0, |
||
17599 | |||
17600 | // will only set container height if difference between context and container is larger than this number |
||
17601 | jitter : 5, |
||
17602 | |||
17603 | // set width of sticky element when it is fixed to page (used to make sure 100% width is maintained if no fixed size set) |
||
17604 | setSize : true, |
||
17605 | |||
17606 | // Whether to automatically observe changes with Mutation Observers |
||
17607 | observeChanges : false, |
||
17608 | |||
17609 | // Called when position is recalculated |
||
17610 | onReposition : function(){}, |
||
17611 | |||
17612 | // Called on each scroll |
||
17613 | onScroll : function(){}, |
||
17614 | |||
17615 | // Called when element is stuck to viewport |
||
17616 | onStick : function(){}, |
||
17617 | |||
17618 | // Called when element is unstuck from viewport |
||
17619 | onUnstick : function(){}, |
||
17620 | |||
17621 | // Called when element reaches top of context |
||
17622 | onTop : function(){}, |
||
17623 | |||
17624 | // Called when element reaches bottom of context |
||
17625 | onBottom : function(){}, |
||
17626 | |||
17627 | error : { |
||
17628 | container : 'Sticky element must be inside a relative container', |
||
17629 | visible : 'Element is hidden, you must call refresh after element becomes visible. Use silent setting to surpress this warning in production.', |
||
17630 | method : 'The method you called is not defined.', |
||
17631 | invalidContext : 'Context specified does not exist', |
||
17632 | elementSize : 'Sticky element is larger than its container, cannot create sticky.' |
||
17633 | }, |
||
17634 | |||
17635 | className : { |
||
17636 | bound : 'bound', |
||
17637 | fixed : 'fixed', |
||
17638 | supported : 'native', |
||
17639 | top : 'top', |
||
17640 | bottom : 'bottom' |
||
17641 | } |
||
17642 | |||
17643 | }; |
||
17644 | |||
17645 | })( jQuery, window, document ); |
||
17646 | |||
17647 | /*! |
||
17648 | * # Semantic UI 2.2.11 - Tab |
||
17649 | * http://github.com/semantic-org/semantic-ui/ |
||
17650 | * |
||
17651 | * |
||
17652 | * Released under the MIT license |
||
17653 | * http://opensource.org/licenses/MIT |
||
17654 | * |
||
17655 | */ |
||
17656 | |||
17657 | View Code Duplication | ;(function ($, window, document, undefined) { |
|
17658 | |||
17659 | "use strict"; |
||
17660 | |||
17661 | window = (typeof window != 'undefined' && window.Math == Math) |
||
17662 | ? window |
||
17663 | : (typeof self != 'undefined' && self.Math == Math) |
||
17664 | ? self |
||
17665 | : Function('return this')() |
||
17666 | ; |
||
17667 | |||
17668 | $.fn.tab = function(parameters) { |
||
17669 | |||
17670 | var |
||
17671 | // use window context if none specified |
||
17672 | $allModules = $.isFunction(this) |
||
17673 | ? $(window) |
||
17674 | : $(this), |
||
17675 | |||
17676 | moduleSelector = $allModules.selector || '', |
||
17677 | time = new Date().getTime(), |
||
17678 | performance = [], |
||
17679 | |||
17680 | query = arguments[0], |
||
17681 | methodInvoked = (typeof query == 'string'), |
||
17682 | queryArguments = [].slice.call(arguments, 1), |
||
17683 | |||
17684 | initializedHistory = false, |
||
17685 | returnedValue |
||
17686 | ; |
||
17687 | |||
17688 | $allModules |
||
17689 | .each(function() { |
||
17690 | var |
||
17691 | |||
17692 | settings = ( $.isPlainObject(parameters) ) |
||
17693 | ? $.extend(true, {}, $.fn.tab.settings, parameters) |
||
17694 | : $.extend({}, $.fn.tab.settings), |
||
17695 | |||
17696 | className = settings.className, |
||
17697 | metadata = settings.metadata, |
||
17698 | selector = settings.selector, |
||
17699 | error = settings.error, |
||
17700 | |||
17701 | eventNamespace = '.' + settings.namespace, |
||
17702 | moduleNamespace = 'module-' + settings.namespace, |
||
17703 | |||
17704 | $module = $(this), |
||
17705 | $context, |
||
17706 | $tabs, |
||
17707 | |||
17708 | cache = {}, |
||
17709 | firstLoad = true, |
||
17710 | recursionDepth = 0, |
||
17711 | element = this, |
||
17712 | instance = $module.data(moduleNamespace), |
||
17713 | |||
17714 | activeTabPath, |
||
17715 | parameterArray, |
||
17716 | module, |
||
17717 | |||
17718 | historyEvent |
||
17719 | |||
17720 | ; |
||
17721 | |||
17722 | module = { |
||
17723 | |||
17724 | initialize: function() { |
||
17725 | module.debug('Initializing tab menu item', $module); |
||
17726 | module.fix.callbacks(); |
||
17727 | module.determineTabs(); |
||
17728 | |||
17729 | module.debug('Determining tabs', settings.context, $tabs); |
||
17730 | // set up automatic routing |
||
17731 | if(settings.auto) { |
||
17732 | module.set.auto(); |
||
17733 | } |
||
17734 | module.bind.events(); |
||
17735 | |||
17736 | if(settings.history && !initializedHistory) { |
||
17737 | module.initializeHistory(); |
||
17738 | initializedHistory = true; |
||
17739 | } |
||
17740 | |||
17741 | module.instantiate(); |
||
17742 | }, |
||
17743 | |||
17744 | instantiate: function () { |
||
17745 | module.verbose('Storing instance of module', module); |
||
17746 | instance = module; |
||
17747 | $module |
||
17748 | .data(moduleNamespace, module) |
||
17749 | ; |
||
17750 | }, |
||
17751 | |||
17752 | destroy: function() { |
||
17753 | module.debug('Destroying tabs', $module); |
||
17754 | $module |
||
17755 | .removeData(moduleNamespace) |
||
17756 | .off(eventNamespace) |
||
17757 | ; |
||
17758 | }, |
||
17759 | |||
17760 | bind: { |
||
17761 | events: function() { |
||
17762 | // if using $.tab don't add events |
||
17763 | if( !$.isWindow( element ) ) { |
||
17764 | module.debug('Attaching tab activation events to element', $module); |
||
17765 | $module |
||
17766 | .on('click' + eventNamespace, module.event.click) |
||
17767 | ; |
||
17768 | } |
||
17769 | } |
||
17770 | }, |
||
17771 | |||
17772 | determineTabs: function() { |
||
17773 | var |
||
17774 | $reference |
||
17775 | ; |
||
17776 | |||
17777 | // determine tab context |
||
17778 | if(settings.context === 'parent') { |
||
17779 | if($module.closest(selector.ui).length > 0) { |
||
17780 | $reference = $module.closest(selector.ui); |
||
17781 | module.verbose('Using closest UI element as parent', $reference); |
||
17782 | } |
||
17783 | else { |
||
17784 | $reference = $module; |
||
17785 | } |
||
17786 | $context = $reference.parent(); |
||
17787 | module.verbose('Determined parent element for creating context', $context); |
||
17788 | } |
||
17789 | else if(settings.context) { |
||
17790 | $context = $(settings.context); |
||
17791 | module.verbose('Using selector for tab context', settings.context, $context); |
||
17792 | } |
||
17793 | else { |
||
17794 | $context = $('body'); |
||
17795 | } |
||
17796 | // find tabs |
||
17797 | if(settings.childrenOnly) { |
||
17798 | $tabs = $context.children(selector.tabs); |
||
17799 | module.debug('Searching tab context children for tabs', $context, $tabs); |
||
17800 | } |
||
17801 | else { |
||
17802 | $tabs = $context.find(selector.tabs); |
||
17803 | module.debug('Searching tab context for tabs', $context, $tabs); |
||
17804 | } |
||
17805 | }, |
||
17806 | |||
17807 | fix: { |
||
17808 | callbacks: function() { |
||
17809 | if( $.isPlainObject(parameters) && (parameters.onTabLoad || parameters.onTabInit) ) { |
||
17810 | if(parameters.onTabLoad) { |
||
17811 | parameters.onLoad = parameters.onTabLoad; |
||
17812 | delete parameters.onTabLoad; |
||
17813 | module.error(error.legacyLoad, parameters.onLoad); |
||
17814 | } |
||
17815 | if(parameters.onTabInit) { |
||
17816 | parameters.onFirstLoad = parameters.onTabInit; |
||
17817 | delete parameters.onTabInit; |
||
17818 | module.error(error.legacyInit, parameters.onFirstLoad); |
||
17819 | } |
||
17820 | settings = $.extend(true, {}, $.fn.tab.settings, parameters); |
||
17821 | } |
||
17822 | } |
||
17823 | }, |
||
17824 | |||
17825 | initializeHistory: function() { |
||
17826 | module.debug('Initializing page state'); |
||
17827 | if( $.address === undefined ) { |
||
17828 | module.error(error.state); |
||
17829 | return false; |
||
17830 | } |
||
17831 | else { |
||
17832 | if(settings.historyType == 'state') { |
||
17833 | module.debug('Using HTML5 to manage state'); |
||
17834 | if(settings.path !== false) { |
||
17835 | $.address |
||
17836 | .history(true) |
||
17837 | .state(settings.path) |
||
17838 | ; |
||
17839 | } |
||
17840 | else { |
||
17841 | module.error(error.path); |
||
17842 | return false; |
||
17843 | } |
||
17844 | } |
||
17845 | $.address |
||
17846 | .bind('change', module.event.history.change) |
||
17847 | ; |
||
17848 | } |
||
17849 | }, |
||
17850 | |||
17851 | event: { |
||
17852 | click: function(event) { |
||
17853 | var |
||
17854 | tabPath = $(this).data(metadata.tab) |
||
17855 | ; |
||
17856 | if(tabPath !== undefined) { |
||
17857 | if(settings.history) { |
||
17858 | module.verbose('Updating page state', event); |
||
17859 | $.address.value(tabPath); |
||
17860 | } |
||
17861 | else { |
||
17862 | module.verbose('Changing tab', event); |
||
17863 | module.changeTab(tabPath); |
||
17864 | } |
||
17865 | event.preventDefault(); |
||
17866 | } |
||
17867 | else { |
||
17868 | module.debug('No tab specified'); |
||
17869 | } |
||
17870 | }, |
||
17871 | history: { |
||
17872 | change: function(event) { |
||
17873 | var |
||
17874 | tabPath = event.pathNames.join('/') || module.get.initialPath(), |
||
17875 | pageTitle = settings.templates.determineTitle(tabPath) || false |
||
17876 | ; |
||
17877 | module.performance.display(); |
||
17878 | module.debug('History change event', tabPath, event); |
||
17879 | historyEvent = event; |
||
17880 | if(tabPath !== undefined) { |
||
17881 | module.changeTab(tabPath); |
||
17882 | } |
||
17883 | if(pageTitle) { |
||
17884 | $.address.title(pageTitle); |
||
17885 | } |
||
17886 | } |
||
17887 | } |
||
17888 | }, |
||
17889 | |||
17890 | refresh: function() { |
||
17891 | if(activeTabPath) { |
||
17892 | module.debug('Refreshing tab', activeTabPath); |
||
17893 | module.changeTab(activeTabPath); |
||
17894 | } |
||
17895 | }, |
||
17896 | |||
17897 | cache: { |
||
17898 | |||
17899 | read: function(cacheKey) { |
||
17900 | return (cacheKey !== undefined) |
||
17901 | ? cache[cacheKey] |
||
17902 | : false |
||
17903 | ; |
||
17904 | }, |
||
17905 | add: function(cacheKey, content) { |
||
17906 | cacheKey = cacheKey || activeTabPath; |
||
17907 | module.debug('Adding cached content for', cacheKey); |
||
17908 | cache[cacheKey] = content; |
||
17909 | }, |
||
17910 | remove: function(cacheKey) { |
||
17911 | cacheKey = cacheKey || activeTabPath; |
||
17912 | module.debug('Removing cached content for', cacheKey); |
||
17913 | delete cache[cacheKey]; |
||
17914 | } |
||
17915 | }, |
||
17916 | |||
17917 | set: { |
||
17918 | auto: function() { |
||
17919 | var |
||
17920 | url = (typeof settings.path == 'string') |
||
17921 | ? settings.path.replace(/\/$/, '') + '/{$tab}' |
||
17922 | : '/{$tab}' |
||
17923 | ; |
||
17924 | module.verbose('Setting up automatic tab retrieval from server', url); |
||
17925 | if($.isPlainObject(settings.apiSettings)) { |
||
17926 | settings.apiSettings.url = url; |
||
17927 | } |
||
17928 | else { |
||
17929 | settings.apiSettings = { |
||
17930 | url: url |
||
17931 | }; |
||
17932 | } |
||
17933 | }, |
||
17934 | loading: function(tabPath) { |
||
17935 | var |
||
17936 | $tab = module.get.tabElement(tabPath), |
||
17937 | isLoading = $tab.hasClass(className.loading) |
||
17938 | ; |
||
17939 | if(!isLoading) { |
||
17940 | module.verbose('Setting loading state for', $tab); |
||
17941 | $tab |
||
17942 | .addClass(className.loading) |
||
17943 | .siblings($tabs) |
||
17944 | .removeClass(className.active + ' ' + className.loading) |
||
17945 | ; |
||
17946 | if($tab.length > 0) { |
||
17947 | settings.onRequest.call($tab[0], tabPath); |
||
17948 | } |
||
17949 | } |
||
17950 | }, |
||
17951 | state: function(state) { |
||
17952 | $.address.value(state); |
||
17953 | } |
||
17954 | }, |
||
17955 | |||
17956 | changeTab: function(tabPath) { |
||
17957 | var |
||
17958 | pushStateAvailable = (window.history && window.history.pushState), |
||
17959 | shouldIgnoreLoad = (pushStateAvailable && settings.ignoreFirstLoad && firstLoad), |
||
17960 | remoteContent = (settings.auto || $.isPlainObject(settings.apiSettings) ), |
||
17961 | // only add default path if not remote content |
||
17962 | pathArray = (remoteContent && !shouldIgnoreLoad) |
||
17963 | ? module.utilities.pathToArray(tabPath) |
||
17964 | : module.get.defaultPathArray(tabPath) |
||
17965 | ; |
||
17966 | tabPath = module.utilities.arrayToPath(pathArray); |
||
17967 | $.each(pathArray, function(index, tab) { |
||
17968 | var |
||
17969 | currentPathArray = pathArray.slice(0, index + 1), |
||
17970 | currentPath = module.utilities.arrayToPath(currentPathArray), |
||
17971 | |||
17972 | isTab = module.is.tab(currentPath), |
||
17973 | isLastIndex = (index + 1 == pathArray.length), |
||
17974 | |||
17975 | $tab = module.get.tabElement(currentPath), |
||
17976 | $anchor, |
||
17977 | nextPathArray, |
||
17978 | nextPath, |
||
17979 | isLastTab |
||
17980 | ; |
||
17981 | module.verbose('Looking for tab', tab); |
||
17982 | if(isTab) { |
||
17983 | module.verbose('Tab was found', tab); |
||
17984 | // scope up |
||
17985 | activeTabPath = currentPath; |
||
17986 | parameterArray = module.utilities.filterArray(pathArray, currentPathArray); |
||
17987 | |||
17988 | if(isLastIndex) { |
||
17989 | isLastTab = true; |
||
17990 | } |
||
17991 | else { |
||
17992 | nextPathArray = pathArray.slice(0, index + 2); |
||
17993 | nextPath = module.utilities.arrayToPath(nextPathArray); |
||
17994 | isLastTab = ( !module.is.tab(nextPath) ); |
||
17995 | if(isLastTab) { |
||
17996 | module.verbose('Tab parameters found', nextPathArray); |
||
17997 | } |
||
17998 | } |
||
17999 | if(isLastTab && remoteContent) { |
||
18000 | if(!shouldIgnoreLoad) { |
||
18001 | module.activate.navigation(currentPath); |
||
18002 | module.fetch.content(currentPath, tabPath); |
||
18003 | } |
||
18004 | else { |
||
18005 | module.debug('Ignoring remote content on first tab load', currentPath); |
||
18006 | firstLoad = false; |
||
18007 | module.cache.add(tabPath, $tab.html()); |
||
18008 | module.activate.all(currentPath); |
||
18009 | settings.onFirstLoad.call($tab[0], currentPath, parameterArray, historyEvent); |
||
18010 | settings.onLoad.call($tab[0], currentPath, parameterArray, historyEvent); |
||
18011 | } |
||
18012 | return false; |
||
18013 | } |
||
18014 | else { |
||
18015 | module.debug('Opened local tab', currentPath); |
||
18016 | module.activate.all(currentPath); |
||
18017 | if( !module.cache.read(currentPath) ) { |
||
18018 | module.cache.add(currentPath, true); |
||
18019 | module.debug('First time tab loaded calling tab init'); |
||
18020 | settings.onFirstLoad.call($tab[0], currentPath, parameterArray, historyEvent); |
||
18021 | } |
||
18022 | settings.onLoad.call($tab[0], currentPath, parameterArray, historyEvent); |
||
18023 | } |
||
18024 | |||
18025 | } |
||
18026 | else if(tabPath.search('/') == -1 && tabPath !== '') { |
||
18027 | // look for in page anchor |
||
18028 | $anchor = $('#' + tabPath + ', a[name="' + tabPath + '"]'); |
||
18029 | currentPath = $anchor.closest('[data-tab]').data(metadata.tab); |
||
18030 | $tab = module.get.tabElement(currentPath); |
||
18031 | // if anchor exists use parent tab |
||
18032 | if($anchor && $anchor.length > 0 && currentPath) { |
||
18033 | module.debug('Anchor link used, opening parent tab', $tab, $anchor); |
||
18034 | if( !$tab.hasClass(className.active) ) { |
||
18035 | setTimeout(function() { |
||
18036 | module.scrollTo($anchor); |
||
18037 | }, 0); |
||
18038 | } |
||
18039 | module.activate.all(currentPath); |
||
18040 | if( !module.cache.read(currentPath) ) { |
||
18041 | module.cache.add(currentPath, true); |
||
18042 | module.debug('First time tab loaded calling tab init'); |
||
18043 | settings.onFirstLoad.call($tab[0], currentPath, parameterArray, historyEvent); |
||
18044 | } |
||
18045 | settings.onLoad.call($tab[0], currentPath, parameterArray, historyEvent); |
||
18046 | return false; |
||
18047 | } |
||
18048 | } |
||
18049 | else { |
||
18050 | module.error(error.missingTab, $module, $context, currentPath); |
||
18051 | return false; |
||
18052 | } |
||
18053 | }); |
||
18054 | }, |
||
18055 | |||
18056 | scrollTo: function($element) { |
||
18057 | var |
||
18058 | scrollOffset = ($element && $element.length > 0) |
||
18059 | ? $element.offset().top |
||
18060 | : false |
||
18061 | ; |
||
18062 | if(scrollOffset !== false) { |
||
18063 | module.debug('Forcing scroll to an in-page link in a hidden tab', scrollOffset, $element); |
||
18064 | $(document).scrollTop(scrollOffset); |
||
18065 | } |
||
18066 | }, |
||
18067 | |||
18068 | update: { |
||
18069 | content: function(tabPath, html, evaluateScripts) { |
||
18070 | var |
||
18071 | $tab = module.get.tabElement(tabPath), |
||
18072 | tab = $tab[0] |
||
18073 | ; |
||
18074 | evaluateScripts = (evaluateScripts !== undefined) |
||
18075 | ? evaluateScripts |
||
18076 | : settings.evaluateScripts |
||
18077 | ; |
||
18078 | if(typeof settings.cacheType == 'string' && settings.cacheType.toLowerCase() == 'dom' && typeof html !== 'string') { |
||
18079 | $tab |
||
18080 | .empty() |
||
18081 | .append($(html).clone(true)) |
||
18082 | ; |
||
18083 | } |
||
18084 | else { |
||
18085 | if(evaluateScripts) { |
||
18086 | module.debug('Updating HTML and evaluating inline scripts', tabPath, html); |
||
18087 | $tab.html(html); |
||
18088 | } |
||
18089 | else { |
||
18090 | module.debug('Updating HTML', tabPath, html); |
||
18091 | tab.innerHTML = html; |
||
18092 | } |
||
18093 | } |
||
18094 | } |
||
18095 | }, |
||
18096 | |||
18097 | fetch: { |
||
18098 | |||
18099 | content: function(tabPath, fullTabPath) { |
||
18100 | var |
||
18101 | $tab = module.get.tabElement(tabPath), |
||
18102 | apiSettings = { |
||
18103 | dataType : 'html', |
||
18104 | encodeParameters : false, |
||
18105 | on : 'now', |
||
18106 | cache : settings.alwaysRefresh, |
||
18107 | headers : { |
||
18108 | 'X-Remote': true |
||
18109 | }, |
||
18110 | onSuccess : function(response) { |
||
18111 | if(settings.cacheType == 'response') { |
||
18112 | module.cache.add(fullTabPath, response); |
||
18113 | } |
||
18114 | module.update.content(tabPath, response); |
||
18115 | if(tabPath == activeTabPath) { |
||
18116 | module.debug('Content loaded', tabPath); |
||
18117 | module.activate.tab(tabPath); |
||
18118 | } |
||
18119 | else { |
||
18120 | module.debug('Content loaded in background', tabPath); |
||
18121 | } |
||
18122 | settings.onFirstLoad.call($tab[0], tabPath, parameterArray, historyEvent); |
||
18123 | settings.onLoad.call($tab[0], tabPath, parameterArray, historyEvent); |
||
18124 | |||
18125 | if(settings.loadOnce) { |
||
18126 | module.cache.add(fullTabPath, true); |
||
18127 | } |
||
18128 | else if(typeof settings.cacheType == 'string' && settings.cacheType.toLowerCase() == 'dom' && $tab.children().length > 0) { |
||
18129 | setTimeout(function() { |
||
18130 | var |
||
18131 | $clone = $tab.children().clone(true) |
||
18132 | ; |
||
18133 | $clone = $clone.not('script'); |
||
18134 | module.cache.add(fullTabPath, $clone); |
||
18135 | }, 0); |
||
18136 | } |
||
18137 | else { |
||
18138 | module.cache.add(fullTabPath, $tab.html()); |
||
18139 | } |
||
18140 | }, |
||
18141 | urlData: { |
||
18142 | tab: fullTabPath |
||
18143 | } |
||
18144 | }, |
||
18145 | request = $tab.api('get request') || false, |
||
18146 | existingRequest = ( request && request.state() === 'pending' ), |
||
18147 | requestSettings, |
||
18148 | cachedContent |
||
18149 | ; |
||
18150 | |||
18151 | fullTabPath = fullTabPath || tabPath; |
||
18152 | cachedContent = module.cache.read(fullTabPath); |
||
18153 | |||
18154 | |||
18155 | if(settings.cache && cachedContent) { |
||
18156 | module.activate.tab(tabPath); |
||
18157 | module.debug('Adding cached content', fullTabPath); |
||
18158 | if(!settings.loadOnce) { |
||
18159 | if(settings.evaluateScripts == 'once') { |
||
18160 | module.update.content(tabPath, cachedContent, false); |
||
18161 | } |
||
18162 | else { |
||
18163 | module.update.content(tabPath, cachedContent); |
||
18164 | } |
||
18165 | } |
||
18166 | settings.onLoad.call($tab[0], tabPath, parameterArray, historyEvent); |
||
18167 | } |
||
18168 | else if(existingRequest) { |
||
18169 | module.set.loading(tabPath); |
||
18170 | module.debug('Content is already loading', fullTabPath); |
||
18171 | } |
||
18172 | else if($.api !== undefined) { |
||
18173 | requestSettings = $.extend(true, {}, settings.apiSettings, apiSettings); |
||
18174 | module.debug('Retrieving remote content', fullTabPath, requestSettings); |
||
18175 | module.set.loading(tabPath); |
||
18176 | $tab.api(requestSettings); |
||
18177 | } |
||
18178 | else { |
||
18179 | module.error(error.api); |
||
18180 | } |
||
18181 | } |
||
18182 | }, |
||
18183 | |||
18184 | activate: { |
||
18185 | all: function(tabPath) { |
||
18186 | module.activate.tab(tabPath); |
||
18187 | module.activate.navigation(tabPath); |
||
18188 | }, |
||
18189 | tab: function(tabPath) { |
||
18190 | var |
||
18191 | $tab = module.get.tabElement(tabPath), |
||
18192 | $deactiveTabs = (settings.deactivate == 'siblings') |
||
18193 | ? $tab.siblings($tabs) |
||
18194 | : $tabs.not($tab), |
||
18195 | isActive = $tab.hasClass(className.active) |
||
18196 | ; |
||
18197 | module.verbose('Showing tab content for', $tab); |
||
18198 | if(!isActive) { |
||
18199 | $tab |
||
18200 | .addClass(className.active) |
||
18201 | ; |
||
18202 | $deactiveTabs |
||
18203 | .removeClass(className.active + ' ' + className.loading) |
||
18204 | ; |
||
18205 | if($tab.length > 0) { |
||
18206 | settings.onVisible.call($tab[0], tabPath); |
||
18207 | } |
||
18208 | } |
||
18209 | }, |
||
18210 | navigation: function(tabPath) { |
||
18211 | var |
||
18212 | $navigation = module.get.navElement(tabPath), |
||
18213 | $deactiveNavigation = (settings.deactivate == 'siblings') |
||
18214 | ? $navigation.siblings($allModules) |
||
18215 | : $allModules.not($navigation), |
||
18216 | isActive = $navigation.hasClass(className.active) |
||
18217 | ; |
||
18218 | module.verbose('Activating tab navigation for', $navigation, tabPath); |
||
18219 | if(!isActive) { |
||
18220 | $navigation |
||
18221 | .addClass(className.active) |
||
18222 | ; |
||
18223 | $deactiveNavigation |
||
18224 | .removeClass(className.active + ' ' + className.loading) |
||
18225 | ; |
||
18226 | } |
||
18227 | } |
||
18228 | }, |
||
18229 | |||
18230 | deactivate: { |
||
18231 | all: function() { |
||
18232 | module.deactivate.navigation(); |
||
18233 | module.deactivate.tabs(); |
||
18234 | }, |
||
18235 | navigation: function() { |
||
18236 | $allModules |
||
18237 | .removeClass(className.active) |
||
18238 | ; |
||
18239 | }, |
||
18240 | tabs: function() { |
||
18241 | $tabs |
||
18242 | .removeClass(className.active + ' ' + className.loading) |
||
18243 | ; |
||
18244 | } |
||
18245 | }, |
||
18246 | |||
18247 | is: { |
||
18248 | tab: function(tabName) { |
||
18249 | return (tabName !== undefined) |
||
18250 | ? ( module.get.tabElement(tabName).length > 0 ) |
||
18251 | : false |
||
18252 | ; |
||
18253 | } |
||
18254 | }, |
||
18255 | |||
18256 | get: { |
||
18257 | initialPath: function() { |
||
18258 | return $allModules.eq(0).data(metadata.tab) || $tabs.eq(0).data(metadata.tab); |
||
18259 | }, |
||
18260 | path: function() { |
||
18261 | return $.address.value(); |
||
18262 | }, |
||
18263 | // adds default tabs to tab path |
||
18264 | defaultPathArray: function(tabPath) { |
||
18265 | return module.utilities.pathToArray( module.get.defaultPath(tabPath) ); |
||
18266 | }, |
||
18267 | defaultPath: function(tabPath) { |
||
18268 | var |
||
18269 | $defaultNav = $allModules.filter('[data-' + metadata.tab + '^="' + tabPath + '/"]').eq(0), |
||
18270 | defaultTab = $defaultNav.data(metadata.tab) || false |
||
18271 | ; |
||
18272 | if( defaultTab ) { |
||
18273 | module.debug('Found default tab', defaultTab); |
||
18274 | if(recursionDepth < settings.maxDepth) { |
||
18275 | recursionDepth++; |
||
18276 | return module.get.defaultPath(defaultTab); |
||
18277 | } |
||
18278 | module.error(error.recursion); |
||
18279 | } |
||
18280 | else { |
||
18281 | module.debug('No default tabs found for', tabPath, $tabs); |
||
18282 | } |
||
18283 | recursionDepth = 0; |
||
18284 | return tabPath; |
||
18285 | }, |
||
18286 | navElement: function(tabPath) { |
||
18287 | tabPath = tabPath || activeTabPath; |
||
18288 | return $allModules.filter('[data-' + metadata.tab + '="' + tabPath + '"]'); |
||
18289 | }, |
||
18290 | tabElement: function(tabPath) { |
||
18291 | var |
||
18292 | $fullPathTab, |
||
18293 | $simplePathTab, |
||
18294 | tabPathArray, |
||
18295 | lastTab |
||
18296 | ; |
||
18297 | tabPath = tabPath || activeTabPath; |
||
18298 | tabPathArray = module.utilities.pathToArray(tabPath); |
||
18299 | lastTab = module.utilities.last(tabPathArray); |
||
18300 | $fullPathTab = $tabs.filter('[data-' + metadata.tab + '="' + tabPath + '"]'); |
||
18301 | $simplePathTab = $tabs.filter('[data-' + metadata.tab + '="' + lastTab + '"]'); |
||
18302 | return ($fullPathTab.length > 0) |
||
18303 | ? $fullPathTab |
||
18304 | : $simplePathTab |
||
18305 | ; |
||
18306 | }, |
||
18307 | tab: function() { |
||
18308 | return activeTabPath; |
||
18309 | } |
||
18310 | }, |
||
18311 | |||
18312 | utilities: { |
||
18313 | filterArray: function(keepArray, removeArray) { |
||
18314 | return $.grep(keepArray, function(keepValue) { |
||
18315 | return ( $.inArray(keepValue, removeArray) == -1); |
||
18316 | }); |
||
18317 | }, |
||
18318 | last: function(array) { |
||
18319 | return $.isArray(array) |
||
18320 | ? array[ array.length - 1] |
||
18321 | : false |
||
18322 | ; |
||
18323 | }, |
||
18324 | pathToArray: function(pathName) { |
||
18325 | if(pathName === undefined) { |
||
18326 | pathName = activeTabPath; |
||
18327 | } |
||
18328 | return typeof pathName == 'string' |
||
18329 | ? pathName.split('/') |
||
18330 | : [pathName] |
||
18331 | ; |
||
18332 | }, |
||
18333 | arrayToPath: function(pathArray) { |
||
18334 | return $.isArray(pathArray) |
||
18335 | ? pathArray.join('/') |
||
18336 | : false |
||
18337 | ; |
||
18338 | } |
||
18339 | }, |
||
18340 | |||
18341 | setting: function(name, value) { |
||
18342 | module.debug('Changing setting', name, value); |
||
18343 | if( $.isPlainObject(name) ) { |
||
18344 | $.extend(true, settings, name); |
||
18345 | } |
||
18346 | else if(value !== undefined) { |
||
18347 | if($.isPlainObject(settings[name])) { |
||
18348 | $.extend(true, settings[name], value); |
||
18349 | } |
||
18350 | else { |
||
18351 | settings[name] = value; |
||
18352 | } |
||
18353 | } |
||
18354 | else { |
||
18355 | return settings[name]; |
||
18356 | } |
||
18357 | }, |
||
18358 | internal: function(name, value) { |
||
18359 | if( $.isPlainObject(name) ) { |
||
18360 | $.extend(true, module, name); |
||
18361 | } |
||
18362 | else if(value !== undefined) { |
||
18363 | module[name] = value; |
||
18364 | } |
||
18365 | else { |
||
18366 | return module[name]; |
||
18367 | } |
||
18368 | }, |
||
18369 | debug: function() { |
||
18370 | if(!settings.silent && settings.debug) { |
||
18371 | if(settings.performance) { |
||
18372 | module.performance.log(arguments); |
||
18373 | } |
||
18374 | else { |
||
18375 | module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':'); |
||
18376 | module.debug.apply(console, arguments); |
||
18377 | } |
||
18378 | } |
||
18379 | }, |
||
18380 | verbose: function() { |
||
18381 | if(!settings.silent && settings.verbose && settings.debug) { |
||
18382 | if(settings.performance) { |
||
18383 | module.performance.log(arguments); |
||
18384 | } |
||
18385 | else { |
||
18386 | module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':'); |
||
18387 | module.verbose.apply(console, arguments); |
||
18388 | } |
||
18389 | } |
||
18390 | }, |
||
18391 | error: function() { |
||
18392 | if(!settings.silent) { |
||
18393 | module.error = Function.prototype.bind.call(console.error, console, settings.name + ':'); |
||
18394 | module.error.apply(console, arguments); |
||
18395 | } |
||
18396 | }, |
||
18397 | performance: { |
||
18398 | log: function(message) { |
||
18399 | var |
||
18400 | currentTime, |
||
18401 | executionTime, |
||
18402 | previousTime |
||
18403 | ; |
||
18404 | if(settings.performance) { |
||
18405 | currentTime = new Date().getTime(); |
||
18406 | previousTime = time || currentTime; |
||
18407 | executionTime = currentTime - previousTime; |
||
18408 | time = currentTime; |
||
18409 | performance.push({ |
||
18410 | 'Name' : message[0], |
||
18411 | 'Arguments' : [].slice.call(message, 1) || '', |
||
18412 | 'Element' : element, |
||
18413 | 'Execution Time' : executionTime |
||
18414 | }); |
||
18415 | } |
||
18416 | clearTimeout(module.performance.timer); |
||
18417 | module.performance.timer = setTimeout(module.performance.display, 500); |
||
18418 | }, |
||
18419 | display: function() { |
||
18420 | var |
||
18421 | title = settings.name + ':', |
||
18422 | totalTime = 0 |
||
18423 | ; |
||
18424 | time = false; |
||
18425 | clearTimeout(module.performance.timer); |
||
18426 | $.each(performance, function(index, data) { |
||
18427 | totalTime += data['Execution Time']; |
||
18428 | }); |
||
18429 | title += ' ' + totalTime + 'ms'; |
||
18430 | if(moduleSelector) { |
||
18431 | title += ' \'' + moduleSelector + '\''; |
||
18432 | } |
||
18433 | if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) { |
||
18434 | console.groupCollapsed(title); |
||
18435 | if(console.table) { |
||
18436 | console.table(performance); |
||
18437 | } |
||
18438 | else { |
||
18439 | $.each(performance, function(index, data) { |
||
18440 | console.log(data['Name'] + ': ' + data['Execution Time']+'ms'); |
||
18441 | }); |
||
18442 | } |
||
18443 | console.groupEnd(); |
||
18444 | } |
||
18445 | performance = []; |
||
18446 | } |
||
18447 | }, |
||
18448 | invoke: function(query, passedArguments, context) { |
||
18449 | var |
||
18450 | object = instance, |
||
18451 | maxDepth, |
||
18452 | found, |
||
18453 | response |
||
18454 | ; |
||
18455 | passedArguments = passedArguments || queryArguments; |
||
18456 | context = element || context; |
||
18457 | if(typeof query == 'string' && object !== undefined) { |
||
18458 | query = query.split(/[\. ]/); |
||
18459 | maxDepth = query.length - 1; |
||
18460 | $.each(query, function(depth, value) { |
||
18461 | var camelCaseValue = (depth != maxDepth) |
||
18462 | ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1) |
||
18463 | : query |
||
18464 | ; |
||
18465 | if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) { |
||
18466 | object = object[camelCaseValue]; |
||
18467 | } |
||
18468 | else if( object[camelCaseValue] !== undefined ) { |
||
18469 | found = object[camelCaseValue]; |
||
18470 | return false; |
||
18471 | } |
||
18472 | else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) { |
||
18473 | object = object[value]; |
||
18474 | } |
||
18475 | else if( object[value] !== undefined ) { |
||
18476 | found = object[value]; |
||
18477 | return false; |
||
18478 | } |
||
18479 | else { |
||
18480 | module.error(error.method, query); |
||
18481 | return false; |
||
18482 | } |
||
18483 | }); |
||
18484 | } |
||
18485 | if ( $.isFunction( found ) ) { |
||
18486 | response = found.apply(context, passedArguments); |
||
18487 | } |
||
18488 | else if(found !== undefined) { |
||
18489 | response = found; |
||
18490 | } |
||
18491 | if($.isArray(returnedValue)) { |
||
18492 | returnedValue.push(response); |
||
18493 | } |
||
18494 | else if(returnedValue !== undefined) { |
||
18495 | returnedValue = [returnedValue, response]; |
||
18496 | } |
||
18497 | else if(response !== undefined) { |
||
18498 | returnedValue = response; |
||
18499 | } |
||
18500 | return found; |
||
18501 | } |
||
18502 | }; |
||
18503 | if(methodInvoked) { |
||
18504 | if(instance === undefined) { |
||
18505 | module.initialize(); |
||
18506 | } |
||
18507 | module.invoke(query); |
||
18508 | } |
||
18509 | else { |
||
18510 | if(instance !== undefined) { |
||
18511 | instance.invoke('destroy'); |
||
18512 | } |
||
18513 | module.initialize(); |
||
18514 | } |
||
18515 | }) |
||
18516 | ; |
||
18517 | return (returnedValue !== undefined) |
||
18518 | ? returnedValue |
||
18519 | : this |
||
18520 | ; |
||
18521 | |||
18522 | }; |
||
18523 | |||
18524 | // shortcut for tabbed content with no defined navigation |
||
18525 | $.tab = function() { |
||
18526 | $(window).tab.apply(this, arguments); |
||
18527 | }; |
||
18528 | |||
18529 | $.fn.tab.settings = { |
||
18530 | |||
18531 | name : 'Tab', |
||
18532 | namespace : 'tab', |
||
18533 | |||
18534 | silent : false, |
||
18535 | debug : false, |
||
18536 | verbose : false, |
||
18537 | performance : true, |
||
18538 | |||
18539 | auto : false, // uses pjax style endpoints fetching content from same url with remote-content headers |
||
18540 | history : false, // use browser history |
||
18541 | historyType : 'hash', // #/ or html5 state |
||
18542 | path : false, // base path of url |
||
18543 | |||
18544 | context : false, // specify a context that tabs must appear inside |
||
18545 | childrenOnly : false, // use only tabs that are children of context |
||
18546 | maxDepth : 25, // max depth a tab can be nested |
||
18547 | |||
18548 | deactivate : 'siblings', // whether tabs should deactivate sibling menu elements or all elements initialized together |
||
18549 | |||
18550 | alwaysRefresh : false, // load tab content new every tab click |
||
18551 | cache : true, // cache the content requests to pull locally |
||
18552 | loadOnce : false, // Whether tab data should only be loaded once when using remote content |
||
18553 | cacheType : 'response', // Whether to cache exact response, or to html cache contents after scripts execute |
||
18554 | ignoreFirstLoad : false, // don't load remote content on first load |
||
18555 | |||
18556 | apiSettings : false, // settings for api call |
||
18557 | evaluateScripts : 'once', // whether inline scripts should be parsed (true/false/once). Once will not re-evaluate on cached content |
||
18558 | |||
18559 | onFirstLoad : function(tabPath, parameterArray, historyEvent) {}, // called first time loaded |
||
18560 | onLoad : function(tabPath, parameterArray, historyEvent) {}, // called on every load |
||
18561 | onVisible : function(tabPath, parameterArray, historyEvent) {}, // called every time tab visible |
||
18562 | onRequest : function(tabPath, parameterArray, historyEvent) {}, // called ever time a tab beings loading remote content |
||
18563 | |||
18564 | templates : { |
||
18565 | determineTitle: function(tabArray) {} // returns page title for path |
||
18566 | }, |
||
18567 | |||
18568 | error: { |
||
18569 | api : 'You attempted to load content without API module', |
||
18570 | method : 'The method you called is not defined', |
||
18571 | missingTab : 'Activated tab cannot be found. Tabs are case-sensitive.', |
||
18572 | noContent : 'The tab you specified is missing a content url.', |
||
18573 | path : 'History enabled, but no path was specified', |
||
18574 | recursion : 'Max recursive depth reached', |
||
18575 | legacyInit : 'onTabInit has been renamed to onFirstLoad in 2.0, please adjust your code.', |
||
18576 | legacyLoad : 'onTabLoad has been renamed to onLoad in 2.0. Please adjust your code', |
||
18577 | state : 'History requires Asual\'s Address library <https://github.com/asual/jquery-address>' |
||
18578 | }, |
||
18579 | |||
18580 | metadata : { |
||
18581 | tab : 'tab', |
||
18582 | loaded : 'loaded', |
||
18583 | promise: 'promise' |
||
18584 | }, |
||
18585 | |||
18586 | className : { |
||
18587 | loading : 'loading', |
||
18588 | active : 'active' |
||
18589 | }, |
||
18590 | |||
18591 | selector : { |
||
18592 | tabs : '.ui.tab', |
||
18593 | ui : '.ui' |
||
18594 | } |
||
18595 | |||
18596 | }; |
||
18597 | |||
18598 | })( jQuery, window, document ); |
||
18599 | |||
18600 | /*! |
||
18601 | * # Semantic UI 2.2.11 - Transition |
||
18602 | * http://github.com/semantic-org/semantic-ui/ |
||
18603 | * |
||
18604 | * |
||
18605 | * Released under the MIT license |
||
18606 | * http://opensource.org/licenses/MIT |
||
18607 | * |
||
18608 | */ |
||
18609 | |||
18610 | View Code Duplication | ;(function ($, window, document, undefined) { |
|
18611 | |||
18612 | "use strict"; |
||
18613 | |||
18614 | window = (typeof window != 'undefined' && window.Math == Math) |
||
18615 | ? window |
||
18616 | : (typeof self != 'undefined' && self.Math == Math) |
||
18617 | ? self |
||
18618 | : Function('return this')() |
||
18619 | ; |
||
18620 | |||
18621 | $.fn.transition = function() { |
||
18622 | var |
||
18623 | $allModules = $(this), |
||
18624 | moduleSelector = $allModules.selector || '', |
||
18625 | |||
18626 | time = new Date().getTime(), |
||
18627 | performance = [], |
||
18628 | |||
18629 | moduleArguments = arguments, |
||
18630 | query = moduleArguments[0], |
||
18631 | queryArguments = [].slice.call(arguments, 1), |
||
18632 | methodInvoked = (typeof query === 'string'), |
||
18633 | |||
18634 | requestAnimationFrame = window.requestAnimationFrame |
||
18635 | || window.mozRequestAnimationFrame |
||
18636 | || window.webkitRequestAnimationFrame |
||
18637 | || window.msRequestAnimationFrame |
||
18638 | || function(callback) { setTimeout(callback, 0); }, |
||
18639 | |||
18640 | returnedValue |
||
18641 | ; |
||
18642 | $allModules |
||
18643 | .each(function(index) { |
||
18644 | var |
||
18645 | $module = $(this), |
||
18646 | element = this, |
||
18647 | |||
18648 | // set at run time |
||
18649 | settings, |
||
18650 | instance, |
||
18651 | |||
18652 | error, |
||
18653 | className, |
||
18654 | metadata, |
||
18655 | animationEnd, |
||
18656 | animationName, |
||
18657 | |||
18658 | namespace, |
||
18659 | moduleNamespace, |
||
18660 | eventNamespace, |
||
18661 | module |
||
18662 | ; |
||
18663 | |||
18664 | module = { |
||
18665 | |||
18666 | initialize: function() { |
||
18667 | |||
18668 | // get full settings |
||
18669 | settings = module.get.settings.apply(element, moduleArguments); |
||
18670 | |||
18671 | // shorthand |
||
18672 | className = settings.className; |
||
18673 | error = settings.error; |
||
18674 | metadata = settings.metadata; |
||
18675 | |||
18676 | // define namespace |
||
18677 | eventNamespace = '.' + settings.namespace; |
||
18678 | moduleNamespace = 'module-' + settings.namespace; |
||
18679 | instance = $module.data(moduleNamespace) || module; |
||
18680 | |||
18681 | // get vendor specific events |
||
18682 | animationEnd = module.get.animationEndEvent(); |
||
18683 | |||
18684 | if(methodInvoked) { |
||
18685 | methodInvoked = module.invoke(query); |
||
18686 | } |
||
18687 | |||
18688 | // method not invoked, lets run an animation |
||
18689 | if(methodInvoked === false) { |
||
18690 | module.verbose('Converted arguments into settings object', settings); |
||
18691 | if(settings.interval) { |
||
18692 | module.delay(settings.animate); |
||
18693 | } |
||
18694 | else { |
||
18695 | module.animate(); |
||
18696 | } |
||
18697 | module.instantiate(); |
||
18698 | } |
||
18699 | }, |
||
18700 | |||
18701 | instantiate: function() { |
||
18702 | module.verbose('Storing instance of module', module); |
||
18703 | instance = module; |
||
18704 | $module |
||
18705 | .data(moduleNamespace, instance) |
||
18706 | ; |
||
18707 | }, |
||
18708 | |||
18709 | destroy: function() { |
||
18710 | module.verbose('Destroying previous module for', element); |
||
18711 | $module |
||
18712 | .removeData(moduleNamespace) |
||
18713 | ; |
||
18714 | }, |
||
18715 | |||
18716 | refresh: function() { |
||
18717 | module.verbose('Refreshing display type on next animation'); |
||
18718 | delete module.displayType; |
||
18719 | }, |
||
18720 | |||
18721 | forceRepaint: function() { |
||
18722 | module.verbose('Forcing element repaint'); |
||
18723 | var |
||
18724 | $parentElement = $module.parent(), |
||
18725 | $nextElement = $module.next() |
||
18726 | ; |
||
18727 | if($nextElement.length === 0) { |
||
18728 | $module.detach().appendTo($parentElement); |
||
18729 | } |
||
18730 | else { |
||
18731 | $module.detach().insertBefore($nextElement); |
||
18732 | } |
||
18733 | }, |
||
18734 | |||
18735 | repaint: function() { |
||
18736 | module.verbose('Repainting element'); |
||
18737 | var |
||
18738 | fakeAssignment = element.offsetWidth |
||
18739 | ; |
||
18740 | }, |
||
18741 | |||
18742 | delay: function(interval) { |
||
18743 | var |
||
18744 | direction = module.get.animationDirection(), |
||
18745 | shouldReverse, |
||
18746 | delay |
||
18747 | ; |
||
18748 | if(!direction) { |
||
18749 | direction = module.can.transition() |
||
18750 | ? module.get.direction() |
||
18751 | : 'static' |
||
18752 | ; |
||
18753 | } |
||
18754 | interval = (interval !== undefined) |
||
18755 | ? interval |
||
18756 | : settings.interval |
||
18757 | ; |
||
18758 | shouldReverse = (settings.reverse == 'auto' && direction == className.outward); |
||
18759 | delay = (shouldReverse || settings.reverse == true) |
||
18760 | ? ($allModules.length - index) * settings.interval |
||
18761 | : index * settings.interval |
||
18762 | ; |
||
18763 | module.debug('Delaying animation by', delay); |
||
18764 | setTimeout(module.animate, delay); |
||
18765 | }, |
||
18766 | |||
18767 | animate: function(overrideSettings) { |
||
18768 | settings = overrideSettings || settings; |
||
18769 | if(!module.is.supported()) { |
||
18770 | module.error(error.support); |
||
18771 | return false; |
||
18772 | } |
||
18773 | module.debug('Preparing animation', settings.animation); |
||
18774 | if(module.is.animating()) { |
||
18775 | if(settings.queue) { |
||
18776 | if(!settings.allowRepeats && module.has.direction() && module.is.occurring() && module.queuing !== true) { |
||
18777 | module.debug('Animation is currently occurring, preventing queueing same animation', settings.animation); |
||
18778 | } |
||
18779 | else { |
||
18780 | module.queue(settings.animation); |
||
18781 | } |
||
18782 | return false; |
||
18783 | } |
||
18784 | else if(!settings.allowRepeats && module.is.occurring()) { |
||
18785 | module.debug('Animation is already occurring, will not execute repeated animation', settings.animation); |
||
18786 | return false; |
||
18787 | } |
||
18788 | else { |
||
18789 | module.debug('New animation started, completing previous early', settings.animation); |
||
18790 | instance.complete(); |
||
18791 | } |
||
18792 | } |
||
18793 | if( module.can.animate() ) { |
||
18794 | module.set.animating(settings.animation); |
||
18795 | } |
||
18796 | else { |
||
18797 | module.error(error.noAnimation, settings.animation, element); |
||
18798 | } |
||
18799 | }, |
||
18800 | |||
18801 | reset: function() { |
||
18802 | module.debug('Resetting animation to beginning conditions'); |
||
18803 | module.remove.animationCallbacks(); |
||
18804 | module.restore.conditions(); |
||
18805 | module.remove.animating(); |
||
18806 | }, |
||
18807 | |||
18808 | queue: function(animation) { |
||
18809 | module.debug('Queueing animation of', animation); |
||
18810 | module.queuing = true; |
||
18811 | $module |
||
18812 | .one(animationEnd + '.queue' + eventNamespace, function() { |
||
18813 | module.queuing = false; |
||
18814 | module.repaint(); |
||
18815 | module.animate.apply(this, settings); |
||
18816 | }) |
||
18817 | ; |
||
18818 | }, |
||
18819 | |||
18820 | complete: function (event) { |
||
18821 | module.debug('Animation complete', settings.animation); |
||
18822 | module.remove.completeCallback(); |
||
18823 | module.remove.failSafe(); |
||
18824 | if(!module.is.looping()) { |
||
18825 | if( module.is.outward() ) { |
||
18826 | module.verbose('Animation is outward, hiding element'); |
||
18827 | module.restore.conditions(); |
||
18828 | module.hide(); |
||
18829 | } |
||
18830 | else if( module.is.inward() ) { |
||
18831 | module.verbose('Animation is outward, showing element'); |
||
18832 | module.restore.conditions(); |
||
18833 | module.show(); |
||
18834 | } |
||
18835 | else { |
||
18836 | module.verbose('Static animation completed'); |
||
18837 | module.restore.conditions(); |
||
18838 | settings.onComplete.call(element); |
||
18839 | } |
||
18840 | } |
||
18841 | }, |
||
18842 | |||
18843 | force: { |
||
18844 | visible: function() { |
||
18845 | var |
||
18846 | style = $module.attr('style'), |
||
18847 | userStyle = module.get.userStyle(), |
||
18848 | displayType = module.get.displayType(), |
||
18849 | overrideStyle = userStyle + 'display: ' + displayType + ' !important;', |
||
18850 | currentDisplay = $module.css('display'), |
||
18851 | emptyStyle = (style === undefined || style === '') |
||
18852 | ; |
||
18853 | if(currentDisplay !== displayType) { |
||
18854 | module.verbose('Overriding default display to show element', displayType); |
||
18855 | $module |
||
18856 | .attr('style', overrideStyle) |
||
18857 | ; |
||
18858 | } |
||
18859 | else if(emptyStyle) { |
||
18860 | $module.removeAttr('style'); |
||
18861 | } |
||
18862 | }, |
||
18863 | hidden: function() { |
||
18864 | var |
||
18865 | style = $module.attr('style'), |
||
18866 | currentDisplay = $module.css('display'), |
||
18867 | emptyStyle = (style === undefined || style === '') |
||
18868 | ; |
||
18869 | if(currentDisplay !== 'none' && !module.is.hidden()) { |
||
18870 | module.verbose('Overriding default display to hide element'); |
||
18871 | $module |
||
18872 | .css('display', 'none') |
||
18873 | ; |
||
18874 | } |
||
18875 | else if(emptyStyle) { |
||
18876 | $module |
||
18877 | .removeAttr('style') |
||
18878 | ; |
||
18879 | } |
||
18880 | } |
||
18881 | }, |
||
18882 | |||
18883 | has: { |
||
18884 | direction: function(animation) { |
||
18885 | var |
||
18886 | hasDirection = false |
||
18887 | ; |
||
18888 | animation = animation || settings.animation; |
||
18889 | if(typeof animation === 'string') { |
||
18890 | animation = animation.split(' '); |
||
18891 | $.each(animation, function(index, word){ |
||
18892 | if(word === className.inward || word === className.outward) { |
||
18893 | hasDirection = true; |
||
18894 | } |
||
18895 | }); |
||
18896 | } |
||
18897 | return hasDirection; |
||
18898 | }, |
||
18899 | inlineDisplay: function() { |
||
18900 | var |
||
18901 | style = $module.attr('style') || '' |
||
18902 | ; |
||
18903 | return $.isArray(style.match(/display.*?;/, '')); |
||
18904 | } |
||
18905 | }, |
||
18906 | |||
18907 | set: { |
||
18908 | animating: function(animation) { |
||
18909 | var |
||
18910 | animationClass, |
||
18911 | direction |
||
18912 | ; |
||
18913 | // remove previous callbacks |
||
18914 | module.remove.completeCallback(); |
||
18915 | |||
18916 | // determine exact animation |
||
18917 | animation = animation || settings.animation; |
||
18918 | animationClass = module.get.animationClass(animation); |
||
18919 | |||
18920 | // save animation class in cache to restore class names |
||
18921 | module.save.animation(animationClass); |
||
18922 | |||
18923 | // override display if necessary so animation appears visibly |
||
18924 | module.force.visible(); |
||
18925 | |||
18926 | module.remove.hidden(); |
||
18927 | module.remove.direction(); |
||
18928 | |||
18929 | module.start.animation(animationClass); |
||
18930 | |||
18931 | }, |
||
18932 | duration: function(animationName, duration) { |
||
18933 | duration = duration || settings.duration; |
||
18934 | duration = (typeof duration == 'number') |
||
18935 | ? duration + 'ms' |
||
18936 | : duration |
||
18937 | ; |
||
18938 | if(duration || duration === 0) { |
||
18939 | module.verbose('Setting animation duration', duration); |
||
18940 | $module |
||
18941 | .css({ |
||
18942 | 'animation-duration': duration |
||
18943 | }) |
||
18944 | ; |
||
18945 | } |
||
18946 | }, |
||
18947 | direction: function(direction) { |
||
18948 | direction = direction || module.get.direction(); |
||
18949 | if(direction == className.inward) { |
||
18950 | module.set.inward(); |
||
18951 | } |
||
18952 | else { |
||
18953 | module.set.outward(); |
||
18954 | } |
||
18955 | }, |
||
18956 | looping: function() { |
||
18957 | module.debug('Transition set to loop'); |
||
18958 | $module |
||
18959 | .addClass(className.looping) |
||
18960 | ; |
||
18961 | }, |
||
18962 | hidden: function() { |
||
18963 | $module |
||
18964 | .addClass(className.transition) |
||
18965 | .addClass(className.hidden) |
||
18966 | ; |
||
18967 | }, |
||
18968 | inward: function() { |
||
18969 | module.debug('Setting direction to inward'); |
||
18970 | $module |
||
18971 | .removeClass(className.outward) |
||
18972 | .addClass(className.inward) |
||
18973 | ; |
||
18974 | }, |
||
18975 | outward: function() { |
||
18976 | module.debug('Setting direction to outward'); |
||
18977 | $module |
||
18978 | .removeClass(className.inward) |
||
18979 | .addClass(className.outward) |
||
18980 | ; |
||
18981 | }, |
||
18982 | visible: function() { |
||
18983 | $module |
||
18984 | .addClass(className.transition) |
||
18985 | .addClass(className.visible) |
||
18986 | ; |
||
18987 | } |
||
18988 | }, |
||
18989 | |||
18990 | start: { |
||
18991 | animation: function(animationClass) { |
||
18992 | animationClass = animationClass || module.get.animationClass(); |
||
18993 | module.debug('Starting tween', animationClass); |
||
18994 | $module |
||
18995 | .addClass(animationClass) |
||
18996 | .one(animationEnd + '.complete' + eventNamespace, module.complete) |
||
18997 | ; |
||
18998 | if(settings.useFailSafe) { |
||
18999 | module.add.failSafe(); |
||
19000 | } |
||
19001 | module.set.duration(settings.duration); |
||
19002 | settings.onStart.call(element); |
||
19003 | } |
||
19004 | }, |
||
19005 | |||
19006 | save: { |
||
19007 | animation: function(animation) { |
||
19008 | if(!module.cache) { |
||
19009 | module.cache = {}; |
||
19010 | } |
||
19011 | module.cache.animation = animation; |
||
19012 | }, |
||
19013 | displayType: function(displayType) { |
||
19014 | if(displayType !== 'none') { |
||
19015 | $module.data(metadata.displayType, displayType); |
||
19016 | } |
||
19017 | }, |
||
19018 | transitionExists: function(animation, exists) { |
||
19019 | $.fn.transition.exists[animation] = exists; |
||
19020 | module.verbose('Saving existence of transition', animation, exists); |
||
19021 | } |
||
19022 | }, |
||
19023 | |||
19024 | restore: { |
||
19025 | conditions: function() { |
||
19026 | var |
||
19027 | animation = module.get.currentAnimation() |
||
19028 | ; |
||
19029 | if(animation) { |
||
19030 | $module |
||
19031 | .removeClass(animation) |
||
19032 | ; |
||
19033 | module.verbose('Removing animation class', module.cache); |
||
19034 | } |
||
19035 | module.remove.duration(); |
||
19036 | } |
||
19037 | }, |
||
19038 | |||
19039 | add: { |
||
19040 | failSafe: function() { |
||
19041 | var |
||
19042 | duration = module.get.duration() |
||
19043 | ; |
||
19044 | module.timer = setTimeout(function() { |
||
19045 | $module.triggerHandler(animationEnd); |
||
19046 | }, duration + settings.failSafeDelay); |
||
19047 | module.verbose('Adding fail safe timer', module.timer); |
||
19048 | } |
||
19049 | }, |
||
19050 | |||
19051 | remove: { |
||
19052 | animating: function() { |
||
19053 | $module.removeClass(className.animating); |
||
19054 | }, |
||
19055 | animationCallbacks: function() { |
||
19056 | module.remove.queueCallback(); |
||
19057 | module.remove.completeCallback(); |
||
19058 | }, |
||
19059 | queueCallback: function() { |
||
19060 | $module.off('.queue' + eventNamespace); |
||
19061 | }, |
||
19062 | completeCallback: function() { |
||
19063 | $module.off('.complete' + eventNamespace); |
||
19064 | }, |
||
19065 | display: function() { |
||
19066 | $module.css('display', ''); |
||
19067 | }, |
||
19068 | direction: function() { |
||
19069 | $module |
||
19070 | .removeClass(className.inward) |
||
19071 | .removeClass(className.outward) |
||
19072 | ; |
||
19073 | }, |
||
19074 | duration: function() { |
||
19075 | $module |
||
19076 | .css('animation-duration', '') |
||
19077 | ; |
||
19078 | }, |
||
19079 | failSafe: function() { |
||
19080 | module.verbose('Removing fail safe timer', module.timer); |
||
19081 | if(module.timer) { |
||
19082 | clearTimeout(module.timer); |
||
19083 | } |
||
19084 | }, |
||
19085 | hidden: function() { |
||
19086 | $module.removeClass(className.hidden); |
||
19087 | }, |
||
19088 | visible: function() { |
||
19089 | $module.removeClass(className.visible); |
||
19090 | }, |
||
19091 | looping: function() { |
||
19092 | module.debug('Transitions are no longer looping'); |
||
19093 | if( module.is.looping() ) { |
||
19094 | module.reset(); |
||
19095 | $module |
||
19096 | .removeClass(className.looping) |
||
19097 | ; |
||
19098 | } |
||
19099 | }, |
||
19100 | transition: function() { |
||
19101 | $module |
||
19102 | .removeClass(className.visible) |
||
19103 | .removeClass(className.hidden) |
||
19104 | ; |
||
19105 | } |
||
19106 | }, |
||
19107 | get: { |
||
19108 | settings: function(animation, duration, onComplete) { |
||
19109 | // single settings object |
||
19110 | if(typeof animation == 'object') { |
||
19111 | return $.extend(true, {}, $.fn.transition.settings, animation); |
||
19112 | } |
||
19113 | // all arguments provided |
||
19114 | else if(typeof onComplete == 'function') { |
||
19115 | return $.extend({}, $.fn.transition.settings, { |
||
19116 | animation : animation, |
||
19117 | onComplete : onComplete, |
||
19118 | duration : duration |
||
19119 | }); |
||
19120 | } |
||
19121 | // only duration provided |
||
19122 | else if(typeof duration == 'string' || typeof duration == 'number') { |
||
19123 | return $.extend({}, $.fn.transition.settings, { |
||
19124 | animation : animation, |
||
19125 | duration : duration |
||
19126 | }); |
||
19127 | } |
||
19128 | // duration is actually settings object |
||
19129 | else if(typeof duration == 'object') { |
||
19130 | return $.extend({}, $.fn.transition.settings, duration, { |
||
19131 | animation : animation |
||
19132 | }); |
||
19133 | } |
||
19134 | // duration is actually callback |
||
19135 | else if(typeof duration == 'function') { |
||
19136 | return $.extend({}, $.fn.transition.settings, { |
||
19137 | animation : animation, |
||
19138 | onComplete : duration |
||
19139 | }); |
||
19140 | } |
||
19141 | // only animation provided |
||
19142 | else { |
||
19143 | return $.extend({}, $.fn.transition.settings, { |
||
19144 | animation : animation |
||
19145 | }); |
||
19146 | } |
||
19147 | }, |
||
19148 | animationClass: function(animation) { |
||
19149 | var |
||
19150 | animationClass = animation || settings.animation, |
||
19151 | directionClass = (module.can.transition() && !module.has.direction()) |
||
19152 | ? module.get.direction() + ' ' |
||
19153 | : '' |
||
19154 | ; |
||
19155 | return className.animating + ' ' |
||
19156 | + className.transition + ' ' |
||
19157 | + directionClass |
||
19158 | + animationClass |
||
19159 | ; |
||
19160 | }, |
||
19161 | currentAnimation: function() { |
||
19162 | return (module.cache && module.cache.animation !== undefined) |
||
19163 | ? module.cache.animation |
||
19164 | : false |
||
19165 | ; |
||
19166 | }, |
||
19167 | currentDirection: function() { |
||
19168 | return module.is.inward() |
||
19169 | ? className.inward |
||
19170 | : className.outward |
||
19171 | ; |
||
19172 | }, |
||
19173 | direction: function() { |
||
19174 | return module.is.hidden() || !module.is.visible() |
||
19175 | ? className.inward |
||
19176 | : className.outward |
||
19177 | ; |
||
19178 | }, |
||
19179 | animationDirection: function(animation) { |
||
19180 | var |
||
19181 | direction |
||
19182 | ; |
||
19183 | animation = animation || settings.animation; |
||
19184 | if(typeof animation === 'string') { |
||
19185 | animation = animation.split(' '); |
||
19186 | // search animation name for out/in class |
||
19187 | $.each(animation, function(index, word){ |
||
19188 | if(word === className.inward) { |
||
19189 | direction = className.inward; |
||
19190 | } |
||
19191 | else if(word === className.outward) { |
||
19192 | direction = className.outward; |
||
19193 | } |
||
19194 | }); |
||
19195 | } |
||
19196 | // return found direction |
||
19197 | if(direction) { |
||
19198 | return direction; |
||
19199 | } |
||
19200 | return false; |
||
19201 | }, |
||
19202 | duration: function(duration) { |
||
19203 | duration = duration || settings.duration; |
||
19204 | if(duration === false) { |
||
19205 | duration = $module.css('animation-duration') || 0; |
||
19206 | } |
||
19207 | return (typeof duration === 'string') |
||
19208 | ? (duration.indexOf('ms') > -1) |
||
19209 | ? parseFloat(duration) |
||
19210 | : parseFloat(duration) * 1000 |
||
19211 | : duration |
||
19212 | ; |
||
19213 | }, |
||
19214 | displayType: function(shouldDetermine) { |
||
19215 | shouldDetermine = (shouldDetermine !== undefined) |
||
19216 | ? shouldDetermine |
||
19217 | : true |
||
19218 | ; |
||
19219 | if(settings.displayType) { |
||
19220 | return settings.displayType; |
||
19221 | } |
||
19222 | if(shouldDetermine && $module.data(metadata.displayType) === undefined) { |
||
19223 | // create fake element to determine display state |
||
19224 | module.can.transition(true); |
||
19225 | } |
||
19226 | return $module.data(metadata.displayType); |
||
19227 | }, |
||
19228 | userStyle: function(style) { |
||
19229 | style = style || $module.attr('style') || ''; |
||
19230 | return style.replace(/display.*?;/, ''); |
||
19231 | }, |
||
19232 | transitionExists: function(animation) { |
||
19233 | return $.fn.transition.exists[animation]; |
||
19234 | }, |
||
19235 | animationStartEvent: function() { |
||
19236 | var |
||
19237 | element = document.createElement('div'), |
||
19238 | animations = { |
||
19239 | 'animation' :'animationstart', |
||
19240 | 'OAnimation' :'oAnimationStart', |
||
19241 | 'MozAnimation' :'mozAnimationStart', |
||
19242 | 'WebkitAnimation' :'webkitAnimationStart' |
||
19243 | }, |
||
19244 | animation |
||
19245 | ; |
||
19246 | for(animation in animations){ |
||
19247 | if( element.style[animation] !== undefined ){ |
||
19248 | return animations[animation]; |
||
19249 | } |
||
19250 | } |
||
19251 | return false; |
||
19252 | }, |
||
19253 | animationEndEvent: function() { |
||
19254 | var |
||
19255 | element = document.createElement('div'), |
||
19256 | animations = { |
||
19257 | 'animation' :'animationend', |
||
19258 | 'OAnimation' :'oAnimationEnd', |
||
19259 | 'MozAnimation' :'mozAnimationEnd', |
||
19260 | 'WebkitAnimation' :'webkitAnimationEnd' |
||
19261 | }, |
||
19262 | animation |
||
19263 | ; |
||
19264 | for(animation in animations){ |
||
19265 | if( element.style[animation] !== undefined ){ |
||
19266 | return animations[animation]; |
||
19267 | } |
||
19268 | } |
||
19269 | return false; |
||
19270 | } |
||
19271 | |||
19272 | }, |
||
19273 | |||
19274 | can: { |
||
19275 | transition: function(forced) { |
||
19276 | var |
||
19277 | animation = settings.animation, |
||
19278 | transitionExists = module.get.transitionExists(animation), |
||
19279 | displayType = module.get.displayType(false), |
||
19280 | elementClass, |
||
19281 | tagName, |
||
19282 | $clone, |
||
19283 | currentAnimation, |
||
19284 | inAnimation, |
||
19285 | directionExists |
||
19286 | ; |
||
19287 | if( transitionExists === undefined || forced) { |
||
19288 | module.verbose('Determining whether animation exists'); |
||
19289 | elementClass = $module.attr('class'); |
||
19290 | tagName = $module.prop('tagName'); |
||
19291 | |||
19292 | $clone = $('<' + tagName + ' />').addClass( elementClass ).insertAfter($module); |
||
19293 | currentAnimation = $clone |
||
19294 | .addClass(animation) |
||
19295 | .removeClass(className.inward) |
||
19296 | .removeClass(className.outward) |
||
19297 | .addClass(className.animating) |
||
19298 | .addClass(className.transition) |
||
19299 | .css('animationName') |
||
19300 | ; |
||
19301 | inAnimation = $clone |
||
19302 | .addClass(className.inward) |
||
19303 | .css('animationName') |
||
19304 | ; |
||
19305 | if(!displayType) { |
||
19306 | displayType = $clone |
||
19307 | .attr('class', elementClass) |
||
19308 | .removeAttr('style') |
||
19309 | .removeClass(className.hidden) |
||
19310 | .removeClass(className.visible) |
||
19311 | .show() |
||
19312 | .css('display') |
||
19313 | ; |
||
19314 | module.verbose('Determining final display state', displayType); |
||
19315 | module.save.displayType(displayType); |
||
19316 | } |
||
19317 | |||
19318 | $clone.remove(); |
||
19319 | if(currentAnimation != inAnimation) { |
||
19320 | module.debug('Direction exists for animation', animation); |
||
19321 | directionExists = true; |
||
19322 | } |
||
19323 | else if(currentAnimation == 'none' || !currentAnimation) { |
||
19324 | module.debug('No animation defined in css', animation); |
||
19325 | return; |
||
19326 | } |
||
19327 | else { |
||
19328 | module.debug('Static animation found', animation, displayType); |
||
19329 | directionExists = false; |
||
19330 | } |
||
19331 | module.save.transitionExists(animation, directionExists); |
||
19332 | } |
||
19333 | return (transitionExists !== undefined) |
||
19334 | ? transitionExists |
||
19335 | : directionExists |
||
19336 | ; |
||
19337 | }, |
||
19338 | animate: function() { |
||
19339 | // can transition does not return a value if animation does not exist |
||
19340 | return (module.can.transition() !== undefined); |
||
19341 | } |
||
19342 | }, |
||
19343 | |||
19344 | is: { |
||
19345 | animating: function() { |
||
19346 | return $module.hasClass(className.animating); |
||
19347 | }, |
||
19348 | inward: function() { |
||
19349 | return $module.hasClass(className.inward); |
||
19350 | }, |
||
19351 | outward: function() { |
||
19352 | return $module.hasClass(className.outward); |
||
19353 | }, |
||
19354 | looping: function() { |
||
19355 | return $module.hasClass(className.looping); |
||
19356 | }, |
||
19357 | occurring: function(animation) { |
||
19358 | animation = animation || settings.animation; |
||
19359 | animation = '.' + animation.replace(' ', '.'); |
||
19360 | return ( $module.filter(animation).length > 0 ); |
||
19361 | }, |
||
19362 | visible: function() { |
||
19363 | return $module.is(':visible'); |
||
19364 | }, |
||
19365 | hidden: function() { |
||
19366 | return $module.css('visibility') === 'hidden'; |
||
19367 | }, |
||
19368 | supported: function() { |
||
19369 | return(animationEnd !== false); |
||
19370 | } |
||
19371 | }, |
||
19372 | |||
19373 | hide: function() { |
||
19374 | module.verbose('Hiding element'); |
||
19375 | if( module.is.animating() ) { |
||
19376 | module.reset(); |
||
19377 | } |
||
19378 | element.blur(); // IE will trigger focus change if element is not blurred before hiding |
||
19379 | module.remove.display(); |
||
19380 | module.remove.visible(); |
||
19381 | module.set.hidden(); |
||
19382 | module.force.hidden(); |
||
19383 | settings.onHide.call(element); |
||
19384 | settings.onComplete.call(element); |
||
19385 | // module.repaint(); |
||
19386 | }, |
||
19387 | |||
19388 | show: function(display) { |
||
19389 | module.verbose('Showing element', display); |
||
19390 | module.remove.hidden(); |
||
19391 | module.set.visible(); |
||
19392 | module.force.visible(); |
||
19393 | settings.onShow.call(element); |
||
19394 | settings.onComplete.call(element); |
||
19395 | // module.repaint(); |
||
19396 | }, |
||
19397 | |||
19398 | toggle: function() { |
||
19399 | if( module.is.visible() ) { |
||
19400 | module.hide(); |
||
19401 | } |
||
19402 | else { |
||
19403 | module.show(); |
||
19404 | } |
||
19405 | }, |
||
19406 | |||
19407 | stop: function() { |
||
19408 | module.debug('Stopping current animation'); |
||
19409 | $module.triggerHandler(animationEnd); |
||
19410 | }, |
||
19411 | |||
19412 | stopAll: function() { |
||
19413 | module.debug('Stopping all animation'); |
||
19414 | module.remove.queueCallback(); |
||
19415 | $module.triggerHandler(animationEnd); |
||
19416 | }, |
||
19417 | |||
19418 | clear: { |
||
19419 | queue: function() { |
||
19420 | module.debug('Clearing animation queue'); |
||
19421 | module.remove.queueCallback(); |
||
19422 | } |
||
19423 | }, |
||
19424 | |||
19425 | enable: function() { |
||
19426 | module.verbose('Starting animation'); |
||
19427 | $module.removeClass(className.disabled); |
||
19428 | }, |
||
19429 | |||
19430 | disable: function() { |
||
19431 | module.debug('Stopping animation'); |
||
19432 | $module.addClass(className.disabled); |
||
19433 | }, |
||
19434 | |||
19435 | setting: function(name, value) { |
||
19436 | module.debug('Changing setting', name, value); |
||
19437 | if( $.isPlainObject(name) ) { |
||
19438 | $.extend(true, settings, name); |
||
19439 | } |
||
19440 | else if(value !== undefined) { |
||
19441 | if($.isPlainObject(settings[name])) { |
||
19442 | $.extend(true, settings[name], value); |
||
19443 | } |
||
19444 | else { |
||
19445 | settings[name] = value; |
||
19446 | } |
||
19447 | } |
||
19448 | else { |
||
19449 | return settings[name]; |
||
19450 | } |
||
19451 | }, |
||
19452 | internal: function(name, value) { |
||
19453 | if( $.isPlainObject(name) ) { |
||
19454 | $.extend(true, module, name); |
||
19455 | } |
||
19456 | else if(value !== undefined) { |
||
19457 | module[name] = value; |
||
19458 | } |
||
19459 | else { |
||
19460 | return module[name]; |
||
19461 | } |
||
19462 | }, |
||
19463 | debug: function() { |
||
19464 | if(!settings.silent && settings.debug) { |
||
19465 | if(settings.performance) { |
||
19466 | module.performance.log(arguments); |
||
19467 | } |
||
19468 | else { |
||
19469 | module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':'); |
||
19470 | module.debug.apply(console, arguments); |
||
19471 | } |
||
19472 | } |
||
19473 | }, |
||
19474 | verbose: function() { |
||
19475 | if(!settings.silent && settings.verbose && settings.debug) { |
||
19476 | if(settings.performance) { |
||
19477 | module.performance.log(arguments); |
||
19478 | } |
||
19479 | else { |
||
19480 | module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':'); |
||
19481 | module.verbose.apply(console, arguments); |
||
19482 | } |
||
19483 | } |
||
19484 | }, |
||
19485 | error: function() { |
||
19486 | if(!settings.silent) { |
||
19487 | module.error = Function.prototype.bind.call(console.error, console, settings.name + ':'); |
||
19488 | module.error.apply(console, arguments); |
||
19489 | } |
||
19490 | }, |
||
19491 | performance: { |
||
19492 | log: function(message) { |
||
19493 | var |
||
19494 | currentTime, |
||
19495 | executionTime, |
||
19496 | previousTime |
||
19497 | ; |
||
19498 | if(settings.performance) { |
||
19499 | currentTime = new Date().getTime(); |
||
19500 | previousTime = time || currentTime; |
||
19501 | executionTime = currentTime - previousTime; |
||
19502 | time = currentTime; |
||
19503 | performance.push({ |
||
19504 | 'Name' : message[0], |
||
19505 | 'Arguments' : [].slice.call(message, 1) || '', |
||
19506 | 'Element' : element, |
||
19507 | 'Execution Time' : executionTime |
||
19508 | }); |
||
19509 | } |
||
19510 | clearTimeout(module.performance.timer); |
||
19511 | module.performance.timer = setTimeout(module.performance.display, 500); |
||
19512 | }, |
||
19513 | display: function() { |
||
19514 | var |
||
19515 | title = settings.name + ':', |
||
19516 | totalTime = 0 |
||
19517 | ; |
||
19518 | time = false; |
||
19519 | clearTimeout(module.performance.timer); |
||
19520 | $.each(performance, function(index, data) { |
||
19521 | totalTime += data['Execution Time']; |
||
19522 | }); |
||
19523 | title += ' ' + totalTime + 'ms'; |
||
19524 | if(moduleSelector) { |
||
19525 | title += ' \'' + moduleSelector + '\''; |
||
19526 | } |
||
19527 | if($allModules.length > 1) { |
||
19528 | title += ' ' + '(' + $allModules.length + ')'; |
||
19529 | } |
||
19530 | if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) { |
||
19531 | console.groupCollapsed(title); |
||
19532 | if(console.table) { |
||
19533 | console.table(performance); |
||
19534 | } |
||
19535 | else { |
||
19536 | $.each(performance, function(index, data) { |
||
19537 | console.log(data['Name'] + ': ' + data['Execution Time']+'ms'); |
||
19538 | }); |
||
19539 | } |
||
19540 | console.groupEnd(); |
||
19541 | } |
||
19542 | performance = []; |
||
19543 | } |
||
19544 | }, |
||
19545 | // modified for transition to return invoke success |
||
19546 | invoke: function(query, passedArguments, context) { |
||
19547 | var |
||
19548 | object = instance, |
||
19549 | maxDepth, |
||
19550 | found, |
||
19551 | response |
||
19552 | ; |
||
19553 | passedArguments = passedArguments || queryArguments; |
||
19554 | context = element || context; |
||
19555 | if(typeof query == 'string' && object !== undefined) { |
||
19556 | query = query.split(/[\. ]/); |
||
19557 | maxDepth = query.length - 1; |
||
19558 | $.each(query, function(depth, value) { |
||
19559 | var camelCaseValue = (depth != maxDepth) |
||
19560 | ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1) |
||
19561 | : query |
||
19562 | ; |
||
19563 | if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) { |
||
19564 | object = object[camelCaseValue]; |
||
19565 | } |
||
19566 | else if( object[camelCaseValue] !== undefined ) { |
||
19567 | found = object[camelCaseValue]; |
||
19568 | return false; |
||
19569 | } |
||
19570 | else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) { |
||
19571 | object = object[value]; |
||
19572 | } |
||
19573 | else if( object[value] !== undefined ) { |
||
19574 | found = object[value]; |
||
19575 | return false; |
||
19576 | } |
||
19577 | else { |
||
19578 | return false; |
||
19579 | } |
||
19580 | }); |
||
19581 | } |
||
19582 | if ( $.isFunction( found ) ) { |
||
19583 | response = found.apply(context, passedArguments); |
||
19584 | } |
||
19585 | else if(found !== undefined) { |
||
19586 | response = found; |
||
19587 | } |
||
19588 | |||
19589 | if($.isArray(returnedValue)) { |
||
19590 | returnedValue.push(response); |
||
19591 | } |
||
19592 | else if(returnedValue !== undefined) { |
||
19593 | returnedValue = [returnedValue, response]; |
||
19594 | } |
||
19595 | else if(response !== undefined) { |
||
19596 | returnedValue = response; |
||
19597 | } |
||
19598 | return (found !== undefined) |
||
19599 | ? found |
||
19600 | : false |
||
19601 | ; |
||
19602 | } |
||
19603 | }; |
||
19604 | module.initialize(); |
||
19605 | }) |
||
19606 | ; |
||
19607 | return (returnedValue !== undefined) |
||
19608 | ? returnedValue |
||
19609 | : this |
||
19610 | ; |
||
19611 | }; |
||
19612 | |||
19613 | // Records if CSS transition is available |
||
19614 | $.fn.transition.exists = {}; |
||
19615 | |||
19616 | $.fn.transition.settings = { |
||
19617 | |||
19618 | // module info |
||
19619 | name : 'Transition', |
||
19620 | |||
19621 | // hide all output from this component regardless of other settings |
||
19622 | silent : false, |
||
19623 | |||
19624 | // debug content outputted to console |
||
19625 | debug : false, |
||
19626 | |||
19627 | // verbose debug output |
||
19628 | verbose : false, |
||
19629 | |||
19630 | // performance data output |
||
19631 | performance : true, |
||
19632 | |||
19633 | // event namespace |
||
19634 | namespace : 'transition', |
||
19635 | |||
19636 | // delay between animations in group |
||
19637 | interval : 0, |
||
19638 | |||
19639 | // whether group animations should be reversed |
||
19640 | reverse : 'auto', |
||
19641 | |||
19642 | // animation callback event |
||
19643 | onStart : function() {}, |
||
19644 | onComplete : function() {}, |
||
19645 | onShow : function() {}, |
||
19646 | onHide : function() {}, |
||
19647 | |||
19648 | // whether timeout should be used to ensure callback fires in cases animationend does not |
||
19649 | useFailSafe : true, |
||
19650 | |||
19651 | // delay in ms for fail safe |
||
19652 | failSafeDelay : 100, |
||
19653 | |||
19654 | // whether EXACT animation can occur twice in a row |
||
19655 | allowRepeats : false, |
||
19656 | |||
19657 | // Override final display type on visible |
||
19658 | displayType : false, |
||
19659 | |||
19660 | // animation duration |
||
19661 | animation : 'fade', |
||
19662 | duration : false, |
||
19663 | |||
19664 | // new animations will occur after previous ones |
||
19665 | queue : true, |
||
19666 | |||
19667 | metadata : { |
||
19668 | displayType: 'display' |
||
19669 | }, |
||
19670 | |||
19671 | className : { |
||
19672 | animating : 'animating', |
||
19673 | disabled : 'disabled', |
||
19674 | hidden : 'hidden', |
||
19675 | inward : 'in', |
||
19676 | loading : 'loading', |
||
19677 | looping : 'looping', |
||
19678 | outward : 'out', |
||
19679 | transition : 'transition', |
||
19680 | visible : 'visible' |
||
19681 | }, |
||
19682 | |||
19683 | // possible errors |
||
19684 | error: { |
||
19685 | noAnimation : 'Element is no longer attached to DOM. Unable to animate. Use silent setting to surpress this warning in production.', |
||
19686 | repeated : 'That animation is already occurring, cancelling repeated animation', |
||
19687 | method : 'The method you called is not defined', |
||
19688 | support : 'This browser does not support CSS animations' |
||
19689 | } |
||
19690 | |||
19691 | }; |
||
19692 | |||
19693 | |||
19694 | })( jQuery, window, document ); |
||
19695 | |||
19696 | /*! |
||
19697 | * # Semantic UI 2.2.11 - API |
||
19698 | * http://github.com/semantic-org/semantic-ui/ |
||
19699 | * |
||
19700 | * |
||
19701 | * Released under the MIT license |
||
19702 | * http://opensource.org/licenses/MIT |
||
19703 | * |
||
19704 | */ |
||
19705 | |||
19706 | View Code Duplication | ;(function ($, window, document, undefined) { |
|
19707 | |||
19708 | "use strict"; |
||
19709 | |||
19710 | var |
||
19711 | window = (typeof window != 'undefined' && window.Math == Math) |
||
19712 | ? window |
||
19713 | : (typeof self != 'undefined' && self.Math == Math) |
||
19714 | ? self |
||
19715 | : Function('return this')() |
||
19716 | ; |
||
19717 | |||
19718 | $.api = $.fn.api = function(parameters) { |
||
19719 | |||
19720 | var |
||
19721 | // use window context if none specified |
||
19722 | $allModules = $.isFunction(this) |
||
19723 | ? $(window) |
||
19724 | : $(this), |
||
19725 | moduleSelector = $allModules.selector || '', |
||
19726 | time = new Date().getTime(), |
||
19727 | performance = [], |
||
19728 | |||
19729 | query = arguments[0], |
||
19730 | methodInvoked = (typeof query == 'string'), |
||
19731 | queryArguments = [].slice.call(arguments, 1), |
||
19732 | |||
19733 | returnedValue |
||
19734 | ; |
||
19735 | |||
19736 | $allModules |
||
19737 | .each(function() { |
||
19738 | var |
||
19739 | settings = ( $.isPlainObject(parameters) ) |
||
19740 | ? $.extend(true, {}, $.fn.api.settings, parameters) |
||
19741 | : $.extend({}, $.fn.api.settings), |
||
19742 | |||
19743 | // internal aliases |
||
19744 | namespace = settings.namespace, |
||
19745 | metadata = settings.metadata, |
||
19746 | selector = settings.selector, |
||
19747 | error = settings.error, |
||
19748 | className = settings.className, |
||
19749 | |||
19750 | // define namespaces for modules |
||
19751 | eventNamespace = '.' + namespace, |
||
19752 | moduleNamespace = 'module-' + namespace, |
||
19753 | |||
19754 | // element that creates request |
||
19755 | $module = $(this), |
||
19756 | $form = $module.closest(selector.form), |
||
19757 | |||
19758 | // context used for state |
||
19759 | $context = (settings.stateContext) |
||
19760 | ? $(settings.stateContext) |
||
19761 | : $module, |
||
19762 | |||
19763 | // request details |
||
19764 | ajaxSettings, |
||
19765 | requestSettings, |
||
19766 | url, |
||
19767 | data, |
||
19768 | requestStartTime, |
||
19769 | |||
19770 | // standard module |
||
19771 | element = this, |
||
19772 | context = $context[0], |
||
19773 | instance = $module.data(moduleNamespace), |
||
19774 | module |
||
19775 | ; |
||
19776 | |||
19777 | module = { |
||
19778 | |||
19779 | initialize: function() { |
||
19780 | if(!methodInvoked) { |
||
19781 | module.bind.events(); |
||
19782 | } |
||
19783 | module.instantiate(); |
||
19784 | }, |
||
19785 | |||
19786 | instantiate: function() { |
||
19787 | module.verbose('Storing instance of module', module); |
||
19788 | instance = module; |
||
19789 | $module |
||
19790 | .data(moduleNamespace, instance) |
||
19791 | ; |
||
19792 | }, |
||
19793 | |||
19794 | destroy: function() { |
||
19795 | module.verbose('Destroying previous module for', element); |
||
19796 | $module |
||
19797 | .removeData(moduleNamespace) |
||
19798 | .off(eventNamespace) |
||
19799 | ; |
||
19800 | }, |
||
19801 | |||
19802 | bind: { |
||
19803 | events: function() { |
||
19804 | var |
||
19805 | triggerEvent = module.get.event() |
||
19806 | ; |
||
19807 | if( triggerEvent ) { |
||
19808 | module.verbose('Attaching API events to element', triggerEvent); |
||
19809 | $module |
||
19810 | .on(triggerEvent + eventNamespace, module.event.trigger) |
||
19811 | ; |
||
19812 | } |
||
19813 | else if(settings.on == 'now') { |
||
19814 | module.debug('Querying API endpoint immediately'); |
||
19815 | module.query(); |
||
19816 | } |
||
19817 | } |
||
19818 | }, |
||
19819 | |||
19820 | decode: { |
||
19821 | json: function(response) { |
||
19822 | if(response !== undefined && typeof response == 'string') { |
||
19823 | try { |
||
19824 | response = JSON.parse(response); |
||
19825 | } |
||
19826 | catch(e) { |
||
19827 | // isnt json string |
||
19828 | } |
||
19829 | } |
||
19830 | return response; |
||
19831 | } |
||
19832 | }, |
||
19833 | |||
19834 | read: { |
||
19835 | cachedResponse: function(url) { |
||
19836 | var |
||
19837 | response |
||
19838 | ; |
||
19839 | if(window.Storage === undefined) { |
||
19840 | module.error(error.noStorage); |
||
19841 | return; |
||
19842 | } |
||
19843 | response = sessionStorage.getItem(url); |
||
19844 | module.debug('Using cached response', url, response); |
||
19845 | response = module.decode.json(response); |
||
19846 | return response; |
||
19847 | } |
||
19848 | }, |
||
19849 | write: { |
||
19850 | cachedResponse: function(url, response) { |
||
19851 | if(response && response === '') { |
||
19852 | module.debug('Response empty, not caching', response); |
||
19853 | return; |
||
19854 | } |
||
19855 | if(window.Storage === undefined) { |
||
19856 | module.error(error.noStorage); |
||
19857 | return; |
||
19858 | } |
||
19859 | if( $.isPlainObject(response) ) { |
||
19860 | response = JSON.stringify(response); |
||
19861 | } |
||
19862 | sessionStorage.setItem(url, response); |
||
19863 | module.verbose('Storing cached response for url', url, response); |
||
19864 | } |
||
19865 | }, |
||
19866 | |||
19867 | query: function() { |
||
19868 | |||
19869 | if(module.is.disabled()) { |
||
19870 | module.debug('Element is disabled API request aborted'); |
||
19871 | return; |
||
19872 | } |
||
19873 | |||
19874 | if(module.is.loading()) { |
||
19875 | if(settings.interruptRequests) { |
||
19876 | module.debug('Interrupting previous request'); |
||
19877 | module.abort(); |
||
19878 | } |
||
19879 | else { |
||
19880 | module.debug('Cancelling request, previous request is still pending'); |
||
19881 | return; |
||
19882 | } |
||
19883 | } |
||
19884 | |||
19885 | // pass element metadata to url (value, text) |
||
19886 | if(settings.defaultData) { |
||
19887 | $.extend(true, settings.urlData, module.get.defaultData()); |
||
19888 | } |
||
19889 | |||
19890 | // Add form content |
||
19891 | if(settings.serializeForm) { |
||
19892 | settings.data = module.add.formData(settings.data); |
||
19893 | } |
||
19894 | |||
19895 | // call beforesend and get any settings changes |
||
19896 | requestSettings = module.get.settings(); |
||
19897 | |||
19898 | // check if before send cancelled request |
||
19899 | if(requestSettings === false) { |
||
19900 | module.cancelled = true; |
||
19901 | module.error(error.beforeSend); |
||
19902 | return; |
||
19903 | } |
||
19904 | else { |
||
19905 | module.cancelled = false; |
||
19906 | } |
||
19907 | |||
19908 | // get url |
||
19909 | url = module.get.templatedURL(); |
||
19910 | |||
19911 | if(!url && !module.is.mocked()) { |
||
19912 | module.error(error.missingURL); |
||
19913 | return; |
||
19914 | } |
||
19915 | |||
19916 | // replace variables |
||
19917 | url = module.add.urlData( url ); |
||
19918 | // missing url parameters |
||
19919 | if( !url && !module.is.mocked()) { |
||
19920 | return; |
||
19921 | } |
||
19922 | |||
19923 | requestSettings.url = settings.base + url; |
||
19924 | |||
19925 | // look for jQuery ajax parameters in settings |
||
19926 | ajaxSettings = $.extend(true, {}, settings, { |
||
19927 | type : settings.method || settings.type, |
||
19928 | data : data, |
||
19929 | url : settings.base + url, |
||
19930 | beforeSend : settings.beforeXHR, |
||
19931 | success : function() {}, |
||
19932 | failure : function() {}, |
||
19933 | complete : function() {} |
||
19934 | }); |
||
19935 | |||
19936 | module.debug('Querying URL', ajaxSettings.url); |
||
19937 | module.verbose('Using AJAX settings', ajaxSettings); |
||
19938 | if(settings.cache === 'local' && module.read.cachedResponse(url)) { |
||
19939 | module.debug('Response returned from local cache'); |
||
19940 | module.request = module.create.request(); |
||
19941 | module.request.resolveWith(context, [ module.read.cachedResponse(url) ]); |
||
19942 | return; |
||
19943 | } |
||
19944 | |||
19945 | if( !settings.throttle ) { |
||
19946 | module.debug('Sending request', data, ajaxSettings.method); |
||
19947 | module.send.request(); |
||
19948 | } |
||
19949 | else { |
||
19950 | if(!settings.throttleFirstRequest && !module.timer) { |
||
19951 | module.debug('Sending request', data, ajaxSettings.method); |
||
19952 | module.send.request(); |
||
19953 | module.timer = setTimeout(function(){}, settings.throttle); |
||
19954 | } |
||
19955 | else { |
||
19956 | module.debug('Throttling request', settings.throttle); |
||
19957 | clearTimeout(module.timer); |
||
19958 | module.timer = setTimeout(function() { |
||
19959 | if(module.timer) { |
||
19960 | delete module.timer; |
||
19961 | } |
||
19962 | module.debug('Sending throttled request', data, ajaxSettings.method); |
||
19963 | module.send.request(); |
||
19964 | }, settings.throttle); |
||
19965 | } |
||
19966 | } |
||
19967 | |||
19968 | }, |
||
19969 | |||
19970 | should: { |
||
19971 | removeError: function() { |
||
19972 | return ( settings.hideError === true || (settings.hideError === 'auto' && !module.is.form()) ); |
||
19973 | } |
||
19974 | }, |
||
19975 | |||
19976 | is: { |
||
19977 | disabled: function() { |
||
19978 | return ($module.filter(selector.disabled).length > 0); |
||
19979 | }, |
||
19980 | expectingJSON: function() { |
||
19981 | return settings.dataType === 'json' || settings.dataType === 'jsonp'; |
||
19982 | }, |
||
19983 | form: function() { |
||
19984 | return $module.is('form') || $context.is('form'); |
||
19985 | }, |
||
19986 | mocked: function() { |
||
19987 | return (settings.mockResponse || settings.mockResponseAsync || settings.response || settings.responseAsync); |
||
19988 | }, |
||
19989 | input: function() { |
||
19990 | return $module.is('input'); |
||
19991 | }, |
||
19992 | loading: function() { |
||
19993 | return (module.request) |
||
19994 | ? (module.request.state() == 'pending') |
||
19995 | : false |
||
19996 | ; |
||
19997 | }, |
||
19998 | abortedRequest: function(xhr) { |
||
19999 | if(xhr && xhr.readyState !== undefined && xhr.readyState === 0) { |
||
20000 | module.verbose('XHR request determined to be aborted'); |
||
20001 | return true; |
||
20002 | } |
||
20003 | else { |
||
20004 | module.verbose('XHR request was not aborted'); |
||
20005 | return false; |
||
20006 | } |
||
20007 | }, |
||
20008 | validResponse: function(response) { |
||
20009 | if( (!module.is.expectingJSON()) || !$.isFunction(settings.successTest) ) { |
||
20010 | module.verbose('Response is not JSON, skipping validation', settings.successTest, response); |
||
20011 | return true; |
||
20012 | } |
||
20013 | module.debug('Checking JSON returned success', settings.successTest, response); |
||
20014 | if( settings.successTest(response) ) { |
||
20015 | module.debug('Response passed success test', response); |
||
20016 | return true; |
||
20017 | } |
||
20018 | else { |
||
20019 | module.debug('Response failed success test', response); |
||
20020 | return false; |
||
20021 | } |
||
20022 | } |
||
20023 | }, |
||
20024 | |||
20025 | was: { |
||
20026 | cancelled: function() { |
||
20027 | return (module.cancelled || false); |
||
20028 | }, |
||
20029 | succesful: function() { |
||
20030 | return (module.request && module.request.state() == 'resolved'); |
||
20031 | }, |
||
20032 | failure: function() { |
||
20033 | return (module.request && module.request.state() == 'rejected'); |
||
20034 | }, |
||
20035 | complete: function() { |
||
20036 | return (module.request && (module.request.state() == 'resolved' || module.request.state() == 'rejected') ); |
||
20037 | } |
||
20038 | }, |
||
20039 | |||
20040 | add: { |
||
20041 | urlData: function(url, urlData) { |
||
20042 | var |
||
20043 | requiredVariables, |
||
20044 | optionalVariables |
||
20045 | ; |
||
20046 | if(url) { |
||
20047 | requiredVariables = url.match(settings.regExp.required); |
||
20048 | optionalVariables = url.match(settings.regExp.optional); |
||
20049 | urlData = urlData || settings.urlData; |
||
20050 | if(requiredVariables) { |
||
20051 | module.debug('Looking for required URL variables', requiredVariables); |
||
20052 | $.each(requiredVariables, function(index, templatedString) { |
||
20053 | var |
||
20054 | // allow legacy {$var} style |
||
20055 | variable = (templatedString.indexOf('$') !== -1) |
||
20056 | ? templatedString.substr(2, templatedString.length - 3) |
||
20057 | : templatedString.substr(1, templatedString.length - 2), |
||
20058 | value = ($.isPlainObject(urlData) && urlData[variable] !== undefined) |
||
20059 | ? urlData[variable] |
||
20060 | : ($module.data(variable) !== undefined) |
||
20061 | ? $module.data(variable) |
||
20062 | : ($context.data(variable) !== undefined) |
||
20063 | ? $context.data(variable) |
||
20064 | : urlData[variable] |
||
20065 | ; |
||
20066 | // remove value |
||
20067 | if(value === undefined) { |
||
20068 | module.error(error.requiredParameter, variable, url); |
||
20069 | url = false; |
||
20070 | return false; |
||
20071 | } |
||
20072 | else { |
||
20073 | module.verbose('Found required variable', variable, value); |
||
20074 | value = (settings.encodeParameters) |
||
20075 | ? module.get.urlEncodedValue(value) |
||
20076 | : value |
||
20077 | ; |
||
20078 | url = url.replace(templatedString, value); |
||
20079 | } |
||
20080 | }); |
||
20081 | } |
||
20082 | if(optionalVariables) { |
||
20083 | module.debug('Looking for optional URL variables', requiredVariables); |
||
20084 | $.each(optionalVariables, function(index, templatedString) { |
||
20085 | var |
||
20086 | // allow legacy {/$var} style |
||
20087 | variable = (templatedString.indexOf('$') !== -1) |
||
20088 | ? templatedString.substr(3, templatedString.length - 4) |
||
20089 | : templatedString.substr(2, templatedString.length - 3), |
||
20090 | value = ($.isPlainObject(urlData) && urlData[variable] !== undefined) |
||
20091 | ? urlData[variable] |
||
20092 | : ($module.data(variable) !== undefined) |
||
20093 | ? $module.data(variable) |
||
20094 | : ($context.data(variable) !== undefined) |
||
20095 | ? $context.data(variable) |
||
20096 | : urlData[variable] |
||
20097 | ; |
||
20098 | // optional replacement |
||
20099 | if(value !== undefined) { |
||
20100 | module.verbose('Optional variable Found', variable, value); |
||
20101 | url = url.replace(templatedString, value); |
||
20102 | } |
||
20103 | else { |
||
20104 | module.verbose('Optional variable not found', variable); |
||
20105 | // remove preceding slash if set |
||
20106 | if(url.indexOf('/' + templatedString) !== -1) { |
||
20107 | url = url.replace('/' + templatedString, ''); |
||
20108 | } |
||
20109 | else { |
||
20110 | url = url.replace(templatedString, ''); |
||
20111 | } |
||
20112 | } |
||
20113 | }); |
||
20114 | } |
||
20115 | } |
||
20116 | return url; |
||
20117 | }, |
||
20118 | formData: function(data) { |
||
20119 | var |
||
20120 | canSerialize = ($.fn.serializeObject !== undefined), |
||
20121 | formData = (canSerialize) |
||
20122 | ? $form.serializeObject() |
||
20123 | : $form.serialize(), |
||
20124 | hasOtherData |
||
20125 | ; |
||
20126 | data = data || settings.data; |
||
20127 | hasOtherData = $.isPlainObject(data); |
||
20128 | |||
20129 | if(hasOtherData) { |
||
20130 | if(canSerialize) { |
||
20131 | module.debug('Extending existing data with form data', data, formData); |
||
20132 | data = $.extend(true, {}, data, formData); |
||
20133 | } |
||
20134 | else { |
||
20135 | module.error(error.missingSerialize); |
||
20136 | module.debug('Cant extend data. Replacing data with form data', data, formData); |
||
20137 | data = formData; |
||
20138 | } |
||
20139 | } |
||
20140 | else { |
||
20141 | module.debug('Adding form data', formData); |
||
20142 | data = formData; |
||
20143 | } |
||
20144 | return data; |
||
20145 | } |
||
20146 | }, |
||
20147 | |||
20148 | send: { |
||
20149 | request: function() { |
||
20150 | module.set.loading(); |
||
20151 | module.request = module.create.request(); |
||
20152 | if( module.is.mocked() ) { |
||
20153 | module.mockedXHR = module.create.mockedXHR(); |
||
20154 | } |
||
20155 | else { |
||
20156 | module.xhr = module.create.xhr(); |
||
20157 | } |
||
20158 | settings.onRequest.call(context, module.request, module.xhr); |
||
20159 | } |
||
20160 | }, |
||
20161 | |||
20162 | event: { |
||
20163 | trigger: function(event) { |
||
20164 | module.query(); |
||
20165 | if(event.type == 'submit' || event.type == 'click') { |
||
20166 | event.preventDefault(); |
||
20167 | } |
||
20168 | }, |
||
20169 | xhr: { |
||
20170 | always: function() { |
||
20171 | // nothing special |
||
20172 | }, |
||
20173 | done: function(response, textStatus, xhr) { |
||
20174 | var |
||
20175 | context = this, |
||
20176 | elapsedTime = (new Date().getTime() - requestStartTime), |
||
20177 | timeLeft = (settings.loadingDuration - elapsedTime), |
||
20178 | translatedResponse = ( $.isFunction(settings.onResponse) ) |
||
20179 | ? module.is.expectingJSON() |
||
20180 | ? settings.onResponse.call(context, $.extend(true, {}, response)) |
||
20181 | : settings.onResponse.call(context, response) |
||
20182 | : false |
||
20183 | ; |
||
20184 | timeLeft = (timeLeft > 0) |
||
20185 | ? timeLeft |
||
20186 | : 0 |
||
20187 | ; |
||
20188 | if(translatedResponse) { |
||
20189 | module.debug('Modified API response in onResponse callback', settings.onResponse, translatedResponse, response); |
||
20190 | response = translatedResponse; |
||
20191 | } |
||
20192 | if(timeLeft > 0) { |
||
20193 | module.debug('Response completed early delaying state change by', timeLeft); |
||
20194 | } |
||
20195 | setTimeout(function() { |
||
20196 | if( module.is.validResponse(response) ) { |
||
20197 | module.request.resolveWith(context, [response, xhr]); |
||
20198 | } |
||
20199 | else { |
||
20200 | module.request.rejectWith(context, [xhr, 'invalid']); |
||
20201 | } |
||
20202 | }, timeLeft); |
||
20203 | }, |
||
20204 | fail: function(xhr, status, httpMessage) { |
||
20205 | var |
||
20206 | context = this, |
||
20207 | elapsedTime = (new Date().getTime() - requestStartTime), |
||
20208 | timeLeft = (settings.loadingDuration - elapsedTime) |
||
20209 | ; |
||
20210 | timeLeft = (timeLeft > 0) |
||
20211 | ? timeLeft |
||
20212 | : 0 |
||
20213 | ; |
||
20214 | if(timeLeft > 0) { |
||
20215 | module.debug('Response completed early delaying state change by', timeLeft); |
||
20216 | } |
||
20217 | setTimeout(function() { |
||
20218 | if( module.is.abortedRequest(xhr) ) { |
||
20219 | module.request.rejectWith(context, [xhr, 'aborted', httpMessage]); |
||
20220 | } |
||
20221 | else { |
||
20222 | module.request.rejectWith(context, [xhr, 'error', status, httpMessage]); |
||
20223 | } |
||
20224 | }, timeLeft); |
||
20225 | } |
||
20226 | }, |
||
20227 | request: { |
||
20228 | done: function(response, xhr) { |
||
20229 | module.debug('Successful API Response', response); |
||
20230 | if(settings.cache === 'local' && url) { |
||
20231 | module.write.cachedResponse(url, response); |
||
20232 | module.debug('Saving server response locally', module.cache); |
||
20233 | } |
||
20234 | settings.onSuccess.call(context, response, $module, xhr); |
||
20235 | }, |
||
20236 | complete: function(firstParameter, secondParameter) { |
||
20237 | var |
||
20238 | xhr, |
||
20239 | response |
||
20240 | ; |
||
20241 | // have to guess callback parameters based on request success |
||
20242 | if( module.was.succesful() ) { |
||
20243 | response = firstParameter; |
||
20244 | xhr = secondParameter; |
||
20245 | } |
||
20246 | else { |
||
20247 | xhr = firstParameter; |
||
20248 | response = module.get.responseFromXHR(xhr); |
||
20249 | } |
||
20250 | module.remove.loading(); |
||
20251 | settings.onComplete.call(context, response, $module, xhr); |
||
20252 | }, |
||
20253 | fail: function(xhr, status, httpMessage) { |
||
20254 | var |
||
20255 | // pull response from xhr if available |
||
20256 | response = module.get.responseFromXHR(xhr), |
||
20257 | errorMessage = module.get.errorFromRequest(response, status, httpMessage) |
||
20258 | ; |
||
20259 | if(status == 'aborted') { |
||
20260 | module.debug('XHR Aborted (Most likely caused by page navigation or CORS Policy)', status, httpMessage); |
||
20261 | settings.onAbort.call(context, status, $module, xhr); |
||
20262 | return true; |
||
20263 | } |
||
20264 | else if(status == 'invalid') { |
||
20265 | module.debug('JSON did not pass success test. A server-side error has most likely occurred', response); |
||
20266 | } |
||
20267 | else if(status == 'error') { |
||
20268 | if(xhr !== undefined) { |
||
20269 | module.debug('XHR produced a server error', status, httpMessage); |
||
20270 | // make sure we have an error to display to console |
||
20271 | if( xhr.status != 200 && httpMessage !== undefined && httpMessage !== '') { |
||
20272 | module.error(error.statusMessage + httpMessage, ajaxSettings.url); |
||
20273 | } |
||
20274 | settings.onError.call(context, errorMessage, $module, xhr); |
||
20275 | } |
||
20276 | } |
||
20277 | |||
20278 | if(settings.errorDuration && status !== 'aborted') { |
||
20279 | module.debug('Adding error state'); |
||
20280 | module.set.error(); |
||
20281 | if( module.should.removeError() ) { |
||
20282 | setTimeout(module.remove.error, settings.errorDuration); |
||
20283 | } |
||
20284 | } |
||
20285 | module.debug('API Request failed', errorMessage, xhr); |
||
20286 | settings.onFailure.call(context, response, $module, xhr); |
||
20287 | } |
||
20288 | } |
||
20289 | }, |
||
20290 | |||
20291 | create: { |
||
20292 | |||
20293 | request: function() { |
||
20294 | // api request promise |
||
20295 | return $.Deferred() |
||
20296 | .always(module.event.request.complete) |
||
20297 | .done(module.event.request.done) |
||
20298 | .fail(module.event.request.fail) |
||
20299 | ; |
||
20300 | }, |
||
20301 | |||
20302 | mockedXHR: function () { |
||
20303 | var |
||
20304 | // xhr does not simulate these properties of xhr but must return them |
||
20305 | textStatus = false, |
||
20306 | status = false, |
||
20307 | httpMessage = false, |
||
20308 | responder = settings.mockResponse || settings.response, |
||
20309 | asyncResponder = settings.mockResponseAsync || settings.responseAsync, |
||
20310 | asyncCallback, |
||
20311 | response, |
||
20312 | mockedXHR |
||
20313 | ; |
||
20314 | |||
20315 | mockedXHR = $.Deferred() |
||
20316 | .always(module.event.xhr.complete) |
||
20317 | .done(module.event.xhr.done) |
||
20318 | .fail(module.event.xhr.fail) |
||
20319 | ; |
||
20320 | |||
20321 | if(responder) { |
||
20322 | if( $.isFunction(responder) ) { |
||
20323 | module.debug('Using specified synchronous callback', responder); |
||
20324 | response = responder.call(context, requestSettings); |
||
20325 | } |
||
20326 | else { |
||
20327 | module.debug('Using settings specified response', responder); |
||
20328 | response = responder; |
||
20329 | } |
||
20330 | // simulating response |
||
20331 | mockedXHR.resolveWith(context, [ response, textStatus, { responseText: response }]); |
||
20332 | } |
||
20333 | else if( $.isFunction(asyncResponder) ) { |
||
20334 | asyncCallback = function(response) { |
||
20335 | module.debug('Async callback returned response', response); |
||
20336 | |||
20337 | if(response) { |
||
20338 | mockedXHR.resolveWith(context, [ response, textStatus, { responseText: response }]); |
||
20339 | } |
||
20340 | else { |
||
20341 | mockedXHR.rejectWith(context, [{ responseText: response }, status, httpMessage]); |
||
20342 | } |
||
20343 | }; |
||
20344 | module.debug('Using specified async response callback', asyncResponder); |
||
20345 | asyncResponder.call(context, requestSettings, asyncCallback); |
||
20346 | } |
||
20347 | return mockedXHR; |
||
20348 | }, |
||
20349 | |||
20350 | xhr: function() { |
||
20351 | var |
||
20352 | xhr |
||
20353 | ; |
||
20354 | // ajax request promise |
||
20355 | xhr = $.ajax(ajaxSettings) |
||
20356 | .always(module.event.xhr.always) |
||
20357 | .done(module.event.xhr.done) |
||
20358 | .fail(module.event.xhr.fail) |
||
20359 | ; |
||
20360 | module.verbose('Created server request', xhr, ajaxSettings); |
||
20361 | return xhr; |
||
20362 | } |
||
20363 | }, |
||
20364 | |||
20365 | set: { |
||
20366 | error: function() { |
||
20367 | module.verbose('Adding error state to element', $context); |
||
20368 | $context.addClass(className.error); |
||
20369 | }, |
||
20370 | loading: function() { |
||
20371 | module.verbose('Adding loading state to element', $context); |
||
20372 | $context.addClass(className.loading); |
||
20373 | requestStartTime = new Date().getTime(); |
||
20374 | } |
||
20375 | }, |
||
20376 | |||
20377 | remove: { |
||
20378 | error: function() { |
||
20379 | module.verbose('Removing error state from element', $context); |
||
20380 | $context.removeClass(className.error); |
||
20381 | }, |
||
20382 | loading: function() { |
||
20383 | module.verbose('Removing loading state from element', $context); |
||
20384 | $context.removeClass(className.loading); |
||
20385 | } |
||
20386 | }, |
||
20387 | |||
20388 | get: { |
||
20389 | responseFromXHR: function(xhr) { |
||
20390 | return $.isPlainObject(xhr) |
||
20391 | ? (module.is.expectingJSON()) |
||
20392 | ? module.decode.json(xhr.responseText) |
||
20393 | : xhr.responseText |
||
20394 | : false |
||
20395 | ; |
||
20396 | }, |
||
20397 | errorFromRequest: function(response, status, httpMessage) { |
||
20398 | return ($.isPlainObject(response) && response.error !== undefined) |
||
20399 | ? response.error // use json error message |
||
20400 | : (settings.error[status] !== undefined) // use server error message |
||
20401 | ? settings.error[status] |
||
20402 | : httpMessage |
||
20403 | ; |
||
20404 | }, |
||
20405 | request: function() { |
||
20406 | return module.request || false; |
||
20407 | }, |
||
20408 | xhr: function() { |
||
20409 | return module.xhr || false; |
||
20410 | }, |
||
20411 | settings: function() { |
||
20412 | var |
||
20413 | runSettings |
||
20414 | ; |
||
20415 | runSettings = settings.beforeSend.call(context, settings); |
||
20416 | if(runSettings) { |
||
20417 | if(runSettings.success !== undefined) { |
||
20418 | module.debug('Legacy success callback detected', runSettings); |
||
20419 | module.error(error.legacyParameters, runSettings.success); |
||
20420 | runSettings.onSuccess = runSettings.success; |
||
20421 | } |
||
20422 | if(runSettings.failure !== undefined) { |
||
20423 | module.debug('Legacy failure callback detected', runSettings); |
||
20424 | module.error(error.legacyParameters, runSettings.failure); |
||
20425 | runSettings.onFailure = runSettings.failure; |
||
20426 | } |
||
20427 | if(runSettings.complete !== undefined) { |
||
20428 | module.debug('Legacy complete callback detected', runSettings); |
||
20429 | module.error(error.legacyParameters, runSettings.complete); |
||
20430 | runSettings.onComplete = runSettings.complete; |
||
20431 | } |
||
20432 | } |
||
20433 | if(runSettings === undefined) { |
||
20434 | module.error(error.noReturnedValue); |
||
20435 | } |
||
20436 | if(runSettings === false) { |
||
20437 | return runSettings; |
||
20438 | } |
||
20439 | return (runSettings !== undefined) |
||
20440 | ? $.extend(true, {}, runSettings) |
||
20441 | : $.extend(true, {}, settings) |
||
20442 | ; |
||
20443 | }, |
||
20444 | urlEncodedValue: function(value) { |
||
20445 | var |
||
20446 | decodedValue = window.decodeURIComponent(value), |
||
20447 | encodedValue = window.encodeURIComponent(value), |
||
20448 | alreadyEncoded = (decodedValue !== value) |
||
20449 | ; |
||
20450 | if(alreadyEncoded) { |
||
20451 | module.debug('URL value is already encoded, avoiding double encoding', value); |
||
20452 | return value; |
||
20453 | } |
||
20454 | module.verbose('Encoding value using encodeURIComponent', value, encodedValue); |
||
20455 | return encodedValue; |
||
20456 | }, |
||
20457 | defaultData: function() { |
||
20458 | var |
||
20459 | data = {} |
||
20460 | ; |
||
20461 | if( !$.isWindow(element) ) { |
||
20462 | if( module.is.input() ) { |
||
20463 | data.value = $module.val(); |
||
20464 | } |
||
20465 | else if( module.is.form() ) { |
||
20466 | |||
20467 | } |
||
20468 | else { |
||
20469 | data.text = $module.text(); |
||
20470 | } |
||
20471 | } |
||
20472 | return data; |
||
20473 | }, |
||
20474 | event: function() { |
||
20475 | if( $.isWindow(element) || settings.on == 'now' ) { |
||
20476 | module.debug('API called without element, no events attached'); |
||
20477 | return false; |
||
20478 | } |
||
20479 | else if(settings.on == 'auto') { |
||
20480 | if( $module.is('input') ) { |
||
20481 | return (element.oninput !== undefined) |
||
20482 | ? 'input' |
||
20483 | : (element.onpropertychange !== undefined) |
||
20484 | ? 'propertychange' |
||
20485 | : 'keyup' |
||
20486 | ; |
||
20487 | } |
||
20488 | else if( $module.is('form') ) { |
||
20489 | return 'submit'; |
||
20490 | } |
||
20491 | else { |
||
20492 | return 'click'; |
||
20493 | } |
||
20494 | } |
||
20495 | else { |
||
20496 | return settings.on; |
||
20497 | } |
||
20498 | }, |
||
20499 | templatedURL: function(action) { |
||
20500 | action = action || $module.data(metadata.action) || settings.action || false; |
||
20501 | url = $module.data(metadata.url) || settings.url || false; |
||
20502 | if(url) { |
||
20503 | module.debug('Using specified url', url); |
||
20504 | return url; |
||
20505 | } |
||
20506 | if(action) { |
||
20507 | module.debug('Looking up url for action', action, settings.api); |
||
20508 | if(settings.api[action] === undefined && !module.is.mocked()) { |
||
20509 | module.error(error.missingAction, settings.action, settings.api); |
||
20510 | return; |
||
20511 | } |
||
20512 | url = settings.api[action]; |
||
20513 | } |
||
20514 | else if( module.is.form() ) { |
||
20515 | url = $module.attr('action') || $context.attr('action') || false; |
||
20516 | module.debug('No url or action specified, defaulting to form action', url); |
||
20517 | } |
||
20518 | return url; |
||
20519 | } |
||
20520 | }, |
||
20521 | |||
20522 | abort: function() { |
||
20523 | var |
||
20524 | xhr = module.get.xhr() |
||
20525 | ; |
||
20526 | if( xhr && xhr.state() !== 'resolved') { |
||
20527 | module.debug('Cancelling API request'); |
||
20528 | xhr.abort(); |
||
20529 | } |
||
20530 | }, |
||
20531 | |||
20532 | // reset state |
||
20533 | reset: function() { |
||
20534 | module.remove.error(); |
||
20535 | module.remove.loading(); |
||
20536 | }, |
||
20537 | |||
20538 | setting: function(name, value) { |
||
20539 | module.debug('Changing setting', name, value); |
||
20540 | if( $.isPlainObject(name) ) { |
||
20541 | $.extend(true, settings, name); |
||
20542 | } |
||
20543 | else if(value !== undefined) { |
||
20544 | if($.isPlainObject(settings[name])) { |
||
20545 | $.extend(true, settings[name], value); |
||
20546 | } |
||
20547 | else { |
||
20548 | settings[name] = value; |
||
20549 | } |
||
20550 | } |
||
20551 | else { |
||
20552 | return settings[name]; |
||
20553 | } |
||
20554 | }, |
||
20555 | internal: function(name, value) { |
||
20556 | if( $.isPlainObject(name) ) { |
||
20557 | $.extend(true, module, name); |
||
20558 | } |
||
20559 | else if(value !== undefined) { |
||
20560 | module[name] = value; |
||
20561 | } |
||
20562 | else { |
||
20563 | return module[name]; |
||
20564 | } |
||
20565 | }, |
||
20566 | debug: function() { |
||
20567 | if(!settings.silent && settings.debug) { |
||
20568 | if(settings.performance) { |
||
20569 | module.performance.log(arguments); |
||
20570 | } |
||
20571 | else { |
||
20572 | module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':'); |
||
20573 | module.debug.apply(console, arguments); |
||
20574 | } |
||
20575 | } |
||
20576 | }, |
||
20577 | verbose: function() { |
||
20578 | if(!settings.silent && settings.verbose && settings.debug) { |
||
20579 | if(settings.performance) { |
||
20580 | module.performance.log(arguments); |
||
20581 | } |
||
20582 | else { |
||
20583 | module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':'); |
||
20584 | module.verbose.apply(console, arguments); |
||
20585 | } |
||
20586 | } |
||
20587 | }, |
||
20588 | error: function() { |
||
20589 | if(!settings.silent) { |
||
20590 | module.error = Function.prototype.bind.call(console.error, console, settings.name + ':'); |
||
20591 | module.error.apply(console, arguments); |
||
20592 | } |
||
20593 | }, |
||
20594 | performance: { |
||
20595 | log: function(message) { |
||
20596 | var |
||
20597 | currentTime, |
||
20598 | executionTime, |
||
20599 | previousTime |
||
20600 | ; |
||
20601 | if(settings.performance) { |
||
20602 | currentTime = new Date().getTime(); |
||
20603 | previousTime = time || currentTime; |
||
20604 | executionTime = currentTime - previousTime; |
||
20605 | time = currentTime; |
||
20606 | performance.push({ |
||
20607 | 'Name' : message[0], |
||
20608 | 'Arguments' : [].slice.call(message, 1) || '', |
||
20609 | //'Element' : element, |
||
20610 | 'Execution Time' : executionTime |
||
20611 | }); |
||
20612 | } |
||
20613 | clearTimeout(module.performance.timer); |
||
20614 | module.performance.timer = setTimeout(module.performance.display, 500); |
||
20615 | }, |
||
20616 | display: function() { |
||
20617 | var |
||
20618 | title = settings.name + ':', |
||
20619 | totalTime = 0 |
||
20620 | ; |
||
20621 | time = false; |
||
20622 | clearTimeout(module.performance.timer); |
||
20623 | $.each(performance, function(index, data) { |
||
20624 | totalTime += data['Execution Time']; |
||
20625 | }); |
||
20626 | title += ' ' + totalTime + 'ms'; |
||
20627 | if(moduleSelector) { |
||
20628 | title += ' \'' + moduleSelector + '\''; |
||
20629 | } |
||
20630 | if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) { |
||
20631 | console.groupCollapsed(title); |
||
20632 | if(console.table) { |
||
20633 | console.table(performance); |
||
20634 | } |
||
20635 | else { |
||
20636 | $.each(performance, function(index, data) { |
||
20637 | console.log(data['Name'] + ': ' + data['Execution Time']+'ms'); |
||
20638 | }); |
||
20639 | } |
||
20640 | console.groupEnd(); |
||
20641 | } |
||
20642 | performance = []; |
||
20643 | } |
||
20644 | }, |
||
20645 | invoke: function(query, passedArguments, context) { |
||
20646 | var |
||
20647 | object = instance, |
||
20648 | maxDepth, |
||
20649 | found, |
||
20650 | response |
||
20651 | ; |
||
20652 | passedArguments = passedArguments || queryArguments; |
||
20653 | context = element || context; |
||
20654 | if(typeof query == 'string' && object !== undefined) { |
||
20655 | query = query.split(/[\. ]/); |
||
20656 | maxDepth = query.length - 1; |
||
20657 | $.each(query, function(depth, value) { |
||
20658 | var camelCaseValue = (depth != maxDepth) |
||
20659 | ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1) |
||
20660 | : query |
||
20661 | ; |
||
20662 | if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) { |
||
20663 | object = object[camelCaseValue]; |
||
20664 | } |
||
20665 | else if( object[camelCaseValue] !== undefined ) { |
||
20666 | found = object[camelCaseValue]; |
||
20667 | return false; |
||
20668 | } |
||
20669 | else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) { |
||
20670 | object = object[value]; |
||
20671 | } |
||
20672 | else if( object[value] !== undefined ) { |
||
20673 | found = object[value]; |
||
20674 | return false; |
||
20675 | } |
||
20676 | else { |
||
20677 | module.error(error.method, query); |
||
20678 | return false; |
||
20679 | } |
||
20680 | }); |
||
20681 | } |
||
20682 | if ( $.isFunction( found ) ) { |
||
20683 | response = found.apply(context, passedArguments); |
||
20684 | } |
||
20685 | else if(found !== undefined) { |
||
20686 | response = found; |
||
20687 | } |
||
20688 | if($.isArray(returnedValue)) { |
||
20689 | returnedValue.push(response); |
||
20690 | } |
||
20691 | else if(returnedValue !== undefined) { |
||
20692 | returnedValue = [returnedValue, response]; |
||
20693 | } |
||
20694 | else if(response !== undefined) { |
||
20695 | returnedValue = response; |
||
20696 | } |
||
20697 | return found; |
||
20698 | } |
||
20699 | }; |
||
20700 | |||
20701 | if(methodInvoked) { |
||
20702 | if(instance === undefined) { |
||
20703 | module.initialize(); |
||
20704 | } |
||
20705 | module.invoke(query); |
||
20706 | } |
||
20707 | else { |
||
20708 | if(instance !== undefined) { |
||
20709 | instance.invoke('destroy'); |
||
20710 | } |
||
20711 | module.initialize(); |
||
20712 | } |
||
20713 | }) |
||
20714 | ; |
||
20715 | |||
20716 | return (returnedValue !== undefined) |
||
20717 | ? returnedValue |
||
20718 | : this |
||
20719 | ; |
||
20720 | }; |
||
20721 | |||
20722 | $.api.settings = { |
||
20723 | |||
20724 | name : 'API', |
||
20725 | namespace : 'api', |
||
20726 | |||
20727 | debug : false, |
||
20728 | verbose : false, |
||
20729 | performance : true, |
||
20730 | |||
20731 | // object containing all templates endpoints |
||
20732 | api : {}, |
||
20733 | |||
20734 | // whether to cache responses |
||
20735 | cache : true, |
||
20736 | |||
20737 | // whether new requests should abort previous requests |
||
20738 | interruptRequests : true, |
||
20739 | |||
20740 | // event binding |
||
20741 | on : 'auto', |
||
20742 | |||
20743 | // context for applying state classes |
||
20744 | stateContext : false, |
||
20745 | |||
20746 | // duration for loading state |
||
20747 | loadingDuration : 0, |
||
20748 | |||
20749 | // whether to hide errors after a period of time |
||
20750 | hideError : 'auto', |
||
20751 | |||
20752 | // duration for error state |
||
20753 | errorDuration : 2000, |
||
20754 | |||
20755 | // whether parameters should be encoded with encodeURIComponent |
||
20756 | encodeParameters : true, |
||
20757 | |||
20758 | // API action to use |
||
20759 | action : false, |
||
20760 | |||
20761 | // templated URL to use |
||
20762 | url : false, |
||
20763 | |||
20764 | // base URL to apply to all endpoints |
||
20765 | base : '', |
||
20766 | |||
20767 | // data that will |
||
20768 | urlData : {}, |
||
20769 | |||
20770 | // whether to add default data to url data |
||
20771 | defaultData : true, |
||
20772 | |||
20773 | // whether to serialize closest form |
||
20774 | serializeForm : false, |
||
20775 | |||
20776 | // how long to wait before request should occur |
||
20777 | throttle : 0, |
||
20778 | |||
20779 | // whether to throttle first request or only repeated |
||
20780 | throttleFirstRequest : true, |
||
20781 | |||
20782 | // standard ajax settings |
||
20783 | method : 'get', |
||
20784 | data : {}, |
||
20785 | dataType : 'json', |
||
20786 | |||
20787 | // mock response |
||
20788 | mockResponse : false, |
||
20789 | mockResponseAsync : false, |
||
20790 | |||
20791 | // aliases for mock |
||
20792 | response : false, |
||
20793 | responseAsync : false, |
||
20794 | |||
20795 | // callbacks before request |
||
20796 | beforeSend : function(settings) { return settings; }, |
||
20797 | beforeXHR : function(xhr) {}, |
||
20798 | onRequest : function(promise, xhr) {}, |
||
20799 | |||
20800 | // after request |
||
20801 | onResponse : false, // function(response) { }, |
||
20802 | |||
20803 | // response was successful, if JSON passed validation |
||
20804 | onSuccess : function(response, $module) {}, |
||
20805 | |||
20806 | // request finished without aborting |
||
20807 | onComplete : function(response, $module) {}, |
||
20808 | |||
20809 | // failed JSON success test |
||
20810 | onFailure : function(response, $module) {}, |
||
20811 | |||
20812 | // server error |
||
20813 | onError : function(errorMessage, $module) {}, |
||
20814 | |||
20815 | // request aborted |
||
20816 | onAbort : function(errorMessage, $module) {}, |
||
20817 | |||
20818 | successTest : false, |
||
20819 | |||
20820 | // errors |
||
20821 | error : { |
||
20822 | beforeSend : 'The before send function has aborted the request', |
||
20823 | error : 'There was an error with your request', |
||
20824 | exitConditions : 'API Request Aborted. Exit conditions met', |
||
20825 | JSONParse : 'JSON could not be parsed during error handling', |
||
20826 | legacyParameters : 'You are using legacy API success callback names', |
||
20827 | method : 'The method you called is not defined', |
||
20828 | missingAction : 'API action used but no url was defined', |
||
20829 | missingSerialize : 'jquery-serialize-object is required to add form data to an existing data object', |
||
20830 | missingURL : 'No URL specified for api event', |
||
20831 | noReturnedValue : 'The beforeSend callback must return a settings object, beforeSend ignored.', |
||
20832 | noStorage : 'Caching responses locally requires session storage', |
||
20833 | parseError : 'There was an error parsing your request', |
||
20834 | requiredParameter : 'Missing a required URL parameter: ', |
||
20835 | statusMessage : 'Server gave an error: ', |
||
20836 | timeout : 'Your request timed out' |
||
20837 | }, |
||
20838 | |||
20839 | regExp : { |
||
20840 | required : /\{\$*[A-z0-9]+\}/g, |
||
20841 | optional : /\{\/\$*[A-z0-9]+\}/g, |
||
20842 | }, |
||
20843 | |||
20844 | className: { |
||
20845 | loading : 'loading', |
||
20846 | error : 'error' |
||
20847 | }, |
||
20848 | |||
20849 | selector: { |
||
20850 | disabled : '.disabled', |
||
20851 | form : 'form' |
||
20852 | }, |
||
20853 | |||
20854 | metadata: { |
||
20855 | action : 'action', |
||
20856 | url : 'url' |
||
20857 | } |
||
20858 | }; |
||
20859 | |||
20860 | |||
20861 | |||
20862 | })( jQuery, window, document ); |
||
20863 | |||
20864 | /*! |
||
20865 | * # Semantic UI 2.2.11 - State |
||
20866 | * http://github.com/semantic-org/semantic-ui/ |
||
20867 | * |
||
20868 | * |
||
20869 | * Released under the MIT license |
||
20870 | * http://opensource.org/licenses/MIT |
||
20871 | * |
||
20872 | */ |
||
20873 | |||
20874 | View Code Duplication | ;(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 |
||
21575 | * http://github.com/semantic-org/semantic-ui/ |
||
21576 | * |
||
21577 | * |
||
21578 | * Released under the MIT license |
||
21579 | * http://opensource.org/licenses/MIT |
||
21580 | * |
||
21581 | */ |
||
21582 | |||
21583 | View Code Duplication | ;(function ($, window, document, undefined) { |
|
21584 | |||
21585 | "use strict"; |
||
21586 | |||
21587 | window = (typeof window != 'undefined' && window.Math == Math) |
||
21588 | ? window |
||
21589 | : (typeof self != 'undefined' && self.Math == Math) |
||
21590 | ? self |
||
21591 | : Function('return this')() |
||
21592 | ; |
||
21593 | |||
21594 | $.fn.visibility = function(parameters) { |
||
21595 | var |
||
21596 | $allModules = $(this), |
||
21597 | moduleSelector = $allModules.selector || '', |
||
21598 | |||
21599 | time = new Date().getTime(), |
||
21600 | performance = [], |
||
21601 | |||
21602 | query = arguments[0], |
||
21603 | methodInvoked = (typeof query == 'string'), |
||
21604 | queryArguments = [].slice.call(arguments, 1), |
||
21605 | returnedValue, |
||
21606 | |||
21607 | moduleCount = $allModules.length, |
||
21608 | loadedCount = 0 |
||
21609 | ; |
||
21610 | |||
21611 | $allModules |
||
21612 | .each(function() { |
||
21613 | var |
||
21614 | settings = ( $.isPlainObject(parameters) ) |
||
21615 | ? $.extend(true, {}, $.fn.visibility.settings, parameters) |
||
21616 | : $.extend({}, $.fn.visibility.settings), |
||
21617 | |||
21618 | className = settings.className, |
||
21619 | namespace = settings.namespace, |
||
21620 | error = settings.error, |
||
21621 | metadata = settings.metadata, |
||
21622 | |||
21623 | eventNamespace = '.' + namespace, |
||
21624 | moduleNamespace = 'module-' + namespace, |
||
21625 | |||
21626 | $window = $(window), |
||
21627 | |||
21628 | $module = $(this), |
||
21629 | $context = $(settings.context), |
||
21630 | |||
21631 | $placeholder, |
||
21632 | |||
21633 | selector = $module.selector || '', |
||
21634 | instance = $module.data(moduleNamespace), |
||
21635 | |||
21636 | requestAnimationFrame = window.requestAnimationFrame |
||
21637 | || window.mozRequestAnimationFrame |
||
21638 | || window.webkitRequestAnimationFrame |
||
21639 | || window.msRequestAnimationFrame |
||
21640 | || function(callback) { setTimeout(callback, 0); }, |
||
21641 | |||
21642 | element = this, |
||
21643 | disabled = false, |
||
21644 | |||
21645 | contextObserver, |
||
21646 | observer, |
||
21647 | module |
||
21648 | ; |
||
21649 | |||
21650 | module = { |
||
21651 | |||
21652 | initialize: function() { |
||
21653 | module.debug('Initializing', settings); |
||
21654 | |||
21655 | module.setup.cache(); |
||
21656 | |||
21657 | if( module.should.trackChanges() ) { |
||
21658 | |||
21659 | if(settings.type == 'image') { |
||
21660 | module.setup.image(); |
||
21661 | } |
||
21662 | if(settings.type == 'fixed') { |
||
21663 | module.setup.fixed(); |
||
21664 | } |
||
21665 | |||
21666 | if(settings.observeChanges) { |
||
21667 | module.observeChanges(); |
||
21668 | } |
||
21669 | module.bind.events(); |
||
21670 | } |
||
21671 | |||
21672 | module.save.position(); |
||
21673 | if( !module.is.visible() ) { |
||
21674 | module.error(error.visible, $module); |
||
21675 | } |
||
21676 | |||
21677 | if(settings.initialCheck) { |
||
21678 | module.checkVisibility(); |
||
21679 | } |
||
21680 | module.instantiate(); |
||
21681 | }, |
||
21682 | |||
21683 | instantiate: function() { |
||
21684 | module.debug('Storing instance', module); |
||
21685 | $module |
||
21686 | .data(moduleNamespace, module) |
||
21687 | ; |
||
21688 | instance = module; |
||
21689 | }, |
||
21690 | |||
21691 | destroy: function() { |
||
21692 | module.verbose('Destroying previous module'); |
||
21693 | if(observer) { |
||
21694 | observer.disconnect(); |
||
21695 | } |
||
21696 | if(contextObserver) { |
||
21697 | contextObserver.disconnect(); |
||
21698 | } |
||
21699 | $window |
||
21700 | .off('load' + eventNamespace, module.event.load) |
||
21701 | .off('resize' + eventNamespace, module.event.resize) |
||
21702 | ; |
||
21703 | $context |
||
21704 | .off('scroll' + eventNamespace, module.event.scroll) |
||
21705 | .off('scrollchange' + eventNamespace, module.event.scrollchange) |
||
21706 | ; |
||
21707 | if(settings.type == 'fixed') { |
||
21708 | module.resetFixed(); |
||
21709 | module.remove.placeholder(); |
||
21710 | } |
||
21711 | $module |
||
21712 | .off(eventNamespace) |
||
21713 | .removeData(moduleNamespace) |
||
21714 | ; |
||
21715 | }, |
||
21716 | |||
21717 | observeChanges: function() { |
||
21718 | if('MutationObserver' in window) { |
||
21719 | contextObserver = new MutationObserver(module.event.contextChanged); |
||
21720 | observer = new MutationObserver(module.event.changed); |
||
21721 | contextObserver.observe(document, { |
||
21722 | childList : true, |
||
21723 | subtree : true |
||
21724 | }); |
||
21725 | observer.observe(element, { |
||
21726 | childList : true, |
||
21727 | subtree : true |
||
21728 | }); |
||
21729 | module.debug('Setting up mutation observer', observer); |
||
21730 | } |
||
21731 | }, |
||
21732 | |||
21733 | bind: { |
||
21734 | events: function() { |
||
21735 | module.verbose('Binding visibility events to scroll and resize'); |
||
21736 | if(settings.refreshOnLoad) { |
||
21737 | $window |
||
21738 | .on('load' + eventNamespace, module.event.load) |
||
21739 | ; |
||
21740 | } |
||
21741 | $window |
||
21742 | .on('resize' + eventNamespace, module.event.resize) |
||
21743 | ; |
||
21744 | // pub/sub pattern |
||
21745 | $context |
||
21746 | .off('scroll' + eventNamespace) |
||
21747 | .on('scroll' + eventNamespace, module.event.scroll) |
||
21748 | .on('scrollchange' + eventNamespace, module.event.scrollchange) |
||
21749 | ; |
||
21750 | } |
||
21751 | }, |
||
21752 | |||
21753 | event: { |
||
21754 | changed: function(mutations) { |
||
21755 | module.verbose('DOM tree modified, updating visibility calculations'); |
||
21756 | module.timer = setTimeout(function() { |
||
21757 | module.verbose('DOM tree modified, updating sticky menu'); |
||
21758 | module.refresh(); |
||
21759 | }, 100); |
||
21760 | }, |
||
21761 | contextChanged: function(mutations) { |
||
21762 | [].forEach.call(mutations, function(mutation) { |
||
21763 | if(mutation.removedNodes) { |
||
21764 | [].forEach.call(mutation.removedNodes, function(node) { |
||
21765 | if(node == element || $(node).find(element).length > 0) { |
||
21766 | module.debug('Element removed from DOM, tearing down events'); |
||
21767 | module.destroy(); |
||
21768 | } |
||
21769 | }); |
||
21770 | } |
||
21771 | }); |
||
21772 | }, |
||
21773 | resize: function() { |
||
21774 | module.debug('Window resized'); |
||
21775 | if(settings.refreshOnResize) { |
||
21776 | requestAnimationFrame(module.refresh); |
||
21777 | } |
||
21778 | }, |
||
21779 | load: function() { |
||
21780 | module.debug('Page finished loading'); |
||
21781 | requestAnimationFrame(module.refresh); |
||
21782 | }, |
||
21783 | // publishes scrollchange event on one scroll |
||
21784 | scroll: function() { |
||
21785 | if(settings.throttle) { |
||
21786 | clearTimeout(module.timer); |
||
21787 | module.timer = setTimeout(function() { |
||
21788 | $context.triggerHandler('scrollchange' + eventNamespace, [ $context.scrollTop() ]); |
||
21789 | }, settings.throttle); |
||
21790 | } |
||
21791 | else { |
||
21792 | requestAnimationFrame(function() { |
||
21793 | $context.triggerHandler('scrollchange' + eventNamespace, [ $context.scrollTop() ]); |
||
21794 | }); |
||
21795 | } |
||
21796 | }, |
||
21797 | // subscribes to scrollchange |
||
21798 | scrollchange: function(event, scrollPosition) { |
||
21799 | module.checkVisibility(scrollPosition); |
||
21800 | }, |
||
21801 | }, |
||
21802 | |||
21803 | precache: function(images, callback) { |
||
21804 | if (!(images instanceof Array)) { |
||
21805 | images = [images]; |
||
21806 | } |
||
21807 | var |
||
21808 | imagesLength = images.length, |
||
21809 | loadedCounter = 0, |
||
21810 | cache = [], |
||
21811 | cacheImage = document.createElement('img'), |
||
21812 | handleLoad = function() { |
||
21813 | loadedCounter++; |
||
21814 | if (loadedCounter >= images.length) { |
||
21815 | if ($.isFunction(callback)) { |
||
21816 | callback(); |
||
21817 | } |
||
21818 | } |
||
21819 | } |
||
21820 | ; |
||
21821 | while (imagesLength--) { |
||
21822 | cacheImage = document.createElement('img'); |
||
21823 | cacheImage.onload = handleLoad; |
||
21824 | cacheImage.onerror = handleLoad; |
||
21825 | cacheImage.src = images[imagesLength]; |
||
21826 | cache.push(cacheImage); |
||
21827 | } |
||
21828 | }, |
||
21829 | |||
21830 | enableCallbacks: function() { |
||
21831 | module.debug('Allowing callbacks to occur'); |
||
21832 | disabled = false; |
||
21833 | }, |
||
21834 | |||
21835 | disableCallbacks: function() { |
||
21836 | module.debug('Disabling all callbacks temporarily'); |
||
21837 | disabled = true; |
||
21838 | }, |
||
21839 | |||
21840 | should: { |
||
21841 | trackChanges: function() { |
||
21842 | if(methodInvoked) { |
||
21843 | module.debug('One time query, no need to bind events'); |
||
21844 | return false; |
||
21845 | } |
||
21846 | module.debug('Callbacks being attached'); |
||
21847 | return true; |
||
21848 | } |
||
21849 | }, |
||
21850 | |||
21851 | setup: { |
||
21852 | cache: function() { |
||
21853 | module.cache = { |
||
21854 | occurred : {}, |
||
21855 | screen : {}, |
||
21856 | element : {}, |
||
21857 | }; |
||
21858 | }, |
||
21859 | image: function() { |
||
21860 | var |
||
21861 | src = $module.data(metadata.src) |
||
21862 | ; |
||
21863 | if(src) { |
||
21864 | module.verbose('Lazy loading image', src); |
||
21865 | settings.once = true; |
||
21866 | settings.observeChanges = false; |
||
21867 | |||
21868 | // show when top visible |
||
21869 | settings.onOnScreen = function() { |
||
21870 | module.debug('Image on screen', element); |
||
21871 | module.precache(src, function() { |
||
21872 | module.set.image(src, function() { |
||
21873 | loadedCount++; |
||
21874 | if(loadedCount == moduleCount) { |
||
21875 | settings.onAllLoaded.call(this); |
||
21876 | } |
||
21877 | settings.onLoad.call(this); |
||
21878 | }); |
||
21879 | }); |
||
21880 | }; |
||
21881 | } |
||
21882 | }, |
||
21883 | fixed: function() { |
||
21884 | module.debug('Setting up fixed'); |
||
21885 | settings.once = false; |
||
21886 | settings.observeChanges = false; |
||
21887 | settings.initialCheck = true; |
||
21888 | settings.refreshOnLoad = true; |
||
21889 | if(!parameters.transition) { |
||
21890 | settings.transition = false; |
||
21891 | } |
||
21892 | module.create.placeholder(); |
||
21893 | module.debug('Added placeholder', $placeholder); |
||
21894 | settings.onTopPassed = function() { |
||
21895 | module.debug('Element passed, adding fixed position', $module); |
||
21896 | module.show.placeholder(); |
||
21897 | module.set.fixed(); |
||
21898 | if(settings.transition) { |
||
21899 | if($.fn.transition !== undefined) { |
||
21900 | $module.transition(settings.transition, settings.duration); |
||
21901 | } |
||
21902 | } |
||
21903 | }; |
||
21904 | settings.onTopPassedReverse = function() { |
||
21905 | module.debug('Element returned to position, removing fixed', $module); |
||
21906 | module.hide.placeholder(); |
||
21907 | module.remove.fixed(); |
||
21908 | }; |
||
21909 | } |
||
21910 | }, |
||
21911 | |||
21912 | create: { |
||
21913 | placeholder: function() { |
||
21914 | module.verbose('Creating fixed position placeholder'); |
||
21915 | $placeholder = $module |
||
21916 | .clone(false) |
||
21917 | .css('display', 'none') |
||
21918 | .addClass(className.placeholder) |
||
21919 | .insertAfter($module) |
||
21920 | ; |
||
21921 | } |
||
21922 | }, |
||
21923 | |||
21924 | show: { |
||
21925 | placeholder: function() { |
||
21926 | module.verbose('Showing placeholder'); |
||
21927 | $placeholder |
||
21928 | .css('display', 'block') |
||
21929 | .css('visibility', 'hidden') |
||
21930 | ; |
||
21931 | } |
||
21932 | }, |
||
21933 | hide: { |
||
21934 | placeholder: function() { |
||
21935 | module.verbose('Hiding placeholder'); |
||
21936 | $placeholder |
||
21937 | .css('display', 'none') |
||
21938 | .css('visibility', '') |
||
21939 | ; |
||
21940 | } |
||
21941 | }, |
||
21942 | |||
21943 | set: { |
||
21944 | fixed: function() { |
||
21945 | module.verbose('Setting element to fixed position'); |
||
21946 | $module |
||
21947 | .addClass(className.fixed) |
||
21948 | .css({ |
||
21949 | position : 'fixed', |
||
21950 | top : settings.offset + 'px', |
||
21951 | left : 'auto', |
||
21952 | zIndex : settings.zIndex |
||
21953 | }) |
||
21954 | ; |
||
21955 | settings.onFixed.call(element); |
||
21956 | }, |
||
21957 | image: function(src, callback) { |
||
21958 | $module |
||
21959 | .attr('src', src) |
||
21960 | ; |
||
21961 | if(settings.transition) { |
||
21962 | if( $.fn.transition !== undefined) { |
||
21963 | if($module.hasClass(className.visible)) { |
||
21964 | module.debug('Transition already occurred on this image, skipping animation'); |
||
21965 | return; |
||
21966 | } |
||
21967 | $module.transition(settings.transition, settings.duration, callback); |
||
21968 | } |
||
21969 | else { |
||
21970 | $module.fadeIn(settings.duration, callback); |
||
21971 | } |
||
21972 | } |
||
21973 | else { |
||
21974 | $module.show(); |
||
21975 | } |
||
21976 | } |
||
21977 | }, |
||
21978 | |||
21979 | is: { |
||
21980 | onScreen: function() { |
||
21981 | var |
||
21982 | calculations = module.get.elementCalculations() |
||
21983 | ; |
||
21984 | return calculations.onScreen; |
||
21985 | }, |
||
21986 | offScreen: function() { |
||
21987 | var |
||
21988 | calculations = module.get.elementCalculations() |
||
21989 | ; |
||
21990 | return calculations.offScreen; |
||
21991 | }, |
||
21992 | visible: function() { |
||
21993 | if(module.cache && module.cache.element) { |
||
21994 | return !(module.cache.element.width === 0 && module.cache.element.offset.top === 0); |
||
21995 | } |
||
21996 | return false; |
||
21997 | }, |
||
21998 | verticallyScrollableContext: function() { |
||
21999 | var |
||
22000 | overflowY = ($context.get(0) !== window) |
||
22001 | ? $context.css('overflow-y') |
||
22002 | : false |
||
22003 | ; |
||
22004 | return (overflowY == 'auto' || overflowY == 'scroll'); |
||
22005 | }, |
||
22006 | horizontallyScrollableContext: function() { |
||
22007 | var |
||
22008 | overflowX = ($context.get(0) !== window) |
||
22009 | ? $context.css('overflow-x') |
||
22010 | : false |
||
22011 | ; |
||
22012 | return (overflowX == 'auto' || overflowX == 'scroll'); |
||
22013 | } |
||
22014 | }, |
||
22015 | |||
22016 | refresh: function() { |
||
22017 | module.debug('Refreshing constants (width/height)'); |
||
22018 | if(settings.type == 'fixed') { |
||
22019 | module.resetFixed(); |
||
22020 | } |
||
22021 | module.reset(); |
||
22022 | module.save.position(); |
||
22023 | if(settings.checkOnRefresh) { |
||
22024 | module.checkVisibility(); |
||
22025 | } |
||
22026 | settings.onRefresh.call(element); |
||
22027 | }, |
||
22028 | |||
22029 | resetFixed: function () { |
||
22030 | module.remove.fixed(); |
||
22031 | module.remove.occurred(); |
||
22032 | }, |
||
22033 | |||
22034 | reset: function() { |
||
22035 | module.verbose('Resetting all cached values'); |
||
22036 | if( $.isPlainObject(module.cache) ) { |
||
22037 | module.cache.screen = {}; |
||
22038 | module.cache.element = {}; |
||
22039 | } |
||
22040 | }, |
||
22041 | |||
22042 | checkVisibility: function(scroll) { |
||
22043 | module.verbose('Checking visibility of element', module.cache.element); |
||
22044 | |||
22045 | if( !disabled && module.is.visible() ) { |
||
22046 | |||
22047 | // save scroll position |
||
22048 | module.save.scroll(scroll); |
||
22049 | |||
22050 | // update calculations derived from scroll |
||
22051 | module.save.calculations(); |
||
22052 | |||
22053 | // percentage |
||
22054 | module.passed(); |
||
22055 | |||
22056 | // reverse (must be first) |
||
22057 | module.passingReverse(); |
||
22058 | module.topVisibleReverse(); |
||
22059 | module.bottomVisibleReverse(); |
||
22060 | module.topPassedReverse(); |
||
22061 | module.bottomPassedReverse(); |
||
22062 | |||
22063 | // one time |
||
22064 | module.onScreen(); |
||
22065 | module.offScreen(); |
||
22066 | module.passing(); |
||
22067 | module.topVisible(); |
||
22068 | module.bottomVisible(); |
||
22069 | module.topPassed(); |
||
22070 | module.bottomPassed(); |
||
22071 | |||
22072 | // on update callback |
||
22073 | if(settings.onUpdate) { |
||
22074 | settings.onUpdate.call(element, module.get.elementCalculations()); |
||
22075 | } |
||
22076 | } |
||
22077 | }, |
||
22078 | |||
22079 | passed: function(amount, newCallback) { |
||
22080 | var |
||
22081 | calculations = module.get.elementCalculations(), |
||
22082 | amountInPixels |
||
22083 | ; |
||
22084 | // assign callback |
||
22085 | if(amount && newCallback) { |
||
22086 | settings.onPassed[amount] = newCallback; |
||
22087 | } |
||
22088 | else if(amount !== undefined) { |
||
22089 | return (module.get.pixelsPassed(amount) > calculations.pixelsPassed); |
||
22090 | } |
||
22091 | else if(calculations.passing) { |
||
22092 | $.each(settings.onPassed, function(amount, callback) { |
||
22093 | if(calculations.bottomVisible || calculations.pixelsPassed > module.get.pixelsPassed(amount)) { |
||
22094 | module.execute(callback, amount); |
||
22095 | } |
||
22096 | else if(!settings.once) { |
||
22097 | module.remove.occurred(callback); |
||
22098 | } |
||
22099 | }); |
||
22100 | } |
||
22101 | }, |
||
22102 | |||
22103 | onScreen: function(newCallback) { |
||
22104 | var |
||
22105 | calculations = module.get.elementCalculations(), |
||
22106 | callback = newCallback || settings.onOnScreen, |
||
22107 | callbackName = 'onScreen' |
||
22108 | ; |
||
22109 | if(newCallback) { |
||
22110 | module.debug('Adding callback for onScreen', newCallback); |
||
22111 | settings.onOnScreen = newCallback; |
||
22112 | } |
||
22113 | if(calculations.onScreen) { |
||
22114 | module.execute(callback, callbackName); |
||
22115 | } |
||
22116 | else if(!settings.once) { |
||
22117 | module.remove.occurred(callbackName); |
||
22118 | } |
||
22119 | if(newCallback !== undefined) { |
||
22120 | return calculations.onOnScreen; |
||
22121 | } |
||
22122 | }, |
||
22123 | |||
22124 | offScreen: function(newCallback) { |
||
22125 | var |
||
22126 | calculations = module.get.elementCalculations(), |
||
22127 | callback = newCallback || settings.onOffScreen, |
||
22128 | callbackName = 'offScreen' |
||
22129 | ; |
||
22130 | if(newCallback) { |
||
22131 | module.debug('Adding callback for offScreen', newCallback); |
||
22132 | settings.onOffScreen = newCallback; |
||
22133 | } |
||
22134 | if(calculations.offScreen) { |
||
22135 | module.execute(callback, callbackName); |
||
22136 | } |
||
22137 | else if(!settings.once) { |
||
22138 | module.remove.occurred(callbackName); |
||
22139 | } |
||
22140 | if(newCallback !== undefined) { |
||
22141 | return calculations.onOffScreen; |
||
22142 | } |
||
22143 | }, |
||
22144 | |||
22145 | passing: function(newCallback) { |
||
22146 | var |
||
22147 | calculations = module.get.elementCalculations(), |
||
22148 | callback = newCallback || settings.onPassing, |
||
22149 | callbackName = 'passing' |
||
22150 | ; |
||
22151 | if(newCallback) { |
||
22152 | module.debug('Adding callback for passing', newCallback); |
||
22153 | settings.onPassing = newCallback; |
||
22154 | } |
||
22155 | if(calculations.passing) { |
||
22156 | module.execute(callback, callbackName); |
||
22157 | } |
||
22158 | else if(!settings.once) { |
||
22159 | module.remove.occurred(callbackName); |
||
22160 | } |
||
22161 | if(newCallback !== undefined) { |
||
22162 | return calculations.passing; |
||
22163 | } |
||
22164 | }, |
||
22165 | |||
22166 | |||
22167 | topVisible: function(newCallback) { |
||
22168 | var |
||
22169 | calculations = module.get.elementCalculations(), |
||
22170 | callback = newCallback || settings.onTopVisible, |
||
22171 | callbackName = 'topVisible' |
||
22172 | ; |
||
22173 | if(newCallback) { |
||
22174 | module.debug('Adding callback for top visible', newCallback); |
||
22175 | settings.onTopVisible = newCallback; |
||
22176 | } |
||
22177 | if(calculations.topVisible) { |
||
22178 | module.execute(callback, callbackName); |
||
22179 | } |
||
22180 | else if(!settings.once) { |
||
22181 | module.remove.occurred(callbackName); |
||
22182 | } |
||
22183 | if(newCallback === undefined) { |
||
22184 | return calculations.topVisible; |
||
22185 | } |
||
22186 | }, |
||
22187 | |||
22188 | bottomVisible: function(newCallback) { |
||
22189 | var |
||
22190 | calculations = module.get.elementCalculations(), |
||
22191 | callback = newCallback || settings.onBottomVisible, |
||
22192 | callbackName = 'bottomVisible' |
||
22193 | ; |
||
22194 | if(newCallback) { |
||
22195 | module.debug('Adding callback for bottom visible', newCallback); |
||
22196 | settings.onBottomVisible = newCallback; |
||
22197 | } |
||
22198 | if(calculations.bottomVisible) { |
||
22199 | module.execute(callback, callbackName); |
||
22200 | } |
||
22201 | else if(!settings.once) { |
||
22202 | module.remove.occurred(callbackName); |
||
22203 | } |
||
22204 | if(newCallback === undefined) { |
||
22205 | return calculations.bottomVisible; |
||
22206 | } |
||
22207 | }, |
||
22208 | |||
22209 | topPassed: function(newCallback) { |
||
22210 | var |
||
22211 | calculations = module.get.elementCalculations(), |
||
22212 | callback = newCallback || settings.onTopPassed, |
||
22213 | callbackName = 'topPassed' |
||
22214 | ; |
||
22215 | if(newCallback) { |
||
22216 | module.debug('Adding callback for top passed', newCallback); |
||
22217 | settings.onTopPassed = newCallback; |
||
22218 | } |
||
22219 | if(calculations.topPassed) { |
||
22220 | module.execute(callback, callbackName); |
||
22221 | } |
||
22222 | else if(!settings.once) { |
||
22223 | module.remove.occurred(callbackName); |
||
22224 | } |
||
22225 | if(newCallback === undefined) { |
||
22226 | return calculations.topPassed; |
||
22227 | } |
||
22228 | }, |
||
22229 | |||
22230 | bottomPassed: function(newCallback) { |
||
22231 | var |
||
22232 | calculations = module.get.elementCalculations(), |
||
22233 | callback = newCallback || settings.onBottomPassed, |
||
22234 | callbackName = 'bottomPassed' |
||
22235 | ; |
||
22236 | if(newCallback) { |
||
22237 | module.debug('Adding callback for bottom passed', newCallback); |
||
22238 | settings.onBottomPassed = newCallback; |
||
22239 | } |
||
22240 | if(calculations.bottomPassed) { |
||
22241 | module.execute(callback, callbackName); |
||
22242 | } |
||
22243 | else if(!settings.once) { |
||
22244 | module.remove.occurred(callbackName); |
||
22245 | } |
||
22246 | if(newCallback === undefined) { |
||
22247 | return calculations.bottomPassed; |
||
22248 | } |
||
22249 | }, |
||
22250 | |||
22251 | passingReverse: function(newCallback) { |
||
22252 | var |
||
22253 | calculations = module.get.elementCalculations(), |
||
22254 | callback = newCallback || settings.onPassingReverse, |
||
22255 | callbackName = 'passingReverse' |
||
22256 | ; |
||
22257 | if(newCallback) { |
||
22258 | module.debug('Adding callback for passing reverse', newCallback); |
||
22259 | settings.onPassingReverse = newCallback; |
||
22260 | } |
||
22261 | if(!calculations.passing) { |
||
22262 | if(module.get.occurred('passing')) { |
||
22263 | module.execute(callback, callbackName); |
||
22264 | } |
||
22265 | } |
||
22266 | else if(!settings.once) { |
||
22267 | module.remove.occurred(callbackName); |
||
22268 | } |
||
22269 | if(newCallback !== undefined) { |
||
22270 | return !calculations.passing; |
||
22271 | } |
||
22272 | }, |
||
22273 | |||
22274 | |||
22275 | topVisibleReverse: function(newCallback) { |
||
22276 | var |
||
22277 | calculations = module.get.elementCalculations(), |
||
22278 | callback = newCallback || settings.onTopVisibleReverse, |
||
22279 | callbackName = 'topVisibleReverse' |
||
22280 | ; |
||
22281 | if(newCallback) { |
||
22282 | module.debug('Adding callback for top visible reverse', newCallback); |
||
22283 | settings.onTopVisibleReverse = newCallback; |
||
22284 | } |
||
22285 | if(!calculations.topVisible) { |
||
22286 | if(module.get.occurred('topVisible')) { |
||
22287 | module.execute(callback, callbackName); |
||
22288 | } |
||
22289 | } |
||
22290 | else if(!settings.once) { |
||
22291 | module.remove.occurred(callbackName); |
||
22292 | } |
||
22293 | if(newCallback === undefined) { |
||
22294 | return !calculations.topVisible; |
||
22295 | } |
||
22296 | }, |
||
22297 | |||
22298 | bottomVisibleReverse: function(newCallback) { |
||
22299 | var |
||
22300 | calculations = module.get.elementCalculations(), |
||
22301 | callback = newCallback || settings.onBottomVisibleReverse, |
||
22302 | callbackName = 'bottomVisibleReverse' |
||
22303 | ; |
||
22304 | if(newCallback) { |
||
22305 | module.debug('Adding callback for bottom visible reverse', newCallback); |
||
22306 | settings.onBottomVisibleReverse = newCallback; |
||
22307 | } |
||
22308 | if(!calculations.bottomVisible) { |
||
22309 | if(module.get.occurred('bottomVisible')) { |
||
22310 | module.execute(callback, callbackName); |
||
22311 | } |
||
22312 | } |
||
22313 | else if(!settings.once) { |
||
22314 | module.remove.occurred(callbackName); |
||
22315 | } |
||
22316 | if(newCallback === undefined) { |
||
22317 | return !calculations.bottomVisible; |
||
22318 | } |
||
22319 | }, |
||
22320 | |||
22321 | topPassedReverse: function(newCallback) { |
||
22322 | var |
||
22323 | calculations = module.get.elementCalculations(), |
||
22324 | callback = newCallback || settings.onTopPassedReverse, |
||
22325 | callbackName = 'topPassedReverse' |
||
22326 | ; |
||
22327 | if(newCallback) { |
||
22328 | module.debug('Adding callback for top passed reverse', newCallback); |
||
22329 | settings.onTopPassedReverse = newCallback; |
||
22330 | } |
||
22331 | if(!calculations.topPassed) { |
||
22332 | if(module.get.occurred('topPassed')) { |
||
22333 | module.execute(callback, callbackName); |
||
22334 | } |
||
22335 | } |
||
22336 | else if(!settings.once) { |
||
22337 | module.remove.occurred(callbackName); |
||
22338 | } |
||
22339 | if(newCallback === undefined) { |
||
22340 | return !calculations.onTopPassed; |
||
22341 | } |
||
22342 | }, |
||
22343 | |||
22344 | bottomPassedReverse: function(newCallback) { |
||
22345 | var |
||
22346 | calculations = module.get.elementCalculations(), |
||
22347 | callback = newCallback || settings.onBottomPassedReverse, |
||
22348 | callbackName = 'bottomPassedReverse' |
||
22349 | ; |
||
22350 | if(newCallback) { |
||
22351 | module.debug('Adding callback for bottom passed reverse', newCallback); |
||
22352 | settings.onBottomPassedReverse = newCallback; |
||
22353 | } |
||
22354 | if(!calculations.bottomPassed) { |
||
22355 | if(module.get.occurred('bottomPassed')) { |
||
22356 | module.execute(callback, callbackName); |
||
22357 | } |
||
22358 | } |
||
22359 | else if(!settings.once) { |
||
22360 | module.remove.occurred(callbackName); |
||
22361 | } |
||
22362 | if(newCallback === undefined) { |
||
22363 | return !calculations.bottomPassed; |
||
22364 | } |
||
22365 | }, |
||
22366 | |||
22367 | execute: function(callback, callbackName) { |
||
22368 | var |
||
22369 | calculations = module.get.elementCalculations(), |
||
22370 | screen = module.get.screenCalculations() |
||
22371 | ; |
||
22372 | callback = callback || false; |
||
22373 | if(callback) { |
||
22374 | if(settings.continuous) { |
||
22375 | module.debug('Callback being called continuously', callbackName, calculations); |
||
22376 | callback.call(element, calculations, screen); |
||
22377 | } |
||
22378 | else if(!module.get.occurred(callbackName)) { |
||
22379 | module.debug('Conditions met', callbackName, calculations); |
||
22380 | callback.call(element, calculations, screen); |
||
22381 | } |
||
22382 | } |
||
22383 | module.save.occurred(callbackName); |
||
22384 | }, |
||
22385 | |||
22386 | remove: { |
||
22387 | fixed: function() { |
||
22388 | module.debug('Removing fixed position'); |
||
22389 | $module |
||
22390 | .removeClass(className.fixed) |
||
22391 | .css({ |
||
22392 | position : '', |
||
22393 | top : '', |
||
22394 | left : '', |
||
22395 | zIndex : '' |
||
22396 | }) |
||
22397 | ; |
||
22398 | settings.onUnfixed.call(element); |
||
22399 | }, |
||
22400 | placeholder: function() { |
||
22401 | module.debug('Removing placeholder content'); |
||
22402 | if($placeholder) { |
||
22403 | $placeholder.remove(); |
||
22404 | } |
||
22405 | }, |
||
22406 | occurred: function(callback) { |
||
22407 | if(callback) { |
||
22408 | var |
||
22409 | occurred = module.cache.occurred |
||
22410 | ; |
||
22411 | if(occurred[callback] !== undefined && occurred[callback] === true) { |
||
22412 | module.debug('Callback can now be called again', callback); |
||
22413 | module.cache.occurred[callback] = false; |
||
22414 | } |
||
22415 | } |
||
22416 | else { |
||
22417 | module.cache.occurred = {}; |
||
22418 | } |
||
22419 | } |
||
22420 | }, |
||
22421 | |||
22422 | save: { |
||
22423 | calculations: function() { |
||
22424 | module.verbose('Saving all calculations necessary to determine positioning'); |
||
22425 | module.save.direction(); |
||
22426 | module.save.screenCalculations(); |
||
22427 | module.save.elementCalculations(); |
||
22428 | }, |
||
22429 | occurred: function(callback) { |
||
22430 | if(callback) { |
||
22431 | if(module.cache.occurred[callback] === undefined || (module.cache.occurred[callback] !== true)) { |
||
22432 | module.verbose('Saving callback occurred', callback); |
||
22433 | module.cache.occurred[callback] = true; |
||
22434 | } |
||
22435 | } |
||
22436 | }, |
||
22437 | scroll: function(scrollPosition) { |
||
22438 | scrollPosition = scrollPosition + settings.offset || $context.scrollTop() + settings.offset; |
||
22439 | module.cache.scroll = scrollPosition; |
||
22440 | }, |
||
22441 | direction: function() { |
||
22442 | var |
||
22443 | scroll = module.get.scroll(), |
||
22444 | lastScroll = module.get.lastScroll(), |
||
22445 | direction |
||
22446 | ; |
||
22447 | if(scroll > lastScroll && lastScroll) { |
||
22448 | direction = 'down'; |
||
22449 | } |
||
22450 | else if(scroll < lastScroll && lastScroll) { |
||
22451 | direction = 'up'; |
||
22452 | } |
||
22453 | else { |
||
22454 | direction = 'static'; |
||
22455 | } |
||
22456 | module.cache.direction = direction; |
||
22457 | return module.cache.direction; |
||
22458 | }, |
||
22459 | elementPosition: function() { |
||
22460 | var |
||
22461 | element = module.cache.element, |
||
22462 | screen = module.get.screenSize() |
||
22463 | ; |
||
22464 | module.verbose('Saving element position'); |
||
22465 | // (quicker than $.extend) |
||
22466 | element.fits = (element.height < screen.height); |
||
22467 | element.offset = $module.offset(); |
||
22468 | element.width = $module.outerWidth(); |
||
22469 | element.height = $module.outerHeight(); |
||
22470 | // compensate for scroll in context |
||
22471 | if(module.is.verticallyScrollableContext()) { |
||
22472 | element.offset.top += $context.scrollTop() - $context.offset().top; |
||
22473 | } |
||
22474 | if(module.is.horizontallyScrollableContext()) { |
||
22475 | element.offset.left += $context.scrollLeft - $context.offset().left; |
||
22476 | } |
||
22477 | // store |
||
22478 | module.cache.element = element; |
||
22479 | return element; |
||
22480 | }, |
||
22481 | elementCalculations: function() { |
||
22482 | var |
||
22483 | screen = module.get.screenCalculations(), |
||
22484 | element = module.get.elementPosition() |
||
22485 | ; |
||
22486 | // offset |
||
22487 | if(settings.includeMargin) { |
||
22488 | element.margin = {}; |
||
22489 | element.margin.top = parseInt($module.css('margin-top'), 10); |
||
22490 | element.margin.bottom = parseInt($module.css('margin-bottom'), 10); |
||
22491 | element.top = element.offset.top - element.margin.top; |
||
22492 | element.bottom = element.offset.top + element.height + element.margin.bottom; |
||
22493 | } |
||
22494 | else { |
||
22495 | element.top = element.offset.top; |
||
22496 | element.bottom = element.offset.top + element.height; |
||
22497 | } |
||
22498 | |||
22499 | // visibility |
||
22500 | element.topPassed = (screen.top >= element.top); |
||
22501 | element.bottomPassed = (screen.top >= element.bottom); |
||
22502 | element.topVisible = (screen.bottom >= element.top) && !element.bottomPassed; |
||
22503 | element.bottomVisible = (screen.bottom >= element.bottom) && !element.topPassed; |
||
22504 | element.pixelsPassed = 0; |
||
22505 | element.percentagePassed = 0; |
||
22506 | |||
22507 | // meta calculations |
||
22508 | element.onScreen = (element.topVisible && !element.bottomPassed); |
||
22509 | element.passing = (element.topPassed && !element.bottomPassed); |
||
22510 | element.offScreen = (!element.onScreen); |
||
22511 | |||
22512 | // passing calculations |
||
22513 | if(element.passing) { |
||
22514 | element.pixelsPassed = (screen.top - element.top); |
||
22515 | element.percentagePassed = (screen.top - element.top) / element.height; |
||
22516 | } |
||
22517 | module.cache.element = element; |
||
22518 | module.verbose('Updated element calculations', element); |
||
22519 | return element; |
||
22520 | }, |
||
22521 | screenCalculations: function() { |
||
22522 | var |
||
22523 | scroll = module.get.scroll() |
||
22524 | ; |
||
22525 | module.save.direction(); |
||
22526 | module.cache.screen.top = scroll; |
||
22527 | module.cache.screen.bottom = scroll + module.cache.screen.height; |
||
22528 | return module.cache.screen; |
||
22529 | }, |
||
22530 | screenSize: function() { |
||
22531 | module.verbose('Saving window position'); |
||
22532 | module.cache.screen = { |
||
22533 | height: $context.height() |
||
22534 | }; |
||
22535 | }, |
||
22536 | position: function() { |
||
22537 | module.save.screenSize(); |
||
22538 | module.save.elementPosition(); |
||
22539 | } |
||
22540 | }, |
||
22541 | |||
22542 | get: { |
||
22543 | pixelsPassed: function(amount) { |
||
22544 | var |
||
22545 | element = module.get.elementCalculations() |
||
22546 | ; |
||
22547 | if(amount.search('%') > -1) { |
||
22548 | return ( element.height * (parseInt(amount, 10) / 100) ); |
||
22549 | } |
||
22550 | return parseInt(amount, 10); |
||
22551 | }, |
||
22552 | occurred: function(callback) { |
||
22553 | return (module.cache.occurred !== undefined) |
||
22554 | ? module.cache.occurred[callback] || false |
||
22555 | : false |
||
22556 | ; |
||
22557 | }, |
||
22558 | direction: function() { |
||
22559 | if(module.cache.direction === undefined) { |
||
22560 | module.save.direction(); |
||
22561 | } |
||
22562 | return module.cache.direction; |
||
22563 | }, |
||
22564 | elementPosition: function() { |
||
22565 | if(module.cache.element === undefined) { |
||
22566 | module.save.elementPosition(); |
||
22567 | } |
||
22568 | return module.cache.element; |
||
22569 | }, |
||
22570 | elementCalculations: function() { |
||
22571 | if(module.cache.element === undefined) { |
||
22572 | module.save.elementCalculations(); |
||
22573 | } |
||
22574 | return module.cache.element; |
||
22575 | }, |
||
22576 | screenCalculations: function() { |
||
22577 | if(module.cache.screen === undefined) { |
||
22578 | module.save.screenCalculations(); |
||
22579 | } |
||
22580 | return module.cache.screen; |
||
22581 | }, |
||
22582 | screenSize: function() { |
||
22583 | if(module.cache.screen === undefined) { |
||
22584 | module.save.screenSize(); |
||
22585 | } |
||
22586 | return module.cache.screen; |
||
22587 | }, |
||
22588 | scroll: function() { |
||
22589 | if(module.cache.scroll === undefined) { |
||
22590 | module.save.scroll(); |
||
22591 | } |
||
22592 | return module.cache.scroll; |
||
22593 | }, |
||
22594 | lastScroll: function() { |
||
22595 | if(module.cache.screen === undefined) { |
||
22596 | module.debug('First scroll event, no last scroll could be found'); |
||
22597 | return false; |
||
22598 | } |
||
22599 | return module.cache.screen.top; |
||
22600 | } |
||
22601 | }, |
||
22602 | |||
22603 | setting: function(name, value) { |
||
22604 | if( $.isPlainObject(name) ) { |
||
22605 | $.extend(true, settings, name); |
||
22606 | } |
||
22607 | else if(value !== undefined) { |
||
22608 | settings[name] = value; |
||
22609 | } |
||
22610 | else { |
||
22611 | return settings[name]; |
||
22612 | } |
||
22613 | }, |
||
22614 | internal: function(name, value) { |
||
22615 | if( $.isPlainObject(name) ) { |
||
22616 | $.extend(true, module, name); |
||
22617 | } |
||
22618 | else if(value !== undefined) { |
||
22619 | module[name] = value; |
||
22620 | } |
||
22621 | else { |
||
22622 | return module[name]; |
||
22623 | } |
||
22624 | }, |
||
22625 | debug: function() { |
||
22626 | if(!settings.silent && settings.debug) { |
||
22627 | if(settings.performance) { |
||
22628 | module.performance.log(arguments); |
||
22629 | } |
||
22630 | else { |
||
22631 | module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':'); |
||
22632 | module.debug.apply(console, arguments); |
||
22633 | } |
||
22634 | } |
||
22635 | }, |
||
22636 | verbose: function() { |
||
22637 | if(!settings.silent && settings.verbose && settings.debug) { |
||
22638 | if(settings.performance) { |
||
22639 | module.performance.log(arguments); |
||
22640 | } |
||
22641 | else { |
||
22642 | module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':'); |
||
22643 | module.verbose.apply(console, arguments); |
||
22644 | } |
||
22645 | } |
||
22646 | }, |
||
22647 | error: function() { |
||
22648 | if(!settings.silent) { |
||
22649 | module.error = Function.prototype.bind.call(console.error, console, settings.name + ':'); |
||
22650 | module.error.apply(console, arguments); |
||
22651 | } |
||
22652 | }, |
||
22653 | performance: { |
||
22654 | log: function(message) { |
||
22655 | var |
||
22656 | currentTime, |
||
22657 | executionTime, |
||
22658 | previousTime |
||
22659 | ; |
||
22660 | if(settings.performance) { |
||
22661 | currentTime = new Date().getTime(); |
||
22662 | previousTime = time || currentTime; |
||
22663 | executionTime = currentTime - previousTime; |
||
22664 | time = currentTime; |
||
22665 | performance.push({ |
||
22666 | 'Name' : message[0], |
||
22667 | 'Arguments' : [].slice.call(message, 1) || '', |
||
22668 | 'Element' : element, |
||
22669 | 'Execution Time' : executionTime |
||
22670 | }); |
||
22671 | } |
||
22672 | clearTimeout(module.performance.timer); |
||
22673 | module.performance.timer = setTimeout(module.performance.display, 500); |
||
22674 | }, |
||
22675 | display: function() { |
||
22676 | var |
||
22677 | title = settings.name + ':', |
||
22678 | totalTime = 0 |
||
22679 | ; |
||
22680 | time = false; |
||
22681 | clearTimeout(module.performance.timer); |
||
22682 | $.each(performance, function(index, data) { |
||
22683 | totalTime += data['Execution Time']; |
||
22684 | }); |
||
22685 | title += ' ' + totalTime + 'ms'; |
||
22686 | if(moduleSelector) { |
||
22687 | title += ' \'' + moduleSelector + '\''; |
||
22688 | } |
||
22689 | if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) { |
||
22690 | console.groupCollapsed(title); |
||
22691 | if(console.table) { |
||
22692 | console.table(performance); |
||
22693 | } |
||
22694 | else { |
||
22695 | $.each(performance, function(index, data) { |
||
22696 | console.log(data['Name'] + ': ' + data['Execution Time']+'ms'); |
||
22697 | }); |
||
22698 | } |
||
22699 | console.groupEnd(); |
||
22700 | } |
||
22701 | performance = []; |
||
22702 | } |
||
22703 | }, |
||
22704 | invoke: function(query, passedArguments, context) { |
||
22705 | var |
||
22706 | object = instance, |
||
22707 | maxDepth, |
||
22708 | found, |
||
22709 | response |
||
22710 | ; |
||
22711 | passedArguments = passedArguments || queryArguments; |
||
22712 | context = element || context; |
||
22713 | if(typeof query == 'string' && object !== undefined) { |
||
22714 | query = query.split(/[\. ]/); |
||
22715 | maxDepth = query.length - 1; |
||
22716 | $.each(query, function(depth, value) { |
||
22717 | var camelCaseValue = (depth != maxDepth) |
||
22718 | ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1) |
||
22719 | : query |
||
22720 | ; |
||
22721 | if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) { |
||
22722 | object = object[camelCaseValue]; |
||
22723 | } |
||
22724 | else if( object[camelCaseValue] !== undefined ) { |
||
22725 | found = object[camelCaseValue]; |
||
22726 | return false; |
||
22727 | } |
||
22728 | else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) { |
||
22729 | object = object[value]; |
||
22730 | } |
||
22731 | else if( object[value] !== undefined ) { |
||
22732 | found = object[value]; |
||
22733 | return false; |
||
22734 | } |
||
22735 | else { |
||
22736 | module.error(error.method, query); |
||
22737 | return false; |
||
22738 | } |
||
22739 | }); |
||
22740 | } |
||
22741 | if ( $.isFunction( found ) ) { |
||
22742 | response = found.apply(context, passedArguments); |
||
22743 | } |
||
22744 | else if(found !== undefined) { |
||
22745 | response = found; |
||
22746 | } |
||
22747 | if($.isArray(returnedValue)) { |
||
22748 | returnedValue.push(response); |
||
22749 | } |
||
22750 | else if(returnedValue !== undefined) { |
||
22751 | returnedValue = [returnedValue, response]; |
||
22752 | } |
||
22753 | else if(response !== undefined) { |
||
22754 | returnedValue = response; |
||
22755 | } |
||
22756 | return found; |
||
22757 | } |
||
22758 | }; |
||
22759 | |||
22760 | if(methodInvoked) { |
||
22761 | if(instance === undefined) { |
||
22762 | module.initialize(); |
||
22763 | } |
||
22764 | instance.save.scroll(); |
||
22765 | instance.save.calculations(); |
||
22766 | module.invoke(query); |
||
22767 | } |
||
22768 | else { |
||
22769 | if(instance !== undefined) { |
||
22770 | instance.invoke('destroy'); |
||
22771 | } |
||
22772 | module.initialize(); |
||
22773 | } |
||
22774 | }) |
||
22775 | ; |
||
22776 | |||
22777 | return (returnedValue !== undefined) |
||
22778 | ? returnedValue |
||
22779 | : this |
||
22780 | ; |
||
22781 | }; |
||
22782 | |||
22783 | $.fn.visibility.settings = { |
||
22784 | |||
22785 | name : 'Visibility', |
||
22786 | namespace : 'visibility', |
||
22787 | |||
22788 | debug : false, |
||
22789 | verbose : false, |
||
22790 | performance : true, |
||
22791 | |||
22792 | // whether to use mutation observers to follow changes |
||
22793 | observeChanges : true, |
||
22794 | |||
22795 | // check position immediately on init |
||
22796 | initialCheck : true, |
||
22797 | |||
22798 | // whether to refresh calculations after all page images load |
||
22799 | refreshOnLoad : true, |
||
22800 | |||
22801 | // whether to refresh calculations after page resize event |
||
22802 | refreshOnResize : true, |
||
22803 | |||
22804 | // should call callbacks on refresh event (resize, etc) |
||
22805 | checkOnRefresh : true, |
||
22806 | |||
22807 | // callback should only occur one time |
||
22808 | once : true, |
||
22809 | |||
22810 | // callback should fire continuously whe evaluates to true |
||
22811 | continuous : false, |
||
22812 | |||
22813 | // offset to use with scroll top |
||
22814 | offset : 0, |
||
22815 | |||
22816 | // whether to include margin in elements position |
||
22817 | includeMargin : false, |
||
22818 | |||
22819 | // scroll context for visibility checks |
||
22820 | context : window, |
||
22821 | |||
22822 | // visibility check delay in ms (defaults to animationFrame) |
||
22823 | throttle : false, |
||
22824 | |||
22825 | // special visibility type (image, fixed) |
||
22826 | type : false, |
||
22827 | |||
22828 | // z-index to use with visibility 'fixed' |
||
22829 | zIndex : '10', |
||
22830 | |||
22831 | // image only animation settings |
||
22832 | transition : 'fade in', |
||
22833 | duration : 1000, |
||
22834 | |||
22835 | // array of callbacks for percentage |
||
22836 | onPassed : {}, |
||
22837 | |||
22838 | // standard callbacks |
||
22839 | onOnScreen : false, |
||
22840 | onOffScreen : false, |
||
22841 | onPassing : false, |
||
22842 | onTopVisible : false, |
||
22843 | onBottomVisible : false, |
||
22844 | onTopPassed : false, |
||
22845 | onBottomPassed : false, |
||
22846 | |||
22847 | // reverse callbacks |
||
22848 | onPassingReverse : false, |
||
22849 | onTopVisibleReverse : false, |
||
22850 | onBottomVisibleReverse : false, |
||
22851 | onTopPassedReverse : false, |
||
22852 | onBottomPassedReverse : false, |
||
22853 | |||
22854 | // special callbacks for image |
||
22855 | onLoad : function() {}, |
||
22856 | onAllLoaded : function() {}, |
||
22857 | |||
22858 | // special callbacks for fixed position |
||
22859 | onFixed : function() {}, |
||
22860 | onUnfixed : function() {}, |
||
22861 | |||
22862 | // utility callbacks |
||
22863 | onUpdate : false, // disabled by default for performance |
||
22864 | onRefresh : function(){}, |
||
22865 | |||
22866 | metadata : { |
||
22867 | src: 'src' |
||
22868 | }, |
||
22869 | |||
22870 | className: { |
||
22871 | fixed : 'fixed', |
||
22872 | placeholder : 'placeholder', |
||
22873 | visible : 'visible' |
||
22874 | }, |
||
22875 | |||
22876 | error : { |
||
22877 | method : 'The method you called is not defined.', |
||
22878 | visible : 'Element is hidden, you must call refresh after element becomes visible' |
||
22879 | } |
||
22880 | |||
22881 | }; |
||
22882 | |||
22883 | })( jQuery, window, document ); |
||
22884 |