gumbie 0.1.0

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 (35) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +29 -0
  6. data/Rakefile +1 -0
  7. data/gumbie.gemspec +25 -0
  8. data/lib/gumbie/version.rb +3 -0
  9. data/lib/gumbie.rb +7 -0
  10. data/vendor/assets/fonts/icons/entypo.eot +0 -0
  11. data/vendor/assets/fonts/icons/entypo.ttf +0 -0
  12. data/vendor/assets/fonts/icons/entypo.woff +0 -0
  13. data/vendor/assets/javascripts/libs/gumby.init.js +47 -0
  14. data/vendor/assets/javascripts/libs/gumby.js +258 -0
  15. data/vendor/assets/javascripts/libs/gumby.min.js +1 -0
  16. data/vendor/assets/javascripts/libs/jquery-1.10.1.min.js +6 -0
  17. data/vendor/assets/javascripts/libs/jquery-1.10.1.min.map +1 -0
  18. data/vendor/assets/javascripts/libs/jquery-2.0.2.min.js +6 -0
  19. data/vendor/assets/javascripts/libs/jquery-2.0.2.min.map +1 -0
  20. data/vendor/assets/javascripts/libs/jquery.mobile.custom.min.js +3 -0
  21. data/vendor/assets/javascripts/libs/modernizr-2.6.2.min.js +4 -0
  22. data/vendor/assets/javascripts/libs/ui/gumby.checkbox.js +101 -0
  23. data/vendor/assets/javascripts/libs/ui/gumby.fixed.js +240 -0
  24. data/vendor/assets/javascripts/libs/ui/gumby.navbar.js +115 -0
  25. data/vendor/assets/javascripts/libs/ui/gumby.radiobtn.js +90 -0
  26. data/vendor/assets/javascripts/libs/ui/gumby.retina.js +81 -0
  27. data/vendor/assets/javascripts/libs/ui/gumby.skiplink.js +157 -0
  28. data/vendor/assets/javascripts/libs/ui/gumby.tabs.js +80 -0
  29. data/vendor/assets/javascripts/libs/ui/gumby.toggleswitch.js +264 -0
  30. data/vendor/assets/javascripts/libs/ui/jquery.validation.js +142 -0
  31. data/vendor/assets/javascripts/main.js +23 -0
  32. data/vendor/assets/javascripts/plugins.js +4 -0
  33. data/vendor/assets/stylesheets/gumby.css +1683 -0
  34. data/vendor/assets/stylesheets/style.css +4 -0
  35. metadata +134 -0
@@ -0,0 +1,240 @@
1
+ /**
2
+ * Gumby Fixed
3
+ */
4
+ !function($) {
5
+
6
+ 'use strict';
7
+
8
+ function Fixed($el) {
9
+
10
+ Gumby.debug('Initializing Fixed Position', $el);
11
+
12
+ this.$el = $el;
13
+
14
+ this.$window = $(window);
15
+ this.fixedPoint = '';
16
+ this.pinPoint = false;
17
+ this.fixedPointjQ = false;
18
+ this.pinPointjQ = false;
19
+ this.offset = 0;
20
+ this.pinOffset = 0;
21
+ this.top = 0;
22
+ this.constrainEl = true;
23
+ this.state = false;
24
+ this.measurements = {
25
+ left: 0,
26
+ width: 0
27
+ };
28
+
29
+ // set up module based on attributes
30
+ this.setup();
31
+
32
+ var scope = this;
33
+
34
+ // monitor scroll and update fixed elements accordingly
35
+ this.$window.on('scroll load', function() {
36
+ scope.monitorScroll();
37
+ });
38
+
39
+ // reinitialize event listener
40
+ this.$el.on('gumby.initialize', function() {
41
+ Gumby.debug('Re-initializing Fixed Position', $el);
42
+ scope.setup();
43
+ scope.monitorScroll();
44
+ });
45
+ }
46
+
47
+ // set up module based on attributes
48
+ Fixed.prototype.setup = function() {
49
+ var scope = this;
50
+
51
+ this.fixedPoint = this.parseAttrValue(Gumby.selectAttr.apply(this.$el, ['fixed']));
52
+
53
+ // pin point is optional
54
+ this.pinPoint = Gumby.selectAttr.apply(this.$el, ['pin']) || false;
55
+
56
+ // offset from fixed point
57
+ this.offset = Number(Gumby.selectAttr.apply(this.$el, ['offset'])) || 0;
58
+
59
+ // offset from pin point
60
+ this.pinOffset = Number(Gumby.selectAttr.apply(this.$el, ['pinoffset'])) || 0;
61
+
62
+ // top position when fixed
63
+ this.top = Number(Gumby.selectAttr.apply(this.$el, ['top'])) || 0;
64
+
65
+ // constrain can be turned off
66
+ this.constrainEl = Gumby.selectAttr.apply(this.$el, ['constrain']) || true;
67
+ if(this.constrainEl === 'false') {
68
+ this.constrainEl = false;
69
+ }
70
+
71
+ // reference to the parent, row/column
72
+ this.$parent = this.$el.parents('.columns, .column, .row');
73
+ this.$parent = this.$parent.length ? this.$parent.first() : false;
74
+ this.parentRow = this.$parent ? !!this.$parent.hasClass('row') : false;
75
+
76
+ // if optional pin point set then parse now
77
+ if(this.pinPoint) {
78
+ this.pinPoint = this.parseAttrValue(this.pinPoint);
79
+ }
80
+
81
+ this.fixedPointjQ = this.fixedPoint instanceof jQuery;
82
+ this.pinPointjQ = this.pinPoint instanceof jQuery;
83
+
84
+ // if we have a parent constrain dimenions
85
+ if(this.$parent && this.constrainEl) {
86
+ // measure up
87
+ this.measure();
88
+ // and on resize reset measurement
89
+ this.$window.resize(function() {
90
+ if(scope.state) {
91
+ scope.measure();
92
+ scope.constrain();
93
+ }
94
+ });
95
+ }
96
+ };
97
+
98
+ // monitor scroll and trigger changes based on position
99
+ Fixed.prototype.monitorScroll = function() {
100
+ var scrollAmount = this.$window.scrollTop(),
101
+ // recalculate selector attributes as position may have changed
102
+ fixedPoint = this.fixedPointjQ ? this.fixedPoint.offset().top : this.fixedPoint,
103
+ pinPoint = false,
104
+ timer;
105
+
106
+ // if a pin point is set recalculate
107
+ if(this.pinPoint) {
108
+ pinPoint = this.pinPointjQ ? this.pinPoint.offset().top : this.pinPoint;
109
+ }
110
+
111
+ // apply offsets
112
+ if(this.offset) { fixedPoint -= this.offset; }
113
+ if(this.pinOffset) { pinPoint -= this.pinOffset; }
114
+
115
+ // fix it
116
+ if((scrollAmount >= fixedPoint) && this.state !== 'fixed') {
117
+ if(!pinPoint || scrollAmount < pinPoint) {
118
+ this.fix();
119
+ }
120
+ // unfix it
121
+ } else if(scrollAmount < fixedPoint && this.state === 'fixed') {
122
+ this.unfix();
123
+
124
+ // pin it
125
+ } else if(pinPoint && scrollAmount >= pinPoint && this.state !== 'pinned') {
126
+ this.pin();
127
+ }
128
+ };
129
+
130
+ // fix the element and update state
131
+ Fixed.prototype.fix = function() {
132
+ Gumby.debug('Element has been fixed', this.$el);
133
+ Gumby.debug('Triggering onFixed event', this.$el);
134
+
135
+ this.state = 'fixed';
136
+ this.$el.css({
137
+ 'top' : this.top
138
+ }).addClass('fixed').removeClass('unfixed pinned').trigger('gumby.onFixed');
139
+
140
+ // if we have a parent constrain dimenions
141
+ if(this.$parent) {
142
+ this.constrain();
143
+ }
144
+ };
145
+
146
+ // unfix the element and update state
147
+ Fixed.prototype.unfix = function() {
148
+ Gumby.debug('Element has been unfixed', this.$el);
149
+ Gumby.debug('Triggering onUnfixed event', this.$el);
150
+
151
+ this.state = 'unfixed';
152
+ this.$el.addClass('unfixed').removeClass('fixed pinned').trigger('gumby.onUnfixed');
153
+ };
154
+
155
+ // pin the element in position
156
+ Fixed.prototype.pin = function() {
157
+ Gumby.debug('Element has been pinned', this.$el);
158
+ Gumby.debug('Triggering onPinned event', this.$el);
159
+ this.state = 'pinned';
160
+ this.$el.css({
161
+ 'top' : this.$el.offset().top
162
+ }).addClass('pinned fixed').removeClass('unfixed').trigger('gumby.onPinned');
163
+ };
164
+
165
+ // constrain elements dimensions to match width/height
166
+ Fixed.prototype.constrain = function() {
167
+ Gumby.debug("Constraining element", this.$el);
168
+ this.$el.css({
169
+ left: this.measurements.left,
170
+ width: this.measurements.width
171
+ });
172
+ };
173
+
174
+ // measure up the parent for constraining
175
+ Fixed.prototype.measure = function() {
176
+ var parentPadding;
177
+
178
+ this.measurements.left = this.$parent.offset().left;
179
+ this.measurements.width = this.$parent.width();
180
+
181
+ // if element has a parent row then need to consider padding
182
+ if(this.parentRow) {
183
+ parentPadding = Number(this.$parent.css('paddingLeft').replace(/px/, ''));
184
+ if(parentPadding) {
185
+ this.measurements.left += parentPadding;
186
+ }
187
+ }
188
+ };
189
+
190
+ // parse attribute values, could be px, top, selector
191
+ Fixed.prototype.parseAttrValue = function(attr) {
192
+ // px value fixed point
193
+ if($.isNumeric(attr)) {
194
+ return Number(attr);
195
+ // 'top' string fixed point
196
+ } else if(attr === 'top') {
197
+ return this.$el.offset().top;
198
+ // selector specified
199
+ } else {
200
+ var $el = $(attr);
201
+ if(!$el.length) {
202
+ Gumby.error('Cannot find Fixed target: '+attr);
203
+ return false;
204
+ }
205
+ return $el;
206
+ }
207
+ };
208
+
209
+ // add initialisation
210
+ Gumby.addInitalisation('fixed', function(all) {
211
+ $('[data-fixed],[gumby-fixed],[fixed]').each(function() {
212
+ var $this = $(this);
213
+
214
+ // this element has already been initialized
215
+ // and we're only initializing new modules
216
+ if($this.data('isFixed') && !all) {
217
+ return true;
218
+
219
+ // this element has already been initialized
220
+ // and we need to reinitialize it
221
+ } else if($this.data('isFixed') && all) {
222
+ $this.trigger('gumby.initialize');
223
+ return true;
224
+ }
225
+
226
+ // mark element as initialized
227
+ $this.data('isFixed', true);
228
+ new Fixed($this);
229
+ });
230
+ });
231
+
232
+ // register UI module
233
+ Gumby.UIModule({
234
+ module: 'fixed',
235
+ events: ['initialize', 'onFixed', 'onUnfixed'],
236
+ init: function() {
237
+ Gumby.initialize('fixed');
238
+ }
239
+ });
240
+ }(jQuery);
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Gumby Navbar
3
+ */
4
+ !function($) {
5
+
6
+ 'use strict';
7
+
8
+ // define and init module on touch enabled devices only
9
+ if(!Gumby.gumbyTouch) {
10
+ return;
11
+ }
12
+
13
+ function Navbar($el) {
14
+
15
+ Gumby.debug('Initializing Navbar', $el);
16
+
17
+ this.$el = $el;
18
+ this.$dropDowns = this.$el.find('li:has(.dropdown)');
19
+ var scope = this;
20
+
21
+ var persist = this.$el.attr('gumby-persist');
22
+ if(typeof persist === 'undefined' && persist !== 'false') {
23
+ this.$el.find('li:not(:has(.dropdown)) a').on(Gumby.click, function() {
24
+ scope.$el.find('ul').removeClass('active');
25
+ });
26
+ }
27
+
28
+ // when navbar items
29
+ this.$dropDowns
30
+ // are tapped hide/show dropdowns
31
+ .on(Gumby.click, this.toggleDropdown)
32
+ // are swiped right open link
33
+ .on('swiperight', this.openLink);
34
+
35
+ // if there's a link set
36
+ if(this.$dropDowns.children('a').attr('href') !== '#') {
37
+ // append an icon
38
+ this.$dropDowns.children('a').append('<i class="icon-popup"></i>').children('i')
39
+ // and bind to click event to open link
40
+ .on(Gumby.click, this.openLink);
41
+ }
42
+
43
+ // override with childlinks
44
+ this.$el.find('li:not(:has(.dropdown)) a[href]').on(Gumby.click, this.openLink);
45
+ }
46
+
47
+ Navbar.prototype.toggleDropdown = function(e) {
48
+ e.preventDefault();
49
+
50
+ if($(this).parents('.dropdown')) {
51
+ e.stopImmediatePropagation();
52
+ }
53
+
54
+ if($(e.target).is('i')) {
55
+ return;
56
+ }
57
+
58
+ var $this = $(this);
59
+
60
+ if($this.hasClass('active')) {
61
+ $this.removeClass('active');
62
+ } else {
63
+ $this.addClass('active');
64
+ }
65
+ };
66
+
67
+ // handle opening list item link
68
+ Navbar.prototype.openLink = function(e) {
69
+ e.preventDefault();
70
+
71
+ var $this = $(this),
72
+ $el = $this, href;
73
+
74
+ // tapped icon
75
+ if($this.is('i')) {
76
+ $el = $this.parent('a');
77
+ // swiped li
78
+ } else if($this.is('li')) {
79
+ $el = $this.children('a');
80
+ }
81
+
82
+ href = $el.attr('href');
83
+
84
+ // open in new window
85
+ if($el.attr('target') == 'blank') {
86
+ window.open(href);
87
+ // regular relocation
88
+ } else {
89
+ window.location = href;
90
+ }
91
+ };
92
+
93
+ // add initialisation
94
+ Gumby.addInitalisation('navbar', function() {
95
+ $('.navbar').each(function() {
96
+ var $this = $(this);
97
+ // this element has already been initialized
98
+ if($this.data('isNavbar')) {
99
+ return true;
100
+ }
101
+ // mark element as initialized
102
+ $this.data('isNavbar', true);
103
+ new Navbar($this);
104
+ });
105
+ });
106
+
107
+ // register UI module
108
+ Gumby.UIModule({
109
+ module: 'navbar',
110
+ events: [],
111
+ init: function() {
112
+ Gumby.initialize('navbar');
113
+ }
114
+ });
115
+ }(jQuery);
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Gumby RadioBtn
3
+ */
4
+ !function($) {
5
+
6
+ 'use strict';
7
+
8
+ function RadioBtn($el) {
9
+
10
+ Gumby.debug('Initializing Radio Button', $el);
11
+
12
+ this.$el = $el;
13
+ this.$input = this.$el.find('input[type=radio]');
14
+
15
+ var scope = this;
16
+
17
+ // listen for click event and custom gumby check event
18
+ this.$el.on(Gumby.click, function(e) {
19
+ // prevent radio button checking, we'll do that manually
20
+ e.preventDefault();
21
+
22
+ // do nothing if radio is disabled
23
+ if (scope.$input.is('[disabled]')) {
24
+ return;
25
+ }
26
+
27
+ // check radio button
28
+ scope.update();
29
+ }).on('gumby.check', function() {
30
+ Gumby.debug('Check event triggered', scope.$el);
31
+ scope.update();
32
+ });
33
+
34
+ // update any prechecked on load
35
+ if(this.$input.prop('checked') || this.$el.hasClass('checked')) {
36
+ scope.update(true);
37
+ }
38
+ }
39
+
40
+ // check radio button, uncheck all others in name group
41
+ RadioBtn.prototype.update = function() {
42
+
43
+ // already checked so no need to update
44
+ if(this.$el.hasClass('checked') && this.$input.prop('checked') && this.$el.find('i.icon-dot').length) {
45
+ return;
46
+ }
47
+
48
+ Gumby.debug('Updating Radio Button group', this.$el);
49
+
50
+ var $span = this.$el.find('span'),
51
+ // the group of radio buttons
52
+ group = 'input[name="'+this.$input.attr('name')+'"]';
53
+
54
+ // uncheck radio buttons in same group - uncheck input, remove checked class, remove <i>
55
+ $('.radio').has(group).removeClass('checked')
56
+ .find('input').prop('checked', false).end()
57
+ .find('i').remove();
58
+
59
+ // check this radio button - check input, add checked class, append <i>
60
+ this.$input.prop('checked', true);
61
+ $span.append('<i class="icon-dot" />');
62
+
63
+ Gumby.debug('Triggering onCheck event', this.$el);
64
+
65
+ this.$el.addClass('checked').trigger('gumby.onCheck');
66
+ };
67
+
68
+ // add initialisation
69
+ Gumby.addInitalisation('radiobtn', function() {
70
+ $('.radio').each(function() {
71
+ var $this = $(this);
72
+ // this element has already been initialized
73
+ if($this.data('isRadioBtn')) {
74
+ return true;
75
+ }
76
+ // mark element as initialized
77
+ $this.data('isRadioBtn', true);
78
+ new RadioBtn($this);
79
+ });
80
+ });
81
+
82
+ // register UI module
83
+ Gumby.UIModule({
84
+ module: 'radiobtn',
85
+ events: ['onCheck', 'check'],
86
+ init: function() {
87
+ Gumby.initialize('radiobtn');
88
+ }
89
+ });
90
+ }(jQuery);
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Gumby Retina
3
+ */
4
+ !function($) {
5
+
6
+ 'use strict';
7
+
8
+ function Retina($el) {
9
+
10
+ Gumby.debug('Initializing Retina', $el);
11
+
12
+ this.$el = $el;
13
+ this.imageSrc = this.$el.attr('src');
14
+ this.retinaSrc = this.fetchRetinaImage();
15
+ this.$retinaImg = $(new Image());
16
+
17
+ var scope = this;
18
+
19
+ // image src not valid
20
+ if(!this.retinaSrc) {
21
+ return false;
22
+ }
23
+
24
+ // load retina image
25
+ this.$retinaImg.attr('src', this.retinaSrc).load(function() {
26
+ scope.retinaImageLoaded();
27
+ }).error(function() {
28
+ Gumby.error('Couln\'t load retina image: '+scope.retinaSrc);
29
+ });
30
+ }
31
+
32
+ // fetch retina src by appending '@2x' to image string before extension
33
+ Retina.prototype.fetchRetinaImage = function() {
34
+ var imgSrc = this.imageSrc,
35
+ index = this.imageSrc.search(/(\.|\/)(gif|jpe?g|png)$/i);
36
+
37
+ // image src is not valid
38
+ if(index < 0) {
39
+ return false;
40
+ }
41
+
42
+ // return retina src
43
+ return imgSrc.substr(0, index) + '@2x' + imgSrc.substr(index, imgSrc.length);
44
+ };
45
+
46
+ // once retina image loaded swap original src
47
+ Retina.prototype.retinaImageLoaded = function() {
48
+ Gumby.debug('Swapping image for retina version', this.$el);
49
+ Gumby.debug('Triggering onRetina event', this.$el);
50
+ this.$el.attr('src', this.$retinaImg.attr('src')).trigger('gumby.onRetina');
51
+ };
52
+
53
+ // add initialisation
54
+ Gumby.addInitalisation('retina', function() {
55
+
56
+ // this module is for retina devices only
57
+ if(!window.devicePixelRatio || window.devicePixelRatio <= 1) {
58
+ return;
59
+ }
60
+
61
+ $('img[data-retina],img[gumby-retina],img[retina]').each(function() {
62
+ var $this = $(this);
63
+ // this element has already been initialized
64
+ if($this.data('isRetina')) {
65
+ return true;
66
+ }
67
+ // mark element as initialized
68
+ $this.data('isRetina', true);
69
+ new Retina($this);
70
+ });
71
+ });
72
+
73
+ // register UI module
74
+ Gumby.UIModule({
75
+ module: 'retina',
76
+ events: ['onRetina'],
77
+ init: function() {
78
+ Gumby.initialize('retina');
79
+ }
80
+ });
81
+ }(jQuery);
@@ -0,0 +1,157 @@
1
+ /**
2
+ * Gumby SkipLink
3
+ */
4
+ !function($) {
5
+
6
+ 'use strict';
7
+
8
+ function SkipLink($el) {
9
+
10
+ Gumby.debug('Initializing Skiplink', $el);
11
+
12
+ this.$el = $el;
13
+ this.targetPos = 0;
14
+ this.duration = 0;
15
+ this.offset = false;
16
+ this.easing = '';
17
+ this.update = false;
18
+
19
+ // set up module based on attributes
20
+ this.setup();
21
+
22
+ var scope = this;
23
+
24
+ // skip to target element on click or trigger of gumby.skipTo event
25
+ this.$el.on(Gumby.click+' gumby.skip', function(e) {
26
+ e.preventDefault();
27
+
28
+ if(e.namespace === 'skip') {
29
+ Gumby.debug('Skip event triggered', scope.$el);
30
+ }
31
+
32
+ // calculate target on each click if update var set to true
33
+ if(scope.update) {
34
+ scope.calculateTarget(scope.skipTo);
35
+
36
+ // skip straight to target
37
+ } else {
38
+ scope.skipTo();
39
+ }
40
+ }).on('gumby.initialize', function() {
41
+ Gumby.debug('Re-initializing Skiplink', scope.$el);
42
+ scope.setup();
43
+ });
44
+ }
45
+
46
+ // set up module based on attributes
47
+ SkipLink.prototype.setup = function() {
48
+ this.duration = Number(Gumby.selectAttr.apply(this.$el, ['duration'])) || 200;
49
+ this.offset = Gumby.selectAttr.apply(this.$el, ['offset']) || false;
50
+ this.easing = Gumby.selectAttr.apply(this.$el, ['easing']) || 'swing';
51
+ this.update = Gumby.selectAttr.apply(this.$el, ['update']) ? true : false;
52
+
53
+ this.calculateTarget();
54
+ };
55
+
56
+ // calculate target px point to skip to
57
+ SkipLink.prototype.calculateTarget = function(cb) {
58
+
59
+ var scope = this,
60
+ target = Gumby.selectAttr.apply(this.$el, ['goto']),
61
+ $target;
62
+
63
+ // 'top' specified so target is 0px
64
+ if(target == 'top') {
65
+ this.targetPos = 0;
66
+
67
+ // px point specified
68
+ } else if($.isNumeric(target)) {
69
+ this.targetPos = Number(target);
70
+ } else {
71
+
72
+ // check for element with target as selector
73
+ $target = $(target);
74
+
75
+ // target does not exist, we need a target
76
+ if(!$target.length) {
77
+ Gumby.error('Cannot find skiplink target: '+target);
78
+ return false;
79
+ }
80
+
81
+ this.targetPos = $target.offset().top;
82
+ }
83
+
84
+ if(cb) {
85
+ cb.apply(this);
86
+ }
87
+ };
88
+
89
+ // animate body, html scrollTop value to target px point
90
+ SkipLink.prototype.skipTo = function() {
91
+
92
+ Gumby.debug('Skipping to target', this.$el);
93
+
94
+ var scope = this;
95
+
96
+ // slide to position of target
97
+ $('html,body').animate({
98
+ 'scrollTop' : this.calculateOffset()
99
+ }, this.duration, this.easing).promise().done(function() {
100
+
101
+ Gumby.debug('Triggering onComplete event', scope.$el);
102
+ scope.$el.trigger('gumby.onComplete');
103
+ });
104
+ };
105
+
106
+ // calculate offset with current target point
107
+ SkipLink.prototype.calculateOffset = function() {
108
+ // no offset so return target here
109
+ if(!this.offset) {
110
+ return this.targetPos;
111
+ }
112
+
113
+ // negative / positive
114
+ var op = this.offset.substr(0, 1),
115
+ off = Number(this.offset.substr(1, this.offset.length));
116
+
117
+ // subtract offset from target position
118
+ if(op === '-') {
119
+ return this.targetPos - off;
120
+ // add offset to target position
121
+ } else if(op === '+') {
122
+ return this.targetPos + off;
123
+ }
124
+ };
125
+
126
+ // add initialisation
127
+ Gumby.addInitalisation('skiplink', function(all) {
128
+ $('.skiplink > a, .skip').each(function() {
129
+ var $this = $(this);
130
+
131
+ // this element has already been initialized
132
+ // and we're only initializing new modules
133
+ if($this.data('isSkipLink') && !all) {
134
+ return true;
135
+
136
+ // this element has already been initialized
137
+ // and we need to reinitialize it
138
+ } else if($this.data('isSkipLink') && all) {
139
+ $this.trigger('gumby.initialize');
140
+ return true;
141
+ }
142
+
143
+ // mark element as initialized
144
+ $this.data('isSkipLink', true);
145
+ new SkipLink($this);
146
+ });
147
+ });
148
+
149
+ // register UI module
150
+ Gumby.UIModule({
151
+ module: 'skiplink',
152
+ events: ['initialize', 'onComplete', 'skip'],
153
+ init: function() {
154
+ Gumby.initialize('skiplink');
155
+ }
156
+ });
157
+ }(jQuery);