foundation-rails 6.2.1.0 → 6.2.3.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 (45) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/bower.json +1 -1
  4. data/lib/foundation/rails/version.rb +1 -1
  5. data/lib/generators/foundation/templates/_settings.scss +1 -1
  6. data/vendor/assets/js/foundation.abide.js.es6 +27 -11
  7. data/vendor/assets/js/foundation.accordion.js.es6 +1 -1
  8. data/vendor/assets/js/foundation.accordionMenu.js.es6 +10 -7
  9. data/vendor/assets/js/foundation.core.js.es6 +3 -3
  10. data/vendor/assets/js/foundation.drilldown.js.es6 +31 -23
  11. data/vendor/assets/js/foundation.dropdown.js.es6 +1 -1
  12. data/vendor/assets/js/foundation.dropdownMenu.js.es6 +34 -26
  13. data/vendor/assets/js/foundation.equalizer.js.es6 +27 -6
  14. data/vendor/assets/js/foundation.interchange.js.es6 +22 -16
  15. data/vendor/assets/js/foundation.magellan.js.es6 +1 -1
  16. data/vendor/assets/js/foundation.offcanvas.js.es6 +6 -3
  17. data/vendor/assets/js/foundation.responsiveToggle.js.es6 +10 -3
  18. data/vendor/assets/js/foundation.reveal.js.es6 +53 -35
  19. data/vendor/assets/js/foundation.slider.js.es6 +31 -11
  20. data/vendor/assets/js/foundation.sticky.js.es6 +30 -27
  21. data/vendor/assets/js/foundation.tabs.js.es6 +13 -5
  22. data/vendor/assets/js/foundation.tooltip.js.es6 +12 -6
  23. data/vendor/assets/js/foundation.util.box.js.es6 +1 -1
  24. data/vendor/assets/js/foundation.util.keyboard.js.es6 +3 -3
  25. data/vendor/assets/js/foundation.util.mediaQuery.js.es6 +15 -11
  26. data/vendor/assets/js/foundation.util.touch.js.es6 +1 -1
  27. data/vendor/assets/scss/components/_accordion.scss +27 -7
  28. data/vendor/assets/scss/components/_button-group.scss +15 -23
  29. data/vendor/assets/scss/components/_button.scss +5 -0
  30. data/vendor/assets/scss/components/_dropdown-menu.scss +16 -5
  31. data/vendor/assets/scss/components/_media-object.scss +8 -2
  32. data/vendor/assets/scss/components/_menu.scss +9 -7
  33. data/vendor/assets/scss/components/_reveal.scss +7 -0
  34. data/vendor/assets/scss/components/_title-bar.scss +1 -1
  35. data/vendor/assets/scss/forms/_input-group.scss +1 -0
  36. data/vendor/assets/scss/forms/_select.scss +2 -1
  37. data/vendor/assets/scss/foundation.scss +1 -1
  38. data/vendor/assets/scss/grid/_classes.scss +2 -1
  39. data/vendor/assets/scss/grid/_flex-grid.scss +1 -1
  40. data/vendor/assets/scss/grid/_position.scss +1 -1
  41. data/vendor/assets/scss/grid/_row.scss +1 -1
  42. data/vendor/assets/scss/settings/_settings.scss +1 -1
  43. data/vendor/assets/scss/util/_breakpoint.scss +4 -3
  44. data/vendor/assets/scss/util/_mixins.scss +1 -1
  45. metadata +2 -2
@@ -38,6 +38,10 @@ class Equalizer {
38
38
  this.hasNested = this.$element.find('[data-equalizer]').length > 0;
39
39
  this.isNested = this.$element.parentsUntil(document.body, '[data-equalizer]').length > 0;
40
40
  this.isOn = false;
41
+ this._bindHandler = {
42
+ onResizeMeBound: this._onResizeMe.bind(this),
43
+ onPostEqualizedBound: this._onPostEqualized.bind(this)
44
+ };
41
45
 
42
46
  var imgs = this.$element.find('img');
43
47
  var tooSmall;
@@ -62,7 +66,26 @@ class Equalizer {
62
66
  */
63
67
  _pauseEvents() {
64
68
  this.isOn = false;
65
- this.$element.off('.zf.equalizer resizeme.zf.trigger');
69
+ this.$element.off({
70
+ '.zf.equalizer': this._bindHandler.onPostEqualizedBound,
71
+ 'resizeme.zf.trigger': this._bindHandler.onResizeMeBound
72
+ });
73
+ }
74
+
75
+ /**
76
+ * function to handle $elements resizeme.zf.trigger, with bound this on _bindHandler.onResizeMeBound
77
+ * @private
78
+ */
79
+ _onResizeMe(e) {
80
+ this._reflow();
81
+ }
82
+
83
+ /**
84
+ * function to handle $elements postequalized.zf.equalizer, with bound this on _bindHandler.onPostEqualizedBound
85
+ * @private
86
+ */
87
+ _onPostEqualized(e) {
88
+ if(e.target !== this.$element[0]){ this._reflow(); }
66
89
  }
67
90
 
68
91
  /**
@@ -73,11 +96,9 @@ class Equalizer {
73
96
  var _this = this;
74
97
  this._pauseEvents();
75
98
  if(this.hasNested){
76
- this.$element.on('postequalized.zf.equalizer', function(e){
77
- if(e.target !== _this.$element[0]){ _this._reflow(); }
78
- });
99
+ this.$element.on('postequalized.zf.equalizer', this._bindHandler.onPostEqualizedBound);
79
100
  }else{
80
- this.$element.on('resizeme.zf.trigger', this._reflow.bind(this));
101
+ this.$element.on('resizeme.zf.trigger', this._bindHandler.onResizeMeBound);
81
102
  }
82
103
  this.isOn = true;
83
104
  }
@@ -132,7 +153,7 @@ class Equalizer {
132
153
  * @private
133
154
  */
134
155
  _isStacked() {
135
- return this.$watched[0].offsetTop !== this.$watched[1].offsetTop;
156
+ return this.$watched[0].getBoundingClientRect().top !== this.$watched[1].getBoundingClientRect().top;
136
157
  }
137
158
 
138
159
  /**
@@ -59,10 +59,12 @@ class Interchange {
59
59
 
60
60
  // Iterate through each rule, but only save the last match
61
61
  for (var i in this.rules) {
62
- var rule = this.rules[i];
62
+ if(this.rules.hasOwnProperty(i)) {
63
+ var rule = this.rules[i];
63
64
 
64
- if (window.matchMedia(rule.query).matches) {
65
- match = rule;
65
+ if (window.matchMedia(rule.query).matches) {
66
+ match = rule;
67
+ }
66
68
  }
67
69
  }
68
70
 
@@ -78,8 +80,10 @@ class Interchange {
78
80
  */
79
81
  _addBreakpoints() {
80
82
  for (var i in Foundation.MediaQuery.queries) {
81
- var query = Foundation.MediaQuery.queries[i];
82
- Interchange.SPECIAL_QUERIES[query.name] = query.value;
83
+ if (Foundation.MediaQuery.queries.hasOwnProperty(i)) {
84
+ var query = Foundation.MediaQuery.queries[i];
85
+ Interchange.SPECIAL_QUERIES[query.name] = query.value;
86
+ }
83
87
  }
84
88
  }
85
89
 
@@ -102,18 +106,20 @@ class Interchange {
102
106
  }
103
107
 
104
108
  for (var i in rules) {
105
- var rule = rules[i].slice(1, -1).split(', ');
106
- var path = rule.slice(0, -1).join('');
107
- var query = rule[rule.length - 1];
108
-
109
- if (Interchange.SPECIAL_QUERIES[query]) {
110
- query = Interchange.SPECIAL_QUERIES[query];
109
+ if(rules.hasOwnProperty(i)) {
110
+ var rule = rules[i].slice(1, -1).split(', ');
111
+ var path = rule.slice(0, -1).join('');
112
+ var query = rule[rule.length - 1];
113
+
114
+ if (Interchange.SPECIAL_QUERIES[query]) {
115
+ query = Interchange.SPECIAL_QUERIES[query];
116
+ }
117
+
118
+ rulesList.push({
119
+ path: path,
120
+ query: query
121
+ });
111
122
  }
112
-
113
- rulesList.push({
114
- path: path,
115
- query: query
116
- });
117
123
  }
118
124
 
119
125
  this.rules = rulesList;
@@ -133,7 +133,7 @@ class Magellan {
133
133
  var isDown = this.scrollPos < winPos,
134
134
  _this = this,
135
135
  curVisible = this.points.filter(function(p, i){
136
- return isDown ? p <= winPos : p - _this.options.threshold <= winPos;//&& winPos >= _this.points[i -1] - _this.options.threshold;
136
+ return isDown ? p - _this.options.barOffset <= winPos : p - _this.options.barOffset - _this.options.threshold <= winPos;
137
137
  });
138
138
  curIdx = curVisible.length ? curVisible.length - 1 : 0;
139
139
  }
@@ -22,6 +22,7 @@ class OffCanvas {
22
22
  this.$element = element;
23
23
  this.options = $.extend({}, OffCanvas.defaults, this.$element.data(), options);
24
24
  this.$lastTrigger = $();
25
+ this.$triggers = $();
25
26
 
26
27
  this._init();
27
28
  this._events();
@@ -40,7 +41,7 @@ class OffCanvas {
40
41
  this.$element.attr('aria-hidden', 'true');
41
42
 
42
43
  // Find triggers that affect this element and add aria-expanded to them
43
- $(document)
44
+ this.$triggers = $(document)
44
45
  .find('[data-open="'+id+'"], [data-close="'+id+'"], [data-toggle="'+id+'"]')
45
46
  .attr('aria-expanded', 'false')
46
47
  .attr('aria-controls', id);
@@ -178,6 +179,8 @@ class OffCanvas {
178
179
  // _this._stick();
179
180
  // }
180
181
  });
182
+
183
+ this.$triggers.attr('aria-expanded', 'true');
181
184
  this.$element.attr('aria-hidden', 'false')
182
185
  .trigger('opened.zf.offcanvas');
183
186
 
@@ -186,7 +189,7 @@ class OffCanvas {
186
189
  }
187
190
 
188
191
  if (trigger) {
189
- this.$lastTrigger = trigger.attr('aria-expanded', 'true');
192
+ this.$lastTrigger = trigger;
190
193
  }
191
194
 
192
195
  if (this.options.autoFocus) {
@@ -275,7 +278,7 @@ class OffCanvas {
275
278
  this.$exiter.removeClass('is-visible');
276
279
  }
277
280
 
278
- this.$lastTrigger.attr('aria-expanded', 'false');
281
+ this.$triggers.attr('aria-expanded', 'false');
279
282
  if (this.options.trapFocus) {
280
283
  $('[data-off-canvas-content]').removeAttr('tabindex');
281
284
  }
@@ -51,7 +51,9 @@ class ResponsiveToggle {
51
51
  _events() {
52
52
  var _this = this;
53
53
 
54
- $(window).on('changed.zf.mediaquery', this._update.bind(this));
54
+ this._updateMqHandler = this._update.bind(this);
55
+
56
+ $(window).on('changed.zf.mediaquery', this._updateMqHandler);
55
57
 
56
58
  this.$toggler.on('click.zf.responsiveToggle', this.toggleMenu.bind(this));
57
59
  }
@@ -80,7 +82,7 @@ class ResponsiveToggle {
80
82
  * @function
81
83
  * @fires ResponsiveToggle#toggled
82
84
  */
83
- toggleMenu() {
85
+ toggleMenu() {
84
86
  if (!Foundation.MediaQuery.atLeast(this.options.hideFor)) {
85
87
  this.$targetMenu.toggle(0);
86
88
 
@@ -93,7 +95,12 @@ class ResponsiveToggle {
93
95
  };
94
96
 
95
97
  destroy() {
96
- //TODO this...
98
+ this.$element.off('.zf.responsiveToggle');
99
+ this.$toggler.off('.zf.responsiveToggle');
100
+
101
+ $(window).off('changed.zf.mediaquery', this._updateMqHandler);
102
+
103
+ Foundation.unregisterPlugin(this);
97
104
  }
98
105
  }
99
106
 
@@ -42,23 +42,14 @@ class Reveal {
42
42
  this.id = this.$element.attr('id');
43
43
  this.isActive = false;
44
44
  this.cached = {mq: Foundation.MediaQuery.current};
45
- this.isiOS = iPhoneSniff();
46
-
47
- if(this.isiOS){ this.$element.addClass('is-ios'); }
45
+ this.isMobile = mobileSniff();
48
46
 
49
47
  this.$anchor = $(`[data-open="${this.id}"]`).length ? $(`[data-open="${this.id}"]`) : $(`[data-toggle="${this.id}"]`);
50
-
51
- if (this.$anchor.length) {
52
- var anchorId = this.$anchor[0].id || Foundation.GetYoDigits(6, 'reveal');
53
-
54
- this.$anchor.attr({
55
- 'aria-controls': this.id,
56
- 'id': anchorId,
57
- 'aria-haspopup': true,
58
- 'tabindex': 0
59
- });
60
- this.$element.attr({'aria-labelledby': anchorId});
61
- }
48
+ this.$anchor.attr({
49
+ 'aria-controls': this.id,
50
+ 'aria-haspopup': true,
51
+ 'tabindex': 0
52
+ });
62
53
 
63
54
  if (this.options.fullScreen || this.$element.hasClass('full')) {
64
55
  this.options.fullScreen = true;
@@ -94,7 +85,6 @@ class Reveal {
94
85
  _makeOverlay(id) {
95
86
  var $overlay = $('<div></div>')
96
87
  .addClass('reveal-overlay')
97
- .attr({'tabindex': -1, 'aria-hidden': true})
98
88
  .appendTo('body');
99
89
  return $overlay;
100
90
  }
@@ -143,7 +133,12 @@ class Reveal {
143
133
 
144
134
  this.$element.on({
145
135
  'open.zf.trigger': this.open.bind(this),
146
- 'close.zf.trigger': this.close.bind(this),
136
+ 'close.zf.trigger': (event, $element) => {
137
+ if ((event.target === _this.$element[0]) ||
138
+ ($(event.target).parents('[data-closable]')[0] === $element)) { // only close reveal when it's explicitly called
139
+ return this.close.apply(this);
140
+ }
141
+ },
147
142
  'toggle.zf.trigger': this.toggle.bind(this),
148
143
  'resizeme.zf.trigger': function() {
149
144
  _this._updatePosition();
@@ -217,6 +212,11 @@ class Reveal {
217
212
 
218
213
  if(this.$overlay) {
219
214
  this.$overlay.css({'visibility': ''}).hide();
215
+ if(this.$element.hasClass('fast')) {
216
+ this.$overlay.addClass('fast');
217
+ } else if (this.$element.hasClass('slow')) {
218
+ this.$overlay.addClass('slow');
219
+ }
220
220
  }
221
221
 
222
222
 
@@ -228,14 +228,24 @@ class Reveal {
228
228
  */
229
229
  this.$element.trigger('closeme.zf.reveal', this.id);
230
230
  }
231
-
232
231
  // Motion UI method of reveal
233
232
  if (this.options.animationIn) {
233
+ var _this = this;
234
+ function afterAnimationFocus(){
235
+ _this.$element
236
+ .attr({
237
+ 'aria-hidden': false,
238
+ 'tabindex': -1
239
+ })
240
+ .focus();
241
+ console.log('focus');
242
+ }
234
243
  if (this.options.overlay) {
235
244
  Foundation.Motion.animateIn(this.$overlay, 'fade-in');
236
245
  }
237
246
  Foundation.Motion.animateIn(this.$element, this.options.animationIn, () => {
238
247
  this.focusableElements = Foundation.Keyboard.findFocusable(this.$element);
248
+ afterAnimationFocus();
239
249
  });
240
250
  }
241
251
  // jQuery method of reveal
@@ -260,18 +270,14 @@ class Reveal {
260
270
  */
261
271
  this.$element.trigger('open.zf.reveal');
262
272
 
263
- if (this.isiOS) {
264
- var scrollPos = window.pageYOffset;
265
- $('html, body').addClass('is-reveal-open').scrollTop(scrollPos);
273
+ if (this.isMobile) {
274
+ this.originalScrollPos = window.pageYOffset;
275
+ $('html, body').addClass('is-reveal-open');
266
276
  }
267
277
  else {
268
278
  $('body').addClass('is-reveal-open');
269
279
  }
270
280
 
271
- $('body')
272
- .addClass('is-reveal-open')
273
- .attr('aria-hidden', (this.options.overlay || this.options.fullScreen) ? true : false);
274
-
275
281
  setTimeout(() => {
276
282
  this._extraHandlers();
277
283
  }, 0);
@@ -313,19 +319,19 @@ class Reveal {
313
319
  tab_forward: function() {
314
320
  if (_this.$element.find(':focus').is(_this.focusableElements.eq(-1))) { // left modal downwards, setting focus to first element
315
321
  _this.focusableElements.eq(0).focus();
316
- e.preventDefault();
322
+ return true;
317
323
  }
318
324
  if (_this.focusableElements.length === 0) { // no focusable elements inside the modal at all, prevent tabbing in general
319
- e.preventDefault();
325
+ return true;
320
326
  }
321
327
  },
322
328
  tab_backward: function() {
323
329
  if (_this.$element.find(':focus').is(_this.focusableElements.eq(0)) || _this.$element.is(':focus')) { // left modal upwards, setting focus to last element
324
330
  _this.focusableElements.eq(-1).focus();
325
- e.preventDefault();
331
+ return true;
326
332
  }
327
333
  if (_this.focusableElements.length === 0) { // no focusable elements inside the modal at all, prevent tabbing in general
328
- e.preventDefault();
334
+ return true;
329
335
  }
330
336
  },
331
337
  open: function() {
@@ -342,6 +348,11 @@ class Reveal {
342
348
  _this.close();
343
349
  _this.$anchor.focus();
344
350
  }
351
+ },
352
+ handled: function(preventDefault) {
353
+ if (preventDefault) {
354
+ e.preventDefault();
355
+ }
345
356
  }
346
357
  });
347
358
  });
@@ -393,18 +404,17 @@ class Reveal {
393
404
  this.$element.off('keydown.zf.reveal');
394
405
 
395
406
  function finishUp() {
396
- if (_this.isiOS) {
407
+ if (_this.isMobile) {
397
408
  $('html, body').removeClass('is-reveal-open');
409
+ if(_this.originalScrollPos) {
410
+ $('body').scrollTop(_this.originalScrollPos);
411
+ _this.originalScrollPos = null;
412
+ }
398
413
  }
399
414
  else {
400
415
  $('body').removeClass('is-reveal-open');
401
416
  }
402
417
 
403
- $('body').attr({
404
- 'aria-hidden': false,
405
- 'tabindex': ''
406
- });
407
-
408
418
  _this.$element.attr('aria-hidden', true);
409
419
 
410
420
  /**
@@ -555,4 +565,12 @@ function iPhoneSniff() {
555
565
  return /iP(ad|hone|od).*OS/.test(window.navigator.userAgent);
556
566
  }
557
567
 
568
+ function androidSniff() {
569
+ return /Android/.test(window.navigator.userAgent);
570
+ }
571
+
572
+ function mobileSniff() {
573
+ return iPhoneSniff() || androidSniff();
574
+ }
575
+
558
576
  }(jQuery);
@@ -106,7 +106,11 @@ class Slider {
106
106
  * @fires Slider#changed
107
107
  */
108
108
  _setHandlePos($hndl, location, noInvert, cb) {
109
- //might need to alter that slightly for bars that will have odd number selections.
109
+ // don't move if the slider has been disabled since its initialization
110
+ if (this.$element.hasClass(this.options.disabledClass)) {
111
+ return;
112
+ }
113
+ //might need to alter that slightly for bars that will have odd number selections.
110
114
  location = parseFloat(location);//on input change events, convert string to number...grumble.
111
115
 
112
116
  // prevent slider from running out of bounds, if value exceeds the limits set through options, override the value to min/max
@@ -204,7 +208,7 @@ class Slider {
204
208
  /**
205
209
  * Fires when the value has not been change for a given time.
206
210
  * @event Slider#changed
207
- */
211
+ */
208
212
  clearTimeout(_this.timeout);
209
213
  _this.timeout = setTimeout(function(){
210
214
  _this.$element.trigger('changed.zf.slider', [$hndl]);
@@ -268,13 +272,28 @@ class Slider {
268
272
  vertical = this.options.vertical,
269
273
  param = vertical ? 'height' : 'width',
270
274
  direction = vertical ? 'top' : 'left',
271
- pageXY = vertical ? e.pageY : e.pageX,
275
+ eventOffset = vertical ? e.pageY : e.pageX,
272
276
  halfOfHandle = this.$handle[0].getBoundingClientRect()[param] / 2,
273
277
  barDim = this.$element[0].getBoundingClientRect()[param],
274
- barOffset = (this.$element.offset()[direction] - pageXY),
275
- //if the cursor position is less than or greater than the elements bounding coordinates, set coordinates within those bounds
276
- barXY = barOffset > 0 ? -halfOfHandle : (barOffset - halfOfHandle) < -barDim ? barDim : Math.abs(barOffset),
277
- offsetPct = percent(barXY, barDim);
278
+ windowScroll = vertical ? $(window).scrollTop() : $(window).scrollLeft();
279
+
280
+
281
+ var elemOffset = this.$element.offset()[direction];
282
+
283
+ // touch events emulated by the touch util give position relative to screen, add window.scroll to event coordinates...
284
+ // best way to guess this is simulated is if clientY == pageY
285
+ if (e.clientY === e.pageY) { eventOffset = eventOffset + windowScroll; }
286
+ var eventFromBar = eventOffset - elemOffset;
287
+ var barXY;
288
+ if (eventFromBar < 0) {
289
+ barXY = 0;
290
+ } else if (eventFromBar > barDim) {
291
+ barXY = barDim;
292
+ } else {
293
+ barXY = eventFromBar;
294
+ }
295
+ offsetPct = percent(barXY, barDim);
296
+
278
297
  value = (this.options.end - this.options.start) * offsetPct + this.options.start;
279
298
 
280
299
  // turn everything around for RTL, yay math!
@@ -333,8 +352,6 @@ class Slider {
333
352
  * @param {jQuery} $handle - the current handle to apply listeners to.
334
353
  */
335
354
  _events($handle) {
336
- if (this.options.disabled) { return false; }
337
-
338
355
  var _this = this,
339
356
  curHandle,
340
357
  timer;
@@ -373,7 +390,6 @@ class Slider {
373
390
 
374
391
  $body.on('mousemove.zf.slider', function(e) {
375
392
  e.preventDefault();
376
-
377
393
  _this._handleEvent(e, curHandle);
378
394
 
379
395
  }).on('mouseup.zf.slider', function(e) {
@@ -385,6 +401,10 @@ class Slider {
385
401
 
386
402
  $body.off('mousemove.zf.slider mouseup.zf.slider');
387
403
  });
404
+ })
405
+ // prevent events triggered by touch
406
+ .on('selectstart.zf.slider touchmove.zf.slider', function(e) {
407
+ e.preventDefault();
388
408
  });
389
409
  }
390
410
 
@@ -532,7 +552,7 @@ Slider.defaults = {
532
552
  */
533
553
  invertVertical: false,
534
554
  /**
535
- * Milliseconds before the `changed.zf-slider` event is triggered after value change.
555
+ * Milliseconds before the `changed.zf-slider` event is triggered after value change.
536
556
  * @option
537
557
  * @example 500
538
558
  */