gumby 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,206 @@
1
+ /**
2
+ * Gumby Fixed
3
+ */
4
+ !function() {
5
+
6
+ 'use strict';
7
+
8
+ function Fixed($el) {
9
+ this.$el = $el;
10
+
11
+ this.fixedPoint = '';
12
+ this.pinPoint = false;
13
+ this.offset = 0;
14
+ this.pinOffset = 0;
15
+ this.top = 0;
16
+ this.constrainEl = true;
17
+ this.state = false;
18
+ this.measurements = {
19
+ left: 0,
20
+ width: 0
21
+ };
22
+
23
+ // set up module based on attributes
24
+ this.setup();
25
+
26
+ var scope = this;
27
+
28
+ // monitor scroll and update fixed elements accordingly
29
+ $(window).on('scroll load', function() {
30
+ scope.monitorScroll();
31
+ });
32
+
33
+ // reinitialize event listener
34
+ this.$el.on('gumby.initialize', function() {
35
+ scope.setup();
36
+ });
37
+ }
38
+
39
+ // set up module based on attributes
40
+ Fixed.prototype.setup = function() {
41
+ var scope = this;
42
+
43
+ this.fixedPoint = this.parseAttrValue(Gumby.selectAttr.apply(this.$el, ['fixed']));
44
+
45
+ // pin point is optional
46
+ this.pinPoint = Gumby.selectAttr.apply(this.$el, ['pin']) || false;
47
+
48
+ // offset from fixed point
49
+ this.offset = Number(Gumby.selectAttr.apply(this.$el, ['offset'])) || 0;
50
+
51
+ // offset from pin point
52
+ this.pinOffset = Number(Gumby.selectAttr.apply(this.$el, ['pinoffset'])) || 0;
53
+
54
+ // top position when fixed
55
+ this.top = Number(Gumby.selectAttr.apply(this.$el, ['top'])) || 0;
56
+
57
+ // constrain can be turned off
58
+ this.constrainEl = Gumby.selectAttr.apply(this.$el, ['constrain']) || true;
59
+ if(this.constrainEl === 'false') {
60
+ this.constrainEl = false;
61
+ }
62
+
63
+ // reference to the parent, row/column
64
+ this.$parent = this.$el.parents('.columns, .column, .row');
65
+ this.$parent = this.$parent.length ? this.$parent.first() : false;
66
+ this.parentRow = this.$parent ? !!this.$parent.hasClass('row') : false;
67
+
68
+ // if optional pin point set then parse now
69
+ if(this.pinPoint) {
70
+ this.pinPoint = this.parseAttrValue(this.pinPoint);
71
+ }
72
+
73
+ // if we have a parent constrain dimenions
74
+ if(this.$parent && this.constrainEl) {
75
+ // measure up
76
+ this.measure();
77
+ // and on resize reset measurement
78
+ $(window).resize(function() {
79
+ if(scope.state) {
80
+ scope.measure();
81
+ scope.constrain();
82
+ }
83
+ });
84
+ }
85
+ };
86
+
87
+ // monitor scroll and trigger changes based on position
88
+ Fixed.prototype.monitorScroll = function() {
89
+ var scrollAmount = $(window).scrollTop(),
90
+ // recalculate selector attributes as position may have changed
91
+ fixedPoint = this.fixedPoint instanceof jQuery ? this.fixedPoint.offset().top : this.fixedPoint,
92
+ pinPoint = false;
93
+
94
+ // if a pin point is set recalculate
95
+ if(this.pinPoint) {
96
+ pinPoint = this.pinPoint instanceof jQuery ? this.pinPoint.offset().top : this.pinPoint;
97
+ }
98
+
99
+ // apply offsets
100
+ if(this.offset) { fixedPoint -= this.offset; }
101
+ if(this.pinOffset) { pinPoint -= this.pinOffset; }
102
+
103
+ // fix it
104
+ if((scrollAmount >= fixedPoint) && this.state !== 'fixed') {
105
+ if(!pinPoint || scrollAmount < pinPoint) {
106
+ this.fix();
107
+ }
108
+ // unfix it
109
+ } else if(scrollAmount < fixedPoint && this.state === 'fixed') {
110
+ this.unfix();
111
+
112
+ // pin it
113
+ } else if(pinPoint && scrollAmount >= pinPoint && this.state !== 'pinned') {
114
+ this.pin();
115
+ }
116
+ };
117
+
118
+ // fix the element and update state
119
+ Fixed.prototype.fix = function() {
120
+ this.state = 'fixed';
121
+ this.$el.css({
122
+ 'top' : 0 + this.top
123
+ }).addClass('fixed').removeClass('unfixed pinned').trigger('gumby.onFixed');
124
+
125
+ // if we have a parent constrain dimenions
126
+ if(this.$parent) {
127
+ this.constrain();
128
+ }
129
+ };
130
+
131
+ // unfix the element and update state
132
+ Fixed.prototype.unfix = function() {
133
+ this.state = 'unfixed';
134
+ this.$el.addClass('unfixed').removeClass('fixed pinned').trigger('gumby.onUnfixed');
135
+ };
136
+
137
+ // pin the element in position
138
+ Fixed.prototype.pin = function() {
139
+ this.state = 'pinned';
140
+ this.$el.css({
141
+ 'top' : this.$el.offset().top
142
+ }).addClass('pinned fixed').removeClass('unfixed').trigger('gumby.onPinned');
143
+ };
144
+
145
+ // constrain elements dimensions to match width/height
146
+ Fixed.prototype.constrain = function() {
147
+ this.$el.css({
148
+ left: this.measurements.left,
149
+ width: this.measurements.width
150
+ });
151
+ };
152
+
153
+ // measure up the parent for constraining
154
+ Fixed.prototype.measure = function() {
155
+ var offsets = this.$parent.offset(), parentPadding;
156
+
157
+ this.measurements.left = offsets.left;
158
+ this.measurements.width = this.$parent.width();
159
+
160
+ // if element has a parent row then need to consider padding
161
+ if(this.parentRow) {
162
+ parentPadding = Number(this.$parent.css('paddingLeft').replace(/px/, ''));
163
+ if(parentPadding) {
164
+ this.measurements.left += parentPadding;
165
+ }
166
+ }
167
+ };
168
+
169
+ // parse attribute values, could be px, top, selector
170
+ Fixed.prototype.parseAttrValue = function(attr) {
171
+ // px value fixed point
172
+ if($.isNumeric(attr)) {
173
+ return Number(attr);
174
+ // 'top' string fixed point
175
+ } else if(attr === 'top') {
176
+ return this.$el.offset().top;
177
+ // selector specified
178
+ } else {
179
+ var $el = $(attr);
180
+ return $el;
181
+ }
182
+ };
183
+
184
+ // add initialisation
185
+ Gumby.addInitalisation('fixed', function() {
186
+ $('[data-fixed],[gumby-fixed],[fixed]').each(function() {
187
+ var $this = $(this);
188
+ // this element has already been initialized
189
+ if($this.data('isFixed')) {
190
+ return true;
191
+ }
192
+ // mark element as initialized
193
+ $this.data('isFixed', true);
194
+ new Fixed($this);
195
+ });
196
+ });
197
+
198
+ // register UI module
199
+ Gumby.UIModule({
200
+ module: 'fixed',
201
+ events: ['onFixed', 'onUnfixed'],
202
+ init: function() {
203
+ Gumby.initialize('fixed');
204
+ }
205
+ });
206
+ }();
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Gumby Navbar
3
+ */
4
+ !function() {
5
+
6
+ 'use strict';
7
+
8
+ var $html = Gumby.$dom.find('html');
9
+
10
+ // define and init module on touch enabled devices only
11
+ // when we are at tablet size or smaller
12
+ if(!Modernizr.touch || $(window).width() > Gumby.breakpoint) {
13
+
14
+ // add Gumby no touch class
15
+ $html.addClass('gumby-no-touch');
16
+ return;
17
+ }
18
+
19
+ // add Gumby touch class
20
+ $html.addClass('gumby-touch');
21
+
22
+ function Navbar($el) {
23
+ this.$el = $el;
24
+ this.$dropDowns = this.$el.find('li:has(.dropdown)');
25
+ var scope = this;
26
+
27
+ // when navbar items
28
+ this.$dropDowns
29
+ // are tapped hide/show dropdowns
30
+ .on('tap', this.toggleDropdown)
31
+ // are swiped right open link
32
+ .on('swiperight', this.openLink);
33
+
34
+ // if there's a link set
35
+ if(this.$dropDowns.children('a').attr('href') !== '#') {
36
+ // append an icon
37
+ this.$dropDowns.children('a').append('<i class="icon-popup"></i>').children('i')
38
+ // and bind to click event to open link
39
+ .on('tap', this.openLink);
40
+ }
41
+
42
+ // on mousemove and touchstart toggle modernizr classes and disable/enable this module
43
+ // workaround for Pixel and other multi input devices
44
+ $(window).on('mousemove touchstart', function(e) {
45
+ e.stopImmediatePropagation();
46
+ if(e.type === 'mousemove') {
47
+ scope.$dropDowns.on('mouseover mouseout', scope.toggleDropdown);
48
+ }
49
+ });
50
+ }
51
+
52
+ Navbar.prototype.toggleDropdown = function(e) {
53
+ // prevent click from triggering here too
54
+ e.stopImmediatePropagation();
55
+ e.preventDefault();
56
+
57
+ var $this = $(this);
58
+
59
+ if($this.hasClass('active')) {
60
+ $this.removeClass('active');
61
+ } else {
62
+ $this.addClass('active');
63
+ }
64
+ };
65
+
66
+ // handle opening list item link
67
+ Navbar.prototype.openLink = function(e) {
68
+ e.stopImmediatePropagation();
69
+ e.preventDefault();
70
+
71
+ var $this = $(this),
72
+ $el, 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('navbars', 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('navbars');
113
+ }
114
+ });
115
+ }();
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Gumby RadioBtn
3
+ */
4
+ !function() {
5
+
6
+ 'use strict';
7
+
8
+ function RadioBtn($el) {
9
+
10
+ this.$el = $el;
11
+ var scope = this;
12
+
13
+ // listen for click event and custom gumby check event
14
+ this.$el.on(Gumby.click, function(e) {
15
+ // prevent propagation
16
+ e.stopImmediatePropagation();
17
+
18
+ // prevent radio button checking, we'll do that manually
19
+ e.preventDefault();
20
+
21
+ // check radio button
22
+ scope.update();
23
+ }).on('gumby.check', function() {
24
+ scope.update();
25
+ });
26
+
27
+ // update any .checked checkboxes on load
28
+ if(scope.$el.hasClass('checked')) {
29
+ scope.update();
30
+ }
31
+ }
32
+
33
+ // check radio button, uncheck all others in name group
34
+ RadioBtn.prototype.update = function() {
35
+ var // this specific radio button
36
+ $input = this.$el.find('input[type=radio]'),
37
+ $span = this.$el.find('span'),
38
+ // the group of radio buttons
39
+ group = 'input[name="'+$input.attr('name')+'"]';
40
+
41
+ // uncheck radio buttons in same group - uncheck input, remove checked class, remove <i>
42
+ $('.radio').has(group).removeClass('checked')
43
+ .find('input').prop('checked', false).end()
44
+ .find('i').remove();
45
+
46
+ // check this radio button - check input, add checked class, append <i>
47
+ $input.prop('checked', true);
48
+ $span.append('<i class="icon-dot" />');
49
+ this.$el.addClass('checked').trigger('gumby.onChange');
50
+ };
51
+
52
+ // add initialisation
53
+ Gumby.addInitalisation('radiobtns', function() {
54
+ $('.radio').each(function() {
55
+ var $this = $(this);
56
+ // this element has already been initialized
57
+ if($this.data('isRadioBtn')) {
58
+ return true;
59
+ }
60
+ // mark element as initialized
61
+ $this.data('isRadioBtn', true);
62
+ new RadioBtn($this);
63
+ });
64
+ });
65
+
66
+ // register UI module
67
+ Gumby.UIModule({
68
+ module: 'radiobtn',
69
+ events: ['onChange', 'check'],
70
+ init: function() {
71
+ Gumby.initialize('radiobtns');
72
+ }
73
+ });
74
+ }();
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Gumby Retina
3
+ */
4
+ !function() {
5
+
6
+ 'use strict';
7
+
8
+ function Retina($el) {
9
+ this.$el = $el;
10
+ this.imageSrc = this.$el.attr('src');
11
+ this.retinaSrc = this.fetchRetinaImage();
12
+ this.$retinaImg = $(new Image());
13
+
14
+ var scope = this
15
+
16
+ // image src not valid
17
+ if(!this.retinaSrc) {
18
+ return false;
19
+ }
20
+
21
+ // load retina image
22
+ this.$retinaImg.attr('src', this.retinaSrc).load(function() {
23
+ scope.retinaImageLoaded();
24
+ });
25
+ }
26
+
27
+ // fetch retina src by appending '@2x' to image string before extension
28
+ Retina.prototype.fetchRetinaImage = function() {
29
+ var imgSrc = this.imageSrc,
30
+ index = this.imageSrc.search(/(\.|\/)(gif|jpe?g|png)$/i);
31
+
32
+ // image src is not valid
33
+ if(index < 0) {
34
+ return false;
35
+ }
36
+
37
+ // return retina src
38
+ return imgSrc.substr(0, index) + '@2x' + imgSrc.substr(index, imgSrc.length);
39
+ };
40
+
41
+ // once retina image loaded swap original src
42
+ Retina.prototype.retinaImageLoaded = function() {
43
+ this.$el.attr('src', this.$retinaImg.attr('src')).trigger('gumby.onRetina');
44
+ };
45
+
46
+ // add initialisation
47
+ Gumby.addInitalisation('retina', function() {
48
+
49
+ // this module is for retina devices only
50
+ if(!window.devicePixelRatio || window.devicePixelRatio <= 1) {
51
+ return;
52
+ }
53
+
54
+ $('img[data-retina],img[gumby-retina],img[retina]').each(function() {
55
+ var $this = $(this);
56
+ // this element has already been initialized
57
+ if($this.data('isRetina')) {
58
+ return true;
59
+ }
60
+ // mark element as initialized
61
+ $this.data('isRetina', true);
62
+ new Retina($this);
63
+ });
64
+ });
65
+
66
+ // register UI module
67
+ Gumby.UIModule({
68
+ module: 'retina',
69
+ events: ['onRetina'],
70
+ init: function() {
71
+ Gumby.initialize('retina');
72
+ }
73
+ });
74
+ }();