ratchet_design 0.1.5 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/images/ratchet/favicon.ico +0 -0
  3. data/app/assets/javascripts/ratchet/base/form.js +117 -8
  4. data/app/assets/javascripts/ratchet/base/mobilemenu.js +50 -12
  5. data/app/assets/javascripts/ratchet/base/validation.js +263 -0
  6. data/app/assets/javascripts/ratchet/core.js +78 -57
  7. data/app/assets/javascripts/ratchet/enhancement/_collapse.js +6 -3
  8. data/app/assets/javascripts/ratchet/enhancement/_lightbox.js +93 -0
  9. data/app/assets/javascripts/ratchet/enhancement/_swap.js +7 -3
  10. data/app/assets/javascripts/ratchet/{utility → enhancement}/loader.js +8 -15
  11. data/app/assets/javascripts/ratchet/enhancement/notice.js +3 -8
  12. data/app/assets/javascripts/ratchet/enhancement/sticky.js +35 -18
  13. data/app/assets/javascripts/ratchet/enhancement/waypoints.js +162 -125
  14. data/app/assets/javascripts/ratchet/shim/classlist.js +234 -0
  15. data/app/assets/javascripts/ratchet/shim/object.assign.js +30 -0
  16. data/app/assets/javascripts/ratchet/utility/ajax.js +122 -0
  17. data/app/assets/javascripts/ratchet/utility/compile_data.js +40 -0
  18. data/app/assets/javascripts/ratchet/utility/from_top.js +14 -0
  19. data/app/assets/javascripts/ratchet/utility/full_stop.js +55 -0
  20. data/app/assets/javascripts/ratchet/utility/get_closest.js +20 -0
  21. data/app/assets/javascripts/ratchet/utility/get_next.js +17 -0
  22. data/app/assets/javascripts/ratchet/utility/matches.js +15 -0
  23. data/app/assets/javascripts/ratchet/utility/scroll_to.js +74 -0
  24. data/app/assets/javascripts/ratchet/utility/throttle.js +25 -0
  25. data/app/assets/javascripts/ratchet/utility/timeout.js +45 -0
  26. data/app/assets/javascripts/ratchet/utility/unhover.js +56 -0
  27. data/app/assets/javascripts/ratchet/utility/word_count.js +15 -0
  28. data/app/assets/stylesheets/ratchet/_core.scss +2 -4
  29. data/app/assets/stylesheets/ratchet/base/_button.scss +1 -1
  30. data/app/assets/stylesheets/ratchet/base/_form.scss +50 -61
  31. data/app/assets/stylesheets/ratchet/base/_text.scss +8 -8
  32. data/app/assets/stylesheets/ratchet/{utility → enhancement}/_loader.scss +1 -1
  33. data/app/assets/stylesheets/ratchet/enhancement/_tooltip.scss +1 -6
  34. data/app/assets/stylesheets/ratchet/utility/_global.scss +12 -2
  35. data/app/helpers/ratchet/application_helper.rb +2 -28
  36. data/app/views/layouts/ratchet/default.html.slim +4 -5
  37. data/app/views/shared/ratchet/_footer.html.slim +2 -3
  38. data/app/views/shared/ratchet/_header.html.slim +1 -1
  39. data/lib/ratchet_design/version.rb +1 -1
  40. data/lib/ratchet_design.rb +0 -1
  41. data/public/assets/ratchet/core-0.1.6.js +105 -0
  42. data/public/assets/ratchet/core-0.1.6.js.gz +0 -0
  43. data/public/assets/ratchet/core-0.1.6.map.json +1 -0
  44. data/public/assets/ratchet/{fonts-woff-0.1.5.css → fonts-woff-0.1.6.css} +0 -0
  45. data/public/assets/ratchet/{fonts-woff-0.1.5.css.gz → fonts-woff-0.1.6.css.gz} +0 -0
  46. data/public/assets/ratchet/{fonts-woff2-0.1.5.css → fonts-woff2-0.1.6.css} +0 -0
  47. data/public/assets/ratchet/{fonts-woff2-0.1.5.css.gz → fonts-woff2-0.1.6.css.gz} +0 -0
  48. metadata +28 -47
  49. data/app/assets/images/ratchet/safari-pinned-tab.svg +0 -1
  50. data/app/assets/javascripts/ratchet/base/sync-input-value.js +0 -30
  51. data/app/assets/javascripts/ratchet/enhancement/lightbox.js +0 -165
  52. data/app/assets/javascripts/ratchet/shim/scope.js +0 -94
  53. data/app/assets/stylesheets/ratchet/base/_multistep-form.scss +0 -64
  54. data/app/assets/stylesheets/ratchet/enhancement/_lightbox.scss +0 -98
  55. data/app/helpers/ratchet/form_helper.rb +0 -140
  56. data/public/assets/ratchet/core-0.1.5.js +0 -133
  57. data/public/assets/ratchet/core-0.1.5.js.gz +0 -0
  58. data/public/assets/ratchet/core-0.1.5.map.json +0 -1
@@ -6,93 +6,129 @@
6
6
  **/
7
7
 
8
8
  // Dependencies
9
- var toolbox = require( 'compose-toolbox' ),
10
- Event = toolbox.event,
11
- matches = toolbox.matches,
12
- fromTop = toolbox.fromTop,
13
- scrollTo = toolbox.scrollTo,
14
- getClosest = toolbox.getClosest,
15
- callback = Event.callback;
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' );
16
14
 
17
15
  // Public API function
18
- var waypoints = function( settings ) {
16
+ var waypoints = function( elements, settings ) {
19
17
 
20
18
  // Overridable defaults
21
19
  var defaults = {
22
- initWidth : '0px',
23
- elemOffset : 0
24
- }
25
-
26
- function slice( obj, count ) {
27
- return Array.prototype.slice.call( obj, count )
28
- }
20
+ initWidth : '700px',
21
+ activeAnchor : 'active',
22
+ elemOffset : 0,
23
+ showLandmarks : false,
24
+ landmarkSelector : '.landmark',
25
+ activeLandmark : 'pinned',
26
+ };
29
27
 
30
28
  // Scoped variables
31
- var options = toolbox.merge( defaults, settings ),
32
- activeAnchor = 'active',
33
- landmarkSelector = 'dl',
34
- activeLandmark = 'pinned',
35
- nav = document.querySelector('.waypoint-nav'),
36
- elements = [];
29
+ var options = Object.assign( {}, defaults, settings ),
30
+ selectors = document.querySelectorAll( elements );
37
31
 
38
- if ( nav ) slice( nav.querySelectorAll( "a[href^='#']" ) ).forEach( function( el ) {
32
+ // If selectors are not present
33
+ if ( !selectors.length ) {
39
34
 
40
- // Find all elements matching links in the waypoints nav
41
- var section = document.querySelector( el.getAttribute('href') )
35
+ // Abort
36
+ return false;
42
37
 
43
- // If found, add them to the elements list
44
- if ( section ) elements.push( section )
38
+ // Otherwise attach listeners
39
+ } else {
45
40
 
46
- })
41
+ // Scoped variables
42
+ var initWidth = options.initWidth ? options.initWidth : '0px',
43
+ widthQuery = window.matchMedia( '(min-width: ' + initWidth + ')' ),
44
+ docBody = document.body,
45
+ coordinates = [],
46
+ oldActiveItem,
47
+ windowHash,
48
+ docHeight,
49
+ winHeight;
47
50
 
48
- if ( !nav || elements.length < 1 ) { return false }
51
+ // If hash is present
52
+ if ( window.location.hash ) {
49
53
 
50
- // Scoped variables
51
- var docBody = document.body,
52
- coordinates = [],
53
- oldActiveItem,
54
- windowHash,
55
- docHeight,
56
- winHeight;
54
+ // Cache it
55
+ windowHash = window.location.hash.replace( '#', '' );
56
+
57
+ // Then delete it to prevent default page scroll
58
+ window.location.hash = '';
57
59
 
58
- // If hash is present
59
- if ( window.location.hash ) {
60
+ // And replace it
61
+ history.replaceState( null, '', '#' + windowHash );
60
62
 
61
- // Cache it
62
- windowHash = window.location.hash.replace( '#', '' );
63
+ }
64
+
65
+ // Resize throttle function init
66
+ throttle( 'resize', 'optimizedResize' );
67
+
68
+ // Scroll throttle function init
69
+ throttle( 'scroll', 'optimizedScroll' );
63
70
 
64
- // Then delete it to prevent default page scroll
65
- window.location.hash = '';
71
+ // Only run once the window is loaded
72
+ window.addEventListener( 'load', function() {
66
73
 
67
- // And replace it
68
- history.replaceState( null, '', '#' + windowHash );
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 );
69
81
 
70
82
  }
71
83
 
72
- // Only run once the window is loaded
73
- Event.on( window, 'load', function() {
84
+ // Media query handler function
85
+ function queryHandler( condition ) {
86
+
87
+ // If media query matches
88
+ if ( condition.matches ) {
74
89
 
75
- // Media query handler function
76
- Event.media.minWidth( options.initWidth, function( condition ) {
90
+ // Call resize listener function explicitly at run time
91
+ resizeHandler();
77
92
 
78
- // Set up resize listener
79
- resize.toggle( condition.matches )
80
- resize()
93
+ // Resize throttle function init
94
+ window.addEventListener( 'optimizedResize', resizeHandler, false );
81
95
 
82
- // Set up scroll listener
83
- scroll.toggle( condition.matches )
84
- scroll()
85
-
86
- // Set up hash change listener
87
- hashChange.toggle( condition.matches )
88
- hashChange()
96
+ // Call scroll listener function explicitly at run time
97
+ scrollHandler();
89
98
 
90
- })
99
+ // Scroll function listener
100
+ window.addEventListener( 'optimizedScroll', scrollHandler, false );
91
101
 
92
- })
102
+ // Click function listener
103
+ docBody.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
+ docBody.removeEventListener( 'click', clickHandler, false );
122
+
123
+ // Remove hash change listener
124
+ window.removeEventListener( 'hashchange', hashHandler, false );
125
+
126
+ }
127
+
128
+ }
93
129
 
94
130
  // Resize handler function
95
- var resize = callback.new( function() {
131
+ function resizeHandler() {
96
132
 
97
133
  // Update document height variable
98
134
  docHeight = docBody.scrollHeight;
@@ -101,22 +137,23 @@ var waypoints = function( settings ) {
101
137
  winHeight = window.innerHeight;
102
138
 
103
139
  // Loop through waypoints
104
- setCoordinates()
140
+ for ( var i = 0; i < selectors.length; i++ ) {
105
141
 
106
- })
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
+ }
107
152
 
108
- // Store coordinates to elements
109
- var setCoordinates = function() {
110
- elements.forEach( function( element, i ) {
111
- coordinates[ i ] = {
112
- elem : elements[ i ],
113
- offset : fromTop( elements[ i ] )
114
- }
115
- })
116
153
  }
117
154
 
118
155
  // Scroll handler function
119
- var scroll = callback.new( function() {
156
+ function scrollHandler() {
120
157
 
121
158
  // Scoped variables
122
159
  var newScrollY = window.pageYOffset,
@@ -126,10 +163,11 @@ var waypoints = function( settings ) {
126
163
  landmark;
127
164
 
128
165
  // Loop through coordinates
129
- coordinates.forEach( function( currWaypoint, i ) {
166
+ for ( var i = 0; i < coordinates.length; i++ ) {
130
167
 
131
168
  // Scoped variables
132
169
  var firstWaypoint = coordinates[ 0 ],
170
+ currWaypoint = coordinates[ i ],
133
171
  nextWaypoint = coordinates[ i + 1 ],
134
172
  lastWaypoint = coordinates[ coordinates.length - 1 ];
135
173
 
@@ -153,65 +191,76 @@ var waypoints = function( settings ) {
153
191
 
154
192
  }
155
193
 
156
- })
194
+ }
157
195
 
158
196
  // If active item exists
159
197
  if ( newActiveItem ) {
160
198
 
161
199
  // Only run when new active item is triggered
162
- if ( newActiveItem === oldActiveItem ) return false
200
+ if ( newActiveItem === oldActiveItem ) return false;
163
201
 
164
202
  // Update active link
165
- activeLink = nav.querySelector( 'a[href="#' + newActiveItem + '"]' )
203
+ activeLink = docBody.querySelector( 'a[href="#' + newActiveItem + '"]' );
166
204
 
167
205
  // If no active link is found, abort
168
- if ( !activeLink ) return false
206
+ if ( !activeLink ) return false;
169
207
 
170
208
  // And enable navigation item
171
- activateLink( activeLink )
209
+ activate( 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( landmark, options.activeLandmark );
219
+
220
+ }
172
221
 
173
222
  // Update old active item variable
174
- oldActiveItem = newActiveItem
223
+ oldActiveItem = newActiveItem;
175
224
 
176
225
  }
177
226
 
178
- })
227
+ }
179
228
 
180
229
  // Click handler function
181
- var click = callback.new( function( event ) {
230
+ function clickHandler( event ) {
182
231
 
183
232
  // Matches selector function init
184
233
  if ( matches( event.target, 'a[href^="#"]' ) ) {
185
234
 
186
235
  // Prevent default behavior
187
- event.preventDefault()
236
+ event.preventDefault();
188
237
 
189
238
  // Travel to clicked target
190
- travel( event.target, true )
239
+ travel( event.target, 'click' );
191
240
 
192
241
  }
193
- })
242
+ }
194
243
 
195
244
  // Hash change handler function
196
- var hashChange = callback.new( function() {
245
+ function hashHandler() {
197
246
 
198
247
  // Only run when a hash is present
199
- if ( !window.location.hash ) return false
248
+ if ( !window.location.hash ) return false;
200
249
 
201
250
  // Find the hash’s relevant navigation item
202
- var hashAnchor = document.querySelector( 'a[href="' + window.location.hash + '"]' )
251
+ var hashAnchor = document.querySelector( 'a[href="' + window.location.hash + '"]' );
203
252
 
204
253
  // And travel to its target
205
- travel( hashAnchor )
254
+ travel( hashAnchor, 'hash' );
206
255
 
207
- })
256
+ }
208
257
 
209
258
  // Window scroll travel function
210
- var travel = function( destination, animateScroll ) {
259
+ function travel( destination, trigger ) {
211
260
 
212
261
  // Define scoped variable(s)
213
- var targetAnchor = destination.getAttribute('href'),
214
- targetElement = document.querySelector( targetAnchor ),
262
+ var targetAnchor = destination.href.split( '#' )[ 1 ],
263
+ targetElement = document.querySelector( '#' + targetAnchor ),
215
264
  targetOffset,
216
265
  travelTime;
217
266
 
@@ -219,10 +268,10 @@ var waypoints = function( settings ) {
219
268
  if ( targetElement ) {
220
269
 
221
270
  // Enable new active navigation item
222
- activateLink( destination, activeAnchor )
271
+ activate( destination, options.activeAnchor );
223
272
 
224
273
  // Loop through coordinates
225
- coordinates.forEach( function( current, i ) {
274
+ for ( var i = 0; i < coordinates.length; i++ ) {
226
275
 
227
276
  // If coordinate element matches target element
228
277
  if ( coordinates[ i ].elem === targetElement ) {
@@ -230,61 +279,49 @@ var waypoints = function( settings ) {
230
279
  // Assign its coordinates to target offset variable
231
280
  targetOffset = coordinates[ i ].offset;
232
281
  }
233
- })
282
+ }
234
283
 
235
284
  // If trigger was a click
236
- if ( animateScroll ) {
285
+ if ( trigger === 'click' ) {
237
286
 
238
287
  // Temporarily remove scroll listener function
239
- scroll.stop()
288
+ window.removeEventListener( 'optimizedScroll', scrollHandler, false );
240
289
 
241
290
  // Update the hash
242
- history.pushState( null, '', targetAnchor );
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 );
243
298
 
244
- // Animate scroll to appropriate element then renable scroll listener
245
- scrollTo( targetElement, scroll.start )
299
+ });
246
300
 
247
- } else {
301
+ // Otherwise if trigger was a hash
302
+ } else if ( trigger === 'hash' ) {
248
303
 
249
304
  // Skip the scroll animation
250
- window.scrollTo( 0, fromTop( targetElement ) );
305
+ window.scrollTo( 0, targetOffset - options.elemOffset + 1 );
251
306
 
252
307
  }
253
308
  }
254
309
  }
255
310
 
256
- function activate( el, classname ) {
311
+ // Link activation function
312
+ function activate( selector, cls ) {
257
313
 
258
314
  // Find currently active link
259
- var activeEl = nav.querySelector( '.' + classname )
260
-
261
- if ( activeEl == el ) return
315
+ var activeLink = docBody.querySelector( '.' + cls );
262
316
 
263
- // remove active class from existing element
264
- if ( activeEl ) activeEl.classList.remove( classname )
317
+ // And if it exists, disable it
318
+ if ( activeLink ) activeLink.classList.remove( cls );
265
319
 
266
320
  // Then enable the passed selector
267
- el.classList.add( classname )
268
-
269
- }
270
-
271
- // Link activation function
272
- function activateLink( el ) {
273
- activate( el, activeAnchor )
321
+ selector.classList.add( cls );
274
322
 
275
- // Set active landmark to active link’s parent
276
- activateLandmark( getClosest( el, landmarkSelector ) )
277
323
  }
278
324
 
279
- function activateLandmark( el ) {
280
- if ( el ) activate( el, activeLandmark )
281
- }
282
-
283
- Event.resize.stop( resize )
284
- Event.scroll( scroll )
285
- Event.on( document, 'click', click )
286
- Event.on( window, 'hashchange', hashChange )
287
-
288
325
  };
289
326
 
290
327
  // Public API
@@ -0,0 +1,234 @@
1
+ /**
2
+ * ClassList
3
+ * Cross-browser full element.classList implementation
4
+ * @source http://purl.eligrey.com/github/classList.js/blob/master/classList.js
5
+ * @author Eli Grey - http://eligrey.com
6
+ * @license MIT
7
+ **/
8
+
9
+ if ( 'document' in self ) {
10
+
11
+ // Full polyfill for browsers with no classList support
12
+ if ( !( 'classList' in document.createElement( '_' ) ) ) {
13
+
14
+ ( function( view ) {
15
+
16
+ 'use strict';
17
+
18
+ if ( !( 'Element' in view ) ) return;
19
+
20
+ var
21
+ classListProp = 'classList',
22
+ protoProp = 'prototype',
23
+ elemCtrProto = view.Element[ protoProp ],
24
+ objCtr = Object,
25
+
26
+ strTrim = String[ protoProp ].trim || function() {
27
+ return this.replace( /^\s+|\s+$/g, '' );
28
+ },
29
+
30
+ arrIndexOf = Array[ protoProp ].indexOf || function( item ) {
31
+ for ( var i = 0; i < this.length; i++ ) {
32
+ if ( i in this && this[ i ] === item ) {
33
+ return i;
34
+ }
35
+ }
36
+ return -1;
37
+ },
38
+
39
+ DOMEx = function( type, message ) {
40
+ this.name = type;
41
+ this.code = DOMException[ type ];
42
+ this.message = message;
43
+ },
44
+
45
+ checkTokenAndGetIndex = function( classList, token ) {
46
+ if ( token === '' ) {
47
+ throw new DOMEx(
48
+ 'SYNTAX_ERR',
49
+ 'An invalid or illegal string was specified'
50
+ );
51
+ }
52
+ if ( /\s/.test( token ) ) {
53
+ throw new DOMEx(
54
+ 'INVALID_CHARACTER_ERR',
55
+ 'String contains an invalid character'
56
+ );
57
+ }
58
+ return arrIndexOf.call( classList, token );
59
+ },
60
+
61
+ ClassList = function( elem ) {
62
+ var trimmedClasses = strTrim.call( elem.getAttribute( 'class' ) || '' ),
63
+ classes = trimmedClasses ? trimmedClasses.split( /\s+/ ) : [];
64
+
65
+ for ( var i = 0; i < classes.length; i++ ) {
66
+ this.push( classes[ i ] );
67
+ }
68
+
69
+ this._updateClassName = function() {
70
+ elem.setAttribute( 'class', this.toString() );
71
+ };
72
+ },
73
+
74
+ classListProto = ClassList[ protoProp ] = [],
75
+
76
+ classListGetter = function() {
77
+ return new ClassList( this );
78
+ };
79
+
80
+ DOMEx[ protoProp ] = Error[ protoProp ];
81
+
82
+ classListProto.item = function( i ) {
83
+ return this[ i ] || null;
84
+ };
85
+
86
+ classListProto.contains = function( token ) {
87
+ token += '';
88
+ return checkTokenAndGetIndex( this, token ) !== -1;
89
+ };
90
+
91
+ classListProto.add = function() {
92
+ var
93
+ tokens = arguments,
94
+ iter = 0,
95
+ len = tokens.length,
96
+ updated = false,
97
+ token;
98
+
99
+ do {
100
+ token = tokens[ iter ] + '';
101
+ if ( checkTokenAndGetIndex( this, token ) === -1 ) {
102
+ this.push( token );
103
+ updated = true;
104
+ }
105
+ }
106
+
107
+ while ( ++iter < len );
108
+
109
+ if ( updated ) {
110
+ this._updateClassName();
111
+ }
112
+ };
113
+
114
+ classListProto.remove = function() {
115
+ var
116
+ tokens = arguments,
117
+ iter = 0,
118
+ len = tokens.length,
119
+ updated = false,
120
+ token,
121
+ index;
122
+
123
+ do {
124
+ token = tokens[ iter ] + '';
125
+ index = checkTokenAndGetIndex( this, token );
126
+
127
+ while ( index !== -1 ) {
128
+ this.splice( index, 1 );
129
+ updated = true;
130
+ index = checkTokenAndGetIndex( this, token );
131
+ }
132
+ }
133
+
134
+ while ( ++iter < len );
135
+
136
+ if ( updated ) {
137
+ this._updateClassName();
138
+ }
139
+ };
140
+
141
+ classListProto.toggle = function( token, force ) {
142
+ token += '';
143
+
144
+ var
145
+ result = this.contains( token ),
146
+ method = result ? force !== true && 'remove' : force !== false && 'add';
147
+
148
+ if ( method ) {
149
+ this[ method ]( token );
150
+ }
151
+
152
+ if ( force === true || force === false ) {
153
+ return force;
154
+ } else {
155
+ return !result;
156
+ }
157
+ };
158
+
159
+ classListProto.toString = function() {
160
+ return this.join( ' ' );
161
+ };
162
+
163
+ if ( objCtr.defineProperty ) {
164
+ var classListPropDesc = {
165
+ get : classListGetter,
166
+ enumerable : true,
167
+ configurable : true
168
+ };
169
+
170
+ try {
171
+ objCtr.defineProperty( elemCtrProto, classListProp, classListPropDesc );
172
+ }
173
+
174
+ catch ( ex ) {
175
+ if ( ex.number === -0x7FF5EC54 ) {
176
+ classListPropDesc.enumerable = false;
177
+ objCtr.defineProperty( elemCtrProto, classListProp, classListPropDesc );
178
+ }
179
+ }
180
+
181
+ } else if ( objCtr[ protoProp ].__defineGetter__ ) {
182
+ elemCtrProto.__defineGetter__( classListProp, classListGetter );
183
+ }
184
+
185
+ }( self ));
186
+
187
+ } else {
188
+
189
+ ( function() {
190
+
191
+ 'use strict';
192
+
193
+ var testElement = document.createElement( '_' );
194
+
195
+ testElement.classList.add( 'c1', 'c2' );
196
+
197
+ if ( !testElement.classList.contains( 'c2' ) ) {
198
+ var createMethod = function( method ) {
199
+ var original = DOMTokenList.prototype[ method ];
200
+
201
+ DOMTokenList.prototype[ method ] = function( token ) {
202
+ var i, len = arguments.length;
203
+
204
+ for ( i = 0; i < len; i++ ) {
205
+ token = arguments[ i ];
206
+ original.call( this, token );
207
+ }
208
+ };
209
+ };
210
+ createMethod( 'add' );
211
+ createMethod( 'remove' );
212
+ }
213
+
214
+ testElement.classList.toggle( 'c3', false );
215
+
216
+ if ( testElement.classList.contains( 'c3' ) ) {
217
+ var _toggle = DOMTokenList.prototype.toggle;
218
+
219
+ DOMTokenList.prototype.toggle = function( token, force ) {
220
+ if ( 1 in arguments && !this.contains( token ) === !force ) {
221
+ return force;
222
+ } else {
223
+ return _toggle.call( this, token );
224
+ }
225
+ };
226
+
227
+ }
228
+
229
+ testElement = null;
230
+
231
+ }());
232
+
233
+ }
234
+ }