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,337 +0,0 @@
1
- "use strict";
2
-
3
- import $ from 'jquery';
4
- import { GetYoDigits } from './foundation.util.core';
5
- import { MediaQuery } from './foundation.util.mediaQuery';
6
-
7
- var FOUNDATION_VERSION = '6.4.1';
8
-
9
- // Global Foundation object
10
- // This is attached to the window, or used as a module for AMD/Browserify
11
- var Foundation = {
12
- version: FOUNDATION_VERSION,
13
-
14
- /**
15
- * Stores initialized plugins.
16
- */
17
- _plugins: {},
18
-
19
- /**
20
- * Stores generated unique ids for plugin instances
21
- */
22
- _uuids: [],
23
-
24
- /**
25
- * Defines a Foundation plugin, adding it to the `Foundation` namespace and the list of plugins to initialize when reflowing.
26
- * @param {Object} plugin - The constructor of the plugin.
27
- */
28
- plugin: function(plugin, name) {
29
- // Object key to use when adding to global Foundation object
30
- // Examples: Foundation.Reveal, Foundation.OffCanvas
31
- var className = (name || functionName(plugin));
32
- // Object key to use when storing the plugin, also used to create the identifying data attribute for the plugin
33
- // Examples: data-reveal, data-off-canvas
34
- var attrName = hyphenate(className);
35
-
36
- // Add to the Foundation object and the plugins list (for reflowing)
37
- this._plugins[attrName] = this[className] = plugin;
38
- },
39
- /**
40
- * @function
41
- * Populates the _uuids array with pointers to each individual plugin instance.
42
- * Adds the `zfPlugin` data-attribute to programmatically created plugins to allow use of $(selector).foundation(method) calls.
43
- * Also fires the initialization event for each plugin, consolidating repetitive code.
44
- * @param {Object} plugin - an instance of a plugin, usually `this` in context.
45
- * @param {String} name - the name of the plugin, passed as a camelCased string.
46
- * @fires Plugin#init
47
- */
48
- registerPlugin: function(plugin, name){
49
- var pluginName = name ? hyphenate(name) : functionName(plugin.constructor).toLowerCase();
50
- plugin.uuid = GetYoDigits(6, pluginName);
51
-
52
- if(!plugin.$element.attr(`data-${pluginName}`)){ plugin.$element.attr(`data-${pluginName}`, plugin.uuid); }
53
- if(!plugin.$element.data('zfPlugin')){ plugin.$element.data('zfPlugin', plugin); }
54
- /**
55
- * Fires when the plugin has initialized.
56
- * @event Plugin#init
57
- */
58
- plugin.$element.trigger(`init.zf.${pluginName}`);
59
-
60
- this._uuids.push(plugin.uuid);
61
-
62
- return;
63
- },
64
- /**
65
- * @function
66
- * Removes the plugins uuid from the _uuids array.
67
- * Removes the zfPlugin data attribute, as well as the data-plugin-name attribute.
68
- * Also fires the destroyed event for the plugin, consolidating repetitive code.
69
- * @param {Object} plugin - an instance of a plugin, usually `this` in context.
70
- * @fires Plugin#destroyed
71
- */
72
- unregisterPlugin: function(plugin){
73
- var pluginName = hyphenate(functionName(plugin.$element.data('zfPlugin').constructor));
74
-
75
- this._uuids.splice(this._uuids.indexOf(plugin.uuid), 1);
76
- plugin.$element.removeAttr(`data-${pluginName}`).removeData('zfPlugin')
77
- /**
78
- * Fires when the plugin has been destroyed.
79
- * @event Plugin#destroyed
80
- */
81
- .trigger(`destroyed.zf.${pluginName}`);
82
- for(var prop in plugin){
83
- plugin[prop] = null;//clean up script to prep for garbage collection.
84
- }
85
- return;
86
- },
87
-
88
- /**
89
- * @function
90
- * Causes one or more active plugins to re-initialize, resetting event listeners, recalculating positions, etc.
91
- * @param {String} plugins - optional string of an individual plugin key, attained by calling `$(element).data('pluginName')`, or string of a plugin class i.e. `'dropdown'`
92
- * @default If no argument is passed, reflow all currently active plugins.
93
- */
94
- reInit: function(plugins){
95
- var isJQ = plugins instanceof $;
96
- try{
97
- if(isJQ){
98
- plugins.each(function(){
99
- $(this).data('zfPlugin')._init();
100
- });
101
- }else{
102
- var type = typeof plugins,
103
- _this = this,
104
- fns = {
105
- 'object': function(plgs){
106
- plgs.forEach(function(p){
107
- p = hyphenate(p);
108
- $('[data-'+ p +']').foundation('_init');
109
- });
110
- },
111
- 'string': function(){
112
- plugins = hyphenate(plugins);
113
- $('[data-'+ plugins +']').foundation('_init');
114
- },
115
- 'undefined': function(){
116
- this['object'](Object.keys(_this._plugins));
117
- }
118
- };
119
- fns[type](plugins);
120
- }
121
- }catch(err){
122
- console.error(err);
123
- }finally{
124
- return plugins;
125
- }
126
- },
127
-
128
- /**
129
- * Initialize plugins on any elements within `elem` (and `elem` itself) that aren't already initialized.
130
- * @param {Object} elem - jQuery object containing the element to check inside. Also checks the element itself, unless it's the `document` object.
131
- * @param {String|Array} plugins - A list of plugins to initialize. Leave this out to initialize everything.
132
- */
133
- reflow: function(elem, plugins) {
134
-
135
- // If plugins is undefined, just grab everything
136
- if (typeof plugins === 'undefined') {
137
- plugins = Object.keys(this._plugins);
138
- }
139
- // If plugins is a string, convert it to an array with one item
140
- else if (typeof plugins === 'string') {
141
- plugins = [plugins];
142
- }
143
-
144
- var _this = this;
145
-
146
- // Iterate through each plugin
147
- $.each(plugins, function(i, name) {
148
- // Get the current plugin
149
- var plugin = _this._plugins[name];
150
-
151
- // Localize the search to all elements inside elem, as well as elem itself, unless elem === document
152
- var $elem = $(elem).find('[data-'+name+']').addBack('[data-'+name+']');
153
-
154
- // For each plugin found, initialize it
155
- $elem.each(function() {
156
- var $el = $(this),
157
- opts = {};
158
- // Don't double-dip on plugins
159
- if ($el.data('zfPlugin')) {
160
- console.warn("Tried to initialize "+name+" on an element that already has a Foundation plugin.");
161
- return;
162
- }
163
-
164
- if($el.attr('data-options')){
165
- var thing = $el.attr('data-options').split(';').forEach(function(e, i){
166
- var opt = e.split(':').map(function(el){ return el.trim(); });
167
- if(opt[0]) opts[opt[0]] = parseValue(opt[1]);
168
- });
169
- }
170
- try{
171
- $el.data('zfPlugin', new plugin($(this), opts));
172
- }catch(er){
173
- console.error(er);
174
- }finally{
175
- return;
176
- }
177
- });
178
- });
179
- },
180
- getFnName: functionName,
181
-
182
- addToJquery: function($) {
183
- // TODO: consider not making this a jQuery function
184
- // TODO: need way to reflow vs. re-initialize
185
- /**
186
- * The Foundation jQuery method.
187
- * @param {String|Array} method - An action to perform on the current jQuery object.
188
- */
189
- var foundation = function(method) {
190
- var type = typeof method,
191
- $noJS = $('.no-js');
192
-
193
- if($noJS.length){
194
- $noJS.removeClass('no-js');
195
- }
196
-
197
- if(type === 'undefined'){//needs to initialize the Foundation object, or an individual plugin.
198
- MediaQuery._init();
199
- Foundation.reflow(this);
200
- }else if(type === 'string'){//an individual method to invoke on a plugin or group of plugins
201
- var args = Array.prototype.slice.call(arguments, 1);//collect all the arguments, if necessary
202
- var plugClass = this.data('zfPlugin');//determine the class of plugin
203
-
204
- if(plugClass !== undefined && plugClass[method] !== undefined){//make sure both the class and method exist
205
- if(this.length === 1){//if there's only one, call it directly.
206
- plugClass[method].apply(plugClass, args);
207
- }else{
208
- this.each(function(i, el){//otherwise loop through the jQuery collection and invoke the method on each
209
- plugClass[method].apply($(el).data('zfPlugin'), args);
210
- });
211
- }
212
- }else{//error for no class or no method
213
- throw new ReferenceError("We're sorry, '" + method + "' is not an available method for " + (plugClass ? functionName(plugClass) : 'this element') + '.');
214
- }
215
- }else{//error for invalid argument type
216
- throw new TypeError(`We're sorry, ${type} is not a valid parameter. You must use a string representing the method you wish to invoke.`);
217
- }
218
- return this;
219
- };
220
- $.fn.foundation = foundation;
221
- return $;
222
- }
223
- };
224
-
225
- Foundation.util = {
226
- /**
227
- * Function for applying a debounce effect to a function call.
228
- * @function
229
- * @param {Function} func - Function to be called at end of timeout.
230
- * @param {Number} delay - Time in ms to delay the call of `func`.
231
- * @returns function
232
- */
233
- throttle: function (func, delay) {
234
- var timer = null;
235
-
236
- return function () {
237
- var context = this, args = arguments;
238
-
239
- if (timer === null) {
240
- timer = setTimeout(function () {
241
- func.apply(context, args);
242
- timer = null;
243
- }, delay);
244
- }
245
- };
246
- }
247
- };
248
-
249
- window.Foundation = Foundation;
250
-
251
- // Polyfill for requestAnimationFrame
252
- (function() {
253
- if (!Date.now || !window.Date.now)
254
- window.Date.now = Date.now = function() { return new Date().getTime(); };
255
-
256
- var vendors = ['webkit', 'moz'];
257
- for (var i = 0; i < vendors.length && !window.requestAnimationFrame; ++i) {
258
- var vp = vendors[i];
259
- window.requestAnimationFrame = window[vp+'RequestAnimationFrame'];
260
- window.cancelAnimationFrame = (window[vp+'CancelAnimationFrame']
261
- || window[vp+'CancelRequestAnimationFrame']);
262
- }
263
- if (/iP(ad|hone|od).*OS 6/.test(window.navigator.userAgent)
264
- || !window.requestAnimationFrame || !window.cancelAnimationFrame) {
265
- var lastTime = 0;
266
- window.requestAnimationFrame = function(callback) {
267
- var now = Date.now();
268
- var nextTime = Math.max(lastTime + 16, now);
269
- return setTimeout(function() { callback(lastTime = nextTime); },
270
- nextTime - now);
271
- };
272
- window.cancelAnimationFrame = clearTimeout;
273
- }
274
- /**
275
- * Polyfill for performance.now, required by rAF
276
- */
277
- if(!window.performance || !window.performance.now){
278
- window.performance = {
279
- start: Date.now(),
280
- now: function(){ return Date.now() - this.start; }
281
- };
282
- }
283
- })();
284
- if (!Function.prototype.bind) {
285
- Function.prototype.bind = function(oThis) {
286
- if (typeof this !== 'function') {
287
- // closest thing possible to the ECMAScript 5
288
- // internal IsCallable function
289
- throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
290
- }
291
-
292
- var aArgs = Array.prototype.slice.call(arguments, 1),
293
- fToBind = this,
294
- fNOP = function() {},
295
- fBound = function() {
296
- return fToBind.apply(this instanceof fNOP
297
- ? this
298
- : oThis,
299
- aArgs.concat(Array.prototype.slice.call(arguments)));
300
- };
301
-
302
- if (this.prototype) {
303
- // native functions don't have a prototype
304
- fNOP.prototype = this.prototype;
305
- }
306
- fBound.prototype = new fNOP();
307
-
308
- return fBound;
309
- };
310
- }
311
- // Polyfill to get the name of a function in IE9
312
- function functionName(fn) {
313
- if (Function.prototype.name === undefined) {
314
- var funcNameRegex = /function\s([^(]{1,})\(/;
315
- var results = (funcNameRegex).exec((fn).toString());
316
- return (results && results.length > 1) ? results[1].trim() : "";
317
- }
318
- else if (fn.prototype === undefined) {
319
- return fn.constructor.name;
320
- }
321
- else {
322
- return fn.prototype.constructor.name;
323
- }
324
- }
325
- function parseValue(str){
326
- if ('true' === str) return true;
327
- else if ('false' === str) return false;
328
- else if (!isNaN(str * 1)) return parseFloat(str);
329
- return str;
330
- }
331
- // Convert PascalCase to kebab-case
332
- // Thank you: http://stackoverflow.com/a/8955580
333
- function hyphenate(str) {
334
- return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
335
- }
336
-
337
- export {Foundation};
@@ -1,536 +0,0 @@
1
- 'use strict';
2
-
3
- import $ from 'jquery';
4
- import { Keyboard } from './foundation.util.keyboard';
5
- import { Nest } from './foundation.util.nest';
6
- import { GetYoDigits, transitionend } from './foundation.util.core';
7
- import { Box } from './foundation.util.box';
8
- import { Plugin } from './foundation.plugin';
9
-
10
- /**
11
- * Drilldown module.
12
- * @module foundation.drilldown
13
- * @requires foundation.util.keyboard
14
- * @requires foundation.util.nest
15
- * @requires foundation.util.box
16
- */
17
-
18
- class Drilldown extends Plugin {
19
- /**
20
- * Creates a new instance of a drilldown menu.
21
- * @class
22
- * @name Drilldown
23
- * @param {jQuery} element - jQuery object to make into an accordion menu.
24
- * @param {Object} options - Overrides to the default plugin settings.
25
- */
26
- _setup(element, options) {
27
- this.$element = element;
28
- this.options = $.extend({}, Drilldown.defaults, this.$element.data(), options);
29
- this.className = 'Drilldown'; // ie9 back compat
30
-
31
- Nest.Feather(this.$element, 'drilldown');
32
-
33
- this._init();
34
-
35
- Keyboard.register('Drilldown', {
36
- 'ENTER': 'open',
37
- 'SPACE': 'open',
38
- 'ARROW_RIGHT': 'next',
39
- 'ARROW_UP': 'up',
40
- 'ARROW_DOWN': 'down',
41
- 'ARROW_LEFT': 'previous',
42
- 'ESCAPE': 'close',
43
- 'TAB': 'down',
44
- 'SHIFT_TAB': 'up'
45
- });
46
- }
47
-
48
- /**
49
- * Initializes the drilldown by creating jQuery collections of elements
50
- * @private
51
- */
52
- _init() {
53
- if(this.options.autoApplyClass) {
54
- this.$element.addClass('drilldown');
55
- }
56
-
57
- this.$element.attr({
58
- 'role': 'tree',
59
- 'aria-multiselectable': false
60
- });
61
- this.$submenuAnchors = this.$element.find('li.is-drilldown-submenu-parent').children('a');
62
- this.$submenus = this.$submenuAnchors.parent('li').children('[data-submenu]').attr('role', 'group');
63
- this.$menuItems = this.$element.find('li').not('.js-drilldown-back').attr('role', 'treeitem').find('a');
64
- this.$element.attr('data-mutate', (this.$element.attr('data-drilldown') || GetYoDigits(6, 'drilldown')));
65
-
66
- this._prepareMenu();
67
- this._registerEvents();
68
-
69
- this._keyboardEvents();
70
- }
71
-
72
- /**
73
- * prepares drilldown menu by setting attributes to links and elements
74
- * sets a min height to prevent content jumping
75
- * wraps the element if not already wrapped
76
- * @private
77
- * @function
78
- */
79
- _prepareMenu() {
80
- var _this = this;
81
- // if(!this.options.holdOpen){
82
- // this._menuLinkEvents();
83
- // }
84
- this.$submenuAnchors.each(function(){
85
- var $link = $(this);
86
- var $sub = $link.parent();
87
- if(_this.options.parentLink){
88
- $link.clone().prependTo($sub.children('[data-submenu]')).wrap('<li class="is-submenu-parent-item is-submenu-item is-drilldown-submenu-item" role="menu-item"></li>');
89
- }
90
- $link.data('savedHref', $link.attr('href')).removeAttr('href').attr('tabindex', 0);
91
- $link.children('[data-submenu]')
92
- .attr({
93
- 'aria-hidden': true,
94
- 'tabindex': 0,
95
- 'role': 'group'
96
- });
97
- _this._events($link);
98
- });
99
- this.$submenus.each(function(){
100
- var $menu = $(this),
101
- $back = $menu.find('.js-drilldown-back');
102
- if(!$back.length){
103
- switch (_this.options.backButtonPosition) {
104
- case "bottom":
105
- $menu.append(_this.options.backButton);
106
- break;
107
- case "top":
108
- $menu.prepend(_this.options.backButton);
109
- break;
110
- default:
111
- console.error("Unsupported backButtonPosition value '" + _this.options.backButtonPosition + "'");
112
- }
113
- }
114
- _this._back($menu);
115
- });
116
-
117
- this.$submenus.addClass('invisible');
118
- if(!this.options.autoHeight) {
119
- this.$submenus.addClass('drilldown-submenu-cover-previous');
120
- }
121
-
122
- // create a wrapper on element if it doesn't exist.
123
- if(!this.$element.parent().hasClass('is-drilldown')){
124
- this.$wrapper = $(this.options.wrapper).addClass('is-drilldown');
125
- if(this.options.animateHeight) this.$wrapper.addClass('animate-height');
126
- this.$element.wrap(this.$wrapper);
127
- }
128
- // set wrapper
129
- this.$wrapper = this.$element.parent();
130
- this.$wrapper.css(this._getMaxDims());
131
- }
132
-
133
- _resize() {
134
- this.$wrapper.css({'max-width': 'none', 'min-height': 'none'});
135
- // _getMaxDims has side effects (boo) but calling it should update all other necessary heights & widths
136
- this.$wrapper.css(this._getMaxDims());
137
- }
138
-
139
- /**
140
- * Adds event handlers to elements in the menu.
141
- * @function
142
- * @private
143
- * @param {jQuery} $elem - the current menu item to add handlers to.
144
- */
145
- _events($elem) {
146
- var _this = this;
147
-
148
- $elem.off('click.zf.drilldown')
149
- .on('click.zf.drilldown', function(e){
150
- if($(e.target).parentsUntil('ul', 'li').hasClass('is-drilldown-submenu-parent')){
151
- e.stopImmediatePropagation();
152
- e.preventDefault();
153
- }
154
-
155
- // if(e.target !== e.currentTarget.firstElementChild){
156
- // return false;
157
- // }
158
- _this._show($elem.parent('li'));
159
-
160
- if(_this.options.closeOnClick){
161
- var $body = $('body');
162
- $body.off('.zf.drilldown').on('click.zf.drilldown', function(e){
163
- if (e.target === _this.$element[0] || $.contains(_this.$element[0], e.target)) { return; }
164
- e.preventDefault();
165
- _this._hideAll();
166
- $body.off('.zf.drilldown');
167
- });
168
- }
169
- });
170
- }
171
-
172
- /**
173
- * Adds event handlers to the menu element.
174
- * @function
175
- * @private
176
- */
177
- _registerEvents() {
178
- if(this.options.scrollTop){
179
- this._bindHandler = this._scrollTop.bind(this);
180
- this.$element.on('open.zf.drilldown hide.zf.drilldown closed.zf.drilldown',this._bindHandler);
181
- }
182
- this.$element.on('mutateme.zf.trigger', this._resize.bind(this));
183
- }
184
-
185
- /**
186
- * Scroll to Top of Element or data-scroll-top-element
187
- * @function
188
- * @fires Drilldown#scrollme
189
- */
190
- _scrollTop() {
191
- var _this = this;
192
- var $scrollTopElement = _this.options.scrollTopElement!=''?$(_this.options.scrollTopElement):_this.$element,
193
- scrollPos = parseInt($scrollTopElement.offset().top+_this.options.scrollTopOffset, 10);
194
- $('html, body').stop(true).animate({ scrollTop: scrollPos }, _this.options.animationDuration, _this.options.animationEasing,function(){
195
- /**
196
- * Fires after the menu has scrolled
197
- * @event Drilldown#scrollme
198
- */
199
- if(this===$('html')[0])_this.$element.trigger('scrollme.zf.drilldown');
200
- });
201
- }
202
-
203
- /**
204
- * Adds keydown event listener to `li`'s in the menu.
205
- * @private
206
- */
207
- _keyboardEvents() {
208
- var _this = this;
209
-
210
- this.$menuItems.add(this.$element.find('.js-drilldown-back > a, .is-submenu-parent-item > a')).on('keydown.zf.drilldown', function(e){
211
- var $element = $(this),
212
- $elements = $element.parent('li').parent('ul').children('li').children('a'),
213
- $prevElement,
214
- $nextElement;
215
-
216
- $elements.each(function(i) {
217
- if ($(this).is($element)) {
218
- $prevElement = $elements.eq(Math.max(0, i-1));
219
- $nextElement = $elements.eq(Math.min(i+1, $elements.length-1));
220
- return;
221
- }
222
- });
223
-
224
- Keyboard.handleKey(e, 'Drilldown', {
225
- next: function() {
226
- if ($element.is(_this.$submenuAnchors)) {
227
- _this._show($element.parent('li'));
228
- $element.parent('li').one(transitionend($element), function(){
229
- $element.parent('li').find('ul li a').filter(_this.$menuItems).first().focus();
230
- });
231
- return true;
232
- }
233
- },
234
- previous: function() {
235
- _this._hide($element.parent('li').parent('ul'));
236
- $element.parent('li').parent('ul').one(transitionend($element), function(){
237
- setTimeout(function() {
238
- $element.parent('li').parent('ul').parent('li').children('a').first().focus();
239
- }, 1);
240
- });
241
- return true;
242
- },
243
- up: function() {
244
- $prevElement.focus();
245
- // Don't tap focus on first element in root ul
246
- return !$element.is(_this.$element.find('> li:first-child > a'));
247
- },
248
- down: function() {
249
- $nextElement.focus();
250
- // Don't tap focus on last element in root ul
251
- return !$element.is(_this.$element.find('> li:last-child > a'));
252
- },
253
- close: function() {
254
- // Don't close on element in root ul
255
- if (!$element.is(_this.$element.find('> li > a'))) {
256
- _this._hide($element.parent().parent());
257
- $element.parent().parent().siblings('a').focus();
258
- }
259
- },
260
- open: function() {
261
- if (!$element.is(_this.$menuItems)) { // not menu item means back button
262
- _this._hide($element.parent('li').parent('ul'));
263
- $element.parent('li').parent('ul').one(transitionend($element), function(){
264
- setTimeout(function() {
265
- $element.parent('li').parent('ul').parent('li').children('a').first().focus();
266
- }, 1);
267
- });
268
- return true;
269
- } else if ($element.is(_this.$submenuAnchors)) {
270
- _this._show($element.parent('li'));
271
- $element.parent('li').one(transitionend($element), function(){
272
- $element.parent('li').find('ul li a').filter(_this.$menuItems).first().focus();
273
- });
274
- return true;
275
- }
276
- },
277
- handled: function(preventDefault) {
278
- if (preventDefault) {
279
- e.preventDefault();
280
- }
281
- e.stopImmediatePropagation();
282
- }
283
- });
284
- }); // end keyboardAccess
285
- }
286
-
287
- /**
288
- * Closes all open elements, and returns to root menu.
289
- * @function
290
- * @fires Drilldown#closed
291
- */
292
- _hideAll() {
293
- var $elem = this.$element.find('.is-drilldown-submenu.is-active').addClass('is-closing');
294
- if(this.options.autoHeight) this.$wrapper.css({height:$elem.parent().closest('ul').data('calcHeight')});
295
- $elem.one(transitionend($elem), function(e){
296
- $elem.removeClass('is-active is-closing');
297
- });
298
- /**
299
- * Fires when the menu is fully closed.
300
- * @event Drilldown#closed
301
- */
302
- this.$element.trigger('closed.zf.drilldown');
303
- }
304
-
305
- /**
306
- * Adds event listener for each `back` button, and closes open menus.
307
- * @function
308
- * @fires Drilldown#back
309
- * @param {jQuery} $elem - the current sub-menu to add `back` event.
310
- */
311
- _back($elem) {
312
- var _this = this;
313
- $elem.off('click.zf.drilldown');
314
- $elem.children('.js-drilldown-back')
315
- .on('click.zf.drilldown', function(e){
316
- e.stopImmediatePropagation();
317
- // console.log('mouseup on back');
318
- _this._hide($elem);
319
-
320
- // If there is a parent submenu, call show
321
- let parentSubMenu = $elem.parent('li').parent('ul').parent('li');
322
- if (parentSubMenu.length) {
323
- _this._show(parentSubMenu);
324
- }
325
- });
326
- }
327
-
328
- /**
329
- * Adds event listener to menu items w/o submenus to close open menus on click.
330
- * @function
331
- * @private
332
- */
333
- _menuLinkEvents() {
334
- var _this = this;
335
- this.$menuItems.not('.is-drilldown-submenu-parent')
336
- .off('click.zf.drilldown')
337
- .on('click.zf.drilldown', function(e){
338
- // e.stopImmediatePropagation();
339
- setTimeout(function(){
340
- _this._hideAll();
341
- }, 0);
342
- });
343
- }
344
-
345
- /**
346
- * Opens a submenu.
347
- * @function
348
- * @fires Drilldown#open
349
- * @param {jQuery} $elem - the current element with a submenu to open, i.e. the `li` tag.
350
- */
351
- _show($elem) {
352
- if(this.options.autoHeight) this.$wrapper.css({height:$elem.children('[data-submenu]').data('calcHeight')});
353
- $elem.attr('aria-expanded', true);
354
- $elem.children('[data-submenu]').addClass('is-active').removeClass('invisible').attr('aria-hidden', false);
355
- /**
356
- * Fires when the submenu has opened.
357
- * @event Drilldown#open
358
- */
359
- this.$element.trigger('open.zf.drilldown', [$elem]);
360
- };
361
-
362
- /**
363
- * Hides a submenu
364
- * @function
365
- * @fires Drilldown#hide
366
- * @param {jQuery} $elem - the current sub-menu to hide, i.e. the `ul` tag.
367
- */
368
- _hide($elem) {
369
- if(this.options.autoHeight) this.$wrapper.css({height:$elem.parent().closest('ul').data('calcHeight')});
370
- var _this = this;
371
- $elem.parent('li').attr('aria-expanded', false);
372
- $elem.attr('aria-hidden', true).addClass('is-closing')
373
- $elem.addClass('is-closing')
374
- .one(transitionend($elem), function(){
375
- $elem.removeClass('is-active is-closing');
376
- $elem.blur().addClass('invisible');
377
- });
378
- /**
379
- * Fires when the submenu has closed.
380
- * @event Drilldown#hide
381
- */
382
- $elem.trigger('hide.zf.drilldown', [$elem]);
383
- }
384
-
385
- /**
386
- * Iterates through the nested menus to calculate the min-height, and max-width for the menu.
387
- * Prevents content jumping.
388
- * @function
389
- * @private
390
- */
391
- _getMaxDims() {
392
- var maxHeight = 0, result = {}, _this = this;
393
- this.$submenus.add(this.$element).each(function(){
394
- var numOfElems = $(this).children('li').length;
395
- var height = Box.GetDimensions(this).height;
396
- maxHeight = height > maxHeight ? height : maxHeight;
397
- if(_this.options.autoHeight) {
398
- $(this).data('calcHeight',height);
399
- if (!$(this).hasClass('is-drilldown-submenu')) result['height'] = height;
400
- }
401
- });
402
-
403
- if(!this.options.autoHeight) result['min-height'] = `${maxHeight}px`;
404
-
405
- result['max-width'] = `${this.$element[0].getBoundingClientRect().width}px`;
406
-
407
- return result;
408
- }
409
-
410
- /**
411
- * Destroys the Drilldown Menu
412
- * @function
413
- */
414
- _destroy() {
415
- if(this.options.scrollTop) this.$element.off('.zf.drilldown',this._bindHandler);
416
- this._hideAll();
417
- this.$element.off('mutateme.zf.trigger');
418
- Nest.Burn(this.$element, 'drilldown');
419
- this.$element.unwrap()
420
- .find('.js-drilldown-back, .is-submenu-parent-item').remove()
421
- .end().find('.is-active, .is-closing, .is-drilldown-submenu').removeClass('is-active is-closing is-drilldown-submenu')
422
- .end().find('[data-submenu]').removeAttr('aria-hidden tabindex role');
423
- this.$submenuAnchors.each(function() {
424
- $(this).off('.zf.drilldown');
425
- });
426
-
427
- this.$submenus.removeClass('drilldown-submenu-cover-previous invisible');
428
-
429
- this.$element.find('a').each(function(){
430
- var $link = $(this);
431
- $link.removeAttr('tabindex');
432
- if($link.data('savedHref')){
433
- $link.attr('href', $link.data('savedHref')).removeData('savedHref');
434
- }else{ return; }
435
- });
436
- };
437
- }
438
-
439
- Drilldown.defaults = {
440
- /**
441
- * Drilldowns depend on styles in order to function properly; in the default build of Foundation these are
442
- * on the `drilldown` class. This option auto-applies this class to the drilldown upon initialization.
443
- * @option
444
- * @type {boolian}
445
- * @default true
446
- */
447
- autoApplyClass: true,
448
- /**
449
- * Markup used for JS generated back button. Prepended or appended (see backButtonPosition) to submenu lists and deleted on `destroy` method, 'js-drilldown-back' class required. Remove the backslash (`\`) if copy and pasting.
450
- * @option
451
- * @type {string}
452
- * @default '<li class="js-drilldown-back"><a tabindex="0">Back</a></li>'
453
- */
454
- backButton: '<li class="js-drilldown-back"><a tabindex="0">Back</a></li>',
455
- /**
456
- * Position the back button either at the top or bottom of drilldown submenus. Can be `'left'` or `'bottom'`.
457
- * @option
458
- * @type {string}
459
- * @default top
460
- */
461
- backButtonPosition: 'top',
462
- /**
463
- * Markup used to wrap drilldown menu. Use a class name for independent styling; the JS applied class: `is-drilldown` is required. Remove the backslash (`\`) if copy and pasting.
464
- * @option
465
- * @type {string}
466
- * @default '<div></div>'
467
- */
468
- wrapper: '<div></div>',
469
- /**
470
- * Adds the parent link to the submenu.
471
- * @option
472
- * @type {boolean}
473
- * @default false
474
- */
475
- parentLink: false,
476
- /**
477
- * Allow the menu to return to root list on body click.
478
- * @option
479
- * @type {boolean}
480
- * @default false
481
- */
482
- closeOnClick: false,
483
- /**
484
- * Allow the menu to auto adjust height.
485
- * @option
486
- * @type {boolean}
487
- * @default false
488
- */
489
- autoHeight: false,
490
- /**
491
- * Animate the auto adjust height.
492
- * @option
493
- * @type {boolean}
494
- * @default false
495
- */
496
- animateHeight: false,
497
- /**
498
- * Scroll to the top of the menu after opening a submenu or navigating back using the menu back button
499
- * @option
500
- * @type {boolean}
501
- * @default false
502
- */
503
- scrollTop: false,
504
- /**
505
- * String jquery selector (for example 'body') of element to take offset().top from, if empty string the drilldown menu offset().top is taken
506
- * @option
507
- * @type {string}
508
- * @default ''
509
- */
510
- scrollTopElement: '',
511
- /**
512
- * ScrollTop offset
513
- * @option
514
- * @type {number}
515
- * @default 0
516
- */
517
- scrollTopOffset: 0,
518
- /**
519
- * Scroll animation duration
520
- * @option
521
- * @type {number}
522
- * @default 500
523
- */
524
- animationDuration: 500,
525
- /**
526
- * Scroll animation easing. Can be `'swing'` or `'linear'`.
527
- * @option
528
- * @type {string}
529
- * @see {@link https://api.jquery.com/animate|JQuery animate}
530
- * @default 'swing'
531
- */
532
- animationEasing: 'swing'
533
- // holdOpen: false
534
- };
535
-
536
- export {Drilldown};