nailed 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +2 -0
  3. data/Gemfile +14 -0
  4. data/README.md +71 -0
  5. data/README.rdoc +64 -0
  6. data/bin/app +142 -0
  7. data/bin/nailed +90 -0
  8. data/config/products.yml +14 -0
  9. data/config/products.yml.example +65 -0
  10. data/db/database.rb +89 -0
  11. data/lib/nailed.rb +194 -0
  12. data/log/nailed.log +18 -0
  13. data/nailed.gemspec +25 -0
  14. data/public/images/favicon.ico +0 -0
  15. data/public/vendor/css/foundation.css +6031 -0
  16. data/public/vendor/css/foundation.min.css +1 -0
  17. data/public/vendor/css/morris.css +2 -0
  18. data/public/vendor/css/normalize.css +425 -0
  19. data/public/vendor/js/external/fastclick.js +9 -0
  20. data/public/vendor/js/external/jquery.js +26 -0
  21. data/public/vendor/js/external/modernizr.js +8 -0
  22. data/public/vendor/js/external/placeholder.js +2 -0
  23. data/public/vendor/js/foundation.min.js +10 -0
  24. data/public/vendor/js/foundation/foundation.abide.js +294 -0
  25. data/public/vendor/js/foundation/foundation.accordion.js +65 -0
  26. data/public/vendor/js/foundation/foundation.alert.js +43 -0
  27. data/public/vendor/js/foundation/foundation.clearing.js +558 -0
  28. data/public/vendor/js/foundation/foundation.dropdown.js +313 -0
  29. data/public/vendor/js/foundation/foundation.equalizer.js +74 -0
  30. data/public/vendor/js/foundation/foundation.interchange.js +344 -0
  31. data/public/vendor/js/foundation/foundation.joyride.js +915 -0
  32. data/public/vendor/js/foundation/foundation.js +625 -0
  33. data/public/vendor/js/foundation/foundation.magellan.js +189 -0
  34. data/public/vendor/js/foundation/foundation.offcanvas.js +139 -0
  35. data/public/vendor/js/foundation/foundation.orbit.js +472 -0
  36. data/public/vendor/js/foundation/foundation.reveal.js +443 -0
  37. data/public/vendor/js/foundation/foundation.slider.js +231 -0
  38. data/public/vendor/js/foundation/foundation.tab.js +167 -0
  39. data/public/vendor/js/foundation/foundation.tooltip.js +298 -0
  40. data/public/vendor/js/foundation/foundation.topbar.js +436 -0
  41. data/public/vendor/js/morris.min.js +7 -0
  42. data/public/vendor/js/morris/morris.js +1892 -0
  43. data/public/vendor/js/morris/raphael-min.js +11 -0
  44. data/public/vendor/js/morris/raphael.js +8117 -0
  45. data/views/bugzilla.haml +110 -0
  46. data/views/github.haml +63 -0
  47. data/views/index.haml +51 -0
  48. data/views/layout.haml +49 -0
  49. metadata +231 -0
@@ -0,0 +1,167 @@
1
+ ;(function ($, window, document, undefined) {
2
+ 'use strict';
3
+
4
+ Foundation.libs.tab = {
5
+ name : 'tab',
6
+
7
+ version : '5.3.3',
8
+
9
+ settings : {
10
+ active_class: 'active',
11
+ callback : function () {},
12
+ deep_linking: false,
13
+ scroll_to_content: true,
14
+ is_hover: false
15
+ },
16
+
17
+ default_tab_hashes: [],
18
+
19
+ init : function (scope, method, options) {
20
+ var self = this,
21
+ S = this.S;
22
+
23
+ this.bindings(method, options);
24
+ this.handle_location_hash_change();
25
+
26
+ // Store the default active tabs which will be referenced when the
27
+ // location hash is absent, as in the case of navigating the tabs and
28
+ // returning to the first viewing via the browser Back button.
29
+ S('[' + this.attr_name() + '] > .active > a', this.scope).each(function () {
30
+ self.default_tab_hashes.push(this.hash);
31
+ });
32
+ },
33
+
34
+ events : function () {
35
+ var self = this,
36
+ S = this.S;
37
+
38
+ S(this.scope)
39
+ .off('.tab')
40
+ // Click event: tab title
41
+ .on('click.fndtn.tab', '[' + this.attr_name() + '] > * > a', function (e) {
42
+ var settings = S(this).closest('[' + self.attr_name() +']').data(self.attr_name(true) + '-init');
43
+ if (!settings.is_hover || Modernizr.touch) {
44
+ e.preventDefault();
45
+ e.stopPropagation();
46
+ self.toggle_active_tab(S(this).parent());
47
+ }
48
+ })
49
+ // Hover event: tab title
50
+ .on('mouseenter.fndtn.tab', '[' + this.attr_name() + '] > * > a', function (e) {
51
+ var settings = S(this).closest('[' + self.attr_name() +']').data(self.attr_name(true) + '-init');
52
+ if (settings.is_hover) self.toggle_active_tab(S(this).parent());
53
+ });
54
+
55
+ // Location hash change event
56
+ S(window).on('hashchange.fndtn.tab', function (e) {
57
+ e.preventDefault();
58
+ self.handle_location_hash_change();
59
+ });
60
+ },
61
+
62
+ handle_location_hash_change : function () {
63
+ var self = this,
64
+ S = this.S;
65
+
66
+ S('[' + this.attr_name() + ']', this.scope).each(function () {
67
+ var settings = S(this).data(self.attr_name(true) + '-init');
68
+ if (settings.deep_linking) {
69
+ // Match the location hash to a label
70
+ var hash = self.scope.location.hash;
71
+ if (hash != '') {
72
+ // Check whether the location hash references a tab content div or
73
+ // another element on the page (inside or outside the tab content div)
74
+ var hash_element = S(hash);
75
+ if (hash_element.hasClass('content') && hash_element.parent().hasClass('tab-content')) {
76
+ // Tab content div
77
+ self.toggle_active_tab($('[' + self.attr_name() + '] > * > a[href=' + hash + ']').parent());
78
+ } else {
79
+ // Not the tab content div. If inside the tab content, find the
80
+ // containing tab and toggle it as active.
81
+ var hash_tab_container_id = hash_element.closest('.content').attr('id');
82
+ if (hash_tab_container_id != undefined) {
83
+ self.toggle_active_tab($('[' + self.attr_name() + '] > * > a[href=#' + hash_tab_container_id + ']').parent(), hash);
84
+ }
85
+ }
86
+ } else {
87
+ // Reference the default tab hashes which were initialized in the init function
88
+ for (var ind in self.default_tab_hashes) {
89
+ self.toggle_active_tab($('[' + self.attr_name() + '] > * > a[href=' + self.default_tab_hashes[ind] + ']').parent());
90
+ }
91
+ }
92
+ }
93
+ });
94
+ },
95
+
96
+ toggle_active_tab: function (tab, location_hash) {
97
+ var S = this.S,
98
+ tabs = tab.closest('[' + this.attr_name() + ']'),
99
+ anchor = tab.children('a').first(),
100
+ target_hash = '#' + anchor.attr('href').split('#')[1],
101
+ target = S(target_hash),
102
+ siblings = tab.siblings(),
103
+ settings = tabs.data(this.attr_name(true) + '-init');
104
+
105
+ // allow usage of data-tab-content attribute instead of href
106
+ if (S(this).data(this.data_attr('tab-content'))) {
107
+ target_hash = '#' + S(this).data(this.data_attr('tab-content')).split('#')[1];
108
+ target = S(target_hash);
109
+ }
110
+
111
+ if (settings.deep_linking) {
112
+ // Get the scroll Y position prior to moving to the hash ID
113
+ var cur_ypos = $('body,html').scrollTop();
114
+
115
+ // Update the location hash to preserve browser history
116
+ // Note that the hash does not need to correspond to the
117
+ // tab content ID anchor; it can be an ID inside or outside of the tab
118
+ // content div.
119
+ if (location_hash != undefined) {
120
+ window.location.hash = location_hash;
121
+ } else {
122
+ window.location.hash = target_hash;
123
+ }
124
+
125
+ if (settings.scroll_to_content) {
126
+ // If the user is requesting the content of a tab, then scroll to the
127
+ // top of the title area; otherwise, scroll to the element within
128
+ // the content area as defined by the hash value.
129
+ if (location_hash == undefined || location_hash == target_hash) {
130
+ tab.parent()[0].scrollIntoView();
131
+ } else {
132
+ S(target_hash)[0].scrollIntoView();
133
+ }
134
+ } else {
135
+ // Adjust the scrollbar to the Y position prior to setting the hash
136
+ // Only do this for the tab content anchor, otherwise there will be
137
+ // conflicts with in-tab anchor links nested in the tab-content div
138
+ if (location_hash == undefined || location_hash == target_hash) {
139
+ $('body,html').scrollTop(cur_ypos);
140
+ }
141
+ }
142
+ }
143
+
144
+ // WARNING: The activation and deactivation of the tab content must
145
+ // occur after the deep linking in order to properly refresh the browser
146
+ // window (notably in Chrome).
147
+ tab.addClass(settings.active_class).triggerHandler('opened');
148
+ siblings.removeClass(settings.active_class);
149
+ target.siblings().removeClass(settings.active_class).end().addClass(settings.active_class);
150
+ settings.callback(tab);
151
+ target.triggerHandler('toggled', [tab]);
152
+ tabs.triggerHandler('toggled', [target]);
153
+ },
154
+
155
+ data_attr: function (str) {
156
+ if (this.namespace.length > 0) {
157
+ return this.namespace + '-' + str;
158
+ }
159
+
160
+ return str;
161
+ },
162
+
163
+ off : function () {},
164
+
165
+ reflow : function () {}
166
+ };
167
+ }(jQuery, window, window.document));
@@ -0,0 +1,298 @@
1
+ ;(function ($, window, document, undefined) {
2
+ 'use strict';
3
+
4
+ Foundation.libs.tooltip = {
5
+ name : 'tooltip',
6
+
7
+ version : '5.3.3',
8
+
9
+ settings : {
10
+ additional_inheritable_classes : [],
11
+ tooltip_class : '.tooltip',
12
+ append_to: 'body',
13
+ touch_close_text: 'Tap To Close',
14
+ disable_for_touch: false,
15
+ hover_delay: 200,
16
+ show_on : 'all',
17
+ tip_template : function (selector, content) {
18
+ return '<span data-selector="' + selector + '" class="'
19
+ + Foundation.libs.tooltip.settings.tooltip_class.substring(1)
20
+ + '">' + content + '<span class="nub"></span></span>';
21
+ }
22
+ },
23
+
24
+ cache : {},
25
+
26
+ init : function (scope, method, options) {
27
+ Foundation.inherit(this, 'random_str');
28
+ this.bindings(method, options);
29
+ },
30
+
31
+ should_show: function (target, tip) {
32
+ var settings = $.extend({}, this.settings, this.data_options(target));
33
+
34
+ if (settings.show_on === 'all') {
35
+ return true;
36
+ } else if (this.small() && settings.show_on === 'small') {
37
+ return true;
38
+ } else if (this.medium() && settings.show_on === 'medium') {
39
+ return true;
40
+ } else if (this.large() && settings.show_on === 'large') {
41
+ return true;
42
+ }
43
+ return false;
44
+ },
45
+
46
+ medium : function () {
47
+ return matchMedia(Foundation.media_queries['medium']).matches;
48
+ },
49
+
50
+ large : function () {
51
+ return matchMedia(Foundation.media_queries['large']).matches;
52
+ },
53
+
54
+ events : function (instance) {
55
+ var self = this,
56
+ S = self.S;
57
+
58
+ self.create(this.S(instance));
59
+
60
+ $(this.scope)
61
+ .off('.tooltip')
62
+ .on('mouseenter.fndtn.tooltip mouseleave.fndtn.tooltip touchstart.fndtn.tooltip MSPointerDown.fndtn.tooltip',
63
+ '[' + this.attr_name() + ']', function (e) {
64
+ var $this = S(this),
65
+ settings = $.extend({}, self.settings, self.data_options($this)),
66
+ is_touch = false;
67
+
68
+ if (Modernizr.touch && /touchstart|MSPointerDown/i.test(e.type) && S(e.target).is('a')) {
69
+ return false;
70
+ }
71
+
72
+ if (/mouse/i.test(e.type) && self.ie_touch(e)) return false;
73
+
74
+ if ($this.hasClass('open')) {
75
+ if (Modernizr.touch && /touchstart|MSPointerDown/i.test(e.type)) e.preventDefault();
76
+ self.hide($this);
77
+ } else {
78
+ if (settings.disable_for_touch && Modernizr.touch && /touchstart|MSPointerDown/i.test(e.type)) {
79
+ return;
80
+ } else if(!settings.disable_for_touch && Modernizr.touch && /touchstart|MSPointerDown/i.test(e.type)) {
81
+ e.preventDefault();
82
+ S(settings.tooltip_class + '.open').hide();
83
+ is_touch = true;
84
+ }
85
+
86
+ if (/enter|over/i.test(e.type)) {
87
+ this.timer = setTimeout(function () {
88
+ var tip = self.showTip($this);
89
+ }.bind(this), self.settings.hover_delay);
90
+ } else if (e.type === 'mouseout' || e.type === 'mouseleave') {
91
+ clearTimeout(this.timer);
92
+ self.hide($this);
93
+ } else {
94
+ self.showTip($this);
95
+ }
96
+ }
97
+ })
98
+ .on('mouseleave.fndtn.tooltip touchstart.fndtn.tooltip MSPointerDown.fndtn.tooltip', '[' + this.attr_name() + '].open', function (e) {
99
+ if (/mouse/i.test(e.type) && self.ie_touch(e)) return false;
100
+
101
+ if($(this).data('tooltip-open-event-type') == 'touch' && e.type == 'mouseleave') {
102
+ return;
103
+ }
104
+ else if($(this).data('tooltip-open-event-type') == 'mouse' && /MSPointerDown|touchstart/i.test(e.type)) {
105
+ self.convert_to_touch($(this));
106
+ } else {
107
+ self.hide($(this));
108
+ }
109
+ })
110
+ .on('DOMNodeRemoved DOMAttrModified', '[' + this.attr_name() + ']:not(a)', function (e) {
111
+ self.hide(S(this));
112
+ });
113
+ },
114
+
115
+ ie_touch : function (e) {
116
+ // How do I distinguish between IE11 and Windows Phone 8?????
117
+ return false;
118
+ },
119
+
120
+ showTip : function ($target) {
121
+ var $tip = this.getTip($target);
122
+ if (this.should_show($target, $tip)){
123
+ return this.show($target);
124
+ }
125
+ return;
126
+ },
127
+
128
+ getTip : function ($target) {
129
+ var selector = this.selector($target),
130
+ settings = $.extend({}, this.settings, this.data_options($target)),
131
+ tip = null;
132
+
133
+ if (selector) {
134
+ tip = this.S('span[data-selector="' + selector + '"]' + settings.tooltip_class);
135
+ }
136
+
137
+ return (typeof tip === 'object') ? tip : false;
138
+ },
139
+
140
+ selector : function ($target) {
141
+ var id = $target.attr('id'),
142
+ dataSelector = $target.attr(this.attr_name()) || $target.attr('data-selector');
143
+
144
+ if ((id && id.length < 1 || !id) && typeof dataSelector != 'string') {
145
+ dataSelector = this.random_str(6);
146
+ $target.attr('data-selector', dataSelector);
147
+ }
148
+
149
+ return (id && id.length > 0) ? id : dataSelector;
150
+ },
151
+
152
+ create : function ($target) {
153
+ var self = this,
154
+ settings = $.extend({}, this.settings, this.data_options($target)),
155
+ tip_template = this.settings.tip_template;
156
+
157
+ if (typeof settings.tip_template === 'string' && window.hasOwnProperty(settings.tip_template)) {
158
+ tip_template = window[settings.tip_template];
159
+ }
160
+
161
+ var $tip = $(tip_template(this.selector($target), $('<div></div>').html($target.attr('title')).html())),
162
+ classes = this.inheritable_classes($target);
163
+
164
+ $tip.addClass(classes).appendTo(settings.append_to);
165
+
166
+ if (Modernizr.touch) {
167
+ $tip.append('<span class="tap-to-close">'+settings.touch_close_text+'</span>');
168
+ $tip.on('touchstart.fndtn.tooltip MSPointerDown.fndtn.tooltip', function(e) {
169
+ self.hide($target);
170
+ });
171
+ }
172
+
173
+ $target.removeAttr('title').attr('title','');
174
+ },
175
+
176
+ reposition : function (target, tip, classes) {
177
+ var width, nub, nubHeight, nubWidth, column, objPos;
178
+
179
+ tip.css('visibility', 'hidden').show();
180
+
181
+ width = target.data('width');
182
+ nub = tip.children('.nub');
183
+ nubHeight = nub.outerHeight();
184
+ nubWidth = nub.outerHeight();
185
+
186
+ if (this.small()) {
187
+ tip.css({'width' : '100%' });
188
+ } else {
189
+ tip.css({'width' : (width) ? width : 'auto'});
190
+ }
191
+
192
+ objPos = function (obj, top, right, bottom, left, width) {
193
+ return obj.css({
194
+ 'top' : (top) ? top : 'auto',
195
+ 'bottom' : (bottom) ? bottom : 'auto',
196
+ 'left' : (left) ? left : 'auto',
197
+ 'right' : (right) ? right : 'auto'
198
+ }).end();
199
+ };
200
+
201
+ objPos(tip, (target.offset().top + target.outerHeight() + 10), 'auto', 'auto', target.offset().left);
202
+
203
+ if (this.small()) {
204
+ objPos(tip, (target.offset().top + target.outerHeight() + 10), 'auto', 'auto', 12.5, $(this.scope).width());
205
+ tip.addClass('tip-override');
206
+ objPos(nub, -nubHeight, 'auto', 'auto', target.offset().left);
207
+ } else {
208
+ var left = target.offset().left;
209
+ if (Foundation.rtl) {
210
+ nub.addClass('rtl');
211
+ left = target.offset().left + target.outerWidth() - tip.outerWidth();
212
+ }
213
+ objPos(tip, (target.offset().top + target.outerHeight() + 10), 'auto', 'auto', left);
214
+ tip.removeClass('tip-override');
215
+ if (classes && classes.indexOf('tip-top') > -1) {
216
+ if (Foundation.rtl) nub.addClass('rtl');
217
+ objPos(tip, (target.offset().top - tip.outerHeight()), 'auto', 'auto', left)
218
+ .removeClass('tip-override');
219
+ } else if (classes && classes.indexOf('tip-left') > -1) {
220
+ objPos(tip, (target.offset().top + (target.outerHeight() / 2) - (tip.outerHeight() / 2)), 'auto', 'auto', (target.offset().left - tip.outerWidth() - nubHeight))
221
+ .removeClass('tip-override');
222
+ nub.removeClass('rtl');
223
+ } else if (classes && classes.indexOf('tip-right') > -1) {
224
+ objPos(tip, (target.offset().top + (target.outerHeight() / 2) - (tip.outerHeight() / 2)), 'auto', 'auto', (target.offset().left + target.outerWidth() + nubHeight))
225
+ .removeClass('tip-override');
226
+ nub.removeClass('rtl');
227
+ }
228
+ }
229
+
230
+ tip.css('visibility', 'visible').hide();
231
+ },
232
+
233
+ small : function () {
234
+ return matchMedia(Foundation.media_queries.small).matches &&
235
+ !matchMedia(Foundation.media_queries.medium).matches;
236
+ },
237
+
238
+ inheritable_classes : function ($target) {
239
+ var settings = $.extend({}, this.settings, this.data_options($target)),
240
+ inheritables = ['tip-top', 'tip-left', 'tip-bottom', 'tip-right', 'radius', 'round'].concat(settings.additional_inheritable_classes),
241
+ classes = $target.attr('class'),
242
+ filtered = classes ? $.map(classes.split(' '), function (el, i) {
243
+ if ($.inArray(el, inheritables) !== -1) {
244
+ return el;
245
+ }
246
+ }).join(' ') : '';
247
+
248
+ return $.trim(filtered);
249
+ },
250
+
251
+ convert_to_touch : function($target) {
252
+ var self = this,
253
+ $tip = self.getTip($target),
254
+ settings = $.extend({}, self.settings, self.data_options($target));
255
+
256
+ if ($tip.find('.tap-to-close').length === 0) {
257
+ $tip.append('<span class="tap-to-close">'+settings.touch_close_text+'</span>');
258
+ $tip.on('click.fndtn.tooltip.tapclose touchstart.fndtn.tooltip.tapclose MSPointerDown.fndtn.tooltip.tapclose', function(e) {
259
+ self.hide($target);
260
+ });
261
+ }
262
+
263
+ $target.data('tooltip-open-event-type', 'touch');
264
+ },
265
+
266
+ show : function ($target) {
267
+ var $tip = this.getTip($target);
268
+
269
+ if ($target.data('tooltip-open-event-type') == 'touch') {
270
+ this.convert_to_touch($target);
271
+ }
272
+
273
+ this.reposition($target, $tip, $target.attr('class'));
274
+ $target.addClass('open');
275
+ $tip.fadeIn(150);
276
+ },
277
+
278
+ hide : function ($target) {
279
+ var $tip = this.getTip($target);
280
+
281
+ $tip.fadeOut(150, function() {
282
+ $tip.find('.tap-to-close').remove();
283
+ $tip.off('click.fndtn.tooltip.tapclose MSPointerDown.fndtn.tapclose');
284
+ $target.removeClass('open');
285
+ });
286
+ },
287
+
288
+ off : function () {
289
+ var self = this;
290
+ this.S(this.scope).off('.fndtn.tooltip');
291
+ this.S(this.settings.tooltip_class).each(function (i) {
292
+ $('[' + self.attr_name() + ']').eq(i).attr('title', $(this).text());
293
+ }).remove();
294
+ },
295
+
296
+ reflow : function () {}
297
+ };
298
+ }(jQuery, window, window.document));