gumby-framework 0.0.1

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.
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Gumby Fixed
3
+ */
4
+ !function() {
5
+
6
+ 'use strict';
7
+
8
+ function Fixed($el) {
9
+ this.$el = $el;
10
+ this.$holder = Gumby.selectAttr.apply(this.$el, ['holder']);
11
+ this.fixedPoint = Gumby.selectAttr.apply(this.$el, ['fixed']);
12
+ this.unfixPoint = false;
13
+
14
+ // if holder attr set then create jQuery object
15
+ // otherwise use window for scrolling cals
16
+ if(this.$holder) {
17
+ this.$holder = $(this.$holder);
18
+ } else {
19
+ this.$holder = $(window);
20
+ }
21
+
22
+ // fix/unfix points specified
23
+ if(this.fixedPoint.indexOf('|') > -1) {
24
+ var points = this.fixedPoint.split('|');
25
+ this.fixedPoint = points[0];
26
+ this.unfixPoint = points[1];
27
+ }
28
+
29
+ // parse possible parameters
30
+ this.fixedPoint = this.parseAttrValue(this.fixedPoint);
31
+ if(this.unfixPoint) {
32
+ this.unfixPoint = this.parseAttrValue(this.unfixPoint);
33
+ }
34
+
35
+ var scope = this;
36
+ this.$holder.scroll(function() {
37
+ scope.scroll();
38
+ });
39
+ }
40
+
41
+ // handle scroll event on window/specified holder
42
+ Fixed.prototype.scroll = function() {
43
+ var offset = this.$holder.scrollTop(),
44
+ fixedPoint = this.fixedPoint,
45
+ unfixPoint = this.unfixPoint,
46
+ endPoint = this.endPoint;
47
+
48
+ // if fixed point, unfix point or end point are DOM fragements
49
+ // then re-calculate values as could have been updated
50
+ fixedPoint = fixedPoint instanceof jQuery ? this.fixedPoint.offset().top : this.fixedPoint;
51
+ unfixPoint = unfixPoint instanceof jQuery ? this.unfixPoint.offset().top : this.unfixPoint;
52
+
53
+ // ensure unfix point is never reached if not set
54
+ if(!unfixPoint) {
55
+ unfixPoint = offset * 2;
56
+ }
57
+
58
+ // scrolled past fixed point and no fixed class present
59
+ if((offset >= fixedPoint) && (offset < unfixPoint) && !this.$el.hasClass('fixed')) {
60
+ this.$el.addClass('fixed').trigger('gumby.onFixed');
61
+
62
+ // before fixed point, pass 0 to onUnfixed event
63
+ } else if((offset <= fixedPoint) && this.$el.hasClass('fixed')) {
64
+ this.$el.removeClass('fixed').trigger('gumby.onUnfixed', 0);
65
+ }
66
+
67
+ // after unfix point, pass 1 to onUnfixed event
68
+ // separate conditional as should override
69
+ if(unfixPoint && (offset >= unfixPoint) && this.$el.hasClass('fixed')) {
70
+ this.$el.removeClass('fixed').trigger('gumby.onUnfixed', 1);
71
+ }
72
+ };
73
+
74
+ // parse attribute values, could be px, top, selector
75
+ Fixed.prototype.parseAttrValue = function(attr) {
76
+ // px value fixed point
77
+ if($.isNumeric(attr)) {
78
+ return Number(attr);
79
+ // 'top' string fixed point
80
+ } else if(attr === 'top') {
81
+ return this.$el.offset().top;
82
+ // selector specified
83
+ } else {
84
+ var $el = $(attr);
85
+ return $el.length ? $el : false;
86
+ }
87
+ };
88
+
89
+ // add initialisation
90
+ Gumby.addInitalisation('fixed', function() {
91
+ $('[data-fixed],[gumby-fixed],[fixed]').each(function() {
92
+ var $this = $(this);
93
+ // this element has already been initialized
94
+ if($this.data('isFixed')) {
95
+ return true;
96
+ }
97
+ // mark element as initialized
98
+ $this.data('isFixed', true);
99
+ new Fixed($this);
100
+ });
101
+ });
102
+
103
+ // register UI module
104
+ Gumby.UIModule({
105
+ module: 'fixed',
106
+ events: ['onFixed', 'onUnfixed'],
107
+ init: function() {
108
+ Gumby.initialize('fixed');
109
+ }
110
+ });
111
+ }();
@@ -0,0 +1,81 @@
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
+ scope.click(e);
16
+ }).on('gumby.check', function() {
17
+ scope.update();
18
+ });
19
+
20
+ // update any .checked checkboxes on load
21
+ if(scope.$el.hasClass('checked')) {
22
+ scope.update();
23
+ }
24
+ }
25
+
26
+ // handle radio button click event
27
+ RadioBtn.prototype.click = function(e) {
28
+
29
+ // element responsible for event trigger
30
+ var $target = $(e.target);
31
+
32
+ // prevent propagation
33
+ e.stopPropagation();
34
+
35
+ // prevent radio button checking, we'll do that manually
36
+ e.preventDefault();
37
+
38
+ // check radio button
39
+ this.update();
40
+ };
41
+
42
+ // check radio button, uncheck all others in name group
43
+ RadioBtn.prototype.update = function() {
44
+ var // this specific radio button
45
+ $input = this.$el.find('input[type=radio]'),
46
+ // the group of radio buttons
47
+ group = 'input[name="'+$input.attr('name')+'"]';
48
+
49
+ // uncheck radio buttons in same group - uncheck input, remove checked class, remove <i>
50
+ $('.radio').has(group).removeClass('checked')
51
+ .find('input').attr('checked', false).end()
52
+ .find('i').remove();
53
+
54
+ // check this radio button - check input, add checked class, append <i>
55
+ $input.attr('checked', true);
56
+ this.$el.append('<i class="icon-dot" />').addClass('checked').trigger('gumby.onChange');
57
+ };
58
+
59
+ // add initialisation
60
+ Gumby.addInitalisation('radiobtns', function() {
61
+ $('.radio').each(function() {
62
+ var $this = $(this);
63
+ // this element has already been initialized
64
+ if($this.data('isRadioBtn')) {
65
+ return true;
66
+ }
67
+ // mark element as initialized
68
+ $this.data('isRadioBtn', true);
69
+ new RadioBtn($this);
70
+ });
71
+ });
72
+
73
+ // register UI module
74
+ Gumby.UIModule({
75
+ module: 'radiobtn',
76
+ events: ['onChange', 'check'],
77
+ init: function() {
78
+ Gumby.initialize('radiobtns');
79
+ }
80
+ });
81
+ }();
@@ -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
+ }();
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Gumby SkipLink
3
+ */
4
+ !function() {
5
+
6
+ 'use strict';
7
+
8
+ function SkipLink($el) {
9
+
10
+ this.$el = $el;
11
+ this.animateElement = $.browser.webkit ? 'body' : 'html';
12
+ this.targetPos = 0;
13
+ this.duration = Number(Gumby.selectAttr.apply(this.$el, ['duration'])) || 200;
14
+ this.offset = Gumby.selectAttr.apply(this.$el, ['offset']) || false;
15
+ this.easing = Gumby.selectAttr.apply(this.$el, ['easing']) || 'swing';
16
+
17
+ var scope = this;
18
+
19
+ // skip to target element on click or trigger of gumby.skipTo event
20
+ this.$el.on(Gumby.click+' gumby.skip', function(e) {
21
+ e.preventDefault();
22
+ // calculate target on each click
23
+ // other UI interactions could effect this
24
+ scope.calculateTarget();
25
+ });
26
+ }
27
+
28
+ // calculate target px point to skip to
29
+ SkipLink.prototype.calculateTarget = function() {
30
+
31
+ var scope = this,
32
+ target = Gumby.selectAttr.apply(this.$el, ['goto']),
33
+ $target;
34
+
35
+ // 'top' specified so target is 0px
36
+ if(target == 'top') {
37
+ this.targetPos = 0;
38
+
39
+ // px point specified
40
+ } else if($.isNumeric(target)) {
41
+ this.targetPos = Number(target);
42
+ } else {
43
+
44
+ // check for element with target as selector
45
+ $target = $(target);
46
+
47
+ // target does not exist, we need a target
48
+ if(!$target) {
49
+ return false;
50
+ }
51
+
52
+ this.targetPos = $target.offset().top;
53
+ }
54
+
55
+ // skip to target
56
+ this.skipTo();
57
+ };
58
+
59
+ // animate body, html scrollTop value to target px point
60
+ SkipLink.prototype.skipTo = function() {
61
+ var scope = this;
62
+
63
+ // slide to position of target
64
+ $(scope.animateElement).animate({
65
+ 'scrollTop' : this.calculateOffset()
66
+ }, this.duration, this.easing, function() {
67
+ scope.$el.trigger('gumby.onComplete');
68
+ });
69
+ };
70
+
71
+ // calculate offset with current target point
72
+ SkipLink.prototype.calculateOffset = function() {
73
+ // no offset so return target here
74
+ if(!this.offset) {
75
+ return this.targetPos;
76
+ }
77
+
78
+ // negative / positive
79
+ var op = this.offset.substr(0, 1),
80
+ off = Number(this.offset.substr(1, this.offset.length));
81
+
82
+ // subtract offset from target position
83
+ if(op === '-') {
84
+ return this.targetPos - off;
85
+ // add offset to target position
86
+ } else if(op === '+') {
87
+ return this.targetPos + off;
88
+ }
89
+ };
90
+
91
+ // add initialisation
92
+ Gumby.addInitalisation('skiplinks', function() {
93
+ $('.skiplink > a, .skip').each(function() {
94
+ var $this = $(this);
95
+ // this element has already been initialized
96
+ if($this.data('isSkipLink')) {
97
+ return true;
98
+ }
99
+ // mark element as initialized
100
+ $this.data('isSkipLink', true);
101
+ new SkipLink($this);
102
+ });
103
+ });
104
+
105
+ // register UI module
106
+ Gumby.UIModule({
107
+ module: 'skiplink',
108
+ events: ['onComplete', 'skip'],
109
+ init: function() {
110
+ Gumby.initialize('skiplinks');
111
+ }
112
+ });
113
+ }();
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Gumby Tabs
3
+ */
4
+ !function() {
5
+
6
+ 'use strict';
7
+
8
+ function Tabs($el) {
9
+
10
+ this.$el = $el;
11
+ this.$nav = this.$el.find('ul.tab-nav > li');
12
+ this.$content = this.$el.find('.tab-content');
13
+
14
+ var scope = this;
15
+
16
+ // listen for click event on tab nav and custom gumby set event
17
+ this.$nav.children('a').on(Gumby.click, function(e) {
18
+ e.preventDefault();
19
+ scope.click($(this));
20
+ });
21
+
22
+ // listen for gumby.set value for dynamically set tabs
23
+ this.$el.on('gumby.set', function(e, index) {
24
+ scope.set(e, index);
25
+ });
26
+ }
27
+
28
+ // handle tab nav click event
29
+ Tabs.prototype.click = function($this) {
30
+ // index of item to activate
31
+ var index = $this.parent().index();
32
+
33
+ // deactivate other tab navigation and content
34
+ this.$nav.add(this.$content).removeClass('active');
35
+
36
+ // activate this tab nav link and content
37
+ this.$nav.eq(index).add(this.$content.eq(index)).addClass('active');
38
+
39
+ // trigger gumby.change event and pass current active tab index
40
+ this.$el.trigger('gumby.onChange', index);
41
+ };
42
+
43
+ // set specific tab
44
+ Tabs.prototype.set = function(e, index) {
45
+ this.$nav.eq(index).find('a').trigger(Gumby.click);
46
+ };
47
+
48
+ // add initialisation
49
+ Gumby.addInitalisation('tabs', function() {
50
+ $('.tabs').each(function() {
51
+ var $this = $(this);
52
+ // this element has already been initialized
53
+ if($this.data('isTabs')) {
54
+ return true;
55
+ }
56
+ // mark element as initialized
57
+ $this.data('isTabs', true);
58
+ new Tabs($this);
59
+ });
60
+ });
61
+
62
+ // register UI module
63
+ Gumby.UIModule({
64
+ module: 'tabs',
65
+ events: ['onChange', 'set'],
66
+ init: function() {
67
+ Gumby.initialize('tabs');
68
+ }
69
+ });
70
+ }();