foundation-rails 6.4.1.0 → 6.4.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (105) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -1
  3. data/Rakefile +5 -6
  4. data/lib/foundation/rails/version.rb +1 -1
  5. data/vendor/assets/js/foundation.abide.js +781 -0
  6. data/vendor/assets/js/foundation.accordion.js +511 -0
  7. data/vendor/assets/js/foundation.accordionMenu.js +527 -0
  8. data/vendor/assets/js/foundation.core.js +860 -0
  9. data/vendor/assets/js/foundation.drilldown.js +759 -0
  10. data/vendor/assets/js/foundation.dropdown.js +1131 -0
  11. data/vendor/assets/js/foundation.dropdownMenu.js +678 -0
  12. data/vendor/assets/js/foundation.equalizer.js +542 -0
  13. data/vendor/assets/js/foundation.interchange.js +399 -0
  14. data/vendor/assets/js/{foundation.js.es6 → foundation.js} +11 -12
  15. data/vendor/assets/js/foundation.magellan.js +449 -0
  16. data/vendor/assets/js/foundation.offcanvas.js +1052 -0
  17. data/vendor/assets/js/foundation.orbit.js +767 -0
  18. data/vendor/assets/js/foundation.responsiveAccordionTabs.js +440 -0
  19. data/vendor/assets/js/foundation.responsiveMenu.js +362 -0
  20. data/vendor/assets/js/foundation.responsiveToggle.js +336 -0
  21. data/vendor/assets/js/foundation.reveal.js +1066 -0
  22. data/vendor/assets/js/foundation.slider.js +1236 -0
  23. data/vendor/assets/js/foundation.smoothScroll.js +303 -0
  24. data/vendor/assets/js/foundation.sticky.js +1001 -0
  25. data/vendor/assets/js/foundation.tabs.js +678 -0
  26. data/vendor/assets/js/foundation.toggler.js +602 -0
  27. data/vendor/assets/js/foundation.tooltip.js +1195 -0
  28. data/vendor/assets/js/{foundation.util.box.js.es6 → foundation.util.box.js} +154 -41
  29. data/vendor/assets/js/foundation.util.imageLoader.js +163 -0
  30. data/vendor/assets/js/foundation.util.keyboard.js +298 -0
  31. data/vendor/assets/js/foundation.util.mediaQuery.js +353 -0
  32. data/vendor/assets/js/foundation.util.motion.js +231 -0
  33. data/vendor/assets/js/foundation.util.nest.js +181 -0
  34. data/vendor/assets/js/foundation.util.timer.js +170 -0
  35. data/vendor/assets/js/foundation.util.timerAndImageLoader.js +90 -0
  36. data/vendor/assets/js/foundation.util.touch.js +275 -0
  37. data/vendor/assets/js/foundation.util.triggers.js +399 -0
  38. data/vendor/assets/js/foundation.zf.responsiveAccordionTabs.js +262 -0
  39. metadata +37 -71
  40. data/vendor/assets/js/entries/foundation-plugins.js +0 -25
  41. data/vendor/assets/js/entries/foundation.js +0 -101
  42. data/vendor/assets/js/entries/plugins/foundation.abide.js +0 -4
  43. data/vendor/assets/js/entries/plugins/foundation.accordion.js +0 -4
  44. data/vendor/assets/js/entries/plugins/foundation.accordionMenu.js +0 -5
  45. data/vendor/assets/js/entries/plugins/foundation.core.js +0 -21
  46. data/vendor/assets/js/entries/plugins/foundation.drilldown.js +0 -4
  47. data/vendor/assets/js/entries/plugins/foundation.dropdown.js +0 -5
  48. data/vendor/assets/js/entries/plugins/foundation.dropdownMenu.js +0 -4
  49. data/vendor/assets/js/entries/plugins/foundation.equalizer.js +0 -4
  50. data/vendor/assets/js/entries/plugins/foundation.interchange.js +0 -4
  51. data/vendor/assets/js/entries/plugins/foundation.magellan.js +0 -4
  52. data/vendor/assets/js/entries/plugins/foundation.offcanvas.js +0 -4
  53. data/vendor/assets/js/entries/plugins/foundation.orbit.js +0 -5
  54. data/vendor/assets/js/entries/plugins/foundation.responsiveAccordionTabs.js +0 -5
  55. data/vendor/assets/js/entries/plugins/foundation.responsiveMenu.js +0 -5
  56. data/vendor/assets/js/entries/plugins/foundation.responsiveToggle.js +0 -5
  57. data/vendor/assets/js/entries/plugins/foundation.reveal.js +0 -4
  58. data/vendor/assets/js/entries/plugins/foundation.slider.js +0 -5
  59. data/vendor/assets/js/entries/plugins/foundation.smoothScroll.js +0 -5
  60. data/vendor/assets/js/entries/plugins/foundation.sticky.js +0 -5
  61. data/vendor/assets/js/entries/plugins/foundation.tabs.js +0 -5
  62. data/vendor/assets/js/entries/plugins/foundation.toggler.js +0 -5
  63. data/vendor/assets/js/entries/plugins/foundation.tooltip.js +0 -4
  64. data/vendor/assets/js/entries/plugins/foundation.util.box.js +0 -4
  65. data/vendor/assets/js/entries/plugins/foundation.util.imageLoader.js +0 -5
  66. data/vendor/assets/js/entries/plugins/foundation.util.keyboard.js +0 -4
  67. data/vendor/assets/js/entries/plugins/foundation.util.mediaQuery.js +0 -4
  68. data/vendor/assets/js/entries/plugins/foundation.util.motion.js +0 -5
  69. data/vendor/assets/js/entries/plugins/foundation.util.nest.js +0 -5
  70. data/vendor/assets/js/entries/plugins/foundation.util.timer.js +0 -5
  71. data/vendor/assets/js/entries/plugins/foundation.util.touch.js +0 -7
  72. data/vendor/assets/js/entries/plugins/foundation.util.triggers.js +0 -5
  73. data/vendor/assets/js/foundation.abide.js.es6 +0 -587
  74. data/vendor/assets/js/foundation.accordion.js.es6 +0 -329
  75. data/vendor/assets/js/foundation.accordionMenu.js.es6 +0 -328
  76. data/vendor/assets/js/foundation.core.js.es6 +0 -337
  77. data/vendor/assets/js/foundation.drilldown.js.es6 +0 -536
  78. data/vendor/assets/js/foundation.dropdown.js.es6 +0 -394
  79. data/vendor/assets/js/foundation.dropdownMenu.js.es6 +0 -458
  80. data/vendor/assets/js/foundation.equalizer.js.es6 +0 -318
  81. data/vendor/assets/js/foundation.interchange.js.es6 +0 -210
  82. data/vendor/assets/js/foundation.magellan.js.es6 +0 -257
  83. data/vendor/assets/js/foundation.offcanvas.js.es6 +0 -546
  84. data/vendor/assets/js/foundation.orbit.js.es6 +0 -531
  85. data/vendor/assets/js/foundation.plugin.js.es6 +0 -54
  86. data/vendor/assets/js/foundation.positionable.js.es6 +0 -206
  87. data/vendor/assets/js/foundation.responsiveAccordionTabs.js.es6 +0 -243
  88. data/vendor/assets/js/foundation.responsiveMenu.js.es6 +0 -155
  89. data/vendor/assets/js/foundation.responsiveToggle.js.es6 +0 -156
  90. data/vendor/assets/js/foundation.reveal.js.es6 +0 -585
  91. data/vendor/assets/js/foundation.slider.js.es6 +0 -712
  92. data/vendor/assets/js/foundation.smoothScroll.js.es6 +0 -135
  93. data/vendor/assets/js/foundation.sticky.js.es6 +0 -507
  94. data/vendor/assets/js/foundation.tabs.js.es6 +0 -498
  95. data/vendor/assets/js/foundation.toggler.js.es6 +0 -150
  96. data/vendor/assets/js/foundation.tooltip.js.es6 +0 -462
  97. data/vendor/assets/js/foundation.util.core.js.es6 +0 -52
  98. data/vendor/assets/js/foundation.util.imageLoader.js.es6 +0 -45
  99. data/vendor/assets/js/foundation.util.keyboard.js.es6 +0 -162
  100. data/vendor/assets/js/foundation.util.mediaQuery.js.es6 +0 -234
  101. data/vendor/assets/js/foundation.util.motion.js.es6 +0 -104
  102. data/vendor/assets/js/foundation.util.nest.js.es6 +0 -67
  103. data/vendor/assets/js/foundation.util.timer.js.es6 +0 -48
  104. data/vendor/assets/js/foundation.util.touch.js.es6 +0 -149
  105. data/vendor/assets/js/foundation.util.triggers.js.es6 +0 -268
@@ -1,257 +0,0 @@
1
- 'use strict';
2
-
3
-
4
- import $ from 'jquery';
5
- import { GetYoDigits } from './foundation.util.core';
6
- import { Plugin } from './foundation.plugin';
7
- import { SmoothScroll } from './foundation.smoothScroll';
8
-
9
- /**
10
- * Magellan module.
11
- * @module foundation.magellan
12
- * @requires foundation.smoothScroll
13
- */
14
-
15
- class Magellan extends Plugin {
16
- /**
17
- * Creates a new instance of Magellan.
18
- * @class
19
- * @name Magellan
20
- * @fires Magellan#init
21
- * @param {Object} element - jQuery object to add the trigger to.
22
- * @param {Object} options - Overrides to the default plugin settings.
23
- */
24
- _setup(element, options) {
25
- this.$element = element;
26
- this.options = $.extend({}, Magellan.defaults, this.$element.data(), options);
27
- this.className = 'Magellan'; // ie9 back compat
28
-
29
- this._init();
30
- this.calcPoints();
31
- }
32
-
33
- /**
34
- * Initializes the Magellan plugin and calls functions to get equalizer functioning on load.
35
- * @private
36
- */
37
- _init() {
38
- var id = this.$element[0].id || GetYoDigits(6, 'magellan');
39
- var _this = this;
40
- this.$targets = $('[data-magellan-target]');
41
- this.$links = this.$element.find('a');
42
- this.$element.attr({
43
- 'data-resize': id,
44
- 'data-scroll': id,
45
- 'id': id
46
- });
47
- this.$active = $();
48
- this.scrollPos = parseInt(window.pageYOffset, 10);
49
-
50
- this._events();
51
- }
52
-
53
- /**
54
- * Calculates an array of pixel values that are the demarcation lines between locations on the page.
55
- * Can be invoked if new elements are added or the size of a location changes.
56
- * @function
57
- */
58
- calcPoints() {
59
- var _this = this,
60
- body = document.body,
61
- html = document.documentElement;
62
-
63
- this.points = [];
64
- this.winHeight = Math.round(Math.max(window.innerHeight, html.clientHeight));
65
- this.docHeight = Math.round(Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight));
66
-
67
- this.$targets.each(function(){
68
- var $tar = $(this),
69
- pt = Math.round($tar.offset().top - _this.options.threshold);
70
- $tar.targetPoint = pt;
71
- _this.points.push(pt);
72
- });
73
- }
74
-
75
- /**
76
- * Initializes events for Magellan.
77
- * @private
78
- */
79
- _events() {
80
- var _this = this,
81
- $body = $('html, body'),
82
- opts = {
83
- duration: _this.options.animationDuration,
84
- easing: _this.options.animationEasing
85
- };
86
- $(window).one('load', function(){
87
- if(_this.options.deepLinking){
88
- if(location.hash){
89
- _this.scrollToLoc(location.hash);
90
- }
91
- }
92
- _this.calcPoints();
93
- _this._updateActive();
94
- });
95
-
96
- this.$element.on({
97
- 'resizeme.zf.trigger': this.reflow.bind(this),
98
- 'scrollme.zf.trigger': this._updateActive.bind(this)
99
- }).on('click.zf.magellan', 'a[href^="#"]', function(e) {
100
- e.preventDefault();
101
- var arrival = this.getAttribute('href');
102
- _this.scrollToLoc(arrival);
103
- });
104
-
105
- this._deepLinkScroll = function(e) {
106
- if(_this.options.deepLinking) {
107
- _this.scrollToLoc(window.location.hash);
108
- }
109
- };
110
-
111
- $(window).on('popstate', this._deepLinkScroll);
112
- }
113
-
114
- /**
115
- * Function to scroll to a given location on the page.
116
- * @param {String} loc - a properly formatted jQuery id selector. Example: '#foo'
117
- * @function
118
- */
119
- scrollToLoc(loc) {
120
- this._inTransition = true;
121
- var _this = this;
122
-
123
- var options = {
124
- animationEasing: this.options.animationEasing,
125
- animationDuration: this.options.animationDuration,
126
- threshold: this.options.threshold,
127
- offset: this.options.offset
128
- };
129
-
130
- SmoothScroll.scrollToLoc(loc, options, function() {
131
- _this._inTransition = false;
132
- _this._updateActive();
133
- })
134
- }
135
-
136
- /**
137
- * Calls necessary functions to update Magellan upon DOM change
138
- * @function
139
- */
140
- reflow() {
141
- this.calcPoints();
142
- this._updateActive();
143
- }
144
-
145
- /**
146
- * Updates the visibility of an active location link, and updates the url hash for the page, if deepLinking enabled.
147
- * @private
148
- * @function
149
- * @fires Magellan#update
150
- */
151
- _updateActive(/*evt, elem, scrollPos*/) {
152
- if(this._inTransition) {return;}
153
- var winPos = /*scrollPos ||*/ parseInt(window.pageYOffset, 10),
154
- curIdx;
155
-
156
- if(winPos + this.winHeight === this.docHeight){ curIdx = this.points.length - 1; }
157
- else if(winPos < this.points[0]){ curIdx = undefined; }
158
- else{
159
- var isDown = this.scrollPos < winPos,
160
- _this = this,
161
- curVisible = this.points.filter(function(p, i){
162
- return isDown ? p - _this.options.offset <= winPos : p - _this.options.offset - _this.options.threshold <= winPos;
163
- });
164
- curIdx = curVisible.length ? curVisible.length - 1 : 0;
165
- }
166
-
167
- this.$active.removeClass(this.options.activeClass);
168
- this.$active = this.$links.filter('[href="#' + this.$targets.eq(curIdx).data('magellan-target') + '"]').addClass(this.options.activeClass);
169
-
170
- if(this.options.deepLinking){
171
- var hash = "";
172
- if(curIdx != undefined){
173
- hash = this.$active[0].getAttribute('href');
174
- }
175
- if(hash !== window.location.hash) {
176
- if(window.history.pushState){
177
- window.history.pushState(null, null, hash);
178
- }else{
179
- window.location.hash = hash;
180
- }
181
- }
182
- }
183
-
184
- this.scrollPos = winPos;
185
- /**
186
- * Fires when magellan is finished updating to the new active element.
187
- * @event Magellan#update
188
- */
189
- this.$element.trigger('update.zf.magellan', [this.$active]);
190
- }
191
-
192
- /**
193
- * Destroys an instance of Magellan and resets the url of the window.
194
- * @function
195
- */
196
- _destroy() {
197
- this.$element.off('.zf.trigger .zf.magellan')
198
- .find(`.${this.options.activeClass}`).removeClass(this.options.activeClass);
199
-
200
- if(this.options.deepLinking){
201
- var hash = this.$active[0].getAttribute('href');
202
- window.location.hash.replace(hash, '');
203
- }
204
- $(window).off('popstate', this._deepLinkScroll);
205
- }
206
- }
207
-
208
- /**
209
- * Default settings for plugin
210
- */
211
- Magellan.defaults = {
212
- /**
213
- * Amount of time, in ms, the animated scrolling should take between locations.
214
- * @option
215
- * @type {number}
216
- * @default 500
217
- */
218
- animationDuration: 500,
219
- /**
220
- * Animation style to use when scrolling between locations. Can be `'swing'` or `'linear'`.
221
- * @option
222
- * @type {string}
223
- * @default 'linear'
224
- * @see {@link https://api.jquery.com/animate|Jquery animate}
225
- */
226
- animationEasing: 'linear',
227
- /**
228
- * Number of pixels to use as a marker for location changes.
229
- * @option
230
- * @type {number}
231
- * @default 50
232
- */
233
- threshold: 50,
234
- /**
235
- * Class applied to the active locations link on the magellan container.
236
- * @option
237
- * @type {string}
238
- * @default 'is-active'
239
- */
240
- activeClass: 'is-active',
241
- /**
242
- * Allows the script to manipulate the url of the current page, and if supported, alter the history.
243
- * @option
244
- * @type {boolean}
245
- * @default false
246
- */
247
- deepLinking: false,
248
- /**
249
- * Number of pixels to offset the scroll of the page on item click if using a sticky nav bar.
250
- * @option
251
- * @type {number}
252
- * @default 0
253
- */
254
- offset: 0
255
- }
256
-
257
- export {Magellan};
@@ -1,546 +0,0 @@
1
- 'use strict';
2
-
3
- import $ from 'jquery';
4
- import { Keyboard } from './foundation.util.keyboard';
5
- import { MediaQuery } from './foundation.util.mediaQuery';
6
- import { transitionend } from './foundation.util.core';
7
- import { Plugin } from './foundation.plugin';
8
-
9
- import { Triggers } from './foundation.util.triggers';
10
-
11
- /**
12
- * OffCanvas module.
13
- * @module foundation.offcanvas
14
- * @requires foundation.util.keyboard
15
- * @requires foundation.util.mediaQuery
16
- * @requires foundation.util.triggers
17
- */
18
-
19
- class OffCanvas extends Plugin {
20
- /**
21
- * Creates a new instance of an off-canvas wrapper.
22
- * @class
23
- * @name OffCanvas
24
- * @fires OffCanvas#init
25
- * @param {Object} element - jQuery object to initialize.
26
- * @param {Object} options - Overrides to the default plugin settings.
27
- */
28
- _setup(element, options) {
29
- this.className = 'OffCanvas'; // ie9 back compat
30
- this.$element = element;
31
- this.options = $.extend({}, OffCanvas.defaults, this.$element.data(), options);
32
- this.contentClasses = { base: [], reveal: [] };
33
- this.$lastTrigger = $();
34
- this.$triggers = $();
35
- this.position = 'left';
36
- this.$content = $();
37
- this.nested = !!(this.options.nested);
38
-
39
- // Defines the CSS transition/position classes of the off-canvas content container.
40
- $(['push', 'overlap']).each((index, val) => {
41
- this.contentClasses.base.push('has-transition-'+val);
42
- });
43
- $(['left', 'right', 'top', 'bottom']).each((index, val) => {
44
- this.contentClasses.base.push('has-position-'+val);
45
- this.contentClasses.reveal.push('has-reveal-'+val);
46
- });
47
-
48
- // Triggers init is idempotent, just need to make sure it is initialized
49
- Triggers.init($);
50
- MediaQuery._init();
51
-
52
- this._init();
53
- this._events();
54
-
55
- Keyboard.register('OffCanvas', {
56
- 'ESCAPE': 'close'
57
- });
58
-
59
- }
60
-
61
- /**
62
- * Initializes the off-canvas wrapper by adding the exit overlay (if needed).
63
- * @function
64
- * @private
65
- */
66
- _init() {
67
- var id = this.$element.attr('id');
68
-
69
- this.$element.attr('aria-hidden', 'true');
70
-
71
- // Find off-canvas content, either by ID (if specified), by siblings or by closest selector (fallback)
72
- if (this.options.contentId) {
73
- this.$content = $('#'+this.options.contentId);
74
- } else if (this.$element.siblings('[data-off-canvas-content]').length) {
75
- this.$content = this.$element.siblings('[data-off-canvas-content]').first();
76
- } else {
77
- this.$content = this.$element.closest('[data-off-canvas-content]').first();
78
- }
79
-
80
- if (!this.options.contentId) {
81
- // Assume that the off-canvas element is nested if it isn't a sibling of the content
82
- this.nested = this.$element.siblings('[data-off-canvas-content]').length === 0;
83
-
84
- } else if (this.options.contentId && this.options.nested === null) {
85
- // Warning if using content ID without setting the nested option
86
- // Once the element is nested it is required to work properly in this case
87
- console.warn('Remember to use the nested option if using the content ID option!');
88
- }
89
-
90
- if (this.nested === true) {
91
- // Force transition overlap if nested
92
- this.options.transition = 'overlap';
93
- // Remove appropriate classes if already assigned in markup
94
- this.$element.removeClass('is-transition-push');
95
- }
96
-
97
- this.$element.addClass(`is-transition-${this.options.transition} is-closed`);
98
-
99
- // Find triggers that affect this element and add aria-expanded to them
100
- this.$triggers = $(document)
101
- .find('[data-open="'+id+'"], [data-close="'+id+'"], [data-toggle="'+id+'"]')
102
- .attr('aria-expanded', 'false')
103
- .attr('aria-controls', id);
104
-
105
- // Get position by checking for related CSS class
106
- this.position = this.$element.is('.position-left, .position-top, .position-right, .position-bottom') ? this.$element.attr('class').match(/position\-(left|top|right|bottom)/)[1] : this.position;
107
-
108
- // Add an overlay over the content if necessary
109
- if (this.options.contentOverlay === true) {
110
- var overlay = document.createElement('div');
111
- var overlayPosition = $(this.$element).css("position") === 'fixed' ? 'is-overlay-fixed' : 'is-overlay-absolute';
112
- overlay.setAttribute('class', 'js-off-canvas-overlay ' + overlayPosition);
113
- this.$overlay = $(overlay);
114
- if(overlayPosition === 'is-overlay-fixed') {
115
- $(this.$overlay).insertAfter(this.$element);
116
- } else {
117
- this.$content.append(this.$overlay);
118
- }
119
- }
120
-
121
- this.options.isRevealed = this.options.isRevealed || new RegExp(this.options.revealClass, 'g').test(this.$element[0].className);
122
-
123
- if (this.options.isRevealed === true) {
124
- this.options.revealOn = this.options.revealOn || this.$element[0].className.match(/(reveal-for-medium|reveal-for-large)/g)[0].split('-')[2];
125
- this._setMQChecker();
126
- }
127
-
128
- if (this.options.transitionTime) {
129
- this.$element.css('transition-duration', this.options.transitionTime);
130
- }
131
-
132
- // Initally remove all transition/position CSS classes from off-canvas content container.
133
- this._removeContentClasses();
134
- }
135
-
136
- /**
137
- * Adds event handlers to the off-canvas wrapper and the exit overlay.
138
- * @function
139
- * @private
140
- */
141
- _events() {
142
- this.$element.off('.zf.trigger .zf.offcanvas').on({
143
- 'open.zf.trigger': this.open.bind(this),
144
- 'close.zf.trigger': this.close.bind(this),
145
- 'toggle.zf.trigger': this.toggle.bind(this),
146
- 'keydown.zf.offcanvas': this._handleKeyboard.bind(this)
147
- });
148
-
149
- if (this.options.closeOnClick === true) {
150
- var $target = this.options.contentOverlay ? this.$overlay : this.$content;
151
- $target.on({'click.zf.offcanvas': this.close.bind(this)});
152
- }
153
- }
154
-
155
- /**
156
- * Applies event listener for elements that will reveal at certain breakpoints.
157
- * @private
158
- */
159
- _setMQChecker() {
160
- var _this = this;
161
-
162
- $(window).on('changed.zf.mediaquery', function() {
163
- if (MediaQuery.atLeast(_this.options.revealOn)) {
164
- _this.reveal(true);
165
- } else {
166
- _this.reveal(false);
167
- }
168
- }).one('load.zf.offcanvas', function() {
169
- if (MediaQuery.atLeast(_this.options.revealOn)) {
170
- _this.reveal(true);
171
- }
172
- });
173
- }
174
-
175
- /**
176
- * Removes the CSS transition/position classes of the off-canvas content container.
177
- * Removing the classes is important when another off-canvas gets opened that uses the same content container.
178
- * @private
179
- */
180
- _removeContentClasses(hasReveal) {
181
- this.$content.removeClass(this.contentClasses.base.join(' '));
182
- if (hasReveal === true) {
183
- this.$content.removeClass(this.contentClasses.reveal.join(' '));
184
- }
185
- }
186
-
187
- /**
188
- * Adds the CSS transition/position classes of the off-canvas content container, based on the opening off-canvas element.
189
- * Beforehand any transition/position class gets removed.
190
- * @param {Boolean} hasReveal - true if related off-canvas element is revealed.
191
- * @private
192
- */
193
- _addContentClasses(hasReveal) {
194
- this._removeContentClasses();
195
- this.$content.addClass(`has-transition-${this.options.transition} has-position-${this.position}`);
196
- if (hasReveal === true) {
197
- this.$content.addClass(`has-reveal-${this.position}`);
198
- }
199
- }
200
-
201
- /**
202
- * Handles the revealing/hiding the off-canvas at breakpoints, not the same as open.
203
- * @param {Boolean} isRevealed - true if element should be revealed.
204
- * @function
205
- */
206
- reveal(isRevealed) {
207
- if (isRevealed) {
208
- this.close();
209
- this.isRevealed = true;
210
- this.$element.attr('aria-hidden', 'false');
211
- this.$element.off('open.zf.trigger toggle.zf.trigger');
212
- this.$element.removeClass('is-closed');
213
- } else {
214
- this.isRevealed = false;
215
- this.$element.attr('aria-hidden', 'true');
216
- this.$element.off('open.zf.trigger toggle.zf.trigger').on({
217
- 'open.zf.trigger': this.open.bind(this),
218
- 'toggle.zf.trigger': this.toggle.bind(this)
219
- });
220
- this.$element.addClass('is-closed');
221
- }
222
- this._addContentClasses(isRevealed);
223
- }
224
-
225
- /**
226
- * Stops scrolling of the body when offcanvas is open on mobile Safari and other troublesome browsers.
227
- * @private
228
- */
229
- _stopScrolling(event) {
230
- return false;
231
- }
232
-
233
- // Taken and adapted from http://stackoverflow.com/questions/16889447/prevent-full-page-scrolling-ios
234
- // Only really works for y, not sure how to extend to x or if we need to.
235
- _recordScrollable(event) {
236
- let elem = this; // called from event handler context with this as elem
237
-
238
- // If the element is scrollable (content overflows), then...
239
- if (elem.scrollHeight !== elem.clientHeight) {
240
- // If we're at the top, scroll down one pixel to allow scrolling up
241
- if (elem.scrollTop === 0) {
242
- elem.scrollTop = 1;
243
- }
244
- // If we're at the bottom, scroll up one pixel to allow scrolling down
245
- if (elem.scrollTop === elem.scrollHeight - elem.clientHeight) {
246
- elem.scrollTop = elem.scrollHeight - elem.clientHeight - 1;
247
- }
248
- }
249
- elem.allowUp = elem.scrollTop > 0;
250
- elem.allowDown = elem.scrollTop < (elem.scrollHeight - elem.clientHeight);
251
- elem.lastY = event.originalEvent.pageY;
252
- }
253
-
254
- _stopScrollPropagation(event) {
255
- let elem = this; // called from event handler context with this as elem
256
- let up = event.pageY < elem.lastY;
257
- let down = !up;
258
- elem.lastY = event.pageY;
259
-
260
- if((up && elem.allowUp) || (down && elem.allowDown)) {
261
- event.stopPropagation();
262
- } else {
263
- event.preventDefault();
264
- }
265
- }
266
-
267
- /**
268
- * Opens the off-canvas menu.
269
- * @function
270
- * @param {Object} event - Event object passed from listener.
271
- * @param {jQuery} trigger - element that triggered the off-canvas to open.
272
- * @fires OffCanvas#opened
273
- */
274
- open(event, trigger) {
275
- if (this.$element.hasClass('is-open') || this.isRevealed) { return; }
276
- var _this = this;
277
-
278
- if (trigger) {
279
- this.$lastTrigger = trigger;
280
- }
281
-
282
- if (this.options.forceTo === 'top') {
283
- window.scrollTo(0, 0);
284
- } else if (this.options.forceTo === 'bottom') {
285
- window.scrollTo(0,document.body.scrollHeight);
286
- }
287
-
288
- if (this.options.transitionTime && this.options.transition !== 'overlap') {
289
- this.$element.siblings('[data-off-canvas-content]').css('transition-duration', this.options.transitionTime);
290
- } else {
291
- this.$element.siblings('[data-off-canvas-content]').css('transition-duration', '');
292
- }
293
-
294
- /**
295
- * Fires when the off-canvas menu opens.
296
- * @event OffCanvas#opened
297
- */
298
- this.$element.addClass('is-open').removeClass('is-closed');
299
-
300
- this.$triggers.attr('aria-expanded', 'true');
301
- this.$element.attr('aria-hidden', 'false')
302
- .trigger('opened.zf.offcanvas');
303
-
304
- this.$content.addClass('is-open-' + this.position);
305
-
306
- // If `contentScroll` is set to false, add class and disable scrolling on touch devices.
307
- if (this.options.contentScroll === false) {
308
- $('body').addClass('is-off-canvas-open').on('touchmove', this._stopScrolling);
309
- this.$element.on('touchstart', this._recordScrollable);
310
- this.$element.on('touchmove', this._stopScrollPropagation);
311
- }
312
-
313
- if (this.options.contentOverlay === true) {
314
- this.$overlay.addClass('is-visible');
315
- }
316
-
317
- if (this.options.closeOnClick === true && this.options.contentOverlay === true) {
318
- this.$overlay.addClass('is-closable');
319
- }
320
-
321
- if (this.options.autoFocus === true) {
322
- this.$element.one(transitionend(this.$element), function() {
323
- if (!_this.$element.hasClass('is-open')) {
324
- return; // exit if prematurely closed
325
- }
326
- var canvasFocus = _this.$element.find('[data-autofocus]');
327
- if (canvasFocus.length) {
328
- canvasFocus.eq(0).focus();
329
- } else {
330
- _this.$element.find('a, button').eq(0).focus();
331
- }
332
- });
333
- }
334
-
335
- if (this.options.trapFocus === true) {
336
- this.$content.attr('tabindex', '-1');
337
- Keyboard.trapFocus(this.$element);
338
- }
339
-
340
- this._addContentClasses();
341
- }
342
-
343
- /**
344
- * Closes the off-canvas menu.
345
- * @function
346
- * @param {Function} cb - optional cb to fire after closure.
347
- * @fires OffCanvas#closed
348
- */
349
- close(cb) {
350
- if (!this.$element.hasClass('is-open') || this.isRevealed) { return; }
351
-
352
- var _this = this;
353
-
354
- this.$element.removeClass('is-open');
355
-
356
- this.$element.attr('aria-hidden', 'true')
357
- /**
358
- * Fires when the off-canvas menu opens.
359
- * @event OffCanvas#closed
360
- */
361
- .trigger('closed.zf.offcanvas');
362
-
363
- this.$content.removeClass('is-open-left is-open-top is-open-right is-open-bottom');
364
-
365
- // If `contentScroll` is set to false, remove class and re-enable scrolling on touch devices.
366
- if (this.options.contentScroll === false) {
367
- $('body').removeClass('is-off-canvas-open').off('touchmove', this._stopScrolling);
368
- this.$element.off('touchstart', this._recordScrollable);
369
- this.$element.off('touchmove', this._stopScrollPropagation);
370
- }
371
-
372
- if (this.options.contentOverlay === true) {
373
- this.$overlay.removeClass('is-visible');
374
- }
375
-
376
- if (this.options.closeOnClick === true && this.options.contentOverlay === true) {
377
- this.$overlay.removeClass('is-closable');
378
- }
379
-
380
- this.$triggers.attr('aria-expanded', 'false');
381
-
382
- if (this.options.trapFocus === true) {
383
- this.$content.removeAttr('tabindex');
384
- Keyboard.releaseFocus(this.$element);
385
- }
386
-
387
- // Listen to transitionEnd and add class when done.
388
- this.$element.one(transitionend(this.$element), function(e) {
389
- _this.$element.addClass('is-closed');
390
- _this._removeContentClasses();
391
- });
392
- }
393
-
394
- /**
395
- * Toggles the off-canvas menu open or closed.
396
- * @function
397
- * @param {Object} event - Event object passed from listener.
398
- * @param {jQuery} trigger - element that triggered the off-canvas to open.
399
- */
400
- toggle(event, trigger) {
401
- if (this.$element.hasClass('is-open')) {
402
- this.close(event, trigger);
403
- }
404
- else {
405
- this.open(event, trigger);
406
- }
407
- }
408
-
409
- /**
410
- * Handles keyboard input when detected. When the escape key is pressed, the off-canvas menu closes, and focus is restored to the element that opened the menu.
411
- * @function
412
- * @private
413
- */
414
- _handleKeyboard(e) {
415
- Keyboard.handleKey(e, 'OffCanvas', {
416
- close: () => {
417
- this.close();
418
- this.$lastTrigger.focus();
419
- return true;
420
- },
421
- handled: () => {
422
- e.stopPropagation();
423
- e.preventDefault();
424
- }
425
- });
426
- }
427
-
428
- /**
429
- * Destroys the offcanvas plugin.
430
- * @function
431
- */
432
- _destroy() {
433
- this.close();
434
- this.$element.off('.zf.trigger .zf.offcanvas');
435
- this.$overlay.off('.zf.offcanvas');
436
- }
437
- }
438
-
439
- OffCanvas.defaults = {
440
- /**
441
- * Allow the user to click outside of the menu to close it.
442
- * @option
443
- * @type {boolean}
444
- * @default true
445
- */
446
- closeOnClick: true,
447
-
448
- /**
449
- * Adds an overlay on top of `[data-off-canvas-content]`.
450
- * @option
451
- * @type {boolean}
452
- * @default true
453
- */
454
- contentOverlay: true,
455
-
456
- /**
457
- * Target an off-canvas content container by ID that may be placed anywhere. If null the closest content container will be taken.
458
- * @option
459
- * @type {?string}
460
- * @default null
461
- */
462
- contentId: null,
463
-
464
- /**
465
- * Define the off-canvas element is nested in an off-canvas content. This is required when using the contentId option for a nested element.
466
- * @option
467
- * @type {boolean}
468
- * @default null
469
- */
470
- nested: null,
471
-
472
- /**
473
- * Enable/disable scrolling of the main content when an off canvas panel is open.
474
- * @option
475
- * @type {boolean}
476
- * @default true
477
- */
478
- contentScroll: true,
479
-
480
- /**
481
- * Amount of time in ms the open and close transition requires. If none selected, pulls from body style.
482
- * @option
483
- * @type {number}
484
- * @default null
485
- */
486
- transitionTime: null,
487
-
488
- /**
489
- * Type of transition for the offcanvas menu. Options are 'push', 'detached' or 'slide'.
490
- * @option
491
- * @type {string}
492
- * @default push
493
- */
494
- transition: 'push',
495
-
496
- /**
497
- * Force the page to scroll to top or bottom on open.
498
- * @option
499
- * @type {?string}
500
- * @default null
501
- */
502
- forceTo: null,
503
-
504
- /**
505
- * Allow the offcanvas to remain open for certain breakpoints.
506
- * @option
507
- * @type {boolean}
508
- * @default false
509
- */
510
- isRevealed: false,
511
-
512
- /**
513
- * Breakpoint at which to reveal. JS will use a RegExp to target standard classes, if changing classnames, pass your class with the `revealClass` option.
514
- * @option
515
- * @type {?string}
516
- * @default null
517
- */
518
- revealOn: null,
519
-
520
- /**
521
- * Force focus to the offcanvas on open. If true, will focus the opening trigger on close.
522
- * @option
523
- * @type {boolean}
524
- * @default true
525
- */
526
- autoFocus: true,
527
-
528
- /**
529
- * Class used to force an offcanvas to remain open. Foundation defaults for this are `reveal-for-large` & `reveal-for-medium`.
530
- * @option
531
- * @type {string}
532
- * @default reveal-for-
533
- * @todo improve the regex testing for this.
534
- */
535
- revealClass: 'reveal-for-',
536
-
537
- /**
538
- * Triggers optional focus trapping when opening an offcanvas. Sets tabindex of [data-off-canvas-content] to -1 for accessibility purposes.
539
- * @option
540
- * @type {boolean}
541
- * @default false
542
- */
543
- trapFocus: false
544
- }
545
-
546
- export {OffCanvas};