semantic-ui-sass 1.12.3.0 → 2.0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/app/assets/javascripts/semantic-ui.js +1 -0
  4. data/app/assets/javascripts/semantic-ui/accordion.js +67 -53
  5. data/app/assets/javascripts/semantic-ui/api.js +395 -189
  6. data/app/assets/javascripts/semantic-ui/checkbox.js +322 -114
  7. data/app/assets/javascripts/semantic-ui/colorize.js +4 -2
  8. data/app/assets/javascripts/semantic-ui/dimmer.js +74 -50
  9. data/app/assets/javascripts/semantic-ui/dropdown.js +2046 -584
  10. data/app/assets/javascripts/semantic-ui/embed.js +662 -0
  11. data/app/assets/javascripts/semantic-ui/form.js +345 -163
  12. data/app/assets/javascripts/semantic-ui/modal.js +119 -90
  13. data/app/assets/javascripts/semantic-ui/nag.js +8 -9
  14. data/app/assets/javascripts/semantic-ui/popup.js +390 -228
  15. data/app/assets/javascripts/semantic-ui/progress.js +112 -103
  16. data/app/assets/javascripts/semantic-ui/rating.js +79 -55
  17. data/app/assets/javascripts/semantic-ui/search.js +305 -123
  18. data/app/assets/javascripts/semantic-ui/shape.js +94 -48
  19. data/app/assets/javascripts/semantic-ui/sidebar.js +84 -151
  20. data/app/assets/javascripts/semantic-ui/site.js +5 -5
  21. data/app/assets/javascripts/semantic-ui/state.js +4 -4
  22. data/app/assets/javascripts/semantic-ui/sticky.js +108 -35
  23. data/app/assets/javascripts/semantic-ui/tab.js +220 -125
  24. data/app/assets/javascripts/semantic-ui/transition.js +205 -171
  25. data/app/assets/javascripts/semantic-ui/visibility.js +220 -100
  26. data/app/assets/javascripts/semantic-ui/visit.js +6 -4
  27. data/app/assets/stylesheets/semantic-ui/collections/_breadcrumb.scss +17 -16
  28. data/app/assets/stylesheets/semantic-ui/collections/_form.scss +223 -121
  29. data/app/assets/stylesheets/semantic-ui/collections/_grid.scss +462 -448
  30. data/app/assets/stylesheets/semantic-ui/collections/_menu.scss +949 -665
  31. data/app/assets/stylesheets/semantic-ui/collections/_message.scss +134 -92
  32. data/app/assets/stylesheets/semantic-ui/collections/_table.scss +270 -208
  33. data/app/assets/stylesheets/semantic-ui/elements/_all.scss +1 -0
  34. data/app/assets/stylesheets/semantic-ui/elements/_button.scss +1357 -521
  35. data/app/assets/stylesheets/semantic-ui/elements/_container.scss +125 -0
  36. data/app/assets/stylesheets/semantic-ui/elements/_divider.scss +51 -31
  37. data/app/assets/stylesheets/semantic-ui/elements/_flag.scss +3 -3
  38. data/app/assets/stylesheets/semantic-ui/elements/_header.scss +270 -144
  39. data/app/assets/stylesheets/semantic-ui/elements/_icon.scss +241 -110
  40. data/app/assets/stylesheets/semantic-ui/elements/_image.scss +30 -16
  41. data/app/assets/stylesheets/semantic-ui/elements/_input.scss +88 -53
  42. data/app/assets/stylesheets/semantic-ui/elements/_label.scss +432 -281
  43. data/app/assets/stylesheets/semantic-ui/elements/_list.scss +172 -128
  44. data/app/assets/stylesheets/semantic-ui/elements/_loader.scss +16 -14
  45. data/app/assets/stylesheets/semantic-ui/elements/_rail.scss +15 -7
  46. data/app/assets/stylesheets/semantic-ui/elements/_reveal.scss +32 -13
  47. data/app/assets/stylesheets/semantic-ui/elements/_segment.scss +329 -212
  48. data/app/assets/stylesheets/semantic-ui/elements/_step.scss +291 -99
  49. data/app/assets/stylesheets/semantic-ui/globals/_reset.scss +2 -2
  50. data/app/assets/stylesheets/semantic-ui/globals/_site.scss +19 -18
  51. data/app/assets/stylesheets/semantic-ui/modules/_accordion.scss +17 -18
  52. data/app/assets/stylesheets/semantic-ui/modules/_all.scss +1 -0
  53. data/app/assets/stylesheets/semantic-ui/modules/_checkbox.scss +265 -161
  54. data/app/assets/stylesheets/semantic-ui/modules/_dimmer.scss +29 -15
  55. data/app/assets/stylesheets/semantic-ui/modules/_dropdown.scss +441 -156
  56. data/app/assets/stylesheets/semantic-ui/modules/_embed.scss +168 -0
  57. data/app/assets/stylesheets/semantic-ui/modules/_modal.scss +163 -85
  58. data/app/assets/stylesheets/semantic-ui/modules/_nag.scss +8 -8
  59. data/app/assets/stylesheets/semantic-ui/modules/_popup.scss +88 -23
  60. data/app/assets/stylesheets/semantic-ui/modules/_progress.scss +185 -129
  61. data/app/assets/stylesheets/semantic-ui/modules/_rating.scss +75 -60
  62. data/app/assets/stylesheets/semantic-ui/modules/_search.scss +99 -52
  63. data/app/assets/stylesheets/semantic-ui/modules/_shape.scss +11 -11
  64. data/app/assets/stylesheets/semantic-ui/modules/_sidebar.scss +16 -12
  65. data/app/assets/stylesheets/semantic-ui/modules/_sticky.scss +4 -4
  66. data/app/assets/stylesheets/semantic-ui/modules/_tab.scss +3 -3
  67. data/app/assets/stylesheets/semantic-ui/modules/_transition.scss +31 -39
  68. data/app/assets/stylesheets/semantic-ui/views/_ad.scss +3 -3
  69. data/app/assets/stylesheets/semantic-ui/views/_all.scss +1 -0
  70. data/app/assets/stylesheets/semantic-ui/views/_card.scss +204 -162
  71. data/app/assets/stylesheets/semantic-ui/views/_comment.scss +6 -6
  72. data/app/assets/stylesheets/semantic-ui/views/_feed.scss +51 -26
  73. data/app/assets/stylesheets/semantic-ui/views/_item.scss +62 -36
  74. data/app/assets/stylesheets/semantic-ui/views/_statistic.scss +265 -90
  75. data/lib/semantic/ui/sass/version.rb +2 -2
  76. data/semantic-ui-sass.gemspec +2 -2
  77. metadata +9 -6
@@ -1,9 +1,9 @@
1
1
  /*!
2
- * # Semantic UI 1.12.3 - Site
2
+ * # Semantic UI - Site
3
3
  * http://github.com/semantic-org/semantic-ui/
4
4
  *
5
5
  *
6
- * Copyright 2014 Contributors
6
+ * Copyright 2015 Contributors
7
7
  * Released under the MIT license
8
8
  * http://opensource.org/licenses/MIT
9
9
  *
@@ -320,7 +320,7 @@ $.site = $.fn.site = function(parameters) {
320
320
  });
321
321
  }
322
322
  clearTimeout(module.performance.timer);
323
- module.performance.timer = setTimeout(module.performance.display, 100);
323
+ module.performance.timer = setTimeout(module.performance.display, 500);
324
324
  },
325
325
  display: function() {
326
326
  var
@@ -433,7 +433,7 @@ $.site.settings = {
433
433
  },
434
434
 
435
435
  debug : false,
436
- verbose : true,
436
+ verbose : false,
437
437
  performance : true,
438
438
 
439
439
  modules: [
@@ -442,6 +442,7 @@ $.site.settings = {
442
442
  'checkbox',
443
443
  'dimmer',
444
444
  'dropdown',
445
+ 'embed',
445
446
  'form',
446
447
  'modal',
447
448
  'nag',
@@ -453,7 +454,6 @@ $.site.settings = {
453
454
  'sticky',
454
455
  'tab',
455
456
  'transition',
456
- 'video',
457
457
  'visit',
458
458
  'visibility'
459
459
  ],
@@ -1,9 +1,9 @@
1
1
  /*!
2
- * # Semantic UI 1.12.3 - State
2
+ * # Semantic UI - State
3
3
  * http://github.com/semantic-org/semantic-ui/
4
4
  *
5
5
  *
6
- * Copyright 2014 Contributors
6
+ * Copyright 2015 Contributors
7
7
  * Released under the MIT license
8
8
  * http://opensource.org/licenses/MIT
9
9
  *
@@ -472,7 +472,7 @@ $.fn.state = function(parameters) {
472
472
  });
473
473
  }
474
474
  clearTimeout(module.performance.timer);
475
- module.performance.timer = setTimeout(module.performance.display, 100);
475
+ module.performance.timer = setTimeout(module.performance.display, 500);
476
476
  },
477
477
  display: function() {
478
478
  var
@@ -589,7 +589,7 @@ $.fn.state.settings = {
589
589
  debug : false,
590
590
 
591
591
  // verbose debug output
592
- verbose : true,
592
+ verbose : false,
593
593
 
594
594
  // namespace for events
595
595
  namespace : 'state',
@@ -1,9 +1,9 @@
1
1
  /*!
2
- * # Semantic UI 1.12.3 - Sticky
2
+ * # Semantic UI - Sticky
3
3
  * http://github.com/semantic-org/semantic-ui/
4
4
  *
5
5
  *
6
- * Copyright 2014 Contributorss
6
+ * Copyright 2015 Contributors
7
7
  * Released under the MIT license
8
8
  * http://opensource.org/licenses/MIT
9
9
  *
@@ -43,8 +43,8 @@ $.fn.sticky = function(parameters) {
43
43
 
44
44
  $module = $(this),
45
45
  $window = $(window),
46
- $container = $module.offsetParent(),
47
46
  $scroll = $(settings.scrollContext),
47
+ $container,
48
48
  $context,
49
49
 
50
50
  selector = $module.selector || '',
@@ -65,6 +65,7 @@ $.fn.sticky = function(parameters) {
65
65
 
66
66
  initialize: function() {
67
67
 
68
+ module.determineContainer();
68
69
  module.determineContext();
69
70
  module.verbose('Initializing sticky', settings, $container);
70
71
 
@@ -110,7 +111,7 @@ $.fn.sticky = function(parameters) {
110
111
  observer = new MutationObserver(function(mutations) {
111
112
  clearTimeout(module.timer);
112
113
  module.timer = setTimeout(function() {
113
- module.verbose('DOM tree modified, updating sticky menu');
114
+ module.verbose('DOM tree modified, updating sticky menu', mutations);
114
115
  module.refresh();
115
116
  }, 100);
116
117
  });
@@ -126,6 +127,10 @@ $.fn.sticky = function(parameters) {
126
127
  }
127
128
  },
128
129
 
130
+ determineContainer: function() {
131
+ $container = $module.offsetParent();
132
+ },
133
+
129
134
  determineContext: function() {
130
135
  if(settings.context) {
131
136
  $context = $(settings.context);
@@ -176,7 +181,7 @@ $.fn.sticky = function(parameters) {
176
181
  },
177
182
  scroll: function() {
178
183
  requestAnimationFrame(function() {
179
- $scroll.trigger('scrollchange' + eventNamespace, $scroll.scrollTop() );
184
+ $scroll.triggerHandler('scrollchange' + eventNamespace, $scroll.scrollTop() );
180
185
  });
181
186
  },
182
187
  scrollchange: function(event, scrollPosition) {
@@ -187,8 +192,11 @@ $.fn.sticky = function(parameters) {
187
192
 
188
193
  refresh: function(hardRefresh) {
189
194
  module.reset();
195
+ if(!settings.context) {
196
+ module.determineContext();
197
+ }
190
198
  if(hardRefresh) {
191
- $container = $module.offsetParent();
199
+ module.determineContainer();
192
200
  }
193
201
  module.save.positions();
194
202
  module.stick();
@@ -199,7 +207,7 @@ $.fn.sticky = function(parameters) {
199
207
  sticky: function() {
200
208
  var
201
209
  $element = $('<div/>'),
202
- element = $element.get()
210
+ element = $element[0]
203
211
  ;
204
212
  $element.addClass(className.supported);
205
213
  return($element.css('position').match('sticky'));
@@ -210,6 +218,9 @@ $.fn.sticky = function(parameters) {
210
218
  lastScroll: function(scroll) {
211
219
  module.lastScroll = scroll;
212
220
  },
221
+ elementScroll: function(scroll) {
222
+ module.elementScroll = scroll;
223
+ },
213
224
  positions: function() {
214
225
  var
215
226
  window = {
@@ -226,8 +237,10 @@ $.fn.sticky = function(parameters) {
226
237
  },
227
238
  context = {
228
239
  offset : $context.offset(),
229
- height : $context.outerHeight(),
230
- bottomPadding : parseInt($context.css('padding-bottom'), 10)
240
+ height : $context.outerHeight()
241
+ },
242
+ container = {
243
+ height: $container.outerHeight()
231
244
  }
232
245
  ;
233
246
  module.cache = {
@@ -246,8 +259,7 @@ $.fn.sticky = function(parameters) {
246
259
  context: {
247
260
  top : context.offset.top,
248
261
  height : context.height,
249
- bottomPadding : context.bottomPadding,
250
- bottom : context.offset.top + context.height - context.bottomPadding
262
+ bottom : context.offset.top + context.height
251
263
  }
252
264
  };
253
265
  module.set.containerSize();
@@ -281,6 +293,9 @@ $.fn.sticky = function(parameters) {
281
293
  ;
282
294
  },
283
295
  currentElementScroll: function() {
296
+ if(module.elementScroll) {
297
+ return module.elementScroll;
298
+ }
284
299
  return ( module.is.top() )
285
300
  ? Math.abs(parseInt($module.css('top'), 10)) || 0
286
301
  : Math.abs(parseInt($module.css('bottom'), 10)) || 0
@@ -295,8 +310,7 @@ $.fn.sticky = function(parameters) {
295
310
  delta = module.get.scrollChange(scroll),
296
311
  maxScroll = (element.height - window.height + settings.offset),
297
312
  elementScroll = module.get.currentElementScroll(),
298
- possibleScroll = (elementScroll + delta),
299
- elementScroll
313
+ possibleScroll = (elementScroll + delta)
300
314
  ;
301
315
  if(module.cache.fits || possibleScroll < 0) {
302
316
  elementScroll = 0;
@@ -312,6 +326,12 @@ $.fn.sticky = function(parameters) {
312
326
  },
313
327
 
314
328
  remove: {
329
+ lastScroll: function() {
330
+ delete module.lastScroll;
331
+ },
332
+ elementScroll: function(scroll) {
333
+ delete module.elementScroll;
334
+ },
315
335
  offset: function() {
316
336
  $module.css('margin-top', '');
317
337
  }
@@ -320,7 +340,9 @@ $.fn.sticky = function(parameters) {
320
340
  set: {
321
341
  offset: function() {
322
342
  module.verbose('Setting offset on element', settings.offset);
323
- $module.css('margin-top', settings.offset);
343
+ $module
344
+ .css('margin-top', settings.offset)
345
+ ;
324
346
  },
325
347
  containerSize: function() {
326
348
  var
@@ -329,10 +351,10 @@ $.fn.sticky = function(parameters) {
329
351
  if(tagName === 'HTML' || tagName == 'body') {
330
352
  // this can trigger for too many reasons
331
353
  //module.error(error.container, tagName, $module);
332
- $container = $module.offsetParent();
354
+ module.determineContainer();
333
355
  }
334
356
  else {
335
- if( Math.abs($container.height() - module.cache.context.height) > 5) {
357
+ if( Math.abs($container.outerHeight() - module.cache.context.height) > settings.jitter) {
336
358
  module.debug('Context has padding, specifying exact height for container', module.cache.context.height);
337
359
  $container.css({
338
360
  height: module.cache.context.height
@@ -340,8 +362,19 @@ $.fn.sticky = function(parameters) {
340
362
  }
341
363
  }
342
364
  },
365
+ minimumSize: function() {
366
+ var
367
+ element = module.cache.element
368
+ ;
369
+ $container
370
+ .css('min-height', element.height)
371
+ ;
372
+ },
343
373
  scroll: function(scroll) {
344
374
  module.debug('Setting scroll on element', scroll);
375
+ if(module.elementScroll == scroll) {
376
+ return;
377
+ }
345
378
  if( module.is.top() ) {
346
379
  $module
347
380
  .css('bottom', '')
@@ -413,20 +446,23 @@ $.fn.sticky = function(parameters) {
413
446
  elementVisible = (element.height !== 0)
414
447
  ;
415
448
 
416
- // save current scroll for next run
417
- module.save.lastScroll(scroll.top);
418
-
419
449
  if(elementVisible) {
420
450
 
421
451
  if( module.is.initialPosition() ) {
422
- if(scroll.top >= context.bottom) {
452
+ if(scroll.top > context.bottom) {
423
453
  module.debug('Element bottom of container');
424
454
  module.bindBottom();
425
455
  }
426
- else if(scroll.top >= element.top) {
456
+ else if(scroll.top > element.top) {
427
457
  module.debug('Element passed, fixing element to page');
428
- module.fixTop();
458
+ if( (element.height + scroll.top - elementScroll) > context.bottom ) {
459
+ module.bindBottom();
460
+ }
461
+ else {
462
+ module.fixTop();
463
+ }
429
464
  }
465
+
430
466
  }
431
467
  else if( module.is.fixed() ) {
432
468
 
@@ -443,6 +479,8 @@ $.fn.sticky = function(parameters) {
443
479
  // scroll element if larger than screen
444
480
  else if(doesntFit) {
445
481
  module.set.scroll(elementScroll);
482
+ module.save.lastScroll(scroll.top);
483
+ module.save.elementScroll(elementScroll);
446
484
  }
447
485
  }
448
486
 
@@ -462,6 +500,8 @@ $.fn.sticky = function(parameters) {
462
500
  // scroll element if larger than screen
463
501
  else if(doesntFit) {
464
502
  module.set.scroll(elementScroll);
503
+ module.save.lastScroll(scroll.top);
504
+ module.save.elementScroll(elementScroll);
465
505
  }
466
506
 
467
507
  }
@@ -487,9 +527,11 @@ $.fn.sticky = function(parameters) {
487
527
  module.debug('Binding element to top of parent container');
488
528
  module.remove.offset();
489
529
  $module
490
- .css('left' , '')
491
- .css('top' , '')
492
- .css('margin-bottom' , '')
530
+ .css({
531
+ left : '',
532
+ top : '',
533
+ marginBottom : ''
534
+ })
493
535
  .removeClass(className.fixed)
494
536
  .removeClass(className.bottom)
495
537
  .addClass(className.bound)
@@ -502,9 +544,10 @@ $.fn.sticky = function(parameters) {
502
544
  module.debug('Binding element to bottom of parent container');
503
545
  module.remove.offset();
504
546
  $module
505
- .css('left' , '')
506
- .css('top' , '')
507
- .css('margin-bottom' , module.cache.context.bottomPadding)
547
+ .css({
548
+ left : '',
549
+ top : ''
550
+ })
508
551
  .removeClass(className.fixed)
509
552
  .removeClass(className.top)
510
553
  .addClass(className.bound)
@@ -522,10 +565,14 @@ $.fn.sticky = function(parameters) {
522
565
 
523
566
  fixTop: function() {
524
567
  module.debug('Fixing element to top of page');
568
+ module.set.minimumSize();
525
569
  module.set.offset();
526
570
  $module
527
- .css('left', module.cache.element.left)
528
- .css('bottom' , '')
571
+ .css({
572
+ left : module.cache.element.left,
573
+ bottom : '',
574
+ marginBottom : ''
575
+ })
529
576
  .removeClass(className.bound)
530
577
  .removeClass(className.bottom)
531
578
  .addClass(className.fixed)
@@ -536,10 +583,14 @@ $.fn.sticky = function(parameters) {
536
583
 
537
584
  fixBottom: function() {
538
585
  module.debug('Sticking element to bottom of page');
586
+ module.set.minimumSize();
539
587
  module.set.offset();
540
588
  $module
541
- .css('left', module.cache.element.left)
542
- .css('bottom' , '')
589
+ .css({
590
+ left : module.cache.element.left,
591
+ bottom : '',
592
+ marginBottom : ''
593
+ })
543
594
  .removeClass(className.bound)
544
595
  .removeClass(className.top)
545
596
  .addClass(className.fixed)
@@ -575,6 +626,7 @@ $.fn.sticky = function(parameters) {
575
626
  module.unfix();
576
627
  module.resetCSS();
577
628
  module.remove.offset();
629
+ module.remove.lastScroll();
578
630
  },
579
631
 
580
632
  resetCSS: function() {
@@ -772,23 +824,44 @@ $.fn.sticky.settings = {
772
824
  namespace : 'sticky',
773
825
 
774
826
  debug : false,
775
- verbose : false,
776
- performance : false,
827
+ verbose : true,
828
+ performance : true,
777
829
 
830
+ // whether to stick in the opposite direction on scroll up
778
831
  pushing : false,
832
+
779
833
  context : false,
834
+
835
+ // Context to watch scroll events
780
836
  scrollContext : window,
781
837
 
838
+ // Offset to adjust scroll
782
839
  offset : 0,
840
+
841
+ // Offset to adjust scroll when attached to bottom of screen
783
842
  bottomOffset : 0,
784
843
 
785
- observeChanges : true,
844
+ jitter : 5, // will only set container height if difference between context and container is larger than this number
786
845
 
846
+ // Whether to automatically observe changes with Mutation Observers
847
+ observeChanges : false,
848
+
849
+ // Called when position is recalculated
787
850
  onReposition : function(){},
851
+
852
+ // Called on each scroll
788
853
  onScroll : function(){},
854
+
855
+ // Called when element is stuck to viewport
789
856
  onStick : function(){},
857
+
858
+ // Called when element is unstuck from viewport
790
859
  onUnstick : function(){},
860
+
861
+ // Called when element reaches top of context
791
862
  onTop : function(){},
863
+
864
+ // Called when element reaches bottom of context
792
865
  onBottom : function(){},
793
866
 
794
867
  error : {
@@ -1,9 +1,9 @@
1
1
  /*!
2
- * # Semantic UI 1.12.3 - Tab
2
+ * # Semantic UI - Tab
3
3
  * http://github.com/semantic-org/semantic-ui/
4
4
  *
5
5
  *
6
- * Copyright 2014 Contributorss
6
+ * Copyright 2015 Contributors
7
7
  * Released under the MIT license
8
8
  * http://opensource.org/licenses/MIT
9
9
  *
@@ -21,10 +21,6 @@ $.fn.tab = function(parameters) {
21
21
  ? $(window)
22
22
  : $(this),
23
23
 
24
- settings = ( $.isPlainObject(parameters) )
25
- ? $.extend(true, {}, $.fn.tab.settings, parameters)
26
- : $.extend({}, $.fn.tab.settings),
27
-
28
24
  moduleSelector = $allModules.selector || '',
29
25
  time = new Date().getTime(),
30
26
  performance = [],
@@ -33,7 +29,7 @@ $.fn.tab = function(parameters) {
33
29
  methodInvoked = (typeof query == 'string'),
34
30
  queryArguments = [].slice.call(arguments, 1),
35
31
 
36
- module,
32
+ initializedHistory = false,
37
33
  returnedValue
38
34
  ;
39
35
 
@@ -41,53 +37,86 @@ $.fn.tab = function(parameters) {
41
37
  .each(function() {
42
38
  var
43
39
 
44
- className = settings.className,
45
- metadata = settings.metadata,
46
- selector = settings.selector,
47
- error = settings.error,
48
-
49
- eventNamespace = '.' + settings.namespace,
50
- moduleNamespace = 'module-' + settings.namespace,
40
+ settings = ( $.isPlainObject(parameters) )
41
+ ? $.extend(true, {}, $.fn.tab.settings, parameters)
42
+ : $.extend({}, $.fn.tab.settings),
51
43
 
52
- $module = $(this),
44
+ className = settings.className,
45
+ metadata = settings.metadata,
46
+ selector = settings.selector,
47
+ error = settings.error,
53
48
 
54
- cache = {},
55
- firstLoad = true,
56
- recursionDepth = 0,
49
+ eventNamespace = '.' + settings.namespace,
50
+ moduleNamespace = 'module-' + settings.namespace,
57
51
 
52
+ $module = $(this),
58
53
  $context,
59
54
  $tabs,
55
+
56
+ cache = {},
57
+ firstLoad = true,
58
+ recursionDepth = 0,
59
+ element = this,
60
+ instance = $module.data(moduleNamespace),
61
+
60
62
  activeTabPath,
61
63
  parameterArray,
62
- historyEvent,
64
+ module,
65
+
66
+ historyEvent
63
67
 
64
- element = this,
65
- instance = $module.data(moduleNamespace)
66
68
  ;
67
69
 
68
70
  module = {
69
71
 
70
72
  initialize: function() {
71
73
  module.debug('Initializing tab menu item', $module);
72
-
74
+ module.fix.callbacks();
73
75
  module.determineTabs();
74
- module.debug('Determining tabs', settings.context, $tabs);
75
76
 
77
+ module.debug('Determining tabs', settings.context, $tabs);
76
78
  // set up automatic routing
77
79
  if(settings.auto) {
78
80
  module.set.auto();
79
81
  }
82
+ module.bind.events();
80
83
 
81
- // attach events if navigation wasn't set to window
82
- if( !$.isWindow( element ) ) {
83
- module.debug('Attaching tab activation events to element', $module);
84
- $module
85
- .on('click' + eventNamespace, module.event.click)
86
- ;
84
+ if(settings.history && !initializedHistory) {
85
+ module.initializeHistory();
86
+ initializedHistory = true;
87
87
  }
88
+
88
89
  module.instantiate();
89
90
  },
90
91
 
92
+ instantiate: function () {
93
+ module.verbose('Storing instance of module', module);
94
+ instance = module;
95
+ $module
96
+ .data(moduleNamespace, module)
97
+ ;
98
+ },
99
+
100
+ destroy: function() {
101
+ module.debug('Destroying tabs', $module);
102
+ $module
103
+ .removeData(moduleNamespace)
104
+ .off(eventNamespace)
105
+ ;
106
+ },
107
+
108
+ bind: {
109
+ events: function() {
110
+ // if using $.tab dont add events
111
+ if( !$.isWindow( element ) ) {
112
+ module.debug('Attaching tab activation events to element', $module);
113
+ $module
114
+ .on('click' + eventNamespace, module.event.click)
115
+ ;
116
+ }
117
+ }
118
+ },
119
+
91
120
  determineTabs: function() {
92
121
  var
93
122
  $reference
@@ -97,7 +126,7 @@ $.fn.tab = function(parameters) {
97
126
  if(settings.context === 'parent') {
98
127
  if($module.closest(selector.ui).length > 0) {
99
128
  $reference = $module.closest(selector.ui);
100
- module.verbose('Using closest UI element for determining parent', $reference);
129
+ module.verbose('Using closest UI element as parent', $reference);
101
130
  }
102
131
  else {
103
132
  $reference = $module;
@@ -112,7 +141,6 @@ $.fn.tab = function(parameters) {
112
141
  else {
113
142
  $context = $('body');
114
143
  }
115
-
116
144
  // find tabs
117
145
  if(settings.childrenOnly) {
118
146
  $tabs = $context.children(selector.tabs);
@@ -124,48 +152,48 @@ $.fn.tab = function(parameters) {
124
152
  }
125
153
  },
126
154
 
127
- initializeHistory: function() {
128
- if(settings.history) {
129
- module.debug('Initializing page state');
130
- if( $.address === undefined ) {
131
- module.error(error.state);
132
- return false;
133
- }
134
- else {
135
- if(settings.historyType == 'state') {
136
- module.debug('Using HTML5 to manage state');
137
- if(settings.path !== false) {
138
- $.address
139
- .history(true)
140
- .state(settings.path)
141
- ;
142
- }
143
- else {
144
- module.error(error.path);
145
- return false;
146
- }
155
+ fix: {
156
+ callbacks: function() {
157
+ if( $.isPlainObject(parameters) && (parameters.onTabLoad || parameters.onTabInit) ) {
158
+ if(parameters.onTabLoad) {
159
+ parameters.onLoad = parameters.onTabLoad;
160
+ delete parameters.onTabLoad;
161
+ module.error(error.legacyLoad, parameters.onLoad);
147
162
  }
148
- $.address
149
- .bind('change', module.event.history.change)
150
- ;
163
+ if(parameters.onTabInit) {
164
+ parameters.onFirstLoad = parameters.onTabInit;
165
+ delete parameters.onTabInit;
166
+ module.error(error.legacyInit, parameters.onFirstLoad);
167
+ }
168
+ settings = $.extend(true, {}, $.fn.tab.settings, parameters);
151
169
  }
152
170
  }
153
171
  },
154
172
 
155
- instantiate: function () {
156
- module.verbose('Storing instance of module', module);
157
- instance = module;
158
- $module
159
- .data(moduleNamespace, module)
160
- ;
161
- },
162
-
163
- destroy: function() {
164
- module.debug('Destroying tabs', $module);
165
- $module
166
- .removeData(moduleNamespace)
167
- .off(eventNamespace)
168
- ;
173
+ initializeHistory: function() {
174
+ module.debug('Initializing page state');
175
+ if( $.address === undefined ) {
176
+ module.error(error.state);
177
+ return false;
178
+ }
179
+ else {
180
+ if(settings.historyType == 'state') {
181
+ module.debug('Using HTML5 to manage state');
182
+ if(settings.path !== false) {
183
+ $.address
184
+ .history(true)
185
+ .state(settings.path)
186
+ ;
187
+ }
188
+ else {
189
+ module.error(error.path);
190
+ return false;
191
+ }
192
+ }
193
+ $.address
194
+ .bind('change', module.event.history.change)
195
+ ;
196
+ }
169
197
  },
170
198
 
171
199
  event: {
@@ -251,6 +279,23 @@ $.fn.tab = function(parameters) {
251
279
  };
252
280
  }
253
281
  },
282
+ loading: function(tabPath) {
283
+ var
284
+ $tab = module.get.tabElement(tabPath),
285
+ isLoading = $tab.hasClass(className.loading)
286
+ ;
287
+ if(!isLoading) {
288
+ module.verbose('Setting loading state for', $tab);
289
+ $tab
290
+ .addClass(className.loading)
291
+ .siblings($tabs)
292
+ .removeClass(className.active + ' ' + className.loading)
293
+ ;
294
+ if($tab.length > 0) {
295
+ settings.onRequest.call($tab[0], tabPath);
296
+ }
297
+ }
298
+ },
254
299
  state: function(state) {
255
300
  $.address.value(state);
256
301
  }
@@ -261,7 +306,7 @@ $.fn.tab = function(parameters) {
261
306
  pushStateAvailable = (window.history && window.history.pushState),
262
307
  shouldIgnoreLoad = (pushStateAvailable && settings.ignoreFirstLoad && firstLoad),
263
308
  remoteContent = (settings.auto || $.isPlainObject(settings.apiSettings) ),
264
- // only get default path if not remote content
309
+ // only add default path if not remote content
265
310
  pathArray = (remoteContent && !shouldIgnoreLoad)
266
311
  ? module.utilities.pathToArray(tabPath)
267
312
  : module.get.defaultPathArray(tabPath)
@@ -283,7 +328,6 @@ $.fn.tab = function(parameters) {
283
328
  ;
284
329
  module.verbose('Looking for tab', tab);
285
330
  if(isTab) {
286
-
287
331
  module.verbose('Tab was found', tab);
288
332
  // scope up
289
333
  activeTabPath = currentPath;
@@ -303,15 +347,15 @@ $.fn.tab = function(parameters) {
303
347
  if(isLastTab && remoteContent) {
304
348
  if(!shouldIgnoreLoad) {
305
349
  module.activate.navigation(currentPath);
306
- module.content.fetch(currentPath, tabPath);
350
+ module.fetch.content(currentPath, tabPath);
307
351
  }
308
352
  else {
309
353
  module.debug('Ignoring remote content on first tab load', currentPath);
310
354
  firstLoad = false;
311
355
  module.cache.add(tabPath, $tab.html());
312
356
  module.activate.all(currentPath);
313
- settings.onTabInit.call($tab, currentPath, parameterArray, historyEvent);
314
- settings.onTabLoad.call($tab, currentPath, parameterArray, historyEvent);
357
+ settings.onFirstLoad.call($tab[0], currentPath, parameterArray, historyEvent);
358
+ settings.onLoad.call($tab[0], currentPath, parameterArray, historyEvent);
315
359
  }
316
360
  return false;
317
361
  }
@@ -321,25 +365,32 @@ $.fn.tab = function(parameters) {
321
365
  if( !module.cache.read(currentPath) ) {
322
366
  module.cache.add(currentPath, true);
323
367
  module.debug('First time tab loaded calling tab init');
324
- settings.onTabInit.call($tab, currentPath, parameterArray, historyEvent);
368
+ settings.onFirstLoad.call($tab[0], currentPath, parameterArray, historyEvent);
325
369
  }
326
- settings.onTabLoad.call($tab, currentPath, parameterArray, historyEvent);
370
+ settings.onLoad.call($tab[0], currentPath, parameterArray, historyEvent);
327
371
  }
372
+
328
373
  }
329
374
  else if(tabPath.search('/') == -1 && tabPath !== '') {
330
375
  // look for in page anchor
331
- $anchor = $('#' + tabPath + ', a[name="' + tabPath + '"]'),
376
+ $anchor = $('#' + tabPath + ', a[name="' + tabPath + '"]');
332
377
  currentPath = $anchor.closest('[data-tab]').data('tab');
333
378
  $tab = module.get.tabElement(currentPath);
334
379
  // if anchor exists use parent tab
335
380
  if($anchor && $anchor.length > 0 && currentPath) {
336
- module.debug('No tab found, but deep anchor link present, opening parent tab');
381
+ module.debug('Anchor link used, opening parent tab', $tab, $anchor);
382
+ if( !$tab.hasClass(className.active) ) {
383
+ setTimeout(function() {
384
+ module.scrollTo($anchor);
385
+ }, 0);
386
+ }
337
387
  module.activate.all(currentPath);
338
388
  if( !module.cache.read(currentPath) ) {
339
389
  module.cache.add(currentPath, true);
340
390
  module.debug('First time tab loaded calling tab init');
341
- settings.onTabInit.call($tab, currentPath, parameterArray, historyEvent);
391
+ settings.onFirstLoad.call($tab[0], currentPath, parameterArray, historyEvent);
342
392
  }
393
+ settings.onLoad.call($tab[0], currentPath, parameterArray, historyEvent);
343
394
  return false;
344
395
  }
345
396
  }
@@ -350,17 +401,54 @@ $.fn.tab = function(parameters) {
350
401
  });
351
402
  },
352
403
 
353
- content: {
404
+ scrollTo: function($element) {
405
+ var
406
+ scrollOffset = ($element && $element.length > 0)
407
+ ? $element.offset().top
408
+ : false
409
+ ;
410
+ if(scrollOffset !== false) {
411
+ module.debug('Forcing scroll to an in-page link in a hidden tab', scrollOffset, $element);
412
+ $(document).scrollTop(scrollOffset);
413
+ }
414
+ },
415
+
416
+ update: {
417
+ content: function(tabPath, html, evaluateScripts) {
418
+ var
419
+ $tab = module.get.tabElement(tabPath),
420
+ tab = $tab[0]
421
+ ;
422
+ evaluateScripts = (evaluateScripts !== undefined)
423
+ ? evaluateScripts
424
+ : settings.evaluateScripts
425
+ ;
426
+ if(evaluateScripts) {
427
+ module.debug('Updating HTML and evaluating inline scripts', tabPath, html);
428
+ $tab.html(html);
429
+ }
430
+ else {
431
+ module.debug('Updating HTML', tabPath, html);
432
+ tab.innerHTML = html;
433
+ }
434
+ }
435
+ },
436
+
437
+ fetch: {
354
438
 
355
- fetch: function(tabPath, fullTabPath) {
439
+ content: function(tabPath, fullTabPath) {
356
440
  var
357
441
  $tab = module.get.tabElement(tabPath),
358
442
  apiSettings = {
359
443
  dataType : 'html',
360
444
  on : 'now',
361
- onSuccess : function(response) {
445
+ cache : settings.alwaysRefresh,
446
+ headers : {
447
+ 'X-Remote': true
448
+ },
449
+ onSuccess : function(response) {
362
450
  module.cache.add(fullTabPath, response);
363
- module.content.update(tabPath, response);
451
+ module.update.content(tabPath, response);
364
452
  if(tabPath == activeTabPath) {
365
453
  module.debug('Content loaded', tabPath);
366
454
  module.activate.tab(tabPath);
@@ -368,10 +456,12 @@ $.fn.tab = function(parameters) {
368
456
  else {
369
457
  module.debug('Content loaded in background', tabPath);
370
458
  }
371
- settings.onTabInit.call($tab, tabPath, parameterArray, historyEvent);
372
- settings.onTabLoad.call($tab, tabPath, parameterArray, historyEvent);
459
+ settings.onFirstLoad.call($tab[0], tabPath, parameterArray, historyEvent);
460
+ settings.onLoad.call($tab[0], tabPath, parameterArray, historyEvent);
373
461
  },
374
- urlData: { tab: fullTabPath }
462
+ urlData: {
463
+ tab: fullTabPath
464
+ }
375
465
  },
376
466
  request = $tab.api('get request') || false,
377
467
  existingRequest = ( request && request.state() === 'pending' ),
@@ -383,37 +473,30 @@ $.fn.tab = function(parameters) {
383
473
  cachedContent = module.cache.read(fullTabPath);
384
474
 
385
475
 
386
- module.activate.tab(tabPath);
387
-
388
476
  if(settings.cache && cachedContent) {
389
- module.debug('Showing existing content', fullTabPath);
390
- module.content.update(tabPath, cachedContent);
391
- settings.onTabLoad.call($tab, tabPath, parameterArray, historyEvent);
477
+ module.activate.tab(tabPath);
478
+ module.debug('Adding cached content', fullTabPath);
479
+ if(settings.evaluateScripts == 'once') {
480
+ module.update.content(tabPath, cachedContent, false);
481
+ }
482
+ else {
483
+ module.update.content(tabPath, cachedContent);
484
+ }
485
+ settings.onLoad.call($tab[0], tabPath, parameterArray, historyEvent);
392
486
  }
393
487
  else if(existingRequest) {
488
+ module.set.loading(tabPath);
394
489
  module.debug('Content is already loading', fullTabPath);
395
- $tab.addClass(className.loading);
396
490
  }
397
491
  else if($.api !== undefined) {
398
- requestSettings = $.extend(true, {
399
- headers: { 'X-Remote': true }
400
- }, settings.apiSettings, apiSettings);
492
+ requestSettings = $.extend(true, {}, settings.apiSettings, apiSettings);
401
493
  module.debug('Retrieving remote content', fullTabPath, requestSettings);
402
- $tab.api( requestSettings );
494
+ module.set.loading(tabPath);
495
+ $tab.api(requestSettings);
403
496
  }
404
497
  else {
405
498
  module.error(error.api);
406
499
  }
407
- },
408
-
409
- update: function(tabPath, html) {
410
- module.debug('Updating html for', tabPath);
411
- var
412
- $tab = module.get.tabElement(tabPath)
413
- ;
414
- $tab
415
- .html(html)
416
- ;
417
500
  }
418
501
  },
419
502
 
@@ -424,25 +507,34 @@ $.fn.tab = function(parameters) {
424
507
  },
425
508
  tab: function(tabPath) {
426
509
  var
427
- $tab = module.get.tabElement(tabPath)
510
+ $tab = module.get.tabElement(tabPath),
511
+ isActive = $tab.hasClass(className.active)
428
512
  ;
429
513
  module.verbose('Showing tab content for', $tab);
430
- $tab
431
- .addClass(className.active)
432
- .siblings($tabs)
433
- .removeClass(className.active + ' ' + className.loading)
434
- ;
514
+ if(!isActive) {
515
+ $tab
516
+ .addClass(className.active)
517
+ .siblings($tabs)
518
+ .removeClass(className.active + ' ' + className.loading)
519
+ ;
520
+ if($tab.length > 0) {
521
+ settings.onVisible.call($tab[0], tabPath);
522
+ }
523
+ }
435
524
  },
436
525
  navigation: function(tabPath) {
437
526
  var
438
- $navigation = module.get.navElement(tabPath)
527
+ $navigation = module.get.navElement(tabPath),
528
+ isActive = $navigation.hasClass(className.active)
439
529
  ;
440
530
  module.verbose('Activating tab navigation for', $navigation, tabPath);
441
- $navigation
442
- .addClass(className.active)
443
- .siblings($allModules)
444
- .removeClass(className.active + ' ' + className.loading)
445
- ;
531
+ if(!isActive) {
532
+ $navigation
533
+ .addClass(className.active)
534
+ .siblings($allModules)
535
+ .removeClass(className.active + ' ' + className.loading)
536
+ ;
537
+ }
446
538
  }
447
539
  },
448
540
 
@@ -626,7 +718,7 @@ $.fn.tab = function(parameters) {
626
718
  });
627
719
  }
628
720
  clearTimeout(module.performance.timer);
629
- module.performance.timer = setTimeout(module.performance.display, 100);
721
+ module.performance.timer = setTimeout(module.performance.display, 500);
630
722
  },
631
723
  display: function() {
632
724
  var
@@ -726,9 +818,6 @@ $.fn.tab = function(parameters) {
726
818
  }
727
819
  })
728
820
  ;
729
- if(module && !methodInvoked) {
730
- module.initializeHistory();
731
- }
732
821
  return (returnedValue !== undefined)
733
822
  ? returnedValue
734
823
  : this
@@ -747,7 +836,7 @@ $.fn.tab.settings = {
747
836
  namespace : 'tab',
748
837
 
749
838
  debug : false,
750
- verbose : true,
839
+ verbose : false,
751
840
  performance : true,
752
841
 
753
842
  auto : false, // uses pjax style endpoints fetching content from same url with remote-content headers
@@ -762,10 +851,14 @@ $.fn.tab.settings = {
762
851
  alwaysRefresh : false, // load tab content new every tab click
763
852
  cache : true, // cache the content requests to pull locally
764
853
  ignoreFirstLoad : false, // don't load remote content on first load
854
+
765
855
  apiSettings : false, // settings for api call
856
+ evaluateScripts : 'once', // whether inline scripts should be parsed (true/false/once). Once will not re-evaluate on cached content
766
857
 
767
- onTabInit : function(tabPath, parameterArray, historyEvent) {}, // called first time loaded
768
- onTabLoad : function(tabPath, parameterArray, historyEvent) {}, // called on every load
858
+ onFirstLoad : function(tabPath, parameterArray, historyEvent) {}, // called first time loaded
859
+ onLoad : function(tabPath, parameterArray, historyEvent) {}, // called on every load
860
+ onVisible : function(tabPath, parameterArray, historyEvent) {}, // called every time tab visible
861
+ onRequest : function(tabPath, parameterArray, historyEvent) {}, // called ever time a tab beings loading remote content
769
862
 
770
863
  templates : {
771
864
  determineTitle: function(tabArray) {} // returns page title for path
@@ -774,10 +867,12 @@ $.fn.tab.settings = {
774
867
  error: {
775
868
  api : 'You attempted to load content without API module',
776
869
  method : 'The method you called is not defined',
777
- missingTab : 'Activated tab cannot be found for this context.',
870
+ missingTab : 'Activated tab cannot be found. Tabs are case-sensitive.',
778
871
  noContent : 'The tab you specified is missing a content url.',
779
872
  path : 'History enabled, but no path was specified',
780
873
  recursion : 'Max recursive depth reached',
874
+ legacyInit : 'onTabInit has been renamed to onFirstLoad in 2.0, please adjust your code.',
875
+ legacyLoad : 'onTabLoad has been renamed to onLoad in 2.0. Please adjust your code',
781
876
  state : 'History requires Asual\'s Address library <https://github.com/asual/jquery-address>'
782
877
  },
783
878