foundation-rails 5.1.1.0 → 5.2.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/README.md +52 -7
  3. data/bower.json +2 -2
  4. data/lib/foundation/rails/version.rb +1 -1
  5. data/vendor/assets/javascripts/foundation/foundation.abide.js +3 -6
  6. data/vendor/assets/javascripts/foundation/foundation.accordion.js +5 -4
  7. data/vendor/assets/javascripts/foundation/foundation.alert.js +1 -1
  8. data/vendor/assets/javascripts/foundation/foundation.clearing.js +70 -34
  9. data/vendor/assets/javascripts/foundation/foundation.dropdown.js +121 -28
  10. data/vendor/assets/javascripts/foundation/foundation.equalizer.js +6 -6
  11. data/vendor/assets/javascripts/foundation/foundation.interchange.js +34 -25
  12. data/vendor/assets/javascripts/foundation/foundation.joyride.js +4 -8
  13. data/vendor/assets/javascripts/foundation/foundation.js +94 -78
  14. data/vendor/assets/javascripts/foundation/foundation.magellan.js +3 -4
  15. data/vendor/assets/javascripts/foundation/foundation.offcanvas.js +19 -1
  16. data/vendor/assets/javascripts/foundation/foundation.orbit.js +151 -102
  17. data/vendor/assets/javascripts/foundation/foundation.reveal.js +43 -15
  18. data/vendor/assets/javascripts/foundation/foundation.slider.js +187 -0
  19. data/vendor/assets/javascripts/foundation/foundation.tab.js +116 -18
  20. data/vendor/assets/javascripts/foundation/foundation.tooltip.js +112 -60
  21. data/vendor/assets/javascripts/foundation/foundation.topbar.js +47 -14
  22. data/vendor/assets/javascripts/vendor/modernizr.js +3 -3
  23. data/vendor/assets/stylesheets/foundation.scss +7 -0
  24. data/vendor/assets/stylesheets/foundation/_functions.scss +4 -0
  25. data/vendor/assets/stylesheets/foundation/_settings.scss +11 -2
  26. data/vendor/assets/stylesheets/foundation/components/_accordion.scss +5 -1
  27. data/vendor/assets/stylesheets/foundation/components/_alert-boxes.scss +4 -0
  28. data/vendor/assets/stylesheets/foundation/components/_block-grid.scss +44 -12
  29. data/vendor/assets/stylesheets/foundation/components/_breadcrumbs.scss +4 -0
  30. data/vendor/assets/stylesheets/foundation/components/_button-groups.scss +4 -0
  31. data/vendor/assets/stylesheets/foundation/components/_buttons.scss +7 -5
  32. data/vendor/assets/stylesheets/foundation/components/_clearing.scss +4 -0
  33. data/vendor/assets/stylesheets/foundation/components/_dropdown-buttons.scss +4 -0
  34. data/vendor/assets/stylesheets/foundation/components/_dropdown.scss +100 -11
  35. data/vendor/assets/stylesheets/foundation/components/_flex-video.scss +4 -0
  36. data/vendor/assets/stylesheets/foundation/components/_forms.scss +25 -21
  37. data/vendor/assets/stylesheets/foundation/components/_global.scss +79 -44
  38. data/vendor/assets/stylesheets/foundation/components/_grid.scss +6 -2
  39. data/vendor/assets/stylesheets/foundation/components/_inline-lists.scss +4 -0
  40. data/vendor/assets/stylesheets/foundation/components/_joyride.scss +4 -0
  41. data/vendor/assets/stylesheets/foundation/components/_keystrokes.scss +5 -1
  42. data/vendor/assets/stylesheets/foundation/components/_labels.scss +4 -0
  43. data/vendor/assets/stylesheets/foundation/components/_magellan.scss +4 -0
  44. data/vendor/assets/stylesheets/foundation/components/_offcanvas.scss +51 -59
  45. data/vendor/assets/stylesheets/foundation/components/_orbit.scss +97 -14
  46. data/vendor/assets/stylesheets/foundation/components/_pagination.scss +7 -2
  47. data/vendor/assets/stylesheets/foundation/components/_panels.scss +5 -1
  48. data/vendor/assets/stylesheets/foundation/components/_pricing-tables.scss +4 -0
  49. data/vendor/assets/stylesheets/foundation/components/_progress-bars.scss +4 -0
  50. data/vendor/assets/stylesheets/foundation/components/_range-slider.scss +148 -0
  51. data/vendor/assets/stylesheets/foundation/components/_reveal.scss +36 -7
  52. data/vendor/assets/stylesheets/foundation/components/_side-nav.scss +8 -3
  53. data/vendor/assets/stylesheets/foundation/components/_split-buttons.scss +4 -0
  54. data/vendor/assets/stylesheets/foundation/components/_sub-nav.scss +6 -2
  55. data/vendor/assets/stylesheets/foundation/components/_switch.scss +4 -0
  56. data/vendor/assets/stylesheets/foundation/components/_tables.scss +4 -0
  57. data/vendor/assets/stylesheets/foundation/components/_tabs.scss +12 -6
  58. data/vendor/assets/stylesheets/foundation/components/_thumbs.scss +4 -0
  59. data/vendor/assets/stylesheets/foundation/components/_tooltips.scss +9 -0
  60. data/vendor/assets/stylesheets/foundation/components/_top-bar.scss +52 -25
  61. data/vendor/assets/stylesheets/foundation/components/_type.scss +132 -75
  62. data/vendor/assets/stylesheets/foundation/components/_visibility.scss +198 -538
  63. data/vendor/assets/stylesheets/normalize.scss +179 -166
  64. metadata +4 -2
@@ -0,0 +1,187 @@
1
+ ;(function ($, window, document, undefined) {
2
+ 'use strict';
3
+
4
+ Foundation.libs.slider = {
5
+ name : 'slider',
6
+
7
+ version : '5.2.0',
8
+
9
+ settings: {
10
+ start: 0,
11
+ end: 100,
12
+ step: 1,
13
+ initial: null,
14
+ display_selector: '',
15
+ on_change: function(){}
16
+ },
17
+
18
+ cache : {},
19
+
20
+ init : function (scope, method, options) {
21
+ Foundation.inherit(this,'throttle');
22
+ this.bindings(method, options);
23
+ this.reflow();
24
+ },
25
+
26
+ events : function() {
27
+ var self = this;
28
+
29
+ $(this.scope)
30
+ .off('.slider')
31
+ .on('mousedown.fndtn.slider touchstart.fndtn.slider pointerdown.fndtn.slider', '[' + self.attr_name() + '] .range-slider-handle', function(e) {
32
+ if (!self.cache.active) {
33
+ self.set_active_slider($(e.target));
34
+ }
35
+ })
36
+ .on('mousemove.fndtn.slider touchmove.fndtn.slider pointermove.fndtn.slider', function(e) {
37
+ if (!!self.cache.active) {
38
+ e.preventDefault();
39
+ self.calculate_position(self.cache.active, e.pageX || e.originalEvent.touches[0].clientX || e.currentPoint.x);
40
+ }
41
+ })
42
+ .on('mouseup.fndtn.slider touchend.fndtn.slider pointerup.fndtn.slider', function(e) {
43
+ self.remove_active_slider();
44
+ })
45
+ .on('change.fndtn.slider', function(e) {
46
+ self.settings.on_change;
47
+ });
48
+
49
+ self.S(window)
50
+ .on('resize.fndtn.slider', self.throttle(function(e) {
51
+ self.reflow();
52
+ }, 300));
53
+ },
54
+
55
+ set_active_slider : function($handle) {
56
+ this.cache.active = $handle;
57
+ },
58
+
59
+ remove_active_slider : function() {
60
+ this.cache.active = null;
61
+ },
62
+
63
+ calculate_position : function($handle, cursor_x) {
64
+ var self = this,
65
+ settings = $.extend({}, self.settings, self.data_options($handle.parent())),
66
+ handle_w = $.data($handle[0], 'handle_w'),
67
+ handle_o = $.data($handle[0], 'handle_o'),
68
+ bar_w = $.data($handle[0], 'bar_w'),
69
+ bar_o = $.data($handle[0], 'bar_o');
70
+
71
+ requestAnimationFrame(function(){
72
+ var pct = self.limit_to((((cursor_x)-bar_o)/bar_w),0,1),
73
+ norm = self.normalized_value(pct, settings.start, settings.end, settings.step);
74
+
75
+ self.set_ui($handle, norm);
76
+ });
77
+ },
78
+
79
+ set_ui : function($handle, value) {
80
+ var settings = $.extend({}, this.settings, this.data_options($handle.parent())),
81
+ handle_w = $.data($handle[0], 'handle_w'),
82
+ bar_w = $.data($handle[0], 'bar_w'),
83
+ norm_pct = this.normalized_percentage(value, settings.start, settings.end),
84
+ handle_offset = norm_pct*(bar_w-handle_w)-1,
85
+ progress_bar_width = norm_pct*100;
86
+
87
+ this.set_translate($handle, handle_offset);
88
+ $handle.siblings('.range-slider-active-segment').css('width', progress_bar_width+'%');
89
+
90
+ $handle.parent().attr(this.attr_name(), value);
91
+ $handle.parent().trigger('change');
92
+
93
+ $handle.parent().children('input[type=hidden]').val(value);
94
+
95
+ if (settings.input_id != '') {
96
+ $(settings.display_selector).each(function(){
97
+ if (this.hasOwnProperty('value')) {
98
+ $(this).val(value);
99
+ } else {
100
+ $(this).text(value);
101
+ }
102
+ });
103
+ }
104
+
105
+ },
106
+
107
+ normalized_percentage : function(val, start, end) {
108
+ return val/(end - start);
109
+ },
110
+
111
+ normalized_value : function(val, start, end, step) {
112
+ var range = end - start,
113
+ step = step,
114
+ point = val*range,
115
+ mod = (point-(point%step)) / step,
116
+ rem = point % step,
117
+ round = ( rem >= step*0.5 ? step : 0);
118
+ return (mod*step + round);
119
+ },
120
+
121
+ set_translate : function(ele, offset, vertical) {
122
+ if (vertical) {
123
+ $(ele)
124
+ .css('-webkit-transform', 'translateY('+offset+'px)')
125
+ .css('-moz-transform', 'translateY('+offset+'px)')
126
+ .css('-ms-transform', 'translateY('+offset+'px)')
127
+ .css('-o-transform', 'translateY('+offset+'px)')
128
+ .css('transform', 'translateY('+offset+'px)');
129
+ } else {
130
+ $(ele)
131
+ .css('-webkit-transform', 'translateX('+offset+'px)')
132
+ .css('-moz-transform', 'translateX('+offset+'px)')
133
+ .css('-ms-transform', 'translateX('+offset+'px)')
134
+ .css('-o-transform', 'translateX('+offset+'px)')
135
+ .css('transform', 'translateX('+offset+'px)');
136
+ }
137
+ },
138
+
139
+ limit_to : function(val, min, max) {
140
+ return Math.min(Math.max(val, min), max);
141
+ },
142
+
143
+ initialize_settings : function(handle) {
144
+ $.data(handle, 'bar', $(handle).parent());
145
+ $.data(handle, 'bar_o', $(handle).parent().offset().left);
146
+ $.data(handle, 'bar_w', $(handle).parent().outerWidth());
147
+ $.data(handle, 'handle_o', $(handle).offset().left);
148
+ $.data(handle, 'handle_w', $(handle).outerWidth());
149
+ $.data(handle, 'settings', $.extend({}, this.settings, this.data_options($(handle).parent())));
150
+ },
151
+
152
+ set_initial_position : function($ele) {
153
+ var settings = $.data($ele.children('.range-slider-handle')[0], 'settings'),
154
+ initial = (!!settings.initial ? settings.initial : Math.floor((settings.end-settings.start)*0.5/settings.step)*settings.step),
155
+ $handle = $ele.children('.range-slider-handle');
156
+ this.set_ui($handle, initial);
157
+ },
158
+
159
+ set_value : function(value) {
160
+ var self = this;
161
+ $('[' + self.attr_name() + ']', this.scope).each(function(){
162
+ $(this).attr(self.attr_name(), value);
163
+ });
164
+ if (!!$(this.scope).attr(self.attr_name())) {
165
+ $(this.scope).attr(self.attr_name(), value);
166
+ }
167
+ self.reflow();
168
+ },
169
+
170
+ reflow : function() {
171
+ var self = this;
172
+ self.S('[' + this.attr_name() + ']').each(function() {
173
+ var handle = $(this).children('.range-slider-handle')[0],
174
+ val = $(this).attr(self.attr_name());
175
+ self.initialize_settings(handle);
176
+
177
+ if (val) {
178
+ self.set_ui($(handle), parseInt(val));
179
+ } else {
180
+ self.set_initial_position($(this));
181
+ }
182
+ });
183
+ }
184
+
185
+ };
186
+
187
+ }(jQuery, this, this.document));
@@ -5,44 +5,142 @@
5
5
  Foundation.libs.tab = {
6
6
  name : 'tab',
7
7
 
8
- version : '5.1.1',
8
+ version : '5.2.0',
9
9
 
10
10
  settings : {
11
11
  active_class: 'active',
12
- callback : function () {}
12
+ callback : function () {},
13
+ deep_linking: false,
14
+ scroll_to_content: true
13
15
  },
14
16
 
17
+ default_tab_hashes: [],
18
+
15
19
  init : function (scope, method, options) {
20
+ var self = this,
21
+ S = this.S;
22
+
16
23
  this.bindings(method, options);
24
+ this.handle_location_hash_change();
25
+
26
+ // Store the default active tabs which will be referenced when the
27
+ // location hash is absent, as in the case of navigating the tabs and
28
+ // returning to the first viewing via the browser Back button.
29
+ S('[' + this.attr_name() + '] > dd.active > a', this.scope).each(function () {
30
+ self.default_tab_hashes.push(this.hash);
31
+ });
17
32
  },
18
33
 
19
34
  events : function () {
20
35
  var self = this,
21
36
  S = this.S;
22
37
 
38
+ // Click event: tab title
23
39
  S(this.scope).off('.tab').on('click.fndtn.tab', '[' + this.attr_name() + '] > dd > a', function (e) {
24
40
  e.preventDefault();
25
41
  e.stopPropagation();
42
+ self.toggle_active_tab(S(this).parent());
43
+ });
26
44
 
27
- var tab = S(this).parent(),
28
- tabs = tab.closest('[' + self.attr_name() + ']'),
29
- target = S('#' + this.href.split('#')[1]),
30
- siblings = tab.siblings(),
31
- settings = tabs.data(self.attr_name(true) + '-init');
32
-
33
- // allow usage of data-tab-content attribute instead of href
34
- if (S(this).data(self.data_attr('tab-content'))) {
35
- target = S('#' + S(this).data(self.data_attr('tab-content')).split('#')[1]);
36
- }
37
-
38
- tab.addClass(settings.active_class).triggerHandler('opened');
39
- siblings.removeClass(settings.active_class);
40
- target.siblings().removeClass(settings.active_class).end().addClass(settings.active_class);
41
- settings.callback(tab);
42
- tabs.triggerHandler('toggled', [tab]);
45
+ // Location hash change event
46
+ S(window).on('hashchange.fndtn.tab', function (e) {
47
+ e.preventDefault();
48
+ self.handle_location_hash_change();
43
49
  });
44
50
  },
45
51
 
52
+ handle_location_hash_change : function () {
53
+ var self = this,
54
+ S = this.S;
55
+
56
+ S('[' + this.attr_name() + ']', this.scope).each(function () {
57
+ var settings = S(this).data(self.attr_name(true) + '-init');
58
+ if (settings.deep_linking) {
59
+ // Match the location hash to a label
60
+ var hash = self.scope.location.hash;
61
+ if (hash != '') {
62
+ // Check whether the location hash references a tab content div or
63
+ // another element on the page (inside or outside the tab content div)
64
+ var hash_element = S(hash);
65
+ if (hash_element.hasClass('content') && hash_element.parent().hasClass('tab-content')) {
66
+ // Tab content div
67
+ self.toggle_active_tab($('[' + self.attr_name() + '] > dd > a[href=' + hash + ']').parent());
68
+ } else {
69
+ // Not the tab content div. If inside the tab content, find the
70
+ // containing tab and toggle it as active.
71
+ var hash_tab_container_id = hash_element.closest('.content').attr('id');
72
+ if (hash_tab_container_id != undefined) {
73
+ self.toggle_active_tab($('[' + self.attr_name() + '] > dd > a[href=#' + hash_tab_container_id + ']').parent(), hash);
74
+ }
75
+ }
76
+ } else {
77
+ // Reference the default tab hashes which were initialized in the init function
78
+ for (var ind in self.default_tab_hashes) {
79
+ self.toggle_active_tab($('[' + self.attr_name() + '] > dd > a[href=' + self.default_tab_hashes[ind] + ']').parent());
80
+ }
81
+ }
82
+ }
83
+ });
84
+ },
85
+
86
+ toggle_active_tab: function (tab, location_hash) {
87
+ var S = this.S,
88
+ tabs = tab.closest('[' + this.attr_name() + ']'),
89
+ anchor = tab.children('a').first(),
90
+ target_hash = '#' + anchor.attr('href').split('#')[1],
91
+ target = S(target_hash),
92
+ siblings = tab.siblings(),
93
+ settings = tabs.data(this.attr_name(true) + '-init');
94
+
95
+ // allow usage of data-tab-content attribute instead of href
96
+ if (S(this).data(this.data_attr('tab-content'))) {
97
+ target_hash = '#' + S(this).data(this.data_attr('tab-content')).split('#')[1];
98
+ target = S(target_hash);
99
+ }
100
+
101
+ if (settings.deep_linking) {
102
+ // Get the scroll Y position prior to moving to the hash ID
103
+ var cur_ypos = $('body,html').scrollTop();
104
+
105
+ // Update the location hash to preserve browser history
106
+ // Note that the hash does not need to correspond to the
107
+ // tab content ID anchor; it can be an ID inside or outside of the tab
108
+ // content div.
109
+ if (location_hash != undefined) {
110
+ window.location.hash = location_hash;
111
+ } else {
112
+ window.location.hash = target_hash;
113
+ }
114
+
115
+ if (settings.scroll_to_content) {
116
+ // If the user is requesting the content of a tab, then scroll to the
117
+ // top of the title area; otherwise, scroll to the element within
118
+ // the content area as defined by the hash value.
119
+ if (location_hash == undefined || location_hash == target_hash) {
120
+ tab.parent()[0].scrollIntoView();
121
+ } else {
122
+ S(target_hash)[0].scrollIntoView();
123
+ }
124
+ } else {
125
+ // Adjust the scrollbar to the Y position prior to setting the hash
126
+ // Only do this for the tab content anchor, otherwise there will be
127
+ // conflicts with in-tab anchor links nested in the tab-content div
128
+ if (location_hash == undefined || location_hash == target_hash) {
129
+ $('body,html').scrollTop(cur_ypos);
130
+ }
131
+ }
132
+ }
133
+
134
+ // WARNING: The activation and deactivation of the tab content must
135
+ // occur after the deep linking in order to properly refresh the browser
136
+ // window (notably in Chrome).
137
+ tab.addClass(settings.active_class).triggerHandler('opened');
138
+ siblings.removeClass(settings.active_class);
139
+ target.siblings().removeClass(settings.active_class).end().addClass(settings.active_class);
140
+ settings.callback(tab);
141
+ tabs.triggerHandler('toggled', [tab]);
142
+ },
143
+
46
144
  data_attr: function (str) {
47
145
  if (this.namespace.length > 0) {
48
146
  return this.namespace + '-' + str;
@@ -4,7 +4,7 @@
4
4
  Foundation.libs.tooltip = {
5
5
  name : 'tooltip',
6
6
 
7
- version : '5.1.1',
7
+ version : '5.2.0',
8
8
 
9
9
  settings : {
10
10
  additional_inheritable_classes : [],
@@ -14,8 +14,8 @@
14
14
  disable_for_touch: false,
15
15
  hover_delay: 200,
16
16
  tip_template : function (selector, content) {
17
- return '<span data-selector="' + selector + '" class="'
18
- + Foundation.libs.tooltip.settings.tooltip_class.substring(1)
17
+ return '<span data-selector="' + selector + '" class="'
18
+ + Foundation.libs.tooltip.settings.tooltip_class.substring(1)
19
19
  + '">' + content + '<span class="nub"></span></span>';
20
20
  }
21
21
  },
@@ -27,62 +27,81 @@
27
27
  this.bindings(method, options);
28
28
  },
29
29
 
30
- events : function () {
30
+ events : function (instance) {
31
31
  var self = this,
32
32
  S = self.S;
33
33
 
34
- if (Modernizr.touch) {
35
- S(document)
36
- .off('.tooltip')
37
- .on('click.fndtn.tooltip touchstart.fndtn.tooltip touchend.fndtn.tooltip',
38
- '[' + this.attr_name() + ']:not(a)', function (e) {
39
- var settings = $.extend({}, self.settings, self.data_options(S(this)));
40
- if (!settings.disable_for_touch) {
34
+ self.create(this.S(instance));
35
+
36
+ $(this.scope)
37
+ .off('.tooltip')
38
+ .on('mouseenter.fndtn.tooltip mouseleave.fndtn.tooltip touchstart.fndtn.tooltip MSPointerDown.fndtn.tooltip',
39
+ '[' + this.attr_name() + ']:not(a)', function (e) {
40
+ var $this = S(this),
41
+ settings = $.extend({}, self.settings, self.data_options($this)),
42
+ is_touch = false;
43
+
44
+ if (/mouse/i.test(e.type) && self.ie_touch(e)) return false;
45
+
46
+ if ($this.hasClass('open')) {
47
+ if (Modernizr.touch && /touchstart|MSPointerDown/i.test(e.type)) e.preventDefault();
48
+ self.hide($this);
49
+ } else {
50
+ if (settings.disable_for_touch && Modernizr.touch && /touchstart|MSPointerDown/i.test(e.type)) {
51
+ return;
52
+ } else if(!settings.disable_for_touch && Modernizr.touch && /touchstart|MSPointerDown/i.test(e.type)) {
41
53
  e.preventDefault();
42
- S(settings.tooltip_class).hide();
43
- self.showOrCreateTip(S(this));
54
+ S(settings.tooltip_class + '.open').hide();
55
+ is_touch = true;
44
56
  }
45
- })
46
- .on('click.fndtn.tooltip touchstart.fndtn.tooltip touchend.fndtn.tooltip',
47
- this.settings.tooltip_class, function (e) {
48
- e.preventDefault();
49
- S(this).fadeOut(150);
50
- });
51
- } else {
52
- S(document)
53
- .off('.tooltip')
54
- .on('mouseenter.fndtn.tooltip mouseleave.fndtn.tooltip',
55
- '[' + this.attr_name() + ']', function (e) {
56
- var $this = S(this);
57
57
 
58
58
  if (/enter|over/i.test(e.type)) {
59
59
  this.timer = setTimeout(function () {
60
- var tip = self.showOrCreateTip($this);
60
+ var tip = self.showTip($this);
61
61
  }.bind(this), self.settings.hover_delay);
62
62
  } else if (e.type === 'mouseout' || e.type === 'mouseleave') {
63
63
  clearTimeout(this.timer);
64
64
  self.hide($this);
65
+ } else {
66
+ self.showTip($this);
65
67
  }
66
- });
67
- }
68
+ }
69
+ })
70
+ .on('mouseleave.fndtn.tooltip touchstart.fndtn.tooltip MSPointerDown.fndtn.tooltip', '[' + this.attr_name() + '].open', function (e) {
71
+ if (/mouse/i.test(e.type) && self.ie_touch(e)) return false;
72
+
73
+ if($(this).data('tooltip-open-event-type') == 'touch' && e.type == 'mouseleave') {
74
+ return;
75
+ }
76
+ else if($(this).data('tooltip-open-event-type') == 'mouse' && /MSPointerDown|touchstart/i.test(e.type)) {
77
+ self.convert_to_touch($(this));
78
+ } else {
79
+ self.hide($(this));
80
+ }
81
+ })
82
+ .on('DOMNodeRemoved DOMAttrModified', '[' + this.attr_name() + ']:not(a)', function (e) {
83
+ self.hide(S(this));
84
+ });
68
85
  },
69
86
 
70
- showOrCreateTip : function ($target) {
87
+ ie_touch : function (e) {
88
+ // How do I distinguish between IE11 and Windows Phone 8?????
89
+ return false;
90
+ },
91
+
92
+ showTip : function ($target) {
71
93
  var $tip = this.getTip($target);
72
94
 
73
- if ($tip && $tip.length > 0) {
74
95
  return this.show($target);
75
- }
76
-
77
- return this.create($target);
78
96
  },
79
97
 
80
98
  getTip : function ($target) {
81
99
  var selector = this.selector($target),
100
+ settings = $.extend({}, this.settings, this.data_options($target)),
82
101
  tip = null;
83
102
 
84
103
  if (selector) {
85
- tip = this.S('span[data-selector="' + selector + '"]' + this.settings.tooltip_class);
104
+ tip = this.S('span[data-selector="' + selector + '"]' + settings.tooltip_class);
86
105
  }
87
106
 
88
107
  return (typeof tip === 'object') ? tip : false;
@@ -93,7 +112,7 @@
93
112
  dataSelector = $target.attr(this.attr_name()) || $target.attr('data-selector');
94
113
 
95
114
  if ((id && id.length < 1 || !id) && typeof dataSelector != 'string') {
96
- dataSelector = 'tooltip' + this.random_str(6);
115
+ dataSelector = this.random_str(6);
97
116
  $target.attr('data-selector', dataSelector);
98
117
  }
99
118
 
@@ -101,15 +120,27 @@
101
120
  },
102
121
 
103
122
  create : function ($target) {
104
- var $tip = $(this.settings.tip_template(this.selector($target), $('<div></div>').html($target.attr('title')).html())),
123
+ var self = this,
124
+ settings = $.extend({}, this.settings, this.data_options($target)),
125
+ tip_template = this.settings.tip_template;
126
+
127
+ if (typeof settings.tip_template === 'string' && window.hasOwnProperty(settings.tip_template)) {
128
+ tip_template = window[settings.tip_template];
129
+ }
130
+
131
+ var $tip = $(tip_template(this.selector($target), $('<div></div>').html($target.attr('title')).html())),
105
132
  classes = this.inheritable_classes($target);
106
133
 
107
- $tip.addClass(classes).appendTo(this.settings.append_to);
134
+ $tip.addClass(classes).appendTo(settings.append_to);
135
+
108
136
  if (Modernizr.touch) {
109
- $tip.append('<span class="tap-to-close">'+this.settings.touch_close_text+'</span>');
137
+ $tip.append('<span class="tap-to-close">'+settings.touch_close_text+'</span>');
138
+ $tip.on('touchstart.fndtn.tooltip MSPointerDown.fndtn.tooltip', function(e) {
139
+ self.hide($target);
140
+ });
110
141
  }
142
+
111
143
  $target.removeAttr('title').attr('title','');
112
- this.show($target);
113
144
  },
114
145
 
115
146
  reposition : function (target, tip, classes) {
@@ -122,45 +153,47 @@
122
153
  nubHeight = nub.outerHeight();
123
154
  nubWidth = nub.outerHeight();
124
155
 
125
- if(this.small()) {
156
+ if (this.small()) {
126
157
  tip.css({'width' : '100%' });
127
158
  } else {
128
159
  tip.css({'width' : (width) ? width : 'auto'});
129
160
  }
130
-
161
+
131
162
  objPos = function (obj, top, right, bottom, left, width) {
132
163
  return obj.css({
133
164
  'top' : (top) ? top : 'auto',
134
165
  'bottom' : (bottom) ? bottom : 'auto',
135
166
  'left' : (left) ? left : 'auto',
136
- 'right' : (right) ? right : 'auto'
167
+ 'right' : (right) ? right : 'auto',
137
168
  }).end();
138
169
  };
139
170
 
140
171
  objPos(tip, (target.offset().top + target.outerHeight() + 10), 'auto', 'auto', target.offset().left);
141
172
 
142
173
  if (this.small()) {
143
- objPos(tip, (target.offset().top + target.outerHeight() + 10), 'auto', 'auto', 12.5, this.S(this.scope).width());
174
+ objPos(tip, (target.offset().top + target.outerHeight() + 10), 'auto', 'auto', 12.5, $(this.scope).width());
144
175
  tip.addClass('tip-override');
145
- objPos(nub, -nubHeight, 'auto', 'auto', target.offset().left + 10);
176
+ objPos(nub, -nubHeight, 'auto', 'auto', target.offset().left);
146
177
  } else {
147
178
  var left = target.offset().left;
148
179
  if (Foundation.rtl) {
180
+ nub.addClass('rtl');
149
181
  left = target.offset().left + target.outerWidth() - tip.outerWidth();
150
182
  }
151
-
152
183
  objPos(tip, (target.offset().top + target.outerHeight() + 10), 'auto', 'auto', left);
153
184
  tip.removeClass('tip-override');
154
- nub.removeAttr( 'style' );
155
185
  if (classes && classes.indexOf('tip-top') > -1) {
156
- objPos(tip, (target.offset().top - tip.outerHeight() - 10), 'auto', 'auto', left)
186
+ if (Foundation.rtl) nub.addClass('rtl');
187
+ objPos(tip, (target.offset().top - tip.outerHeight()), 'auto', 'auto', left)
157
188
  .removeClass('tip-override');
158
189
  } else if (classes && classes.indexOf('tip-left') > -1) {
159
190
  objPos(tip, (target.offset().top + (target.outerHeight() / 2) - (tip.outerHeight() / 2)), 'auto', 'auto', (target.offset().left - tip.outerWidth() - nubHeight))
160
191
  .removeClass('tip-override');
192
+ nub.removeClass('rtl');
161
193
  } else if (classes && classes.indexOf('tip-right') > -1) {
162
194
  objPos(tip, (target.offset().top + (target.outerHeight() / 2) - (tip.outerHeight() / 2)), 'auto', 'auto', (target.offset().left + target.outerWidth() + nubHeight))
163
195
  .removeClass('tip-override');
196
+ nub.removeClass('rtl');
164
197
  }
165
198
  }
166
199
 
@@ -171,9 +204,10 @@
171
204
  return matchMedia(Foundation.media_queries.small).matches;
172
205
  },
173
206
 
174
- inheritable_classes : function (target) {
175
- var inheritables = ['tip-top', 'tip-left', 'tip-bottom', 'tip-right', 'radius', 'round'].concat(this.settings.additional_inheritable_classes),
176
- classes = target.attr('class'),
207
+ inheritable_classes : function ($target) {
208
+ var settings = $.extend({}, this.settings, this.data_options($target)),
209
+ inheritables = ['tip-top', 'tip-left', 'tip-bottom', 'tip-right', 'radius', 'round'].concat(settings.additional_inheritable_classes),
210
+ classes = $target.attr('class'),
177
211
  filtered = classes ? $.map(classes.split(' '), function (el, i) {
178
212
  if ($.inArray(el, inheritables) !== -1) {
179
213
  return el;
@@ -183,30 +217,48 @@
183
217
  return $.trim(filtered);
184
218
  },
185
219
 
220
+ convert_to_touch : function($target) {
221
+ var self = this,
222
+ $tip = self.getTip($target),
223
+ settings = $.extend({}, self.settings, self.data_options($target));
224
+
225
+ if ($tip.find('.tap-to-close').length === 0) {
226
+ $tip.append('<span class="tap-to-close">'+settings.touch_close_text+'</span>');
227
+ $tip.on('click.fndtn.tooltip.tapclose touchstart.fndtn.tooltip.tapclose MSPointerDown.fndtn.tooltip.tapclose', function(e) {
228
+ self.hide($target);
229
+ });
230
+ }
231
+
232
+ $target.data('tooltip-open-event-type', 'touch');
233
+ },
234
+
186
235
  show : function ($target) {
187
236
  var $tip = this.getTip($target);
188
237
 
238
+ if ($target.data('tooltip-open-event-type') == 'touch') {
239
+ this.convert_to_touch($target);
240
+ }
241
+
189
242
  this.reposition($target, $tip, $target.attr('class'));
190
- return $tip.fadeIn(150);
243
+ $target.addClass('open');
244
+ $tip.fadeIn(150);
191
245
  },
192
246
 
193
247
  hide : function ($target) {
194
248
  var $tip = this.getTip($target);
195
249
 
196
- return $tip.fadeOut(150);
197
- },
198
-
199
- // deprecate reload
200
- reload : function () {
201
- var $self = $(this);
202
-
203
- return ($self.data('fndtn-tooltips')) ? $self.foundationTooltips('destroy').foundationTooltips('init') : $self.foundationTooltips('init');
250
+ $tip.fadeOut(150, function() {
251
+ $tip.find('.tap-to-close').remove();
252
+ $tip.off('click.fndtn.tooltip.tapclose touchstart.fndtn.tooltip.tapclose MSPointerDown.fndtn.tapclose');
253
+ $target.removeClass('open');
254
+ });
204
255
  },
205
256
 
206
257
  off : function () {
258
+ var self = this;
207
259
  this.S(this.scope).off('.fndtn.tooltip');
208
260
  this.S(this.settings.tooltip_class).each(function (i) {
209
- $('[' + this.attr_name() + ']').get(i).attr('title', $(this).text());
261
+ $('[' + self.attr_name() + ']').get(i).attr('title', $(this).text());
210
262
  }).remove();
211
263
  },
212
264