locomotivecms_wagon 1.0.2 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. checksums.yaml +15 -0
  2. data/Gemfile +1 -1
  3. data/README.md +1 -1
  4. data/Rakefile +2 -2
  5. data/generators/blank/Gemfile.tt +3 -1
  6. data/generators/blank/config/deploy.yml +4 -1
  7. data/generators/bootstrap/Gemfile.tt +3 -1
  8. data/generators/bootstrap/config/deploy.yml +4 -1
  9. data/generators/cloned/Gemfile.tt +3 -1
  10. data/generators/cloned/config/deploy.yml.tt +5 -1
  11. data/generators/foundation/Gemfile.tt +4 -2
  12. data/generators/foundation/app/views/pages/index.liquid +3 -1
  13. data/generators/foundation/app/views/pages/index.liquid.haml +18 -16
  14. data/generators/foundation/config/deploy.yml +4 -1
  15. data/generators/foundation/public/javascripts/foundation.min.js +32 -14
  16. data/generators/foundation/public/javascripts/foundation/foundation.alerts.js +4 -2
  17. data/generators/foundation/public/javascripts/foundation/foundation.clearing.js +67 -31
  18. data/generators/foundation/public/javascripts/foundation/foundation.cookie.js +1 -1
  19. data/generators/foundation/public/javascripts/foundation/foundation.dropdown.js +73 -25
  20. data/generators/foundation/public/javascripts/foundation/foundation.forms.js +356 -235
  21. data/generators/foundation/public/javascripts/foundation/foundation.interchange.js +271 -0
  22. data/generators/foundation/public/javascripts/foundation/foundation.joyride.js +265 -33
  23. data/generators/foundation/public/javascripts/foundation/foundation.js +130 -55
  24. data/generators/foundation/public/javascripts/foundation/foundation.magellan.js +6 -4
  25. data/generators/foundation/public/javascripts/foundation/foundation.orbit.js +38 -13
  26. data/generators/foundation/public/javascripts/foundation/foundation.placeholder.js +1 -1
  27. data/generators/foundation/public/javascripts/foundation/foundation.reveal.js +74 -14
  28. data/generators/foundation/public/javascripts/foundation/foundation.section.js +210 -66
  29. data/generators/foundation/public/javascripts/foundation/foundation.tooltips.js +25 -12
  30. data/generators/foundation/public/javascripts/foundation/foundation.topbar.js +126 -54
  31. data/generators/foundation/public/javascripts/vendor/custom.modernizr.js +1 -1
  32. data/generators/foundation/public/javascripts/vendor/jquery.js +1 -1
  33. data/generators/foundation/public/javascripts/vendor/zepto.js +1 -1
  34. data/generators/foundation/public/stylesheets/foundation.css +870 -438
  35. data/generators/foundation/public/stylesheets/foundation.min.css +440 -1
  36. data/generators/foundation/public/stylesheets/normalize.css +89 -146
  37. data/generators/page/template.liquid.haml.tt +6 -7
  38. data/generators/page/template.liquid.tt +34 -1
  39. data/lib/locomotive/wagon.rb +15 -1
  40. data/lib/locomotive/wagon/cli.rb +8 -4
  41. data/lib/locomotive/wagon/generators/site/foundation.rb +1 -1
  42. data/lib/locomotive/wagon/liquid.rb +1 -2
  43. data/lib/locomotive/wagon/liquid/drops/content_types.rb +6 -22
  44. data/lib/locomotive/wagon/liquid/drops/page.rb +6 -14
  45. data/lib/locomotive/wagon/liquid/drops/site.rb +4 -1
  46. data/lib/locomotive/wagon/liquid/filters/html.rb +1 -1
  47. data/lib/locomotive/wagon/liquid/filters/translate.rb +10 -6
  48. data/lib/locomotive/wagon/liquid/tags/nav.rb +3 -2
  49. data/lib/locomotive/wagon/misc/dragonfly.rb +1 -1
  50. data/lib/locomotive/wagon/scopeable.rb +28 -0
  51. data/lib/locomotive/wagon/server/page.rb +7 -1
  52. data/lib/locomotive/wagon/version.rb +1 -1
  53. data/locales/de.yml +13 -12
  54. data/locales/en.yml +13 -12
  55. data/locales/es.yml +13 -12
  56. data/locales/et.yml +13 -12
  57. data/locales/fr.yml +14 -12
  58. data/locales/it.yml +13 -12
  59. data/locales/nb.yml +13 -12
  60. data/locales/nl.yml +11 -10
  61. data/locales/pl.yml +13 -12
  62. data/locales/pt-BR.yml +13 -12
  63. data/locales/ru.yml +13 -12
  64. data/locomotivecms_wagon.gemspec +2 -1
  65. data/spec/fixtures/default/app/views/pages/grunge_bands.liquid.haml +8 -0
  66. data/spec/fixtures/default/app/views/pages/index.liquid.haml +3 -0
  67. data/spec/fixtures/default/app/views/pages/music.liquid.haml +1 -1
  68. data/spec/fixtures/default/app/views/pages/songs/template.liquid.haml +4 -0
  69. data/spec/fixtures/default/app/views/pages/tags/nav.liquid.haml +6 -0
  70. data/spec/fixtures/default/app/views/pages/unlisted_pages.liquid.haml +9 -0
  71. data/spec/integration/cassettes/pull.yml +397 -240
  72. data/spec/integration/cassettes/push.yml +468 -438
  73. data/spec/integration/cassettes/staging.yml +846 -0
  74. data/spec/integration/cli_spec.rb +19 -0
  75. data/spec/integration/server/basic_spec.rb +34 -5
  76. data/spec/integration/server/liquid_spec.rb +39 -0
  77. data/spec/integration/sites_spec.rb +28 -4
  78. data/spec/spec_helper.rb +1 -0
  79. data/spec/support/helpers.rb +8 -1
  80. metadata +37 -53
@@ -71,4 +71,4 @@
71
71
  return false;
72
72
  };
73
73
 
74
- })(Foundation.zj, document);
74
+ })(Foundation.zj, document);
@@ -6,15 +6,18 @@
6
6
  Foundation.libs.dropdown = {
7
7
  name : 'dropdown',
8
8
 
9
- version : '4.0.9',
9
+ version : '4.2.0',
10
10
 
11
11
  settings : {
12
- activeClass: 'open'
12
+ activeClass: 'open',
13
+ is_hover: false,
14
+ opened: function(){},
15
+ closed: function(){}
13
16
  },
14
17
 
15
18
  init : function (scope, method, options) {
16
19
  this.scope = scope || this.scope;
17
- Foundation.inherit(this, 'throttle');
20
+ Foundation.inherit(this, 'throttle scrollLeft data_options');
18
21
 
19
22
  if (typeof method === 'object') {
20
23
  $.extend(true, this.settings, method);
@@ -35,18 +38,37 @@
35
38
  events : function () {
36
39
  var self = this;
37
40
 
38
- $(this.scope).on('click.fndtn.dropdown', '[data-dropdown]', function (e) {
39
- e.preventDefault();
40
- e.stopPropagation();
41
- self.toggle($(this));
42
- });
43
-
44
- $('*, html, body').on('click.fndtn.dropdown', function (e) {
45
- if (!$(e.target).data('dropdown')) {
46
- $('[data-dropdown-content]')
47
- .css('left', '-99999px')
48
- .removeClass(self.settings.activeClass);
41
+ $(this.scope)
42
+ .on('click.fndtn.dropdown', '[data-dropdown]', function (e) {
43
+ var settings = $.extend({}, self.settings, self.data_options($(this)));
44
+ e.preventDefault();
45
+
46
+ if (!settings.is_hover) self.toggle($(this));
47
+ })
48
+ .on('mouseenter', '[data-dropdown]', function (e) {
49
+ var settings = $.extend({}, self.settings, self.data_options($(this)));
50
+ if (settings.is_hover) self.toggle($(this));
51
+ })
52
+ .on('mouseleave', '[data-dropdown-content]', function (e) {
53
+ var target = $('[data-dropdown="' + $(this).attr('id') + '"]'),
54
+ settings = $.extend({}, self.settings, self.data_options(target));
55
+ if (settings.is_hover) self.close.call(self, $(this));
56
+ })
57
+ .on('opened.fndtn.dropdown', '[data-dropdown-content]', this.settings.opened)
58
+ .on('closed.fndtn.dropdown', '[data-dropdown-content]', this.settings.closed);
59
+
60
+ $('body').on('click.fndtn.dropdown', function (e) {
61
+ var parent = $(e.target).closest('[data-dropdown-content]');
62
+
63
+ if ($(e.target).data('dropdown')) {
64
+ return;
49
65
  }
66
+ if (parent.length > 0 && ($(e.target).is('[data-dropdown-content]') || $.contains(parent.first()[0], e.target))) {
67
+ e.stopPropagation();
68
+ return;
69
+ }
70
+
71
+ self.close.call(self, $('[data-dropdown-content]'));
50
72
  });
51
73
 
52
74
  $(window).on('resize.fndtn.dropdown', self.throttle(function () {
@@ -56,19 +78,35 @@
56
78
  this.settings.init = true;
57
79
  },
58
80
 
59
- toggle : function (target, resize) {
81
+ close: function (dropdown) {
82
+ var self = this;
83
+ dropdown.each(function () {
84
+ if ($(this).hasClass(self.settings.activeClass)) {
85
+ $(this)
86
+ .css(Foundation.rtl ? 'right':'left', '-99999px')
87
+ .removeClass(self.settings.activeClass);
88
+ $(this).trigger('closed');
89
+ }
90
+ });
91
+ },
92
+
93
+ open: function (dropdown, target) {
94
+ this
95
+ .css(dropdown
96
+ .addClass(this.settings.activeClass), target);
97
+ dropdown.trigger('opened');
98
+ },
99
+
100
+ toggle : function (target) {
60
101
  var dropdown = $('#' + target.data('dropdown'));
61
102
 
62
- $('[data-dropdown-content]').not(dropdown).css('left', '-99999px').removeClass(this.settings.activeClass);
103
+ this.close.call(this, $('[data-dropdown-content]').not(dropdown));
63
104
 
64
105
  if (dropdown.hasClass(this.settings.activeClass)) {
65
- dropdown
66
- .css('left', '-99999px')
67
- .removeClass(this.settings.activeClass);
106
+ this.close.call(this, dropdown);
68
107
  } else {
69
- this
70
- .css(dropdown
71
- .addClass(this.settings.activeClass), target);
108
+ this.close.call(this, $('[data-dropdown-content]'))
109
+ this.open.call(this, dropdown, target);
72
110
  }
73
111
  },
74
112
 
@@ -82,8 +120,12 @@
82
120
  },
83
121
 
84
122
  css : function (dropdown, target) {
85
- if (dropdown.parent()[0] === $('body')[0]) {
123
+ var offset_parent = dropdown.offsetParent();
124
+ // temporary workaround until 4.2
125
+ if (offset_parent.length > 0 && /body/i.test(dropdown.offsetParent()[0].nodeName)) {
86
126
  var position = target.offset();
127
+ position.top -= dropdown.offsetParent().offset().top;
128
+ position.left -= dropdown.offsetParent().offset().left;
87
129
  } else {
88
130
  var position = target.position();
89
131
  }
@@ -97,14 +139,18 @@
97
139
  top: position.top + this.outerHeight(target)
98
140
  });
99
141
  } else {
100
- if ($(window).width() > this.outerWidth(dropdown) + target.offset().left) {
142
+ if (!Foundation.rtl && $(window).width() > this.outerWidth(dropdown) + target.offset().left) {
101
143
  var left = position.left;
144
+ if (dropdown.hasClass('right')) {
145
+ dropdown.removeClass('right');
146
+ }
102
147
  } else {
103
148
  if (!dropdown.hasClass('right')) {
104
149
  dropdown.addClass('right');
105
150
  }
106
151
  var left = position.left - (this.outerWidth(dropdown) - this.outerWidth(target));
107
152
  }
153
+
108
154
  dropdown.attr('style', '').css({
109
155
  position : 'absolute',
110
156
  top: position.top + this.outerHeight(target),
@@ -125,6 +171,8 @@
125
171
  $(window).off('.fndtn.dropdown');
126
172
  $('[data-dropdown-content]').off('.fndtn.dropdown');
127
173
  this.settings.init = false;
128
- }
174
+ },
175
+
176
+ reflow : function () {}
129
177
  };
130
178
  }(Foundation.zj, this, this.document));
@@ -1,19 +1,19 @@
1
- /*jslint unparam: true, browser: true, indent: 2 */
2
-
3
- ;(function ($, window, document, undefined) {
1
+ (function ($, window, document, undefined) {
4
2
  'use strict';
5
3
 
6
4
  Foundation.libs.forms = {
7
- name : 'forms',
5
+ name: 'forms',
6
+
7
+ version: '4.2.1',
8
8
 
9
- version : '4.0.4',
9
+ cache: {},
10
10
 
11
- settings : {
12
- disable_class: 'no-custom'
11
+ settings: {
12
+ disable_class: 'no-custom',
13
+ last_combo : null
13
14
  },
14
15
 
15
- init : function (scope, method, options) {
16
- this.scope = scope || this.scope;
16
+ init: function (scope, method, options) {
17
17
 
18
18
  if (typeof method === 'object') {
19
19
  $.extend(true, this.settings, method);
@@ -32,63 +32,71 @@
32
32
  }
33
33
  },
34
34
 
35
- assemble : function () {
35
+ assemble: function () {
36
36
  $('form.custom input[type="radio"]', $(this.scope)).not('[data-customforms="disabled"]')
37
37
  .each(this.append_custom_markup);
38
38
  $('form.custom input[type="checkbox"]', $(this.scope)).not('[data-customforms="disabled"]')
39
39
  .each(this.append_custom_markup);
40
- $('form.custom select', $(this.scope)).not('[data-customforms="disabled"]')
40
+ $('form.custom select', $(this.scope))
41
+ .not('[data-customforms="disabled"]')
42
+ .not('[multiple=multiple]')
41
43
  .each(this.append_custom_select);
42
44
  },
43
45
 
44
- events : function () {
46
+ events: function () {
45
47
  var self = this;
46
48
 
47
49
  $(this.scope)
48
- .on('change.fndtn.forms', 'form.custom select:not([data-customforms="disabled"])', function (e) {
49
- self.refresh_custom_select($(this));
50
+ .on('click.fndtn.forms', 'form.custom span.custom.checkbox', function (e) {
51
+ e.preventDefault();
52
+ e.stopPropagation();
53
+ self.toggle_checkbox($(this));
54
+ })
55
+ .on('click.fndtn.forms', 'form.custom span.custom.radio', function (e) {
56
+ e.preventDefault();
57
+ e.stopPropagation();
58
+ self.toggle_radio($(this));
59
+ })
60
+ .on('change.fndtn.forms', 'form.custom select:not([data-customforms="disabled"])', function (e, force_refresh) {
61
+ self.refresh_custom_select($(this), force_refresh);
50
62
  })
51
63
  .on('click.fndtn.forms', 'form.custom label', function (e) {
52
- var $associatedElement = $('#' + self.escape($(this).attr('for')) + ':not([data-customforms="disabled"])'),
64
+ if ($(e.target).is('label')) {
65
+ var $associatedElement = $('#' + self.escape($(this).attr('for')) + ':not([data-customforms="disabled"])'),
53
66
  $customCheckbox,
54
67
  $customRadio;
55
- if ($associatedElement.length !== 0) {
56
- if ($associatedElement.attr('type') === 'checkbox') {
57
- e.preventDefault();
58
- $customCheckbox = $(this).find('span.custom.checkbox');
59
-
60
- //the checkbox might be outside after the label
61
- if ($customCheckbox.length == 0) {
62
- $customCheckbox = $(this).next('span.custom.checkbox');
63
- }
64
- //the checkbox might be outside before the label
65
- if ($customCheckbox.length == 0) {
66
- $customCheckbox = $(this).prev('span.custom.checkbox');
67
- }
68
- self.toggle_checkbox($customCheckbox);
69
- } else if ($associatedElement.attr('type') === 'radio') {
70
- e.preventDefault();
71
- $customRadio = $(this).find('span.custom.radio');
72
- //the radio might be outside after the label
73
- if ($customRadio.length == 0) {
74
- $customRadio = $(this).next('span.custom.radio');
75
- }
76
- //the radio might be outside before the label
77
- if ($customRadio.length == 0) {
78
- $customRadio = $(this).prev('span.custom.radio');
68
+
69
+ if ($associatedElement.length !== 0) {
70
+ if ($associatedElement.attr('type') === 'checkbox') {
71
+ e.preventDefault();
72
+ $customCheckbox = $(this).find('span.custom.checkbox');
73
+ //the checkbox might be outside after the label or inside of another element
74
+ if ($customCheckbox.length == 0) {
75
+ $customCheckbox = $associatedElement.add(this).siblings('span.custom.checkbox').first();
76
+ }
77
+ self.toggle_checkbox($customCheckbox);
78
+ } else if ($associatedElement.attr('type') === 'radio') {
79
+ e.preventDefault();
80
+ $customRadio = $(this).find('span.custom.radio');
81
+ //the radio might be outside after the label or inside of another element
82
+ if ($customRadio.length == 0) {
83
+ $customRadio = $associatedElement.add(this).siblings('span.custom.radio').first();
84
+ }
85
+ self.toggle_radio($customRadio);
79
86
  }
80
- self.toggle_radio($customRadio);
81
87
  }
82
88
  }
83
89
  })
90
+ .on('mousedown.fndtn.forms', 'form.custom div.custom.dropdown', function () {
91
+ return false;
92
+ })
84
93
  .on('click.fndtn.forms', 'form.custom div.custom.dropdown a.current, form.custom div.custom.dropdown a.selector', function (e) {
85
94
  var $this = $(this),
86
95
  $dropdown = $this.closest('div.custom.dropdown'),
87
- $select = $dropdown.prev();
96
+ $select = getFirstPrevSibling($dropdown, 'select');
88
97
 
89
98
  // make sure other dropdowns close
90
- if(!$dropdown.hasClass('open'))
91
- $(self.scope).trigger('click');
99
+ if (!$dropdown.hasClass('open')) $(self.scope).trigger('click');
92
100
 
93
101
  e.preventDefault();
94
102
  if (false === $select.is(':disabled')) {
@@ -108,32 +116,29 @@
108
116
  .on('click.fndtn.forms touchend.fndtn.forms', 'form.custom div.custom.dropdown li', function (e) {
109
117
  var $this = $(this),
110
118
  $customDropdown = $this.closest('div.custom.dropdown'),
111
- $select = $customDropdown.prev(),
119
+ $select = getFirstPrevSibling($customDropdown, 'select'),
112
120
  selectedIndex = 0;
113
121
 
114
122
  e.preventDefault();
115
123
  e.stopPropagation();
116
124
 
117
- if ( ! $(this).hasClass('disabled')) {
125
+ if (!$(this).hasClass('disabled')) {
118
126
  $('div.dropdown').not($customDropdown).removeClass('open');
119
127
 
120
- var $oldThis= $this
121
- .closest('ul')
128
+ var $oldThis = $this.closest('ul')
122
129
  .find('li.selected');
123
130
  $oldThis.removeClass('selected');
124
131
 
125
132
  $this.addClass('selected');
126
133
 
127
- $customDropdown
128
- .removeClass('open')
134
+ $customDropdown.removeClass('open')
129
135
  .find('a.current')
130
- .html($this.html());
136
+ .text($this.text());
131
137
 
132
138
  $this.closest('ul').find('li').each(function (index) {
133
139
  if ($this[0] == this) {
134
140
  selectedIndex = index;
135
141
  }
136
-
137
142
  });
138
143
  $select[0].selectedIndex = selectedIndex;
139
144
 
@@ -141,14 +146,89 @@
141
146
  $select.data('prevalue', $oldThis.html());
142
147
  $select.trigger('change');
143
148
  }
144
- });
149
+ });
150
+
151
+ $(window).on('keydown', function (e) {
152
+ var focus = document.activeElement,
153
+ self = Foundation.libs.forms,
154
+ dropdown = $('.custom.dropdown.open');
155
+
156
+ if (dropdown.length > 0) {
157
+ e.preventDefault();
158
+
159
+ if (e.which === 13) {
160
+ dropdown.find('li.selected').trigger('click');
161
+ }
162
+
163
+ if (e.which === 27) {
164
+ dropdown.removeClass('open');
165
+ }
166
+
167
+ if (e.which >= 65 && e.which <= 90) {
168
+ var next = self.go_to(dropdown, e.which),
169
+ current = dropdown.find('li.selected');
170
+
171
+ if (next) {
172
+ current.removeClass('selected');
173
+ self.scrollTo(next.addClass('selected'), 300);
174
+ }
175
+ }
176
+
177
+ if (e.which === 38) {
178
+ var current = dropdown.find('li.selected'),
179
+ prev = current.prev(':not(.disabled)');
180
+
181
+ if (prev.length > 0) {
182
+ prev.parent()[0].scrollTop = prev.parent().scrollTop() - self.outerHeight(prev);
183
+ current.removeClass('selected');
184
+ prev.addClass('selected');
185
+ }
186
+ } else if (e.which === 40) {
187
+ var current = dropdown.find('li.selected'),
188
+ next = current.next(':not(.disabled)');
189
+
190
+ if (next.length > 0) {
191
+ next.parent()[0].scrollTop = next.parent().scrollTop() + self.outerHeight(next);
192
+ current.removeClass('selected');
193
+ next.addClass('selected');
194
+ }
195
+ }
196
+ }
197
+ });
145
198
 
146
199
  this.settings.init = true;
147
200
  },
148
201
 
149
- append_custom_markup : function (idx, sel) {
150
- var $this = $(sel).hide(),
151
- type = $this.attr('type'),
202
+ go_to: function (dropdown, character) {
203
+ var lis = dropdown.find('li'),
204
+ count = lis.length;
205
+
206
+ if (count > 0) {
207
+ for (var i = 0; i < count; i++) {
208
+ var first_letter = lis.eq(i).text().charAt(0).toLowerCase();
209
+ if (first_letter === String.fromCharCode(character).toLowerCase()) return lis.eq(i);
210
+ }
211
+ }
212
+ },
213
+
214
+ scrollTo: function (el, duration) {
215
+ if (duration < 0) return;
216
+ var parent = el.parent();
217
+ var li_height = this.outerHeight(el);
218
+ var difference = (li_height * (el.index())) - parent.scrollTop();
219
+ var perTick = difference / duration * 10;
220
+
221
+ this.scrollToTimerCache = setTimeout(function () {
222
+ if (!isNaN(parseInt(perTick, 10))) {
223
+ parent[0].scrollTop = parent.scrollTop() + perTick;
224
+ this.scrollTo(el, duration - 10);
225
+ }
226
+ }.bind(this), 10);
227
+ },
228
+
229
+ append_custom_markup: function (idx, sel) {
230
+ var $this = $(sel),
231
+ type = $this.attr('type'),
152
232
  $span = $this.next('span.custom.' + type);
153
233
 
154
234
  if ($span.length === 0) {
@@ -159,134 +239,159 @@
159
239
  $span.toggleClass('disabled', $this.is(':disabled'));
160
240
  },
161
241
 
162
- append_custom_select : function (idx, sel) {
163
- var self = Foundation.libs.forms,
164
- $this = $( sel ),
165
- $customSelect = $this.next( 'div.custom.dropdown' ),
166
- $customList = $customSelect.find( 'ul' ),
167
- $selectCurrent = $customSelect.find( ".current" ),
168
- $selector = $customSelect.find( ".selector" ),
169
- $options = $this.find( 'option' ),
170
- $selectedOption = $options.filter( ':selected' ),
171
- copyClasses = $this.attr('class') ? $this.attr('class').split(' ') : [],
172
- maxWidth = 0,
173
- liHtml = '',
174
- $listItems,
175
- $currentSelect = false;
176
-
177
- if ($this.hasClass(self.settings.disable_class)) return;
178
-
179
- if ($customSelect.length === 0) {
180
- var customSelectSize = $this.hasClass( 'small' ) ? 'small' :
181
- $this.hasClass( 'medium' ) ? 'medium' :
182
- $this.hasClass( 'large' ) ? 'large' :
183
- $this.hasClass( 'expand' ) ? 'expand' : '';
184
-
185
- $customSelect = $('<div class="' + ['custom', 'dropdown', customSelectSize ].concat(copyClasses).filter(function(item, idx,arr){ if(item == '') return false; return arr.indexOf(item) == idx; }).join( ' ' ) + '"><a href="#" class="selector"></a><ul /></div>');
186
- $selector = $customSelect.find(".selector");
187
- $customList = $customSelect.find("ul");
188
- liHtml = $options.map(function() { return "<li>" + $( this ).html() + "</li>"; } ).get().join( '' );
189
- $customList.append(liHtml);
190
- $currentSelect = $customSelect.prepend('<a href="#" class="current">' + $selectedOption.html() + '</a>' ).find( ".current" );
191
- $this
192
- .after( $customSelect )
193
- .hide();
194
-
195
- } else {
196
- liHtml = $options.map(function() {
197
- return "<li>" + $( this ).html() + "</li>";
198
- })
199
- .get().join('');
200
- $customList
201
- .html('')
202
- .append(liHtml);
203
-
204
- } // endif $customSelect.length === 0
205
- $customSelect.toggleClass('disabled', $this.is( ':disabled' ) );
206
- $listItems = $customList.find( 'li' );
207
-
208
- $options.each( function ( index ) {
209
- if ( this.selected ) {
210
- $listItems.eq( index ).addClass( 'selected' );
211
-
212
- if ($currentSelect) {
213
- $currentSelect.html( $( this ).html() );
242
+ append_custom_select: function (idx, sel) {
243
+ var self = Foundation.libs.forms,
244
+ $this = $(sel),
245
+ $customSelect = $this.next('div.custom.dropdown'),
246
+ $customList = $customSelect.find('ul'),
247
+ $selectCurrent = $customSelect.find(".current"),
248
+ $selector = $customSelect.find(".selector"),
249
+ $options = $this.find('option'),
250
+ $selectedOption = $options.filter(':selected'),
251
+ copyClasses = $this.attr('class') ? $this.attr('class').split(' ') : [],
252
+ maxWidth = 0,
253
+ liHtml = '',
254
+ $listItems,
255
+ $currentSelect = false;
256
+
257
+ if ($this.hasClass(self.settings.disable_class)) return;
258
+
259
+ if ($customSelect.length === 0) {
260
+ var customSelectSize = $this.hasClass('small') ? 'small' : $this.hasClass('medium') ? 'medium' : $this.hasClass('large') ? 'large' : $this.hasClass('expand') ? 'expand' : '';
261
+
262
+ $customSelect = $('<div class="' + ['custom', 'dropdown', customSelectSize].concat(copyClasses).filter(function (item, idx, arr) {
263
+ if (item == '') return false;
264
+ return arr.indexOf(item) == idx;
265
+ }).join(' ') + '"><a href="#" class="selector"></a><ul /></div>');
266
+
267
+ $selector = $customSelect.find(".selector");
268
+ $customList = $customSelect.find("ul");
269
+
270
+ liHtml = $options.map(function () {
271
+ var copyClasses = $(this).attr('class') ? $(this).attr('class') : '';
272
+ return "<li class='" + copyClasses + "'>" + $(this).html() + "</li>";
273
+ }).get().join('');
274
+
275
+ $customList.append(liHtml);
276
+
277
+ $currentSelect = $customSelect
278
+ .prepend('<a href="#" class="current">' + $selectedOption.html() + '</a>')
279
+ .find(".current");
280
+
281
+ $this.after($customSelect)
282
+ .addClass('hidden-field');
283
+ } else {
284
+ liHtml = $options.map(function () {
285
+ return "<li>" + $(this).html() + "</li>";
286
+ })
287
+ .get().join('');
288
+
289
+ $customList.html('')
290
+ .append(liHtml);
291
+
292
+ } // endif $customSelect.length === 0
293
+
294
+ self.assign_id($this, $customSelect);
295
+ $customSelect.toggleClass('disabled', $this.is(':disabled'));
296
+ $listItems = $customList.find('li');
297
+
298
+ // cache list length
299
+ self.cache[$customSelect.data('id')] = $listItems.length;
300
+
301
+ $options.each(function (index) {
302
+ if (this.selected) {
303
+ $listItems.eq(index).addClass('selected');
304
+
305
+ if ($currentSelect) {
306
+ $currentSelect.html($(this).html());
307
+ }
308
+ }
309
+ if ($(this).is(':disabled')) {
310
+ $listItems.eq(index).addClass('disabled');
214
311
  }
312
+ });
215
313
 
216
- }
217
- if ($(this).is(':disabled')) {
218
- $listItems.eq( index ).addClass( 'disabled' );
219
- }
220
- });
314
+ //
315
+ // If we're not specifying a predetermined form size.
316
+ //
317
+ if (!$customSelect.is('.small, .medium, .large, .expand')) {
221
318
 
222
- //
223
- // If we're not specifying a predetermined form size.
224
- //
225
- if (!$customSelect.is('.small, .medium, .large, .expand')) {
319
+ // ------------------------------------------------------------------------------------
320
+ // This is a work-around for when elements are contained within hidden parents.
321
+ // For example, when custom-form elements are inside of a hidden reveal modal.
322
+ //
323
+ // We need to display the current custom list element as well as hidden parent elements
324
+ // in order to properly calculate the list item element's width property.
325
+ // -------------------------------------------------------------------------------------
226
326
 
227
- // ------------------------------------------------------------------------------------
228
- // This is a work-around for when elements are contained within hidden parents.
229
- // For example, when custom-form elements are inside of a hidden reveal modal.
230
- //
231
- // We need to display the current custom list element as well as hidden parent elements
232
- // in order to properly calculate the list item element's width property.
233
- // -------------------------------------------------------------------------------------
327
+ $customSelect.addClass('open');
328
+ //
329
+ // Quickly, display all parent elements.
330
+ // This should help us calcualate the width of the list item's within the drop down.
331
+ //
332
+ var self = Foundation.libs.forms;
333
+ self.hidden_fix.adjust($customList);
234
334
 
235
- $customSelect.addClass( 'open' );
236
- //
237
- // Quickly, display all parent elements.
238
- // This should help us calcualate the width of the list item's within the drop down.
239
- //
240
- var self = Foundation.libs.forms;
241
- self.hidden_fix.adjust( $customList );
335
+ maxWidth = (self.outerWidth($listItems) > maxWidth) ? self.outerWidth($listItems) : maxWidth;
242
336
 
243
- maxWidth = ( self.outerWidth($listItems) > maxWidth ) ? self.outerWidth($listItems) : maxWidth;
337
+ Foundation.libs.forms.hidden_fix.reset();
244
338
 
245
- Foundation.libs.forms.hidden_fix.reset();
339
+ $customSelect.removeClass('open');
246
340
 
247
- $customSelect.removeClass( 'open' );
341
+ } // endif
248
342
 
249
- } // endif
343
+ },
250
344
 
345
+ assign_id: function ($select, $customSelect) {
346
+ var id = [+new Date(), Foundation.random_str(5)].join('-');
347
+ $select.attr('data-id', id);
348
+ $customSelect.attr('data-id', id);
251
349
  },
252
350
 
253
- refresh_custom_select : function ($select) {
351
+ refresh_custom_select: function ($select, force_refresh) {
254
352
  var self = this;
255
353
  var maxWidth = 0,
256
- $customSelect = $select.next(),
257
- $options = $select.find('option');
354
+ $customSelect = $select.next(),
355
+ $options = $select.find('option'),
356
+ $listItems = $customSelect.find('li');
258
357
 
259
- $customSelect.find('ul').html('');
358
+ if ($listItems.length != this.cache[$customSelect.data('id')] || force_refresh) {
359
+ $customSelect.find('ul').html('');
260
360
 
261
- $options.each(function () {
262
- var $li = $('<li>' + $(this).html() + '</li>');
263
- $customSelect.find('ul').append($li);
264
- });
361
+ $options.each(function () {
362
+ var $li = $('<li>' + $(this).html() + '</li>');
363
+ $customSelect.find('ul').append($li);
364
+ });
265
365
 
266
- // re-populate
267
- $options.each(function (index) {
268
- if (this.selected) {
269
- $customSelect.find('li').eq(index).addClass('selected');
270
- $customSelect.find('.current').html($(this).html());
271
- }
272
- if ($(this).is(':disabled')) {
273
- $customSelect.find('li').eq(index).addClass('disabled');
274
- }
275
- });
366
+ // re-populate
367
+ $options.each(function (index) {
368
+ if (this.selected) {
369
+ $customSelect.find('li').eq(index).addClass('selected');
370
+ $customSelect.find('.current').html($(this).html());
371
+ }
372
+ if ($(this).is(':disabled')) {
373
+ $customSelect.find('li').eq(index).addClass('disabled');
374
+ }
375
+ });
276
376
 
277
- // fix width
278
- $customSelect.removeAttr('style')
279
- .find('ul').removeAttr('style');
280
- $customSelect.find('li').each(function () {
281
- $customSelect.addClass('open');
282
- if (self.outerWidth($(this)) > maxWidth) {
283
- maxWidth = self.outerWidth($(this));
284
- }
285
- $customSelect.removeClass('open');
286
- });
377
+ // fix width
378
+ $customSelect.removeAttr('style')
379
+ .find('ul').removeAttr('style');
380
+ $customSelect.find('li').each(function () {
381
+ $customSelect.addClass('open');
382
+ if (self.outerWidth($(this)) > maxWidth) {
383
+ maxWidth = self.outerWidth($(this));
384
+ }
385
+ $customSelect.removeClass('open');
386
+ });
387
+
388
+ $listItems = $customSelect.find('li');
389
+ // cache list length
390
+ this.cache[$customSelect.data('id')] = $listItems.length;
391
+ }
287
392
  },
288
393
 
289
- toggle_checkbox : function ($element) {
394
+ toggle_checkbox: function ($element) {
290
395
  var $input = $element.prev(),
291
396
  input = $input[0];
292
397
 
@@ -298,98 +403,114 @@
298
403
  }
299
404
  },
300
405
 
301
- toggle_radio : function ($element) {
302
- var $input = $element.prev(),
303
- $form = $input.closest('form.custom'),
304
- input = $input[0];
406
+ toggle_radio: function ($element) {
407
+ var $input = $element.prev(),
408
+ $form = $input.closest('form.custom'),
409
+ input = $input[0];
305
410
 
306
- if (false === $input.is(':disabled')) {
307
- $form.find('input[type="radio"][name="' + this.escape($input.attr('name')) + '"]').next().not($element).removeClass('checked');
308
- if ( !$element.hasClass('checked') ) {
309
- $element.toggleClass('checked');
310
- }
311
- input.checked = $element.hasClass('checked');
411
+ if (false === $input.is(':disabled')) {
412
+ $form.find('input[type="radio"][name="' + this.escape($input.attr('name')) + '"]')
413
+ .next().not($element).removeClass('checked');
312
414
 
313
- $input.trigger('change');
314
- }
415
+ if (!$element.hasClass('checked')) {
416
+ $element.toggleClass('checked');
417
+ }
418
+
419
+ input.checked = $element.hasClass('checked');
420
+
421
+ $input.trigger('change');
422
+ }
315
423
  },
316
424
 
317
- escape : function (text) {
425
+ escape: function (text) {
318
426
  return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
319
427
  },
320
428
 
321
- hidden_fix : {
322
- /**
323
- * Sets all hidden parent elements and self to visibile.
324
- *
325
- * @method adjust
326
- * @param {jQuery Object} $child
327
- */
429
+ hidden_fix: {
430
+ /**
431
+ * Sets all hidden parent elements and self to visibile.
432
+ *
433
+ * @method adjust
434
+ * @param {jQuery Object} $child
435
+ */
328
436
 
329
- // We'll use this to temporarily store style properties.
330
- tmp : [],
437
+ // We'll use this to temporarily store style properties.
438
+ tmp: [],
331
439
 
332
- // We'll use this to set hidden parent elements.
333
- hidden : null,
440
+ // We'll use this to set hidden parent elements.
441
+ hidden: null,
334
442
 
335
- adjust : function( $child ) {
336
- // Internal reference.
337
- var _self = this;
443
+ adjust: function ($child) {
444
+ // Internal reference.
445
+ var _self = this;
338
446
 
339
- // Set all hidden parent elements, including this element.
340
- _self.hidden = $child.parents().andSelf().filter( ":hidden" );
447
+ // Set all hidden parent elements, including this element.
448
+ _self.hidden = $child.parents();
449
+ _self.hidden = _self.hidden.add($child).filter(":hidden");
341
450
 
342
- // Loop through all hidden elements.
343
- _self.hidden.each( function() {
451
+ // Loop through all hidden elements.
452
+ _self.hidden.each(function () {
344
453
 
345
- // Cache the element.
346
- var $elem = $( this );
454
+ // Cache the element.
455
+ var $elem = $(this);
347
456
 
348
- // Store the style attribute.
349
- // Undefined if element doesn't have a style attribute.
350
- _self.tmp.push( $elem.attr( 'style' ) );
457
+ // Store the style attribute.
458
+ // Undefined if element doesn't have a style attribute.
459
+ _self.tmp.push($elem.attr('style'));
351
460
 
352
- // Set the element's display property to block,
353
- // but ensure it's visibility is hidden.
354
- $elem.css( { 'visibility' : 'hidden', 'display' : 'block' } );
355
- });
356
-
357
- }, // end adjust
358
-
359
- /**
360
- * Resets the elements previous state.
361
- *
362
- * @method reset
363
- */
364
- reset : function() {
365
- // Internal reference.
366
- var _self = this;
367
- // Loop through our hidden element collection.
368
- _self.hidden.each( function( i ) {
369
- // Cache this element.
370
- var $elem = $( this ),
371
- _tmp = _self.tmp[ i ]; // Get the stored 'style' value for this element.
372
-
373
- // If the stored value is undefined.
374
- if( _tmp === undefined )
461
+ // Set the element's display property to block,
462
+ // but ensure it's visibility is hidden.
463
+ $elem.css({
464
+ 'visibility': 'hidden',
465
+ 'display': 'block'
466
+ });
467
+ });
468
+
469
+ }, // end adjust
470
+
471
+ /**
472
+ * Resets the elements previous state.
473
+ *
474
+ * @method reset
475
+ */
476
+ reset: function () {
477
+ // Internal reference.
478
+ var _self = this;
479
+ // Loop through our hidden element collection.
480
+ _self.hidden.each(function (i) {
481
+ // Cache this element.
482
+ var $elem = $(this),
483
+ _tmp = _self.tmp[i]; // Get the stored 'style' value for this element.
484
+
485
+ // If the stored value is undefined.
486
+ if (_tmp === undefined)
375
487
  // Remove the style attribute.
376
- $elem.removeAttr( 'style' );
377
- else
488
+ $elem.removeAttr('style');
489
+ else
378
490
  // Otherwise, reset the element style attribute.
379
- $elem.attr( 'style', _tmp );
380
-
381
- });
382
- // Reset the tmp array.
383
- _self.tmp = [];
384
- // Reset the hidden elements variable.
385
- _self.hidden = null;
386
-
387
- } // end reset
388
-
491
+ $elem.attr('style', _tmp);
492
+ });
493
+ // Reset the tmp array.
494
+ _self.tmp = [];
495
+ // Reset the hidden elements variable.
496
+ _self.hidden = null;
497
+
498
+ } // end reset
389
499
  },
390
500
 
391
- off : function () {
501
+ off: function () {
392
502
  $(this.scope).off('.fndtn.forms');
503
+ },
504
+
505
+ reflow : function () {}
506
+ };
507
+
508
+ var getFirstPrevSibling = function($el, selector) {
509
+ var $el = $el.prev();
510
+ while ($el.length) {
511
+ if ($el.is(selector)) return $el;
512
+ $el = $el.prev();
393
513
  }
514
+ return $();
394
515
  };
395
516
  }(Foundation.zj, this, this.document));