foundation-rails 5.5.3.2 → 6.1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (169) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +2 -8
  4. data/Rakefile +23 -0
  5. data/app/views/foundation/rails/styleguide/show.html.erb +2 -5
  6. data/bower.json +2 -2
  7. data/lib/foundation/rails/version.rb +1 -1
  8. data/lib/generators/foundation/install_generator.rb +6 -3
  9. data/lib/generators/foundation/templates/_settings.scss +546 -0
  10. data/lib/generators/foundation/templates/application.html.erb +0 -1
  11. data/lib/generators/foundation/templates/application.html.haml +0 -2
  12. data/lib/generators/foundation/templates/application.html.slim +0 -2
  13. data/lib/generators/foundation/templates/foundation_and_overrides.scss +51 -0
  14. data/vendor/assets/js/foundation.abide.js +418 -0
  15. data/vendor/assets/js/foundation.accordion.js +229 -0
  16. data/vendor/assets/js/foundation.accordionMenu.js +262 -0
  17. data/vendor/assets/js/foundation.core.js +378 -0
  18. data/vendor/assets/js/foundation.drilldown.js +321 -0
  19. data/vendor/assets/js/foundation.dropdown.js +390 -0
  20. data/vendor/assets/js/foundation.dropdownMenu.js +391 -0
  21. data/vendor/assets/js/foundation.equalizer.js +274 -0
  22. data/vendor/assets/js/foundation.interchange.js +184 -0
  23. data/vendor/assets/js/foundation.js +28 -0
  24. data/vendor/assets/js/foundation.magellan.js +212 -0
  25. data/vendor/assets/js/foundation.offcanvas.js +371 -0
  26. data/vendor/assets/js/foundation.orbit.js +419 -0
  27. data/vendor/assets/js/foundation.responsiveMenu.js +145 -0
  28. data/vendor/assets/js/foundation.responsiveToggle.js +106 -0
  29. data/vendor/assets/js/foundation.reveal.js +478 -0
  30. data/vendor/assets/js/foundation.slider.js +484 -0
  31. data/vendor/assets/js/foundation.sticky.js +436 -0
  32. data/vendor/assets/js/foundation.tabs.js +306 -0
  33. data/vendor/assets/js/foundation.toggler.js +147 -0
  34. data/vendor/assets/js/foundation.tooltip.js +429 -0
  35. data/vendor/assets/js/foundation.util.box.js +169 -0
  36. data/vendor/assets/js/foundation.util.keyboard.js +115 -0
  37. data/vendor/assets/js/foundation.util.mediaQuery.js +210 -0
  38. data/vendor/assets/js/foundation.util.motion.js +89 -0
  39. data/vendor/assets/js/foundation.util.nest.js +64 -0
  40. data/vendor/assets/js/foundation.util.timerAndImageLoader.js +78 -0
  41. data/vendor/assets/js/foundation.util.touch.js +339 -0
  42. data/vendor/assets/js/foundation.util.triggers.js +222 -0
  43. data/vendor/assets/scss/_global.scss +626 -0
  44. data/vendor/assets/scss/components/_accordion-menu.scss +32 -0
  45. data/vendor/assets/scss/components/_accordion.scss +113 -0
  46. data/vendor/assets/scss/components/_badge.scss +55 -0
  47. data/vendor/assets/scss/components/_breadcrumbs.scss +94 -0
  48. data/vendor/assets/scss/components/_button-group.scss +130 -0
  49. data/vendor/assets/scss/components/_button.scss +265 -0
  50. data/vendor/assets/scss/components/_callout.scss +105 -0
  51. data/vendor/assets/scss/components/_close-button.scss +61 -0
  52. data/vendor/assets/scss/components/_drilldown.scss +75 -0
  53. data/vendor/assets/scss/components/_dropdown-menu.scss +148 -0
  54. data/vendor/assets/scss/components/_dropdown.scss +64 -0
  55. data/vendor/assets/scss/components/_flex-video.scss +63 -0
  56. data/vendor/assets/scss/components/_float.scss +27 -0
  57. data/vendor/assets/scss/components/_label.scss +56 -0
  58. data/vendor/assets/scss/components/_media-object.scss +74 -0
  59. data/vendor/assets/scss/components/_menu.scss +209 -0
  60. data/vendor/assets/scss/components/_off-canvas.scss +180 -0
  61. data/vendor/assets/scss/components/_orbit.scss +193 -0
  62. data/vendor/assets/scss/components/_pagination.scss +158 -0
  63. data/vendor/assets/scss/components/_progress-bar.scss +83 -0
  64. data/vendor/assets/scss/components/_reveal.scss +156 -0
  65. data/vendor/assets/scss/components/_slider.scss +158 -0
  66. data/vendor/assets/scss/components/_sticky.scss +38 -0
  67. data/vendor/assets/scss/components/_switch.scss +232 -0
  68. data/vendor/assets/scss/components/_table.scss +213 -0
  69. data/vendor/assets/scss/components/_tabs.scss +170 -0
  70. data/vendor/assets/scss/components/_thumbnail.scss +54 -0
  71. data/vendor/assets/scss/components/_title-bar.scss +68 -0
  72. data/vendor/assets/scss/components/_tooltip.scss +100 -0
  73. data/vendor/assets/scss/components/_top-bar.scss +89 -0
  74. data/vendor/assets/scss/components/_visibility.scss +131 -0
  75. data/vendor/assets/scss/forms/_checkbox.scss +36 -0
  76. data/vendor/assets/scss/forms/_error.scss +82 -0
  77. data/vendor/assets/scss/forms/_fieldset.scss +53 -0
  78. data/vendor/assets/scss/forms/_forms.scss +32 -0
  79. data/vendor/assets/scss/forms/_help-text.scss +30 -0
  80. data/vendor/assets/scss/forms/_input-group.scss +91 -0
  81. data/vendor/assets/scss/forms/_label.scss +48 -0
  82. data/vendor/assets/scss/forms/_select.scss +63 -0
  83. data/vendor/assets/scss/forms/_text.scss +154 -0
  84. data/vendor/assets/scss/foundation.scss +91 -0
  85. data/vendor/assets/scss/grid/_classes.scss +153 -0
  86. data/vendor/assets/scss/grid/_column.scss +124 -0
  87. data/vendor/assets/scss/grid/_flex-grid.scss +281 -0
  88. data/vendor/assets/scss/grid/_grid.scss +48 -0
  89. data/vendor/assets/scss/grid/_gutter.scss +34 -0
  90. data/vendor/assets/scss/grid/_layout.scss +33 -0
  91. data/vendor/assets/scss/grid/_position.scss +72 -0
  92. data/vendor/assets/scss/grid/_row.scss +97 -0
  93. data/vendor/assets/scss/grid/_size.scss +24 -0
  94. data/vendor/assets/scss/settings/_settings.scss +547 -0
  95. data/vendor/assets/scss/typography/_alignment.scss +22 -0
  96. data/vendor/assets/scss/typography/_base.scss +439 -0
  97. data/vendor/assets/scss/typography/_helpers.scss +77 -0
  98. data/vendor/assets/scss/typography/_print.scss +73 -0
  99. data/vendor/assets/scss/typography/_typography.scss +28 -0
  100. data/vendor/assets/scss/util/_breakpoint.scss +266 -0
  101. data/vendor/assets/scss/util/_color.scss +41 -0
  102. data/vendor/assets/scss/util/_mixins.scss +223 -0
  103. data/vendor/assets/scss/util/_selector.scss +40 -0
  104. data/vendor/assets/scss/util/_unit.scss +90 -0
  105. data/vendor/assets/scss/util/_util.scss +15 -0
  106. data/vendor/assets/scss/util/_value.scss +126 -0
  107. metadata +97 -64
  108. data/update-gem.sh +0 -20
  109. data/vendor/assets/javascripts/foundation.js +0 -17
  110. data/vendor/assets/javascripts/foundation/foundation.abide.js +0 -426
  111. data/vendor/assets/javascripts/foundation/foundation.accordion.js +0 -125
  112. data/vendor/assets/javascripts/foundation/foundation.alert.js +0 -43
  113. data/vendor/assets/javascripts/foundation/foundation.clearing.js +0 -586
  114. data/vendor/assets/javascripts/foundation/foundation.dropdown.js +0 -468
  115. data/vendor/assets/javascripts/foundation/foundation.equalizer.js +0 -104
  116. data/vendor/assets/javascripts/foundation/foundation.interchange.js +0 -360
  117. data/vendor/assets/javascripts/foundation/foundation.joyride.js +0 -935
  118. data/vendor/assets/javascripts/foundation/foundation.js +0 -732
  119. data/vendor/assets/javascripts/foundation/foundation.magellan.js +0 -214
  120. data/vendor/assets/javascripts/foundation/foundation.offcanvas.js +0 -225
  121. data/vendor/assets/javascripts/foundation/foundation.orbit.js +0 -476
  122. data/vendor/assets/javascripts/foundation/foundation.reveal.js +0 -522
  123. data/vendor/assets/javascripts/foundation/foundation.slider.js +0 -296
  124. data/vendor/assets/javascripts/foundation/foundation.tab.js +0 -247
  125. data/vendor/assets/javascripts/foundation/foundation.tooltip.js +0 -348
  126. data/vendor/assets/javascripts/foundation/foundation.topbar.js +0 -458
  127. data/vendor/assets/javascripts/vendor/modernizr.js +0 -1406
  128. data/vendor/assets/stylesheets/foundation.scss +0 -42
  129. data/vendor/assets/stylesheets/foundation/_functions.scss +0 -156
  130. data/vendor/assets/stylesheets/foundation/_settings.scss +0 -1489
  131. data/vendor/assets/stylesheets/foundation/components/_accordion.scss +0 -161
  132. data/vendor/assets/stylesheets/foundation/components/_alert-boxes.scss +0 -128
  133. data/vendor/assets/stylesheets/foundation/components/_block-grid.scss +0 -133
  134. data/vendor/assets/stylesheets/foundation/components/_breadcrumbs.scss +0 -132
  135. data/vendor/assets/stylesheets/foundation/components/_button-groups.scss +0 -208
  136. data/vendor/assets/stylesheets/foundation/components/_buttons.scss +0 -261
  137. data/vendor/assets/stylesheets/foundation/components/_clearing.scss +0 -260
  138. data/vendor/assets/stylesheets/foundation/components/_dropdown-buttons.scss +0 -130
  139. data/vendor/assets/stylesheets/foundation/components/_dropdown.scss +0 -269
  140. data/vendor/assets/stylesheets/foundation/components/_flex-video.scss +0 -51
  141. data/vendor/assets/stylesheets/foundation/components/_forms.scss +0 -607
  142. data/vendor/assets/stylesheets/foundation/components/_global.scss +0 -566
  143. data/vendor/assets/stylesheets/foundation/components/_grid.scss +0 -292
  144. data/vendor/assets/stylesheets/foundation/components/_icon-bar.scss +0 -460
  145. data/vendor/assets/stylesheets/foundation/components/_inline-lists.scss +0 -58
  146. data/vendor/assets/stylesheets/foundation/components/_joyride.scss +0 -220
  147. data/vendor/assets/stylesheets/foundation/components/_keystrokes.scss +0 -60
  148. data/vendor/assets/stylesheets/foundation/components/_labels.scss +0 -106
  149. data/vendor/assets/stylesheets/foundation/components/_magellan.scss +0 -34
  150. data/vendor/assets/stylesheets/foundation/components/_offcanvas.scss +0 -606
  151. data/vendor/assets/stylesheets/foundation/components/_orbit.scss +0 -388
  152. data/vendor/assets/stylesheets/foundation/components/_pagination.scss +0 -163
  153. data/vendor/assets/stylesheets/foundation/components/_panels.scss +0 -107
  154. data/vendor/assets/stylesheets/foundation/components/_pricing-tables.scss +0 -150
  155. data/vendor/assets/stylesheets/foundation/components/_progress-bars.scss +0 -85
  156. data/vendor/assets/stylesheets/foundation/components/_range-slider.scss +0 -177
  157. data/vendor/assets/stylesheets/foundation/components/_reveal.scss +0 -212
  158. data/vendor/assets/stylesheets/foundation/components/_side-nav.scss +0 -120
  159. data/vendor/assets/stylesheets/foundation/components/_split-buttons.scss +0 -203
  160. data/vendor/assets/stylesheets/foundation/components/_sub-nav.scss +0 -125
  161. data/vendor/assets/stylesheets/foundation/components/_switches.scss +0 -241
  162. data/vendor/assets/stylesheets/foundation/components/_tables.scss +0 -135
  163. data/vendor/assets/stylesheets/foundation/components/_tabs.scss +0 -142
  164. data/vendor/assets/stylesheets/foundation/components/_thumbs.scss +0 -66
  165. data/vendor/assets/stylesheets/foundation/components/_tooltips.scss +0 -142
  166. data/vendor/assets/stylesheets/foundation/components/_top-bar.scss +0 -745
  167. data/vendor/assets/stylesheets/foundation/components/_type.scss +0 -525
  168. data/vendor/assets/stylesheets/foundation/components/_visibility.scss +0 -425
  169. data/vendor/assets/stylesheets/normalize.scss +0 -424
@@ -0,0 +1,378 @@
1
+ !function($) {
2
+ "use strict";
3
+
4
+ var FOUNDATION_VERSION = '6.1.1';
5
+
6
+ // Global Foundation object
7
+ // This is attached to the window, or used as a module for AMD/Browserify
8
+ var Foundation = {
9
+ version: FOUNDATION_VERSION,
10
+
11
+ /**
12
+ * Stores initialized plugins.
13
+ */
14
+ _plugins: {},
15
+
16
+ /**
17
+ * Stores generated unique ids for plugin instances
18
+ */
19
+ _uuids: [],
20
+ /**
21
+ * Stores currently active plugins.
22
+ */
23
+ _activePlugins: {},
24
+
25
+ /**
26
+ * Returns a boolean for RTL support
27
+ */
28
+ rtl: function(){
29
+ return $('html').attr('dir') === 'rtl';
30
+ },
31
+ /**
32
+ * Defines a Foundation plugin, adding it to the `Foundation` namespace and the list of plugins to initialize when reflowing.
33
+ * @param {Object} plugin - The constructor of the plugin.
34
+ */
35
+ plugin: function(plugin, name) {
36
+ // Object key to use when adding to global Foundation object
37
+ // Examples: Foundation.Reveal, Foundation.OffCanvas
38
+ var className = (name || functionName(plugin));
39
+ // Object key to use when storing the plugin, also used to create the identifying data attribute for the plugin
40
+ // Examples: data-reveal, data-off-canvas
41
+ var attrName = hyphenate(className);
42
+
43
+ // Add to the Foundation object and the plugins list (for reflowing)
44
+ this._plugins[attrName] = this[className] = plugin;
45
+ },
46
+ /**
47
+ * @function
48
+ * Creates a pointer to an instance of a Plugin within the Foundation._activePlugins object.
49
+ * Sets the `[data-pluginName="uniqueIdHere"]`, allowing easy access to any plugin's internal methods.
50
+ * Also fires the initialization event for each plugin, consolidating repeditive code.
51
+ * @param {Object} plugin - an instance of a plugin, usually `this` in context.
52
+ * @fires Plugin#init
53
+ */
54
+ registerPlugin: function(plugin, name){
55
+ var pluginName = name ? hyphenate(name) : functionName(plugin.constructor).toLowerCase();
56
+ plugin.uuid = this.GetYoDigits(6, pluginName);
57
+
58
+ if(!plugin.$element.attr('data-' + pluginName)){ plugin.$element.attr('data-' + pluginName, plugin.uuid); }
59
+ if(!plugin.$element.data('zfPlugin')){ plugin.$element.data('zfPlugin', plugin); }
60
+ /**
61
+ * Fires when the plugin has initialized.
62
+ * @event Plugin#init
63
+ */
64
+ plugin.$element.trigger('init.zf.' + pluginName);
65
+
66
+ this._uuids.push(plugin.uuid);
67
+
68
+ return;
69
+ },
70
+ /**
71
+ * @function
72
+ * Removes the pointer for an instance of a Plugin from the Foundation._activePlugins obj.
73
+ * Also fires the destroyed event for the plugin, consolidating repeditive code.
74
+ * @param {Object} plugin - an instance of a plugin, usually `this` in context.
75
+ * @fires Plugin#destroyed
76
+ */
77
+ unregisterPlugin: function(plugin){
78
+ var pluginName = hyphenate(functionName(plugin.$element.data('zfPlugin').constructor));
79
+
80
+ this._uuids.splice(this._uuids.indexOf(plugin.uuid), 1);
81
+ plugin.$element.removeAttr('data-' + pluginName).removeData('zfPlugin')
82
+ /**
83
+ * Fires when the plugin has been destroyed.
84
+ * @event Plugin#destroyed
85
+ */
86
+ .trigger('destroyed.zf.' + pluginName);
87
+ for(var prop in plugin){
88
+ plugin[prop] = null;//clean up script to prep for garbage collection.
89
+ }
90
+ return;
91
+ },
92
+
93
+ /**
94
+ * @function
95
+ * Causes one or more active plugins to re-initialize, resetting event listeners, recalculating positions, etc.
96
+ * @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'`
97
+ * @default If no argument is passed, reflow all currently active plugins.
98
+ */
99
+ reInit: function(plugins){
100
+ var isJQ = plugins instanceof $;
101
+ try{
102
+ if(isJQ){
103
+ plugins.each(function(){
104
+ $(this).data('zfPlugin')._init();
105
+ });
106
+ }else{
107
+ var type = typeof plugins,
108
+ _this = this,
109
+ fns = {
110
+ 'object': function(plgs){
111
+ plgs.forEach(function(p){
112
+ $('[data-'+ p +']').foundation('_init');
113
+ });
114
+ },
115
+ 'string': function(){
116
+ $('[data-'+ plugins +']').foundation('_init');
117
+ },
118
+ 'undefined': function(){
119
+ this['object'](Object.keys(_this._plugins));
120
+ }
121
+ };
122
+ fns[type](plugins);
123
+ }
124
+ }catch(err){
125
+ console.error(err);
126
+ }finally{
127
+ return plugins;
128
+ }
129
+ },
130
+
131
+ /**
132
+ * returns a random base-36 uid with namespacing
133
+ * @function
134
+ * @param {Number} length - number of random base-36 digits desired. Increase for more random strings.
135
+ * @param {String} namespace - name of plugin to be incorporated in uid, optional.
136
+ * @default {String} '' - if no plugin name is provided, nothing is appended to the uid.
137
+ * @returns {String} - unique id
138
+ */
139
+ GetYoDigits: function(length, namespace){
140
+ length = length || 6;
141
+ return Math.round((Math.pow(36, length + 1) - Math.random() * Math.pow(36, length))).toString(36).slice(1) + (namespace ? '-' + namespace : '');
142
+ },
143
+ /**
144
+ * Initialize plugins on any elements within `elem` (and `elem` itself) that aren't already initialized.
145
+ * @param {Object} elem - jQuery object containing the element to check inside. Also checks the element itself, unless it's the `document` object.
146
+ * @param {String|Array} plugins - A list of plugins to initialize. Leave this out to initialize everything.
147
+ */
148
+ reflow: function(elem, plugins) {
149
+
150
+ // If plugins is undefined, just grab everything
151
+ if (typeof plugins === 'undefined') {
152
+ plugins = Object.keys(this._plugins);
153
+ }
154
+ // If plugins is a string, convert it to an array with one item
155
+ else if (typeof plugins === 'string') {
156
+ plugins = [plugins];
157
+ }
158
+
159
+ var _this = this;
160
+
161
+ // Iterate through each plugin
162
+ $.each(plugins, function(i, name) {
163
+ // Get the current plugin
164
+ var plugin = _this._plugins[name];
165
+
166
+ // Localize the search to all elements inside elem, as well as elem itself, unless elem === document
167
+ var $elem = $(elem).find('[data-'+name+']').addBack('[data-'+name+']');
168
+
169
+ // For each plugin found, initialize it
170
+ $elem.each(function() {
171
+ var $el = $(this),
172
+ opts = {};
173
+ // Don't double-dip on plugins
174
+ if ($el.data('zfPlugin')) {
175
+ console.warn("Tried to initialize "+name+" on an element that already has a Foundation plugin.");
176
+ return;
177
+ }
178
+
179
+ if($el.attr('data-options')){
180
+ var thing = $el.attr('data-options').split(';').forEach(function(e, i){
181
+ var opt = e.split(':').map(function(el){ return el.trim(); });
182
+ if(opt[0]) opts[opt[0]] = parseValue(opt[1]);
183
+ });
184
+ }
185
+ try{
186
+ $el.data('zfPlugin', new plugin($(this), opts));
187
+ }catch(er){
188
+ console.error(er);
189
+ }finally{
190
+ return;
191
+ }
192
+ });
193
+ });
194
+ },
195
+ getFnName: functionName,
196
+ transitionend: function($elem){
197
+ var transitions = {
198
+ 'transition': 'transitionend',
199
+ 'WebkitTransition': 'webkitTransitionEnd',
200
+ 'MozTransition': 'transitionend',
201
+ 'OTransition': 'otransitionend'
202
+ };
203
+ var elem = document.createElement('div'),
204
+ end;
205
+
206
+ for (var t in transitions){
207
+ if (typeof elem.style[t] !== 'undefined'){
208
+ end = transitions[t];
209
+ }
210
+ }
211
+ if(end){
212
+ return end;
213
+ }else{
214
+ end = setTimeout(function(){
215
+ $elem.triggerHandler('transitionend', [$elem]);
216
+ }, 1);
217
+ return 'transitionend';
218
+ }
219
+ }
220
+ };
221
+
222
+
223
+ Foundation.util = {
224
+ /**
225
+ * Function for applying a debounce effect to a function call.
226
+ * @function
227
+ * @param {Function} func - Function to be called at end of timeout.
228
+ * @param {Number} delay - Time in ms to delay the call of `func`.
229
+ * @returns function
230
+ */
231
+ throttle: function (func, delay) {
232
+ var timer = null;
233
+
234
+ return function () {
235
+ var context = this, args = arguments;
236
+
237
+ if (timer === null) {
238
+ timer = setTimeout(function () {
239
+ func.apply(context, args);
240
+ timer = null;
241
+ }, delay);
242
+ }
243
+ };
244
+ }
245
+ };
246
+
247
+ // TODO: consider not making this a jQuery function
248
+ // TODO: need way to reflow vs. re-initialize
249
+ /**
250
+ * The Foundation jQuery method.
251
+ * @param {String|Array} method - An action to perform on the current jQuery object.
252
+ */
253
+ var foundation = function(method) {
254
+ var type = typeof method,
255
+ $meta = $('meta.foundation-mq'),
256
+ $noJS = $('.no-js');
257
+
258
+ if(!$meta.length){
259
+ $('<meta class="foundation-mq">').appendTo(document.head);
260
+ }
261
+ if($noJS.length){
262
+ $noJS.removeClass('no-js');
263
+ }
264
+
265
+ if(type === 'undefined'){//needs to initialize the Foundation object, or an individual plugin.
266
+ Foundation.MediaQuery._init();
267
+ Foundation.reflow(this);
268
+ }else if(type === 'string'){//an individual method to invoke on a plugin or group of plugins
269
+ var args = Array.prototype.slice.call(arguments, 1);//collect all the arguments, if necessary
270
+ var plugClass = this.data('zfPlugin');//determine the class of plugin
271
+
272
+ if(plugClass !== undefined && plugClass[method] !== undefined){//make sure both the class and method exist
273
+ if(this.length === 1){//if there's only one, call it directly.
274
+ plugClass[method].apply(plugClass, args);
275
+ }else{
276
+ this.each(function(i, el){//otherwise loop through the jQuery collection and invoke the method on each
277
+ plugClass[method].apply($(el).data('zfPlugin'), args);
278
+ });
279
+ }
280
+ }else{//error for no class or no method
281
+ throw new ReferenceError("We're sorry, '" + method + "' is not an available method for " + (plugClass ? functionName(plugClass) : 'this element') + '.');
282
+ }
283
+ }else{//error for invalid argument type
284
+ throw new TypeError("We're sorry, '" + type + "' is not a valid parameter. You must use a string representing the method you wish to invoke.");
285
+ }
286
+ return this;
287
+ };
288
+
289
+ window.Foundation = Foundation;
290
+ $.fn.foundation = foundation;
291
+
292
+ // Polyfill for requestAnimationFrame
293
+ (function() {
294
+ if (!Date.now || !window.Date.now)
295
+ window.Date.now = Date.now = function() { return new Date().getTime(); };
296
+
297
+ var vendors = ['webkit', 'moz'];
298
+ for (var i = 0; i < vendors.length && !window.requestAnimationFrame; ++i) {
299
+ var vp = vendors[i];
300
+ window.requestAnimationFrame = window[vp+'RequestAnimationFrame'];
301
+ window.cancelAnimationFrame = (window[vp+'CancelAnimationFrame']
302
+ || window[vp+'CancelRequestAnimationFrame']);
303
+ }
304
+ if (/iP(ad|hone|od).*OS 6/.test(window.navigator.userAgent)
305
+ || !window.requestAnimationFrame || !window.cancelAnimationFrame) {
306
+ var lastTime = 0;
307
+ window.requestAnimationFrame = function(callback) {
308
+ var now = Date.now();
309
+ var nextTime = Math.max(lastTime + 16, now);
310
+ return setTimeout(function() { callback(lastTime = nextTime); },
311
+ nextTime - now);
312
+ };
313
+ window.cancelAnimationFrame = clearTimeout;
314
+ }
315
+ /**
316
+ * Polyfill for performance.now, required by rAF
317
+ */
318
+ if(!window.performance || !window.performance.now){
319
+ window.performance = {
320
+ start: Date.now(),
321
+ now: function(){ return Date.now() - this.start; }
322
+ };
323
+ }
324
+ })();
325
+ if (!Function.prototype.bind) {
326
+ Function.prototype.bind = function(oThis) {
327
+ if (typeof this !== 'function') {
328
+ // closest thing possible to the ECMAScript 5
329
+ // internal IsCallable function
330
+ throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
331
+ }
332
+
333
+ var aArgs = Array.prototype.slice.call(arguments, 1),
334
+ fToBind = this,
335
+ fNOP = function() {},
336
+ fBound = function() {
337
+ return fToBind.apply(this instanceof fNOP
338
+ ? this
339
+ : oThis,
340
+ aArgs.concat(Array.prototype.slice.call(arguments)));
341
+ };
342
+
343
+ if (this.prototype) {
344
+ // native functions don't have a prototype
345
+ fNOP.prototype = this.prototype;
346
+ }
347
+ fBound.prototype = new fNOP();
348
+
349
+ return fBound;
350
+ };
351
+ }
352
+ // Polyfill to get the name of a function in IE9
353
+ function functionName(fn) {
354
+ if (Function.prototype.name === undefined) {
355
+ var funcNameRegex = /function\s([^(]{1,})\(/;
356
+ var results = (funcNameRegex).exec((fn).toString());
357
+ return (results && results.length > 1) ? results[1].trim() : "";
358
+ }
359
+ else if (fn.prototype === undefined) {
360
+ return fn.constructor.name;
361
+ }
362
+ else {
363
+ return fn.prototype.constructor.name;
364
+ }
365
+ }
366
+ function parseValue(str){
367
+ if(/true/.test(str)) return true;
368
+ else if(/false/.test(str)) return false;
369
+ else if(!isNaN(str * 1)) return parseFloat(str);
370
+ return str;
371
+ }
372
+ // Convert PascalCase to kebab-case
373
+ // Thank you: http://stackoverflow.com/a/8955580
374
+ function hyphenate(str) {
375
+ return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
376
+ }
377
+
378
+ }(jQuery);
@@ -0,0 +1,321 @@
1
+ /**
2
+ * Drilldown module.
3
+ * @module foundation.drilldown
4
+ * @requires foundation.util.keyboard
5
+ * @requires foundation.util.motion
6
+ * @requires foundation.util.nest
7
+ */
8
+ !function($, Foundation){
9
+ 'use strict';
10
+
11
+ /**
12
+ * Creates a new instance of a drilldown menu.
13
+ * @class
14
+ * @param {jQuery} element - jQuery object to make into an accordion menu.
15
+ * @param {Object} options - Overrides to the default plugin settings.
16
+ */
17
+ function Drilldown(element, options){
18
+ this.$element = element;
19
+ this.options = $.extend({}, Drilldown.defaults, this.$element.data(), options);
20
+
21
+ Foundation.Nest.Feather(this.$element, 'drilldown');
22
+
23
+ this._init();
24
+
25
+ Foundation.registerPlugin(this, 'Drilldown');
26
+ Foundation.Keyboard.register('Drilldown', {
27
+ 'ENTER': 'open',
28
+ 'SPACE': 'open',
29
+ 'ARROW_RIGHT': 'next',
30
+ 'ARROW_UP': 'up',
31
+ 'ARROW_DOWN': 'down',
32
+ 'ARROW_LEFT': 'previous',
33
+ 'ESCAPE': 'close',
34
+ 'TAB': 'down',
35
+ 'SHIFT_TAB': 'up'
36
+ });
37
+ }
38
+ Drilldown.defaults = {
39
+ /**
40
+ * Markup used for JS generated back button. Prepended to submenu lists and deleted on `destroy` method, 'js-drilldown-back' class required. Remove the backslash (`\`) if copy and pasting.
41
+ * @option
42
+ * @example '<\li><\a>Back<\/a><\/li>'
43
+ */
44
+ backButton: '<li class="js-drilldown-back"><a>Back</a></li>',
45
+ /**
46
+ * 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.
47
+ * @option
48
+ * @example '<\div class="is-drilldown"><\/div>'
49
+ */
50
+ wrapper: '<div></div>',
51
+ /**
52
+ * Allow the menu to return to root list on body click.
53
+ * @option
54
+ * @example false
55
+ */
56
+ closeOnClick: false
57
+ // holdOpen: false
58
+ };
59
+ /**
60
+ * Initializes the drilldown by creating jQuery collections of elements
61
+ * @private
62
+ */
63
+ Drilldown.prototype._init = function(){
64
+ this.$submenuAnchors = this.$element.find('li.has-submenu');
65
+ this.$submenus = this.$submenuAnchors.children('[data-submenu]');
66
+ this.$menuItems = this.$element.find('li').not('.js-drilldown-back').attr('role', 'menuitem');
67
+
68
+ this._prepareMenu();
69
+
70
+ this._keyboardEvents();
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
+ Drilldown.prototype._prepareMenu = function(){
80
+ var _this = this;
81
+ // if(!this.options.holdOpen){
82
+ // this._menuLinkEvents();
83
+ // }
84
+ this.$submenuAnchors.each(function(){
85
+ var $sub = $(this);
86
+ var $link = $sub.find('a:first');
87
+ $link.data('savedHref', $link.attr('href')).removeAttr('href');
88
+ $sub.children('[data-submenu]')
89
+ .attr({
90
+ 'aria-hidden': true,
91
+ 'tabindex': 0,
92
+ 'role': 'menu'
93
+ });
94
+ _this._events($sub);
95
+ });
96
+ this.$submenus.each(function(){
97
+ var $menu = $(this),
98
+ $back = $menu.find('.js-drilldown-back');
99
+ if(!$back.length){
100
+ $menu.prepend(_this.options.backButton);
101
+ }
102
+ _this._back($menu);
103
+ });
104
+ if(!this.$element.parent().hasClass('is-drilldown')){
105
+ this.$wrapper = $(this.options.wrapper).addClass('is-drilldown').css(this._getMaxDims());
106
+ this.$element.wrap(this.$wrapper);
107
+ }
108
+
109
+ };
110
+ /**
111
+ * Adds event handlers to elements in the menu.
112
+ * @function
113
+ * @private
114
+ * @param {jQuery} $elem - the current menu item to add handlers to.
115
+ */
116
+ Drilldown.prototype._events = function($elem){
117
+ var _this = this;
118
+
119
+ $elem.off('click.zf.drilldown')
120
+ .on('click.zf.drilldown', function(e){
121
+ if($(e.target).parentsUntil('ul', 'li').hasClass('is-drilldown-submenu-parent')){
122
+ e.stopImmediatePropagation();
123
+ e.preventDefault();
124
+ }
125
+
126
+ // if(e.target !== e.currentTarget.firstElementChild){
127
+ // return false;
128
+ // }
129
+ _this._show($elem);
130
+
131
+ if(_this.options.closeOnClick){
132
+ var $body = $('body').not(_this.$wrapper);
133
+ $body.off('.zf.drilldown').on('click.zf.drilldown', function(e){
134
+ e.preventDefault();
135
+ _this._hideAll();
136
+ $body.off('.zf.drilldown');
137
+ });
138
+ }
139
+ });
140
+ };
141
+ /**
142
+ * Adds keydown event listener to `li`'s in the menu.
143
+ * @private
144
+ */
145
+ Drilldown.prototype._keyboardEvents = function() {
146
+ var _this = this;
147
+ this.$menuItems.add(this.$element.find('.js-drilldown-back')).on('keydown.zf.drilldown', function(e){
148
+ var $element = $(this),
149
+ $elements = $element.parent('ul').children('li'),
150
+ $prevElement,
151
+ $nextElement;
152
+
153
+ $elements.each(function(i) {
154
+ if ($(this).is($element)) {
155
+ $prevElement = $elements.eq(Math.max(0, i-1));
156
+ $nextElement = $elements.eq(Math.min(i+1, $elements.length-1));
157
+ return;
158
+ }
159
+ });
160
+ Foundation.Keyboard.handleKey(e, 'Drilldown', {
161
+ next: function() {
162
+ if ($element.is(_this.$submenuAnchors)) {
163
+ _this._show($element);
164
+ $element.on(Foundation.transitionend($element), function(){
165
+ $element.find('ul li').filter(_this.$menuItems).first().focus();
166
+ });
167
+ }
168
+ },
169
+ previous: function() {
170
+ _this._hide($element.parent('ul'));
171
+ $element.parent('ul').on(Foundation.transitionend($element), function(){
172
+ setTimeout(function() {
173
+ $element.parent('ul').parent('li').focus();
174
+ }, 1);
175
+ });
176
+ },
177
+ up: function() {
178
+ $prevElement.focus();
179
+ },
180
+ down: function() {
181
+ $nextElement.focus();
182
+ },
183
+ close: function() {
184
+ _this._back();
185
+ //_this.$menuItems.first().focus(); // focus to first element
186
+ },
187
+ open: function() {
188
+ if (!$element.is(_this.$menuItems)) { // not menu item means back button
189
+ _this._hide($element.parent('ul'));
190
+ setTimeout(function(){$element.parent('ul').parent('li').focus();}, 1);
191
+ } else if ($element.is(_this.$submenuAnchors)) {
192
+ _this._show($element);
193
+ setTimeout(function(){$element.find('ul li').filter(_this.$menuItems).first().focus();}, 1);
194
+ }
195
+ },
196
+ handled: function() {
197
+ e.preventDefault();
198
+ e.stopImmediatePropagation();
199
+ }
200
+ });
201
+ }); // end keyboardAccess
202
+ };
203
+
204
+ /**
205
+ * Closes all open elements, and returns to root menu.
206
+ * @function
207
+ * @fires Drilldown#closed
208
+ */
209
+ Drilldown.prototype._hideAll = function(){
210
+ var $elem = this.$element.find('.is-drilldown-sub.is-active').addClass('is-closing');
211
+ $elem.one(Foundation.transitionend($elem), function(e){
212
+ $elem.removeClass('is-active is-closing');
213
+ });
214
+ /**
215
+ * Fires when the menu is fully closed.
216
+ * @event Drilldown#closed
217
+ */
218
+ this.$element.trigger('closed.zf.drilldown');
219
+ };
220
+ /**
221
+ * Adds event listener for each `back` button, and closes open menus.
222
+ * @function
223
+ * @fires Drilldown#back
224
+ * @param {jQuery} $elem - the current sub-menu to add `back` event.
225
+ */
226
+ Drilldown.prototype._back = function($elem){
227
+ var _this = this;
228
+ $elem.off('click.zf.drilldown');
229
+ $elem.children('.js-drilldown-back')
230
+ .on('click.zf.drilldown', function(e){
231
+ e.stopImmediatePropagation();
232
+ // console.log('mouseup on back');
233
+ _this._hide($elem);
234
+ });
235
+ };
236
+ /**
237
+ * Adds event listener to menu items w/o submenus to close open menus on click.
238
+ * @function
239
+ * @private
240
+ */
241
+ Drilldown.prototype._menuLinkEvents = function(){
242
+ var _this = this;
243
+ this.$menuItems.not('.has-submenu')
244
+ .off('click.zf.drilldown')
245
+ .on('click.zf.drilldown', function(e){
246
+ // e.stopImmediatePropagation();
247
+ setTimeout(function(){
248
+ _this._hideAll();
249
+ }, 0);
250
+ });
251
+ };
252
+ /**
253
+ * Opens a submenu.
254
+ * @function
255
+ * @fires Drilldown#open
256
+ * @param {jQuery} $elem - the current element with a submenu to open.
257
+ */
258
+ Drilldown.prototype._show = function($elem){
259
+ $elem.children('[data-submenu]').addClass('is-active');
260
+
261
+ this.$element.trigger('open.zf.drilldown', [$elem]);
262
+ };
263
+ /**
264
+ * Hides a submenu
265
+ * @function
266
+ * @fires Drilldown#hide
267
+ * @param {jQuery} $elem - the current sub-menu to hide.
268
+ */
269
+ Drilldown.prototype._hide = function($elem){
270
+ var _this = this;
271
+ $elem.addClass('is-closing')
272
+ .one(Foundation.transitionend($elem), function(){
273
+ $elem.removeClass('is-active is-closing');
274
+ });
275
+ /**
276
+ * Fires when the submenu is has closed.
277
+ * @event Drilldown#hide
278
+ */
279
+ $elem.trigger('hide.zf.drilldown', [$elem]);
280
+
281
+ };
282
+ /**
283
+ * Iterates through the nested menus to calculate the min-height, and max-width for the menu.
284
+ * Prevents content jumping.
285
+ * @function
286
+ * @private
287
+ */
288
+ Drilldown.prototype._getMaxDims = function(){
289
+ var max = 0, result = {};
290
+ this.$submenus.add(this.$element).each(function(){
291
+ var numOfElems = $(this).children('li').length;
292
+ max = numOfElems > max ? numOfElems : max;
293
+ });
294
+
295
+ result.height = max * this.$menuItems[0].getBoundingClientRect().height + 'px';
296
+ result.width = this.$element[0].getBoundingClientRect().width + 'px';
297
+
298
+ return result;
299
+ };
300
+ /**
301
+ * Destroys the Drilldown Menu
302
+ * @function
303
+ */
304
+ Drilldown.prototype.destroy = function(){
305
+ this._hideAll();
306
+ Foundation.Nest.Burn(this.$element, 'drilldown');
307
+ this.$element.unwrap()
308
+ .find('.js-drilldown-back').remove()
309
+ .end().find('.is-active, .is-closing, .is-drilldown-sub').removeClass('is-active is-closing is-drilldown-sub')
310
+ .end().find('[data-submenu]').removeAttr('aria-hidden tabindex role')
311
+ .off('.zf.drilldown').end().off('zf.drilldown');
312
+ this.$element.find('a').each(function(){
313
+ var $link = $(this);
314
+ if($link.data('savedHref')){
315
+ $link.attr('href', $link.data('savedHref')).removeData('savedHref');
316
+ }else{ return; }
317
+ });
318
+ Foundation.unregisterPlugin(this);
319
+ };
320
+ Foundation.plugin(Drilldown, 'Drilldown');
321
+ }(jQuery, window.Foundation);