less-rails-semantic_ui 2.2.13.0 → 2.3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/assets/fonts/semantic_ui/themes/default/assets/fonts/icons.eot +0 -0
  3. data/assets/fonts/semantic_ui/themes/default/assets/fonts/icons.svg +946 -2670
  4. data/assets/fonts/semantic_ui/themes/default/assets/fonts/icons.ttf +0 -0
  5. data/assets/fonts/semantic_ui/themes/default/assets/fonts/icons.woff +0 -0
  6. data/assets/fonts/semantic_ui/themes/default/assets/fonts/icons.woff2 +0 -0
  7. data/assets/javascripts/semantic_ui/definitions/behaviors/form.js +7 -7
  8. data/assets/javascripts/semantic_ui/definitions/behaviors/visibility.js +2 -2
  9. data/assets/javascripts/semantic_ui/definitions/modules/accordion.js +5 -2
  10. data/assets/javascripts/semantic_ui/definitions/modules/dimmer.js +2 -0
  11. data/assets/javascripts/semantic_ui/definitions/modules/dropdown.js +48 -10
  12. data/assets/javascripts/semantic_ui/definitions/modules/modal.js +34 -42
  13. data/assets/javascripts/semantic_ui/definitions/modules/popup.js +49 -12
  14. data/assets/javascripts/semantic_ui/definitions/modules/search.js +71 -18
  15. data/assets/stylesheets/semantic_ui/definitions/collections/menu.less +9 -0
  16. data/assets/stylesheets/semantic_ui/definitions/collections/table.less +7 -2
  17. data/assets/stylesheets/semantic_ui/definitions/elements/button.less +1 -1
  18. data/assets/stylesheets/semantic_ui/definitions/elements/header.less +1 -1
  19. data/assets/stylesheets/semantic_ui/definitions/elements/icon.less +2 -2
  20. data/assets/stylesheets/semantic_ui/definitions/elements/image.less +4 -0
  21. data/assets/stylesheets/semantic_ui/definitions/elements/input.less +35 -35
  22. data/assets/stylesheets/semantic_ui/definitions/elements/label.less +1 -0
  23. data/assets/stylesheets/semantic_ui/definitions/elements/list.less +14 -14
  24. data/assets/stylesheets/semantic_ui/definitions/elements/reveal.less +8 -0
  25. data/assets/stylesheets/semantic_ui/definitions/globals/site.less +1 -0
  26. data/assets/stylesheets/semantic_ui/definitions/modules/dimmer.less +22 -9
  27. data/assets/stylesheets/semantic_ui/definitions/modules/dropdown.less +1 -1
  28. data/assets/stylesheets/semantic_ui/definitions/modules/modal.less +16 -21
  29. data/assets/stylesheets/semantic_ui/definitions/modules/popup.less +1 -1
  30. data/assets/stylesheets/semantic_ui/definitions/modules/rating.less +1 -1
  31. data/assets/stylesheets/semantic_ui/definitions/modules/search.less +34 -17
  32. data/assets/stylesheets/semantic_ui/themes/default/collections/breadcrumb.variables +1 -1
  33. data/assets/stylesheets/semantic_ui/themes/default/collections/form.variables +1 -1
  34. data/assets/stylesheets/semantic_ui/themes/default/collections/menu.variables +20 -20
  35. data/assets/stylesheets/semantic_ui/themes/default/collections/message.variables +1 -1
  36. data/assets/stylesheets/semantic_ui/themes/default/collections/table.variables +7 -6
  37. data/assets/stylesheets/semantic_ui/themes/default/elements/button.variables +4 -4
  38. data/assets/stylesheets/semantic_ui/themes/default/elements/divider.variables +2 -2
  39. data/assets/stylesheets/semantic_ui/themes/default/elements/flag.overrides +4 -0
  40. data/assets/stylesheets/semantic_ui/themes/default/elements/header.variables +1 -1
  41. data/assets/stylesheets/semantic_ui/themes/default/elements/icon.overrides +1263 -879
  42. data/assets/stylesheets/semantic_ui/themes/default/elements/label.variables +3 -3
  43. data/assets/stylesheets/semantic_ui/themes/default/elements/list.variables +1 -1
  44. data/assets/stylesheets/semantic_ui/themes/default/elements/reveal.variables +2 -1
  45. data/assets/stylesheets/semantic_ui/themes/default/elements/step.variables +3 -3
  46. data/assets/stylesheets/semantic_ui/themes/default/globals/site.variables +7 -2
  47. data/assets/stylesheets/semantic_ui/themes/default/modules/accordion.overrides +1 -1
  48. data/assets/stylesheets/semantic_ui/themes/default/modules/accordion.variables +1 -1
  49. data/assets/stylesheets/semantic_ui/themes/default/modules/checkbox.variables +2 -2
  50. data/assets/stylesheets/semantic_ui/themes/default/modules/dimmer.variables +2 -5
  51. data/assets/stylesheets/semantic_ui/themes/default/modules/dropdown.variables +6 -6
  52. data/assets/stylesheets/semantic_ui/themes/default/modules/modal.variables +33 -29
  53. data/assets/stylesheets/semantic_ui/themes/default/modules/popup.variables +4 -3
  54. data/assets/stylesheets/semantic_ui/themes/default/modules/progress.variables +2 -2
  55. data/assets/stylesheets/semantic_ui/themes/default/modules/search.variables +8 -5
  56. data/assets/stylesheets/semantic_ui/themes/default/modules/transition.overrides +54 -2
  57. data/assets/stylesheets/semantic_ui/themes/default/views/ad.variables +2 -2
  58. data/assets/stylesheets/semantic_ui/themes/default/views/card.variables +1 -1
  59. data/assets/stylesheets/semantic_ui/themes/default/views/comment.variables +1 -1
  60. data/assets/stylesheets/semantic_ui/themes/default/views/feed.variables +4 -4
  61. data/assets/stylesheets/semantic_ui/themes/default/views/item.variables +1 -1
  62. data/assets/stylesheets/semantic_ui/themes/default/views/statistic.variables +4 -4
  63. data/lib/less/rails/semantic_ui/version.rb +1 -1
  64. metadata +4 -3
@@ -358,7 +358,7 @@ $.fn.form = function(parameters) {
358
358
  module.validate.field( validationRules );
359
359
  }
360
360
  }
361
- else if(settings.on == 'blur' || settings.on == 'change') {
361
+ else if(settings.on == 'blur') {
362
362
  if(validationRules) {
363
363
  module.validate.field( validationRules );
364
364
  }
@@ -603,9 +603,9 @@ $.fn.form = function(parameters) {
603
603
  }
604
604
  else {
605
605
  if(isRadio) {
606
- if(values[name] === undefined) {
606
+ if(values[name] === undefined || values[name] == false) {
607
607
  values[name] = (isChecked)
608
- ? true
608
+ ? value || true
609
609
  : false
610
610
  ;
611
611
  }
@@ -1263,10 +1263,10 @@ $.fn.form.settings = {
1263
1263
  isExactly : '{name} must be exactly "{ruleValue}"',
1264
1264
  not : '{name} cannot be set to "{ruleValue}"',
1265
1265
  notExactly : '{name} cannot be set to exactly "{ruleValue}"',
1266
- contain : '{name} cannot contain "{ruleValue}"',
1267
- containExactly : '{name} cannot contain exactly "{ruleValue}"',
1268
- doesntContain : '{name} must contain "{ruleValue}"',
1269
- doesntContainExactly : '{name} must contain exactly "{ruleValue}"',
1266
+ contain : '{name} must contain "{ruleValue}"',
1267
+ containExactly : '{name} must contain exactly "{ruleValue}"',
1268
+ doesntContain : '{name} cannot contain "{ruleValue}"',
1269
+ doesntContainExactly : '{name} cannot contain exactly "{ruleValue}"',
1270
1270
  minLength : '{name} must be at least {ruleValue} characters',
1271
1271
  length : '{name} must be at least {ruleValue} characters',
1272
1272
  exactLength : '{name} must be exactly {ruleValue} characters',
@@ -927,8 +927,8 @@ $.fn.visibility = function(parameters) {
927
927
  // visibility
928
928
  element.topPassed = (screen.top >= element.top);
929
929
  element.bottomPassed = (screen.top >= element.bottom);
930
- element.topVisible = (screen.bottom >= element.top) && !element.bottomPassed;
931
- element.bottomVisible = (screen.bottom >= element.bottom) && !element.topPassed;
930
+ element.topVisible = (screen.bottom >= element.top) && !element.topPassed;
931
+ element.bottomVisible = (screen.bottom >= element.bottom) && !element.bottomPassed;
932
932
  element.pixelsPassed = 0;
933
933
  element.percentagePassed = 0;
934
934
 
@@ -169,6 +169,7 @@ $.fn.accordion = function(parameters) {
169
169
  }
170
170
  module.debug('Opening accordion content', $activeTitle);
171
171
  settings.onOpening.call($activeContent);
172
+ settings.onChanging.call($activeContent);
172
173
  if(settings.exclusive) {
173
174
  module.closeOthers.call($activeTitle);
174
175
  }
@@ -232,6 +233,7 @@ $.fn.accordion = function(parameters) {
232
233
  if((isActive || isOpening) && !isClosing) {
233
234
  module.debug('Closing accordion content', $activeContent);
234
235
  settings.onClosing.call($activeContent);
236
+ settings.onChanging.call($activeContent);
235
237
  $activeTitle
236
238
  .removeClass(className.active)
237
239
  ;
@@ -574,10 +576,11 @@ $.fn.accordion.settings = {
574
576
  duration : 350, // duration of animation
575
577
  easing : 'easeOutQuad', // easing equation for animation
576
578
 
577
-
578
579
  onOpening : function(){}, // callback before open animation
579
- onOpen : function(){}, // callback after open animation
580
580
  onClosing : function(){}, // callback before closing animation
581
+ onChanging : function(){}, // callback before closing or opening animation
582
+
583
+ onOpen : function(){}, // callback after open animation
581
584
  onClose : function(){}, // callback after closing animation
582
585
  onChange : function(){}, // callback after closing or opening animation
583
586
 
@@ -238,6 +238,7 @@ $.fn.dimmer = function(parameters) {
238
238
  }
239
239
  $dimmer
240
240
  .transition({
241
+ displayType : 'flex',
241
242
  animation : settings.transition + ' in',
242
243
  queue : false,
243
244
  duration : module.get.duration(),
@@ -282,6 +283,7 @@ $.fn.dimmer = function(parameters) {
282
283
  module.verbose('Hiding dimmer with css');
283
284
  $dimmer
284
285
  .transition({
286
+ displayType : 'flex',
285
287
  animation : settings.transition + ' out',
286
288
  queue : false,
287
289
  duration : module.get.duration(),
@@ -496,7 +496,7 @@ $.fn.dropdown = function(parameters) {
496
496
  ? callback
497
497
  : function(){}
498
498
  ;
499
- if( module.is.active() ) {
499
+ if( module.is.active() && !module.is.animatingOutward() ) {
500
500
  module.debug('Hiding dropdown');
501
501
  if(settings.onHide.call(element) !== false) {
502
502
  module.animate.hide(function() {
@@ -2435,7 +2435,6 @@ $.fn.dropdown = function(parameters) {
2435
2435
  var
2436
2436
  escapedValue = module.escape.value(value),
2437
2437
  hasInput = ($input.length > 0),
2438
- isAddition = !module.has.value(value),
2439
2438
  currentValue = module.get.values(),
2440
2439
  stringValue = (value !== undefined)
2441
2440
  ? String(value)
@@ -2538,8 +2537,8 @@ $.fn.dropdown = function(parameters) {
2538
2537
  module.save.remoteData(selectedText, selectedValue);
2539
2538
  }
2540
2539
  if(settings.useLabels) {
2541
- module.add.value(selectedValue, selectedText, $selected);
2542
2540
  module.add.label(selectedValue, selectedText, shouldAnimate);
2541
+ module.add.value(selectedValue, selectedText, $selected);
2543
2542
  module.set.activeItem($selected);
2544
2543
  module.filterActive();
2545
2544
  module.select.nextAvailable($selectedItem);
@@ -2587,8 +2586,8 @@ $.fn.dropdown = function(parameters) {
2587
2586
  ;
2588
2587
  $label = settings.onLabelCreate.call($label, escapedValue, text);
2589
2588
 
2590
- if(module.has.label(value)) {
2591
- module.debug('Label already exists, skipping', escapedValue);
2589
+ if(module.has.value(value)) {
2590
+ module.debug('User selection already exists, skipping', escapedValue);
2592
2591
  return;
2593
2592
  }
2594
2593
  if(settings.label.variation) {
@@ -2727,6 +2726,10 @@ $.fn.dropdown = function(parameters) {
2727
2726
  currentValue = module.get.values(),
2728
2727
  newValue
2729
2728
  ;
2729
+ if(module.has.value(addedValue)) {
2730
+ module.debug('Value already selected');
2731
+ return;
2732
+ }
2730
2733
  if(addedValue === '') {
2731
2734
  module.debug('Cannot select blank values from multiselect');
2732
2735
  return;
@@ -3058,6 +3061,12 @@ $.fn.dropdown = function(parameters) {
3058
3061
  return (module.get.query() !== '');
3059
3062
  },
3060
3063
  value: function(value) {
3064
+ return (settings.ignoreCase)
3065
+ ? module.has.valueIgnoringCase(value)
3066
+ : module.has.valueMatchingCase(value)
3067
+ ;
3068
+ },
3069
+ valueMatchingCase: function(value) {
3061
3070
  var
3062
3071
  values = module.get.values(),
3063
3072
  hasValue = $.isArray(values)
@@ -3068,6 +3077,22 @@ $.fn.dropdown = function(parameters) {
3068
3077
  ? true
3069
3078
  : false
3070
3079
  ;
3080
+ },
3081
+ valueIgnoringCase: function(value) {
3082
+ var
3083
+ values = module.get.values(),
3084
+ hasValue = false
3085
+ ;
3086
+ if(!$.isArray(values)) {
3087
+ values = [values];
3088
+ }
3089
+ $.each(values, function(index, existingValue) {
3090
+ if(String(value).toLowerCase() == String(existingValue).toLowerCase()) {
3091
+ hasValue = true;
3092
+ return false;
3093
+ }
3094
+ });
3095
+ return hasValue;
3071
3096
  }
3072
3097
  },
3073
3098
 
@@ -3075,6 +3100,12 @@ $.fn.dropdown = function(parameters) {
3075
3100
  active: function() {
3076
3101
  return $module.hasClass(className.active);
3077
3102
  },
3103
+ animatingInward: function() {
3104
+ return $menu.transition('is inward');
3105
+ },
3106
+ animatingOutward: function() {
3107
+ return $menu.transition('is outward');
3108
+ },
3078
3109
  bubbledLabelClick: function(event) {
3079
3110
  return $(event.target).is('select, input') && $module.closest('label').length > 0;
3080
3111
  },
@@ -3210,6 +3241,9 @@ $.fn.dropdown = function(parameters) {
3210
3241
  ;
3211
3242
  calculations = {
3212
3243
  context: {
3244
+ offset : ($context.get(0) === window)
3245
+ ? { top: 0, left: 0}
3246
+ : $context.offset(),
3213
3247
  scrollTop : $context.scrollTop(),
3214
3248
  height : $context.outerHeight()
3215
3249
  },
@@ -3222,8 +3256,8 @@ $.fn.dropdown = function(parameters) {
3222
3256
  calculations.menu.offset.top += calculations.context.scrollTop;
3223
3257
  }
3224
3258
  onScreen = {
3225
- above : (calculations.context.scrollTop) <= calculations.menu.offset.top - calculations.menu.height,
3226
- below : (calculations.context.scrollTop + calculations.context.height) >= calculations.menu.offset.top + calculations.menu.height
3259
+ above : (calculations.context.scrollTop) <= calculations.menu.offset.top - calculations.context.offset.top - calculations.menu.height,
3260
+ below : (calculations.context.scrollTop + calculations.context.height) >= calculations.menu.offset.top - calculations.context.offset.top + calculations.menu.height
3227
3261
  };
3228
3262
  if(onScreen.below) {
3229
3263
  module.verbose('Dropdown can fit in context downward', onScreen);
@@ -3252,6 +3286,9 @@ $.fn.dropdown = function(parameters) {
3252
3286
  ;
3253
3287
  calculations = {
3254
3288
  context: {
3289
+ offset : ($context.get(0) === window)
3290
+ ? { top: 0, left: 0}
3291
+ : $context.offset(),
3255
3292
  scrollLeft : $context.scrollLeft(),
3256
3293
  width : $context.outerWidth()
3257
3294
  },
@@ -3263,7 +3300,7 @@ $.fn.dropdown = function(parameters) {
3263
3300
  if(module.is.horizontallyScrollableContext()) {
3264
3301
  calculations.menu.offset.left += calculations.context.scrollLeft;
3265
3302
  }
3266
- isOffscreenRight = (calculations.menu.offset.left + calculations.menu.width >= calculations.context.scrollLeft + calculations.context.width);
3303
+ isOffscreenRight = (calculations.menu.offset.left - calculations.context.offset.left + calculations.menu.width >= calculations.context.scrollLeft + calculations.context.width);
3267
3304
  if(isOffscreenRight) {
3268
3305
  module.verbose('Dropdown cannot fit in context rightward', isOffscreenRight);
3269
3306
  canOpenRightward = false;
@@ -3369,7 +3406,7 @@ $.fn.dropdown = function(parameters) {
3369
3406
  duration : settings.duration,
3370
3407
  debug : settings.debug,
3371
3408
  verbose : settings.verbose,
3372
- queue : true,
3409
+ queue : false,
3373
3410
  onStart : start,
3374
3411
  onComplete : function() {
3375
3412
  callback.call(element);
@@ -3657,7 +3694,8 @@ $.fn.dropdown.settings = {
3657
3694
  forceSelection : true, // force a choice on blur with search selection
3658
3695
 
3659
3696
  allowAdditions : false, // whether multiple select should allow user added values
3660
- hideAdditions : true, // whether or not to hide special message prompting a user they can enter a value
3697
+ ignoreCase : false, // whether to consider values not matching in case to be the same
3698
+ hideAdditions : true, // whether or not to hide special message prompting a user they can enter a value
3661
3699
 
3662
3700
  maxSelections : false, // When set to a number limits the number of selections to this count
3663
3701
  useLabels : true, // whether multiple select should filter currently active selections from choices
@@ -108,6 +108,10 @@ $.fn.modal = function(parameters) {
108
108
  var
109
109
  defaultSettings = {
110
110
  debug : settings.debug,
111
+ variation : settings.centered
112
+ ? false
113
+ : 'top aligned'
114
+ ,
111
115
  dimmerName : 'modals'
112
116
  },
113
117
  dimmerSettings = $.extend(true, defaultSettings, settings.dimmerSettings)
@@ -165,7 +169,6 @@ $.fn.modal = function(parameters) {
165
169
  module.cacheSizes();
166
170
  module.set.screenHeight();
167
171
  module.set.type();
168
- module.set.position();
169
172
  },
170
173
 
171
174
  refreshModals: function() {
@@ -238,21 +241,23 @@ $.fn.modal = function(parameters) {
238
241
  module.hide();
239
242
  },
240
243
  click: function(event) {
244
+ if(!settings.closable) {
245
+ module.verbose('Dimmer clicked but closable setting is disabled');
246
+ return;
247
+ }
241
248
  var
242
249
  $target = $(event.target),
243
250
  isInModal = ($target.closest(selector.modal).length > 0),
244
251
  isInDOM = $.contains(document.documentElement, event.target)
245
252
  ;
246
- if(!isInModal && isInDOM) {
253
+ if(!isInModal && isInDOM && module.is.active()) {
247
254
  module.debug('Dimmer clicked, hiding all modals');
248
- if( module.is.active() ) {
249
- module.remove.clickaway();
250
- if(settings.allowMultiple) {
251
- module.hide();
252
- }
253
- else {
254
- module.hideAll();
255
- }
255
+ module.remove.clickaway();
256
+ if(settings.allowMultiple) {
257
+ module.hide();
258
+ }
259
+ else {
260
+ module.hideAll();
256
261
  }
257
262
  }
258
263
  },
@@ -320,7 +325,6 @@ $.fn.modal = function(parameters) {
320
325
 
321
326
  module.showDimmer();
322
327
  module.cacheSizes();
323
- module.set.position();
324
328
  module.set.screenHeight();
325
329
  module.set.type();
326
330
  module.set.clickaway();
@@ -487,7 +491,13 @@ $.fn.modal = function(parameters) {
487
491
 
488
492
  save: {
489
493
  focus: function() {
490
- $focusedElement = $(document.activeElement).blur();
494
+ var
495
+ $activeElement = $(document.activeElement),
496
+ inCurrentModal = $activeElement.closest($module).length > 0
497
+ ;
498
+ if(!inCurrentModal) {
499
+ $focusedElement = $(document.activeElement).blur();
500
+ }
491
501
  }
492
502
  },
493
503
 
@@ -504,11 +514,9 @@ $.fn.modal = function(parameters) {
504
514
  $module.removeClass(className.active);
505
515
  },
506
516
  clickaway: function() {
507
- if(settings.closable) {
508
- $dimmer
509
- .off('click' + elementEventNamespace)
510
- ;
511
- }
517
+ $dimmer
518
+ .off('click' + elementEventNamespace)
519
+ ;
512
520
  },
513
521
  bodyStyle: function() {
514
522
  if($body.attr('style') === '') {
@@ -606,11 +614,9 @@ $.fn.modal = function(parameters) {
606
614
  }
607
615
  },
608
616
  clickaway: function() {
609
- if(settings.closable) {
610
- $dimmer
611
- .on('click' + elementEventNamespace, module.event.click)
612
- ;
613
- }
617
+ $dimmer
618
+ .on('click' + elementEventNamespace, module.event.click)
619
+ ;
614
620
  },
615
621
  dimmerSettings: function() {
616
622
  if($.fn.dimmer === undefined) {
@@ -621,8 +627,11 @@ $.fn.modal = function(parameters) {
621
627
  defaultSettings = {
622
628
  debug : settings.debug,
623
629
  dimmerName : 'modals',
624
- variation : false,
625
630
  closable : 'auto',
631
+ variation : settings.centered
632
+ ? false
633
+ : 'top aligned'
634
+ ,
626
635
  duration : {
627
636
  show : settings.duration,
628
637
  hide : settings.duration
@@ -678,25 +687,6 @@ $.fn.modal = function(parameters) {
678
687
  module.set.scrolling();
679
688
  }
680
689
  },
681
- position: function() {
682
- module.verbose('Centering modal on page', module.cache);
683
- if(module.can.fit()) {
684
- $module
685
- .css({
686
- top: '',
687
- marginTop: module.cache.topOffset
688
- })
689
- ;
690
- }
691
- else {
692
- $module
693
- .css({
694
- marginTop : '',
695
- top : $document.scrollTop()
696
- })
697
- ;
698
- }
699
- },
700
690
  undetached: function() {
701
691
  $dimmable.addClass(className.undetached);
702
692
  }
@@ -905,6 +895,8 @@ $.fn.modal.settings = {
905
895
  inverted : false,
906
896
  blurring : false,
907
897
 
898
+ centered : true,
899
+
908
900
  dimmerSettings : {
909
901
  closable : false,
910
902
  useCSS : true
@@ -488,7 +488,7 @@ $.fn.popup = function(parameters) {
488
488
  },
489
489
  content: function() {
490
490
  $module.removeData(metadata.content);
491
- return $module.data(metadata.content) || $module.attr('title') || settings.content;
491
+ return $module.data(metadata.content) || settings.content || $module.attr('title');
492
492
  },
493
493
  variation: function() {
494
494
  $module.removeData(metadata.variation);
@@ -502,9 +502,10 @@ $.fn.popup = function(parameters) {
502
502
  },
503
503
  calculations: function() {
504
504
  var
505
- targetElement = $target[0],
506
- isWindow = ($boundary[0] == window),
507
- targetPosition = (settings.inline || (settings.popup && settings.movePopup))
505
+ $popupOffsetParent = module.get.offsetParent($popup),
506
+ targetElement = $target[0],
507
+ isWindow = ($boundary[0] == window),
508
+ targetPosition = (settings.inline || (settings.popup && settings.movePopup))
508
509
  ? $target.position()
509
510
  : $target.offset(),
510
511
  screenPosition = (isWindow)
@@ -549,6 +550,17 @@ $.fn.popup = function(parameters) {
549
550
  }
550
551
  };
551
552
 
553
+ // if popup offset context is not same as target, then adjust calculations
554
+ if($popupOffsetParent.get(0) !== $offsetParent.get(0)) {
555
+ var
556
+ popupOffset = $popupOffsetParent.offset()
557
+ ;
558
+ calculations.target.top -= popupOffset.top;
559
+ calculations.target.left -= popupOffset.left;
560
+ calculations.parent.width = $popupOffsetParent.outerWidth();
561
+ calculations.parent.height = $popupOffsetParent.outerHeight();
562
+ }
563
+
552
564
  // add in container calcs if fluid
553
565
  if( settings.setFluidWidth && module.is.fluid() ) {
554
566
  calculations.container = {
@@ -625,11 +637,11 @@ $.fn.popup = function(parameters) {
625
637
  }
626
638
  return distanceFromBoundary;
627
639
  },
628
- offsetParent: function($target) {
640
+ offsetParent: function($element) {
629
641
  var
630
- element = ($target !== undefined)
631
- ? $target[0]
632
- : $module[0],
642
+ element = ($element !== undefined)
643
+ ? $element[0]
644
+ : $target[0],
633
645
  parentNode = element.parentNode,
634
646
  $node = $(parentNode)
635
647
  ;
@@ -637,14 +649,14 @@ $.fn.popup = function(parameters) {
637
649
  var
638
650
  is2D = ($node.css('transform') === 'none'),
639
651
  isStatic = ($node.css('position') === 'static'),
640
- isHTML = $node.is('html')
652
+ isBody = $node.is('body')
641
653
  ;
642
- while(parentNode && !isHTML && isStatic && is2D) {
654
+ while(parentNode && !isBody && isStatic && is2D) {
643
655
  parentNode = parentNode.parentNode;
644
656
  $node = $(parentNode);
645
657
  is2D = ($node.css('transform') === 'none');
646
658
  isStatic = ($node.css('position') === 'static');
647
- isHTML = $node.is('html');
659
+ isBody = $node.is('body');
648
660
  }
649
661
  }
650
662
  return ($node && $node.length > 0)
@@ -753,6 +765,18 @@ $.fn.popup = function(parameters) {
753
765
  popup = calculations.popup;
754
766
  parent = calculations.parent;
755
767
 
768
+ if(module.should.centerArrow(calculations)) {
769
+ module.verbose('Adjusting offset to center arrow on small target element');
770
+ if(position == 'top left' || position == 'bottom left') {
771
+ offset += (target.width / 2)
772
+ offset -= settings.arrowPixelsFromEdge;
773
+ }
774
+ if(position == 'top right' || position == 'bottom right') {
775
+ offset -= (target.width / 2)
776
+ offset += settings.arrowPixelsFromEdge;
777
+ }
778
+ }
779
+
756
780
  if(target.width === 0 && target.height === 0 && !module.is.svg(target.element)) {
757
781
  module.debug('Popup target is hidden, no action taken');
758
782
  return false;
@@ -1046,6 +1070,12 @@ $.fn.popup = function(parameters) {
1046
1070
  }
1047
1071
  },
1048
1072
 
1073
+ should: {
1074
+ centerArrow: function(calculations) {
1075
+ return !module.is.basic() && calculations.target.width <= (settings.arrowPixelsFromEdge * 2);
1076
+ }
1077
+ },
1078
+
1049
1079
  is: {
1050
1080
  offstage: function(distanceFromBoundary, position) {
1051
1081
  var
@@ -1068,6 +1098,9 @@ $.fn.popup = function(parameters) {
1068
1098
  svg: function(element) {
1069
1099
  return module.supports.svg() && (element instanceof SVGGraphicsElement);
1070
1100
  },
1101
+ basic: function() {
1102
+ return $module.hasClass(className.basic);
1103
+ },
1071
1104
  active: function() {
1072
1105
  return $module.hasClass(className.active);
1073
1106
  },
@@ -1380,8 +1413,11 @@ $.fn.popup.settings = {
1380
1413
  // specify position to appear even if it doesn't fit
1381
1414
  lastResort : false,
1382
1415
 
1416
+ // number of pixels from edge of popup to pointing arrow center (used from centering)
1417
+ arrowPixelsFromEdge: 20,
1418
+
1383
1419
  // delay used to prevent accidental refiring of animations due to user error
1384
- delay : {
1420
+ delay : {
1385
1421
  show : 50,
1386
1422
  hide : 70
1387
1423
  },
@@ -1425,6 +1461,7 @@ $.fn.popup.settings = {
1425
1461
 
1426
1462
  className : {
1427
1463
  active : 'active',
1464
+ basic : 'basic',
1428
1465
  animating : 'animating',
1429
1466
  dropdown : 'dropdown',
1430
1467
  fluid : 'fluid',