ratchet_design 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +21 -0
  3. data/README.md +41 -0
  4. data/app/assets/images/ratchet/favicon.ico +0 -0
  5. data/app/assets/javascripts/ratchet/_svg.js +55 -0
  6. data/app/assets/javascripts/ratchet/base/form.js +220 -0
  7. data/app/assets/javascripts/ratchet/base/mobilemenu.js +62 -0
  8. data/app/assets/javascripts/ratchet/base/validation.js +230 -0
  9. data/app/assets/javascripts/ratchet/core.js +92 -0
  10. data/app/assets/javascripts/ratchet/enhancement/_collapse.js +96 -0
  11. data/app/assets/javascripts/ratchet/enhancement/_lightbox.js +93 -0
  12. data/app/assets/javascripts/ratchet/enhancement/_swap.js +120 -0
  13. data/app/assets/javascripts/ratchet/enhancement/_switcheroo.js +28 -0
  14. data/app/assets/javascripts/ratchet/enhancement/_textcounter.js +92 -0
  15. data/app/assets/javascripts/ratchet/enhancement/loader.js +77 -0
  16. data/app/assets/javascripts/ratchet/enhancement/notice.js +70 -0
  17. data/app/assets/javascripts/ratchet/enhancement/sticky.js +128 -0
  18. data/app/assets/javascripts/ratchet/enhancement/waypoints.js +328 -0
  19. data/app/assets/javascripts/ratchet/shim/classlist.js +234 -0
  20. data/app/assets/javascripts/ratchet/shim/object.assign.js +30 -0
  21. data/app/assets/javascripts/ratchet/utility/compile_data.js +32 -0
  22. data/app/assets/javascripts/ratchet/utility/from_top.js +14 -0
  23. data/app/assets/javascripts/ratchet/utility/full_stop.js +55 -0
  24. data/app/assets/javascripts/ratchet/utility/get_closest.js +20 -0
  25. data/app/assets/javascripts/ratchet/utility/get_next.js +17 -0
  26. data/app/assets/javascripts/ratchet/utility/load_font.js +72 -0
  27. data/app/assets/javascripts/ratchet/utility/load_script.js +34 -0
  28. data/app/assets/javascripts/ratchet/utility/matches.js +15 -0
  29. data/app/assets/javascripts/ratchet/utility/scroll_to.js +74 -0
  30. data/app/assets/javascripts/ratchet/utility/throttle.js +25 -0
  31. data/app/assets/javascripts/ratchet/utility/timeout.js +45 -0
  32. data/app/assets/javascripts/ratchet/utility/unhover.js +56 -0
  33. data/app/assets/javascripts/ratchet/utility/word_count.js +15 -0
  34. data/app/assets/stylesheets/ratchet/_core.scss +20 -0
  35. data/app/assets/stylesheets/ratchet/base/_button.scss +101 -0
  36. data/app/assets/stylesheets/ratchet/base/_document.scss +306 -0
  37. data/app/assets/stylesheets/ratchet/base/_form.scss +614 -0
  38. data/app/assets/stylesheets/ratchet/base/_list.scss +114 -0
  39. data/app/assets/stylesheets/ratchet/base/_media.scss +41 -0
  40. data/app/assets/stylesheets/ratchet/base/_table.scss +81 -0
  41. data/app/assets/stylesheets/ratchet/base/_text.scss +411 -0
  42. data/app/assets/stylesheets/ratchet/enhancement/_contrast-section.scss +22 -0
  43. data/app/assets/stylesheets/ratchet/enhancement/_feature.scss +49 -0
  44. data/app/assets/stylesheets/ratchet/enhancement/_hero.scss +44 -0
  45. data/app/assets/stylesheets/ratchet/enhancement/_loader.scss +109 -0
  46. data/app/assets/stylesheets/ratchet/enhancement/_notice.scss +74 -0
  47. data/app/assets/stylesheets/ratchet/enhancement/_signup.scss +206 -0
  48. data/app/assets/stylesheets/ratchet/enhancement/_sticky-sidebar.scss +36 -0
  49. data/app/assets/stylesheets/ratchet/fonts-woff.css +55 -0
  50. data/app/assets/stylesheets/ratchet/fonts-woff2.css +55 -0
  51. data/app/assets/stylesheets/ratchet/utility/_global.scss +255 -0
  52. data/app/assets/stylesheets/ratchet/utility/_grid.scss +102 -0
  53. data/app/assets/svgs/ratchet/facebook.svg +1 -0
  54. data/app/assets/svgs/ratchet/github.svg +1 -0
  55. data/app/assets/svgs/ratchet/google-plus.svg +1 -0
  56. data/app/assets/svgs/ratchet/ibm.svg +1 -0
  57. data/app/assets/svgs/ratchet/inbox.svg +1 -0
  58. data/app/assets/svgs/ratchet/linkedin.svg +1 -0
  59. data/app/assets/svgs/ratchet/ratchet.svg +1 -0
  60. data/app/assets/svgs/ratchet/search.svg +1 -0
  61. data/app/assets/svgs/ratchet/subscribe.svg +1 -0
  62. data/app/assets/svgs/ratchet/twitter.svg +1 -0
  63. data/app/assets/svgs/ratchet/y-combinator.svg +1 -0
  64. data/app/helpers/ratchet/application_helper.rb +51 -0
  65. data/app/views/layouts/ratchet/default.html.slim +61 -0
  66. data/app/views/shared/ratchet/_footer.html.slim +2 -0
  67. data/app/views/shared/ratchet/_header.html.slim +17 -0
  68. data/app/views/shared/ratchet/_icons.html.slim +89 -0
  69. data/lib/ratchet_design.rb +12 -0
  70. data/lib/ratchet_design/version.rb +3 -0
  71. data/public/assets/ratchet/core-0.1.0.js +103 -0
  72. data/public/assets/ratchet/core-0.1.0.js.gz +0 -0
  73. data/public/assets/ratchet/core-0.1.0.map.json +1 -0
  74. data/public/assets/ratchet/fonts-woff-0.1.0.css +55 -0
  75. data/public/assets/ratchet/fonts-woff-0.1.0.css.gz +0 -0
  76. data/public/assets/ratchet/fonts-woff2-0.1.0.css +55 -0
  77. data/public/assets/ratchet/fonts-woff2-0.1.0.css.gz +0 -0
  78. metadata +177 -0
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Loader 0.0.1
3
+ * Compose loader module
4
+ * @author Kyle Foster (@hkfoster)
5
+ * @license MIT
6
+ **/
7
+
8
+ // Public API function
9
+ var loader = function( settings ) {
10
+
11
+ // Overridable defaults
12
+ var defaults = {
13
+ selector : document.body,
14
+ loaderClass : 'loader',
15
+ loadingMessage : 'Hang tight…',
16
+ loadingClass : 'loading',
17
+ successMessage : 'Got it!',
18
+ successClass : 'success',
19
+ failureMessage : 'Hold up!',
20
+ failureClass : 'failure'
21
+ };
22
+
23
+ // Extend defaults
24
+ var options = Object.assign( {}, defaults, settings );
25
+
26
+ // Create and prepend loader element
27
+ options.selector.insertAdjacentHTML( 'afterbegin', '<div class="' + options.loaderClass + '"></div>' );
28
+
29
+ // Cache loader element
30
+ var element = document.querySelector( 'div.' + options.loaderClass );
31
+
32
+ // Show loader icon function
33
+ var show = function( state ) {
34
+
35
+ // Loader pending state
36
+ if ( state === 'pending' ) {
37
+
38
+ element.textContent = options.loadingMessage;
39
+ element.classList.remove( options.successClass, options.failureClass );
40
+ element.classList.add( options.loadingClass );
41
+
42
+ // Loader failure state
43
+ } else if ( state === 'failure' ) {
44
+
45
+ element.textContent = options.failureMessage;
46
+ element.classList.remove( options.loadingClass );
47
+ element.classList.add( options.failureClass );
48
+
49
+ // Loader success state
50
+ } else if ( state === 'success' ) {
51
+
52
+ element.textContent = options.successMessage;
53
+ element.classList.remove( options.loadingClass );
54
+ element.classList.add( options.successClass );
55
+
56
+ }
57
+
58
+ };
59
+
60
+ // Hide loader icon function
61
+ var hide = function() {
62
+
63
+ // Remove state classes altogether
64
+ element.classList.remove( options.loadingClass, options.successClass, options.failureClass );
65
+
66
+ };
67
+
68
+ // Public functions
69
+ return {
70
+ show : show,
71
+ hide : hide
72
+ };
73
+
74
+ };
75
+
76
+ // Public API
77
+ module.exports = loader;
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Notice 0.0.1
3
+ * Compose notice module
4
+ * @author Kyle Foster (@hkfoster)
5
+ * @license MIT
6
+ **/
7
+
8
+ // Public API function
9
+ var notice = function( element, settings ) {
10
+
11
+ // Overridable defaults
12
+ var defaults = {
13
+ noticeName : 'notice',
14
+ noticeClass : 'notice',
15
+ noticeMessage : '[your notice message here]'
16
+ };
17
+
18
+ // Scoped variables
19
+ var options = Object.assign( {}, defaults, settings ),
20
+ selector = document.querySelector( element ),
21
+ cookieName = 'dismiss-' + options.noticeName;
22
+
23
+ // Only run if selector exists & no dismiss cookie is found
24
+ if ( !selector || getCookie( cookieName ) ) return false;
25
+
26
+ // Uncomment for development
27
+ // deleteCookie( cookieName );
28
+
29
+ // Create and append notice
30
+ var html = '<aside class="' + options.noticeClass + '">' + options.noticeMessage + '<a href="#?" class="close-btn"></a></aside>'
31
+ document.querySelector( 'main' ).insertAdjacentHTML( 'afterbegin', html );
32
+
33
+ // Listen for close button click
34
+ selector.querySelector( '.' + options.noticeClass + ' > .close-btn' ).addEventListener( 'click', dismissNotice, false );
35
+
36
+ // Dismiss notice on close
37
+ function dismissNotice( event ) {
38
+
39
+ // Prevent default behavior
40
+ event.preventDefault();
41
+
42
+ // Cache notice element
43
+ var noticeElem = selector.querySelector( '.' + options.noticeClass );
44
+
45
+ // Remove notice from page
46
+ selector.removeChild( noticeElem );
47
+
48
+ // Set cookie to prevent it from returning
49
+ document.cookie = cookieName + '=true; expires=Fri, 31 Dec 9999 23:59:59 GMT; path=/';
50
+
51
+ }
52
+
53
+ // Check for cookie by name
54
+ function getCookie( name ) {
55
+ var value = '; ' + document.cookie;
56
+ var parts = value.split( '; ' + name + '=' );
57
+ if ( parts.length == 2 ) return parts.pop().split( ';' ).shift();
58
+ }
59
+
60
+ // Delete a cookie by setting the date of expiry to yesterday
61
+ function deleteCookie( name ) {
62
+ var date = new Date();
63
+ date.setDate( date.getDate() -1 );
64
+ document.cookie = escape( name ) + '=;expires=' + date;
65
+ }
66
+
67
+ };
68
+
69
+ // Public API
70
+ module.exports = notice;
@@ -0,0 +1,128 @@
1
+ /**
2
+ * Sticky 0.0.3
3
+ * Compose sticky elements module
4
+ * @author Kyle Foster (@hkfoster)
5
+ * @license MIT
6
+ **/
7
+
8
+ // Dependencies
9
+ var throttle = require( '../utility/throttle' ),
10
+ fromTop = require( '../utility/from_top' );
11
+
12
+ // Public API function
13
+ var sticky = function( element, settings ) {
14
+
15
+ // Overridable defaults
16
+ var defaults = {
17
+ topPadding : false,
18
+ initWidth : '700px',
19
+ stickyClass : 'sticky',
20
+ anchorPoint : null
21
+ };
22
+
23
+ // Scoped variables
24
+ var options = Object.assign( {}, defaults, settings ),
25
+ selector = document.querySelector( element );
26
+
27
+ // If selector is not present
28
+ if ( !selector ) {
29
+
30
+ // Abort
31
+ return false;
32
+
33
+ // Otherwise attach listeners
34
+ } else {
35
+
36
+ // Scoped variables
37
+ var topPadding = ( options.topPadding === true ) ? parseInt( window.getComputedStyle( selector, null ).getPropertyValue( 'padding-top' ) ) : 0,
38
+ widthQuery = window.matchMedia( '(min-width: ' + options.initWidth + ')' ),
39
+ topOffset = fromTop( selector ) + topPadding,
40
+ elemHeight = selector.offsetHeight,
41
+ anchorInit = options.anchorPoint,
42
+ docBody = document.body,
43
+ docHeight,
44
+ winHeight;
45
+
46
+ // Resize throttle function init
47
+ throttle( 'resize', 'optimizedResize' );
48
+
49
+ // Scroll throttle function init
50
+ throttle( 'scroll', 'optimizedScroll' );
51
+
52
+ // Call listener function explicitly at run time
53
+ queryHandler( widthQuery );
54
+
55
+ // Attach listener function to listen in on state changes
56
+ widthQuery.addListener( queryHandler );
57
+
58
+ }
59
+
60
+ // Media query handler function
61
+ function queryHandler( condition ) {
62
+
63
+ // If media query matches
64
+ if ( condition.matches ) {
65
+
66
+ // Call resize listener function explicitly at run time
67
+ resizeHandler();
68
+
69
+ // Resize function listener
70
+ window.addEventListener( 'optimizedResize', resizeHandler, false );
71
+
72
+ // Call scroll listener function explicitly at run time
73
+ scrollHandler();
74
+
75
+ // Scroll function listener
76
+ window.addEventListener( 'optimizedScroll', scrollHandler, false );
77
+
78
+ } else {
79
+
80
+ // Reset styles
81
+ docBody.classList.remove( 'sticky' );
82
+
83
+ // Remove resize listener
84
+ window.removeEventListener( 'optimizedResize', resizeHandler, false );
85
+
86
+ // Remove scroll listener
87
+ window.removeEventListener( 'optimizedScroll', scrollHandler, false );
88
+
89
+ }
90
+
91
+ }
92
+
93
+ // Resize handler function
94
+ function resizeHandler() {
95
+
96
+ // Update document height variable
97
+ docHeight = document.body.scrollHeight;
98
+
99
+ // Update window height variable
100
+ winHeight = window.innerHeight;
101
+
102
+ }
103
+
104
+ // Scroll handler function
105
+ function scrollHandler() {
106
+
107
+ // Scoped variables
108
+ var newScrollY = window.pageYOffset,
109
+ pastOffset = newScrollY > topOffset,
110
+ anchored = ( anchorInit ) ? newScrollY >= docHeight - elemHeight - anchorInit + topPadding : null;
111
+
112
+ // Where the magic happens
113
+ if ( pastOffset && !anchored ) {
114
+ docBody.classList.remove( 'anchored' );
115
+ docBody.classList.add( 'sticky' );
116
+ } else if ( pastOffset && anchored ) {
117
+ docBody.classList.remove( 'sticky' );
118
+ docBody.classList.add( 'anchored' );
119
+ } else {
120
+ docBody.classList.remove( 'sticky' );
121
+ }
122
+
123
+ }
124
+
125
+ };
126
+
127
+ // Public API
128
+ module.exports = sticky;
@@ -0,0 +1,328 @@
1
+ /**
2
+ * Waypoints 0.0.4
3
+ * Compose waypoint navigation module
4
+ * @author Kyle Foster (@hkfoster)
5
+ * @license MIT
6
+ **/
7
+
8
+ // Dependencies
9
+ var matches = require( '../utility/matches' ),
10
+ fromTop = require( '../utility/from_top' ),
11
+ scrollTo = require( '../utility/scroll_to' ),
12
+ getClosest = require( '../utility/get_closest' ),
13
+ throttle = require( '../utility/throttle' );
14
+
15
+ // Public API function
16
+ var waypoints = function( elements, settings ) {
17
+
18
+ // Overridable defaults
19
+ var defaults = {
20
+ initWidth : '700px',
21
+ navigation : '.secondary',
22
+ activeAnchor : 'active',
23
+ elemOffset : 0,
24
+ showLandmarks : false,
25
+ landmarkSelector : '.landmark',
26
+ activeLandmark : 'pinned',
27
+ };
28
+
29
+ // Scoped variables
30
+ var options = Object.assign( {}, defaults, settings ),
31
+ selectors = document.querySelectorAll( elements );
32
+
33
+ // If selectors are not present
34
+ if ( !selectors.length ) {
35
+
36
+ // Abort
37
+ return false;
38
+
39
+ // Otherwise attach listeners
40
+ } else {
41
+
42
+ // Scoped variables
43
+ var navigation = document.querySelector( options.navigation ),
44
+ widthQuery = window.matchMedia( '(min-width: ' + options.initWidth + ')' ),
45
+ coordinates = [],
46
+ oldActiveItem,
47
+ windowHash,
48
+ docHeight,
49
+ winHeight;
50
+
51
+ // If hash is present
52
+ if ( window.location.hash ) {
53
+
54
+ // Cache it
55
+ windowHash = window.location.hash.replace( '#', '' );
56
+
57
+ // Then delete it to prevent default page scroll
58
+ window.location.hash = '';
59
+
60
+ // And replace it
61
+ history.replaceState( null, '', '#' + windowHash );
62
+
63
+ }
64
+
65
+ // Resize throttle function init
66
+ throttle( 'resize', 'optimizedResize' );
67
+
68
+ // Scroll throttle function init
69
+ throttle( 'scroll', 'optimizedScroll' );
70
+
71
+ // Only run once the window is loaded
72
+ window.addEventListener( 'load', function() {
73
+
74
+ // Call listener function explicitly at run time
75
+ queryHandler( widthQuery );
76
+
77
+ // Attach listener function to listen in on state changes
78
+ widthQuery.addListener( queryHandler );
79
+
80
+ }, false );
81
+
82
+ }
83
+
84
+ // Media query handler function
85
+ function queryHandler( condition ) {
86
+
87
+ // If media query matches
88
+ if ( condition.matches ) {
89
+
90
+ // Call resize listener function explicitly at run time
91
+ resizeHandler();
92
+
93
+ // Resize throttle function init
94
+ window.addEventListener( 'optimizedResize', resizeHandler, false );
95
+
96
+ // Call scroll listener function explicitly at run time
97
+ scrollHandler();
98
+
99
+ // Scroll function listener
100
+ window.addEventListener( 'optimizedScroll', scrollHandler, false );
101
+
102
+ // Click function listener
103
+ navigation.addEventListener( 'click', clickHandler, false );
104
+
105
+ // Call hash change listener function explicitly at run time
106
+ hashHandler();
107
+
108
+ // Hash change function listener
109
+ window.addEventListener( 'hashchange', hashHandler, false );
110
+
111
+ // Otherwise…
112
+ } else {
113
+
114
+ // Remove resize listener
115
+ window.removeEventListener( 'optimizedResize', resizeHandler, false );
116
+
117
+ // Remove scroll listener
118
+ window.removeEventListener( 'optimizedScroll', scrollHandler, false );
119
+
120
+ // Remove click listener
121
+ navigation.removeEventListener( 'click', clickHandler, false );
122
+
123
+ // Remove hash change listener
124
+ window.removeEventListener( 'hashchange', hashHandler, false );
125
+
126
+ }
127
+
128
+ }
129
+
130
+ // Resize handler function
131
+ function resizeHandler() {
132
+
133
+ // Update document height variable
134
+ docHeight = document.body.scrollHeight;
135
+
136
+ // Update window height variable
137
+ winHeight = window.innerHeight;
138
+
139
+ // Loop through waypoints
140
+ for ( var i = 0; i < selectors.length; i++ ) {
141
+
142
+ // Construct coordinate object
143
+ var coordinate = {
144
+ elem : selectors[ i ],
145
+ offset : fromTop( selectors[ i ] )
146
+ };
147
+
148
+ // And update coordinates array
149
+ coordinates[ i ] = coordinate;
150
+
151
+ }
152
+
153
+ }
154
+
155
+ // Scroll handler function
156
+ function scrollHandler() {
157
+
158
+ // Scoped variables
159
+ var newScrollY = window.pageYOffset,
160
+ rockBottom = newScrollY < 0 || newScrollY + winHeight >= docHeight,
161
+ newActiveItem,
162
+ activeLink,
163
+ landmark;
164
+
165
+ // Loop through coordinates
166
+ for ( var i = 0; i < coordinates.length; i++ ) {
167
+
168
+ // Scoped variables
169
+ var firstWaypoint = coordinates[ 0 ],
170
+ currWaypoint = coordinates[ i ],
171
+ nextWaypoint = coordinates[ i + 1 ],
172
+ lastWaypoint = coordinates[ coordinates.length - 1 ];
173
+
174
+ // If scrolled to last waypoint
175
+ if ( newScrollY < firstWaypoint.offset ) {
176
+
177
+ // Set active item to first waypoint
178
+ newActiveItem = firstWaypoint.elem.id;
179
+
180
+ // If scrolled to bottom of page or on past the last waypoint
181
+ } else if ( rockBottom || newScrollY > lastWaypoint.offset - options.elemOffset ) {
182
+
183
+ // Set active item to last waypoint
184
+ newActiveItem = lastWaypoint.elem.id;
185
+
186
+ // Otherwise if a waypoint is in the viewport
187
+ } else if ( newScrollY > currWaypoint.offset - options.elemOffset && newScrollY < nextWaypoint.offset - options.elemOffset ) {
188
+
189
+ // Update active item to match
190
+ newActiveItem = currWaypoint.elem.id;
191
+
192
+ }
193
+
194
+ }
195
+
196
+ // If active item exists
197
+ if ( newActiveItem ) {
198
+
199
+ // Only run when new active item is triggered
200
+ if ( newActiveItem === oldActiveItem ) return false;
201
+
202
+ // Update active link
203
+ activeLink = navigation.querySelector( 'a[href="#' + newActiveItem + '"]' );
204
+
205
+ // If no active link is found, abort
206
+ if ( !activeLink ) return false;
207
+
208
+ // And enable navigation item
209
+ activate( navigation, activeLink, options.activeAnchor );
210
+
211
+ // If landmarks are turned on
212
+ if ( options.showLandmarks === true ) {
213
+
214
+ // Set active landmark to active link’s parent
215
+ landmark = getClosest( activeLink, options.landmarkSelector );
216
+
217
+ // Enable active landmark
218
+ activate( navigation, landmark, options.activeLandmark );
219
+
220
+ }
221
+
222
+ // Update old active item variable
223
+ oldActiveItem = newActiveItem;
224
+
225
+ }
226
+
227
+ }
228
+
229
+ // Click handler function
230
+ function clickHandler( event ) {
231
+
232
+ // Prevent default behavior
233
+ event.preventDefault();
234
+
235
+ // Matches selector function init
236
+ if ( matches( event.target, 'a[href^="#"]' ) ) {
237
+
238
+ // Travel to clicked target
239
+ travel( event.target, 'click' );
240
+
241
+ }
242
+ }
243
+
244
+ // Hash change handler function
245
+ function hashHandler() {
246
+
247
+ // Only run when a hash is present
248
+ if ( !window.location.hash ) return false;
249
+
250
+ // Find the hash’s relevant navigation item
251
+ var hashAnchor = document.querySelector( 'a[href="' + window.location.hash + '"]' );
252
+
253
+ // And travel to its target
254
+ travel( hashAnchor, 'hash' );
255
+
256
+ }
257
+
258
+ // Window scroll travel function
259
+ function travel( destination, trigger ) {
260
+
261
+ // Define scoped variable(s)
262
+ var targetAnchor = destination.href.split( '#' )[ 1 ],
263
+ targetElement = document.querySelector( '#' + targetAnchor ),
264
+ targetOffset,
265
+ travelTime;
266
+
267
+ // If a target element exists
268
+ if ( targetElement ) {
269
+
270
+ // Enable new active navigation item
271
+ activate( navigation, destination, options.activeAnchor );
272
+
273
+ // Loop through coordinates
274
+ for ( var i = 0; i < coordinates.length; i++ ) {
275
+
276
+ // If coordinate element matches target element
277
+ if ( coordinates[ i ].elem === targetElement ) {
278
+
279
+ // Assign its coordinates to target offset variable
280
+ targetOffset = coordinates[ i ].offset;
281
+ }
282
+ }
283
+
284
+ // If trigger was a click
285
+ if ( trigger === 'click' ) {
286
+
287
+ // Temporarily remove scroll listener function
288
+ window.removeEventListener( 'optimizedScroll', scrollHandler, false );
289
+
290
+ // Update the hash
291
+ history.pushState( null, '', '#' + targetAnchor );
292
+
293
+ // Animate scroll to appropriate element
294
+ scrollTo( targetOffset - options.elemOffset + 1, function() {
295
+
296
+ // Once scroll is complete, enable scroll listener
297
+ window.addEventListener( 'optimizedScroll', scrollHandler, false );
298
+
299
+ });
300
+
301
+ // Otherwise if trigger was a hash
302
+ } else if ( trigger === 'hash' ) {
303
+
304
+ // Skip the scroll animation
305
+ window.scrollTo( 0, targetOffset - options.elemOffset + 1 );
306
+
307
+ }
308
+ }
309
+ }
310
+
311
+ // Link activation function
312
+ function activate( container, selector, cls ) {
313
+
314
+ // Find currently active link
315
+ var activeLink = container.querySelector( '.' + cls );
316
+
317
+ // And if it exists, disable it
318
+ if ( activeLink ) activeLink.classList.remove( cls );
319
+
320
+ // Then enable the passed selector
321
+ selector.classList.add( cls );
322
+
323
+ }
324
+
325
+ };
326
+
327
+ // Public API
328
+ module.exports = waypoints;