pushnote 0.0.4 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.rspec +3 -0
  4. data/README.md +11 -30
  5. data/Rakefile +20 -0
  6. data/bin/pushnote +20 -2
  7. data/config.codekit +1005 -0
  8. data/config.ru +2 -0
  9. data/config/database.yml +17 -0
  10. data/db/migrate/20150131202537_create_notes_table.rb +9 -0
  11. data/db/schema.rb +23 -0
  12. data/lib/pushnote.rb +0 -3
  13. data/lib/pushnote/adapters.rb +1 -0
  14. data/lib/pushnote/adapters/base.rb +7 -0
  15. data/lib/pushnote/adapters/local.rb +17 -0
  16. data/lib/pushnote/app.rb +50 -0
  17. data/lib/pushnote/models/note.rb +4 -0
  18. data/lib/pushnote/public/css/foundation.css +6139 -0
  19. data/lib/pushnote/public/css/foundation.min.css +1 -0
  20. data/lib/pushnote/public/css/normalize.css +427 -0
  21. data/lib/pushnote/public/humans.txt +8 -0
  22. data/lib/pushnote/public/img/.gitkeep +1 -0
  23. data/lib/pushnote/public/index.html +166 -0
  24. data/lib/pushnote/public/js/foundation.min.js +5960 -0
  25. data/lib/pushnote/public/js/foundation/foundation.abide.js +318 -0
  26. data/lib/pushnote/public/js/foundation/foundation.accordion.js +67 -0
  27. data/lib/pushnote/public/js/foundation/foundation.alert.js +43 -0
  28. data/lib/pushnote/public/js/foundation/foundation.clearing.js +558 -0
  29. data/lib/pushnote/public/js/foundation/foundation.dropdown.js +439 -0
  30. data/lib/pushnote/public/js/foundation/foundation.equalizer.js +73 -0
  31. data/lib/pushnote/public/js/foundation/foundation.interchange.js +348 -0
  32. data/lib/pushnote/public/js/foundation/foundation.joyride.js +924 -0
  33. data/lib/pushnote/public/js/foundation/foundation.js +690 -0
  34. data/lib/pushnote/public/js/foundation/foundation.magellan.js +198 -0
  35. data/lib/pushnote/public/js/foundation/foundation.offcanvas.js +152 -0
  36. data/lib/pushnote/public/js/foundation/foundation.orbit.js +472 -0
  37. data/lib/pushnote/public/js/foundation/foundation.reveal.js +449 -0
  38. data/lib/pushnote/public/js/foundation/foundation.slider.js +267 -0
  39. data/lib/pushnote/public/js/foundation/foundation.tab.js +217 -0
  40. data/lib/pushnote/public/js/foundation/foundation.tooltip.js +300 -0
  41. data/lib/pushnote/public/js/foundation/foundation.topbar.js +445 -0
  42. data/lib/pushnote/public/js/vendor/fastclick.js +9 -0
  43. data/lib/pushnote/public/js/vendor/jquery.cookie.js +8 -0
  44. data/lib/pushnote/public/js/vendor/jquery.js +26 -0
  45. data/lib/pushnote/public/js/vendor/modernizr.js +8 -0
  46. data/lib/pushnote/public/js/vendor/placeholder.js +2 -0
  47. data/lib/pushnote/public/robots.txt +4 -0
  48. data/lib/pushnote/version.rb +1 -1
  49. data/lib/pushnote/views/index.erb +15 -0
  50. data/lib/pushnote/views/layout.erb +48 -0
  51. data/lib/pushnote/views/show.erb +8 -0
  52. data/pushnote.gemspec +15 -5
  53. data/spec/lib/controllers/notes_spec.rb +21 -0
  54. data/spec/spec_helper.rb +16 -0
  55. metadata +193 -9
  56. data/.pushnote.yml +0 -1
  57. data/lib/pushnote/cli.rb +0 -40
  58. data/lib/pushnote/configuration.rb +0 -12
  59. data/lib/pushnote/note.rb +0 -36
@@ -0,0 +1,348 @@
1
+ ;(function ($, window, document, undefined) {
2
+ 'use strict';
3
+
4
+ Foundation.libs.interchange = {
5
+ name : 'interchange',
6
+
7
+ version : '5.5.0',
8
+
9
+ cache : {},
10
+
11
+ images_loaded : false,
12
+ nodes_loaded : false,
13
+
14
+ settings : {
15
+ load_attr : 'interchange',
16
+
17
+ named_queries : {
18
+ 'default' : 'only screen',
19
+ 'small' : Foundation.media_queries['small'],
20
+ 'small-only' : Foundation.media_queries['small-only'],
21
+ 'medium' : Foundation.media_queries['medium'],
22
+ 'medium-only' : Foundation.media_queries['medium-only'],
23
+ 'large' : Foundation.media_queries['large'],
24
+ 'large-only' : Foundation.media_queries['large-only'],
25
+ 'xlarge' : Foundation.media_queries['xlarge'],
26
+ 'xlarge-only' : Foundation.media_queries['xlarge-only'],
27
+ 'xxlarge' : Foundation.media_queries['xxlarge'],
28
+ 'landscape' : 'only screen and (orientation: landscape)',
29
+ 'portrait' : 'only screen and (orientation: portrait)',
30
+ 'retina' : 'only screen and (-webkit-min-device-pixel-ratio: 2),' +
31
+ 'only screen and (min--moz-device-pixel-ratio: 2),' +
32
+ 'only screen and (-o-min-device-pixel-ratio: 2/1),' +
33
+ 'only screen and (min-device-pixel-ratio: 2),' +
34
+ 'only screen and (min-resolution: 192dpi),' +
35
+ 'only screen and (min-resolution: 2dppx)'
36
+ },
37
+
38
+ directives : {
39
+ replace: function (el, path, trigger) {
40
+ // The trigger argument, if called within the directive, fires
41
+ // an event named after the directive on the element, passing
42
+ // any parameters along to the event that you pass to trigger.
43
+ //
44
+ // ex. trigger(), trigger([a, b, c]), or trigger(a, b, c)
45
+ //
46
+ // This allows you to bind a callback like so:
47
+ // $('#interchangeContainer').on('replace', function (e, a, b, c) {
48
+ // console.log($(this).html(), a, b, c);
49
+ // });
50
+
51
+ if (/IMG/.test(el[0].nodeName)) {
52
+ var orig_path = el[0].src;
53
+
54
+ if (new RegExp(path, 'i').test(orig_path)) return;
55
+
56
+ el[0].src = path;
57
+
58
+ return trigger(el[0].src);
59
+ }
60
+ var last_path = el.data(this.data_attr + '-last-path'),
61
+ self = this;
62
+
63
+ if (last_path == path) return;
64
+
65
+ if (/\.(gif|jpg|jpeg|tiff|png)([?#].*)?/i.test(path)) {
66
+ $(el).css('background-image', 'url('+path+')');
67
+ el.data('interchange-last-path', path);
68
+ return trigger(path);
69
+ }
70
+
71
+ return $.get(path, function (response) {
72
+ el.html(response);
73
+ el.data(self.data_attr + '-last-path', path);
74
+ trigger();
75
+ });
76
+
77
+ }
78
+ }
79
+ },
80
+
81
+ init : function (scope, method, options) {
82
+ Foundation.inherit(this, 'throttle random_str');
83
+
84
+ this.data_attr = this.set_data_attr();
85
+ $.extend(true, this.settings, method, options);
86
+ this.bindings(method, options);
87
+ this.load('images');
88
+ this.load('nodes');
89
+ },
90
+
91
+ get_media_hash : function() {
92
+ var mediaHash='';
93
+ for (var queryName in this.settings.named_queries ) {
94
+ mediaHash += matchMedia(this.settings.named_queries[queryName]).matches.toString();
95
+ }
96
+ return mediaHash;
97
+ },
98
+
99
+ events : function () {
100
+ var self = this, prevMediaHash;
101
+
102
+ $(window)
103
+ .off('.interchange')
104
+ .on('resize.fndtn.interchange', self.throttle(function () {
105
+ var currMediaHash = self.get_media_hash();
106
+ if (currMediaHash !== prevMediaHash) {
107
+ self.resize();
108
+ }
109
+ prevMediaHash = currMediaHash;
110
+ }, 50));
111
+
112
+ return this;
113
+ },
114
+
115
+ resize : function () {
116
+ var cache = this.cache;
117
+
118
+ if(!this.images_loaded || !this.nodes_loaded) {
119
+ setTimeout($.proxy(this.resize, this), 50);
120
+ return;
121
+ }
122
+
123
+ for (var uuid in cache) {
124
+ if (cache.hasOwnProperty(uuid)) {
125
+ var passed = this.results(uuid, cache[uuid]);
126
+
127
+ if (passed) {
128
+ this.settings.directives[passed
129
+ .scenario[1]].call(this, passed.el, passed.scenario[0], function () {
130
+ if (arguments[0] instanceof Array) {
131
+ var args = arguments[0];
132
+ } else {
133
+ var args = Array.prototype.slice.call(arguments, 0);
134
+ }
135
+
136
+ passed.el.trigger(passed.scenario[1], args);
137
+ });
138
+ }
139
+ }
140
+ }
141
+
142
+ },
143
+
144
+ results : function (uuid, scenarios) {
145
+ var count = scenarios.length;
146
+
147
+ if (count > 0) {
148
+ var el = this.S('[' + this.add_namespace('data-uuid') + '="' + uuid + '"]');
149
+
150
+ while (count--) {
151
+ var mq, rule = scenarios[count][2];
152
+ if (this.settings.named_queries.hasOwnProperty(rule)) {
153
+ mq = matchMedia(this.settings.named_queries[rule]);
154
+ } else {
155
+ mq = matchMedia(rule);
156
+ }
157
+ if (mq.matches) {
158
+ return {el: el, scenario: scenarios[count]};
159
+ }
160
+ }
161
+ }
162
+
163
+ return false;
164
+ },
165
+
166
+ load : function (type, force_update) {
167
+ if (typeof this['cached_' + type] === 'undefined' || force_update) {
168
+ this['update_' + type]();
169
+ }
170
+
171
+ return this['cached_' + type];
172
+ },
173
+
174
+ update_images : function () {
175
+ var images = this.S('img[' + this.data_attr + ']'),
176
+ count = images.length,
177
+ i = count,
178
+ loaded_count = 0,
179
+ data_attr = this.data_attr;
180
+
181
+ this.cache = {};
182
+ this.cached_images = [];
183
+ this.images_loaded = (count === 0);
184
+
185
+ while (i--) {
186
+ loaded_count++;
187
+ if (images[i]) {
188
+ var str = images[i].getAttribute(data_attr) || '';
189
+
190
+ if (str.length > 0) {
191
+ this.cached_images.push(images[i]);
192
+ }
193
+ }
194
+
195
+ if (loaded_count === count) {
196
+ this.images_loaded = true;
197
+ this.enhance('images');
198
+ }
199
+ }
200
+
201
+ return this;
202
+ },
203
+
204
+ update_nodes : function () {
205
+ var nodes = this.S('[' + this.data_attr + ']').not('img'),
206
+ count = nodes.length,
207
+ i = count,
208
+ loaded_count = 0,
209
+ data_attr = this.data_attr;
210
+
211
+ this.cached_nodes = [];
212
+ this.nodes_loaded = (count === 0);
213
+
214
+
215
+ while (i--) {
216
+ loaded_count++;
217
+ var str = nodes[i].getAttribute(data_attr) || '';
218
+
219
+ if (str.length > 0) {
220
+ this.cached_nodes.push(nodes[i]);
221
+ }
222
+
223
+ if(loaded_count === count) {
224
+ this.nodes_loaded = true;
225
+ this.enhance('nodes');
226
+ }
227
+ }
228
+
229
+ return this;
230
+ },
231
+
232
+ enhance : function (type) {
233
+ var i = this['cached_' + type].length;
234
+
235
+ while (i--) {
236
+ this.object($(this['cached_' + type][i]));
237
+ }
238
+
239
+ return $(window).trigger('resize').trigger('resize.fndtn.interchange');
240
+ },
241
+
242
+ convert_directive : function (directive) {
243
+
244
+ var trimmed = this.trim(directive);
245
+
246
+ if (trimmed.length > 0) {
247
+ return trimmed;
248
+ }
249
+
250
+ return 'replace';
251
+ },
252
+
253
+ parse_scenario : function (scenario) {
254
+ // This logic had to be made more complex since some users were using commas in the url path
255
+ // So we cannot simply just split on a comma
256
+ var directive_match = scenario[0].match(/(.+),\s*(\w+)\s*$/),
257
+ media_query = scenario[1];
258
+
259
+ if (directive_match) {
260
+ var path = directive_match[1],
261
+ directive = directive_match[2];
262
+ }
263
+ else {
264
+ var cached_split = scenario[0].split(/,\s*$/),
265
+ path = cached_split[0],
266
+ directive = '';
267
+ }
268
+
269
+ return [this.trim(path), this.convert_directive(directive), this.trim(media_query)];
270
+ },
271
+
272
+ object : function(el) {
273
+ var raw_arr = this.parse_data_attr(el),
274
+ scenarios = [],
275
+ i = raw_arr.length;
276
+
277
+ if (i > 0) {
278
+ while (i--) {
279
+ var split = raw_arr[i].split(/\((.*?)(\))$/);
280
+
281
+ if (split.length > 1) {
282
+ var params = this.parse_scenario(split);
283
+ scenarios.push(params);
284
+ }
285
+ }
286
+ }
287
+
288
+ return this.store(el, scenarios);
289
+ },
290
+
291
+ store : function (el, scenarios) {
292
+ var uuid = this.random_str(),
293
+ current_uuid = el.data(this.add_namespace('uuid', true));
294
+
295
+ if (this.cache[current_uuid]) return this.cache[current_uuid];
296
+
297
+ el.attr(this.add_namespace('data-uuid'), uuid);
298
+
299
+ return this.cache[uuid] = scenarios;
300
+ },
301
+
302
+ trim : function(str) {
303
+
304
+ if (typeof str === 'string') {
305
+ return $.trim(str);
306
+ }
307
+
308
+ return str;
309
+ },
310
+
311
+ set_data_attr: function (init) {
312
+ if (init) {
313
+ if (this.namespace.length > 0) {
314
+ return this.namespace + '-' + this.settings.load_attr;
315
+ }
316
+
317
+ return this.settings.load_attr;
318
+ }
319
+
320
+ if (this.namespace.length > 0) {
321
+ return 'data-' + this.namespace + '-' + this.settings.load_attr;
322
+ }
323
+
324
+ return 'data-' + this.settings.load_attr;
325
+ },
326
+
327
+ parse_data_attr : function (el) {
328
+ var raw = el.attr(this.attr_name()).split(/\[(.*?)\]/),
329
+ i = raw.length,
330
+ output = [];
331
+
332
+ while (i--) {
333
+ if (raw[i].replace(/[\W\d]+/, '').length > 4) {
334
+ output.push(raw[i]);
335
+ }
336
+ }
337
+
338
+ return output;
339
+ },
340
+
341
+ reflow : function () {
342
+ this.load('images', true);
343
+ this.load('nodes', true);
344
+ }
345
+
346
+ };
347
+
348
+ }(jQuery, window, window.document));
@@ -0,0 +1,924 @@
1
+ ;(function ($, window, document, undefined) {
2
+ 'use strict';
3
+
4
+ var Modernizr = Modernizr || false;
5
+
6
+ Foundation.libs.joyride = {
7
+ name : 'joyride',
8
+
9
+ version : '5.5.0',
10
+
11
+ defaults : {
12
+ expose : false, // turn on or off the expose feature
13
+ modal : true, // Whether to cover page with modal during the tour
14
+ keyboard : true, // enable left, right and esc keystrokes
15
+ tip_location : 'bottom', // 'top' or 'bottom' in relation to parent
16
+ nub_position : 'auto', // override on a per tooltip bases
17
+ scroll_speed : 1500, // Page scrolling speed in milliseconds, 0 = no scroll animation
18
+ scroll_animation : 'linear', // supports 'swing' and 'linear', extend with jQuery UI.
19
+ timer : 0, // 0 = no timer , all other numbers = timer in milliseconds
20
+ start_timer_on_click : true, // true or false - true requires clicking the first button start the timer
21
+ start_offset : 0, // the index of the tooltip you want to start on (index of the li)
22
+ next_button : true, // true or false to control whether a next button is used
23
+ prev_button : true, // true or false to control whether a prev button is used
24
+ tip_animation : 'fade', // 'pop' or 'fade' in each tip
25
+ pause_after : [], // array of indexes where to pause the tour after
26
+ exposed : [], // array of expose elements
27
+ tip_animation_fade_speed : 300, // when tipAnimation = 'fade' this is speed in milliseconds for the transition
28
+ cookie_monster : false, // true or false to control whether cookies are used
29
+ cookie_name : 'joyride', // Name the cookie you'll use
30
+ cookie_domain : false, // Will this cookie be attached to a domain, ie. '.notableapp.com'
31
+ cookie_expires : 365, // set when you would like the cookie to expire.
32
+ tip_container : 'body', // Where will the tip be attached
33
+ abort_on_close : true, // When true, the close event will not fire any callback
34
+ tip_location_patterns : {
35
+ top: ['bottom'],
36
+ bottom: [], // bottom should not need to be repositioned
37
+ left: ['right', 'top', 'bottom'],
38
+ right: ['left', 'top', 'bottom']
39
+ },
40
+ post_ride_callback : function (){}, // A method to call once the tour closes (canceled or complete)
41
+ post_step_callback : function (){}, // A method to call after each step
42
+ pre_step_callback : function (){}, // A method to call before each step
43
+ pre_ride_callback : function (){}, // A method to call before the tour starts (passed index, tip, and cloned exposed element)
44
+ post_expose_callback : function (){}, // A method to call after an element has been exposed
45
+ template : { // HTML segments for tip layout
46
+ link : '<a href="#close" class="joyride-close-tip">&times;</a>',
47
+ timer : '<div class="joyride-timer-indicator-wrap"><span class="joyride-timer-indicator"></span></div>',
48
+ tip : '<div class="joyride-tip-guide"><span class="joyride-nub"></span></div>',
49
+ wrapper : '<div class="joyride-content-wrapper"></div>',
50
+ button : '<a href="#" class="small button joyride-next-tip"></a>',
51
+ prev_button : '<a href="#" class="small button joyride-prev-tip"></a>',
52
+ modal : '<div class="joyride-modal-bg"></div>',
53
+ expose : '<div class="joyride-expose-wrapper"></div>',
54
+ expose_cover : '<div class="joyride-expose-cover"></div>'
55
+ },
56
+ expose_add_class : '' // One or more space-separated class names to be added to exposed element
57
+ },
58
+
59
+ init : function (scope, method, options) {
60
+ Foundation.inherit(this, 'throttle random_str');
61
+
62
+ this.settings = this.settings || $.extend({}, this.defaults, (options || method));
63
+
64
+ this.bindings(method, options)
65
+ },
66
+
67
+ go_next : function() {
68
+ if (this.settings.$li.next().length < 1) {
69
+ this.end();
70
+ } else if (this.settings.timer > 0) {
71
+ clearTimeout(this.settings.automate);
72
+ this.hide();
73
+ this.show();
74
+ this.startTimer();
75
+ } else {
76
+ this.hide();
77
+ this.show();
78
+ }
79
+ },
80
+
81
+ go_prev : function() {
82
+ if (this.settings.$li.prev().length < 1) {
83
+ // Do nothing if there are no prev element
84
+ } else if (this.settings.timer > 0) {
85
+ clearTimeout(this.settings.automate);
86
+ this.hide();
87
+ this.show(null, true);
88
+ this.startTimer();
89
+ } else {
90
+ this.hide();
91
+ this.show(null, true);
92
+ }
93
+ },
94
+
95
+ events : function () {
96
+ var self = this;
97
+
98
+ $(this.scope)
99
+ .off('.joyride')
100
+ .on('click.fndtn.joyride', '.joyride-next-tip, .joyride-modal-bg', function (e) {
101
+ e.preventDefault();
102
+ this.go_next()
103
+ }.bind(this))
104
+ .on('click.fndtn.joyride', '.joyride-prev-tip', function (e) {
105
+ e.preventDefault();
106
+ this.go_prev();
107
+ }.bind(this))
108
+
109
+ .on('click.fndtn.joyride', '.joyride-close-tip', function (e) {
110
+ e.preventDefault();
111
+ this.end(this.settings.abort_on_close);
112
+ }.bind(this))
113
+
114
+ .on('keyup.fndtn.joyride', function(e) {
115
+ // Don't do anything if keystrokes are disabled
116
+ // or if the joyride is not being shown
117
+ if (!this.settings.keyboard || !this.settings.riding) return;
118
+
119
+ switch (e.which) {
120
+ case 39: // right arrow
121
+ e.preventDefault();
122
+ this.go_next();
123
+ break;
124
+ case 37: // left arrow
125
+ e.preventDefault();
126
+ this.go_prev();
127
+ break;
128
+ case 27: // escape
129
+ e.preventDefault();
130
+ this.end(this.settings.abort_on_close);
131
+ }
132
+ }.bind(this));
133
+
134
+ $(window)
135
+ .off('.joyride')
136
+ .on('resize.fndtn.joyride', self.throttle(function () {
137
+ if ($('[' + self.attr_name() + ']').length > 0 && self.settings.$next_tip && self.settings.riding) {
138
+ if (self.settings.exposed.length > 0) {
139
+ var $els = $(self.settings.exposed);
140
+
141
+ $els.each(function () {
142
+ var $this = $(this);
143
+ self.un_expose($this);
144
+ self.expose($this);
145
+ });
146
+ }
147
+
148
+ if (self.is_phone()) {
149
+ self.pos_phone();
150
+ } else {
151
+ self.pos_default(false);
152
+ }
153
+ }
154
+ }, 100));
155
+ },
156
+
157
+ start : function () {
158
+ var self = this,
159
+ $this = $('[' + this.attr_name() + ']', this.scope),
160
+ integer_settings = ['timer', 'scrollSpeed', 'startOffset', 'tipAnimationFadeSpeed', 'cookieExpires'],
161
+ int_settings_count = integer_settings.length;
162
+
163
+ if (!$this.length > 0) return;
164
+
165
+ if (!this.settings.init) this.events();
166
+
167
+ this.settings = $this.data(this.attr_name(true) + '-init');
168
+
169
+ // non configureable settings
170
+ this.settings.$content_el = $this;
171
+ this.settings.$body = $(this.settings.tip_container);
172
+ this.settings.body_offset = $(this.settings.tip_container).position();
173
+ this.settings.$tip_content = this.settings.$content_el.find('> li');
174
+ this.settings.paused = false;
175
+ this.settings.attempts = 0;
176
+ this.settings.riding = true;
177
+
178
+ // can we create cookies?
179
+ if (typeof $.cookie !== 'function') {
180
+ this.settings.cookie_monster = false;
181
+ }
182
+
183
+ // generate the tips and insert into dom.
184
+ if (!this.settings.cookie_monster || this.settings.cookie_monster && !$.cookie(this.settings.cookie_name)) {
185
+ this.settings.$tip_content.each(function (index) {
186
+ var $this = $(this);
187
+ this.settings = $.extend({}, self.defaults, self.data_options($this));
188
+
189
+ // Make sure that settings parsed from data_options are integers where necessary
190
+ var i = int_settings_count;
191
+ while (i--) {
192
+ self.settings[integer_settings[i]] = parseInt(self.settings[integer_settings[i]], 10);
193
+ }
194
+ self.create({$li : $this, index : index});
195
+ });
196
+
197
+ // show first tip
198
+ if (!this.settings.start_timer_on_click && this.settings.timer > 0) {
199
+ this.show('init');
200
+ this.startTimer();
201
+ } else {
202
+ this.show('init');
203
+ }
204
+
205
+ }
206
+ },
207
+
208
+ resume : function () {
209
+ this.set_li();
210
+ this.show();
211
+ },
212
+
213
+ tip_template : function (opts) {
214
+ var $blank, content;
215
+
216
+ opts.tip_class = opts.tip_class || '';
217
+
218
+ $blank = $(this.settings.template.tip).addClass(opts.tip_class);
219
+ content = $.trim($(opts.li).html()) +
220
+ this.prev_button_text(opts.prev_button_text, opts.index) +
221
+ this.button_text(opts.button_text) +
222
+ this.settings.template.link +
223
+ this.timer_instance(opts.index);
224
+
225
+ $blank.append($(this.settings.template.wrapper));
226
+ $blank.first().attr(this.add_namespace('data-index'), opts.index);
227
+ $('.joyride-content-wrapper', $blank).append(content);
228
+
229
+ return $blank[0];
230
+ },
231
+
232
+ timer_instance : function (index) {
233
+ var txt;
234
+
235
+ if ((index === 0 && this.settings.start_timer_on_click && this.settings.timer > 0) || this.settings.timer === 0) {
236
+ txt = '';
237
+ } else {
238
+ txt = $(this.settings.template.timer)[0].outerHTML;
239
+ }
240
+ return txt;
241
+ },
242
+
243
+ button_text : function (txt) {
244
+ if (this.settings.tip_settings.next_button) {
245
+ txt = $.trim(txt) || 'Next';
246
+ txt = $(this.settings.template.button).append(txt)[0].outerHTML;
247
+ } else {
248
+ txt = '';
249
+ }
250
+ return txt;
251
+ },
252
+
253
+ prev_button_text : function (txt, idx) {
254
+ if (this.settings.tip_settings.prev_button) {
255
+ txt = $.trim(txt) || 'Previous';
256
+
257
+ // Add the disabled class to the button if it's the first element
258
+ if (idx == 0)
259
+ txt = $(this.settings.template.prev_button).append(txt).addClass('disabled')[0].outerHTML;
260
+ else
261
+ txt = $(this.settings.template.prev_button).append(txt)[0].outerHTML;
262
+ } else {
263
+ txt = '';
264
+ }
265
+ return txt;
266
+ },
267
+
268
+ create : function (opts) {
269
+ this.settings.tip_settings = $.extend({}, this.settings, this.data_options(opts.$li));
270
+ var buttonText = opts.$li.attr(this.add_namespace('data-button'))
271
+ || opts.$li.attr(this.add_namespace('data-text')),
272
+ prevButtonText = opts.$li.attr(this.add_namespace('data-button-prev'))
273
+ || opts.$li.attr(this.add_namespace('data-prev-text')),
274
+ tipClass = opts.$li.attr('class'),
275
+ $tip_content = $(this.tip_template({
276
+ tip_class : tipClass,
277
+ index : opts.index,
278
+ button_text : buttonText,
279
+ prev_button_text : prevButtonText,
280
+ li : opts.$li
281
+ }));
282
+
283
+ $(this.settings.tip_container).append($tip_content);
284
+ },
285
+
286
+ show : function (init, is_prev) {
287
+ var $timer = null;
288
+
289
+ // are we paused?
290
+ if (this.settings.$li === undefined
291
+ || ($.inArray(this.settings.$li.index(), this.settings.pause_after) === -1)) {
292
+
293
+ // don't go to the next li if the tour was paused
294
+ if (this.settings.paused) {
295
+ this.settings.paused = false;
296
+ } else {
297
+ this.set_li(init, is_prev);
298
+ }
299
+
300
+ this.settings.attempts = 0;
301
+
302
+ if (this.settings.$li.length && this.settings.$target.length > 0) {
303
+ if (init) { //run when we first start
304
+ this.settings.pre_ride_callback(this.settings.$li.index(), this.settings.$next_tip);
305
+ if (this.settings.modal) {
306
+ this.show_modal();
307
+ }
308
+ }
309
+
310
+ this.settings.pre_step_callback(this.settings.$li.index(), this.settings.$next_tip);
311
+
312
+ if (this.settings.modal && this.settings.expose) {
313
+ this.expose();
314
+ }
315
+
316
+ this.settings.tip_settings = $.extend({}, this.settings, this.data_options(this.settings.$li));
317
+
318
+ this.settings.timer = parseInt(this.settings.timer, 10);
319
+
320
+ this.settings.tip_settings.tip_location_pattern = this.settings.tip_location_patterns[this.settings.tip_settings.tip_location];
321
+
322
+ // scroll and hide bg if not modal
323
+ if (!/body/i.test(this.settings.$target.selector)) {
324
+ var joyridemodalbg = $('.joyride-modal-bg');
325
+ if (/pop/i.test(this.settings.tipAnimation)) {
326
+ joyridemodalbg.hide();
327
+ } else {
328
+ joyridemodalbg.fadeOut(this.settings.tipAnimationFadeSpeed);
329
+ }
330
+ this.scroll_to();
331
+ }
332
+
333
+ if (this.is_phone()) {
334
+ this.pos_phone(true);
335
+ } else {
336
+ this.pos_default(true);
337
+ }
338
+
339
+ $timer = this.settings.$next_tip.find('.joyride-timer-indicator');
340
+
341
+ if (/pop/i.test(this.settings.tip_animation)) {
342
+
343
+ $timer.width(0);
344
+
345
+ if (this.settings.timer > 0) {
346
+
347
+ this.settings.$next_tip.show();
348
+
349
+ setTimeout(function () {
350
+ $timer.animate({
351
+ width: $timer.parent().width()
352
+ }, this.settings.timer, 'linear');
353
+ }.bind(this), this.settings.tip_animation_fade_speed);
354
+
355
+ } else {
356
+ this.settings.$next_tip.show();
357
+
358
+ }
359
+
360
+
361
+ } else if (/fade/i.test(this.settings.tip_animation)) {
362
+
363
+ $timer.width(0);
364
+
365
+ if (this.settings.timer > 0) {
366
+
367
+ this.settings.$next_tip
368
+ .fadeIn(this.settings.tip_animation_fade_speed)
369
+ .show();
370
+
371
+ setTimeout(function () {
372
+ $timer.animate({
373
+ width: $timer.parent().width()
374
+ }, this.settings.timer, 'linear');
375
+ }.bind(this), this.settings.tip_animation_fade_speed);
376
+
377
+ } else {
378
+ this.settings.$next_tip.fadeIn(this.settings.tip_animation_fade_speed);
379
+ }
380
+ }
381
+
382
+ this.settings.$current_tip = this.settings.$next_tip;
383
+
384
+ // skip non-existant targets
385
+ } else if (this.settings.$li && this.settings.$target.length < 1) {
386
+
387
+ this.show(init, is_prev);
388
+
389
+ } else {
390
+
391
+ this.end();
392
+
393
+ }
394
+ } else {
395
+
396
+ this.settings.paused = true;
397
+
398
+ }
399
+
400
+ },
401
+
402
+ is_phone : function () {
403
+ return matchMedia(Foundation.media_queries.small).matches &&
404
+ !matchMedia(Foundation.media_queries.medium).matches;
405
+ },
406
+
407
+ hide : function () {
408
+ if (this.settings.modal && this.settings.expose) {
409
+ this.un_expose();
410
+ }
411
+
412
+ if (!this.settings.modal) {
413
+ $('.joyride-modal-bg').hide();
414
+ }
415
+
416
+ // Prevent scroll bouncing...wait to remove from layout
417
+ this.settings.$current_tip.css('visibility', 'hidden');
418
+ setTimeout($.proxy(function() {
419
+ this.hide();
420
+ this.css('visibility', 'visible');
421
+ }, this.settings.$current_tip), 0);
422
+ this.settings.post_step_callback(this.settings.$li.index(),
423
+ this.settings.$current_tip);
424
+ },
425
+
426
+ set_li : function (init, is_prev) {
427
+ if (init) {
428
+ this.settings.$li = this.settings.$tip_content.eq(this.settings.start_offset);
429
+ this.set_next_tip();
430
+ this.settings.$current_tip = this.settings.$next_tip;
431
+ } else {
432
+ if (is_prev)
433
+ this.settings.$li = this.settings.$li.prev();
434
+ else
435
+ this.settings.$li = this.settings.$li.next();
436
+ this.set_next_tip();
437
+ }
438
+
439
+ this.set_target();
440
+ },
441
+
442
+ set_next_tip : function () {
443
+ this.settings.$next_tip = $('.joyride-tip-guide').eq(this.settings.$li.index());
444
+ this.settings.$next_tip.data('closed', '');
445
+ },
446
+
447
+ set_target : function () {
448
+ var cl = this.settings.$li.attr(this.add_namespace('data-class')),
449
+ id = this.settings.$li.attr(this.add_namespace('data-id')),
450
+ $sel = function () {
451
+ if (id) {
452
+ return $(document.getElementById(id));
453
+ } else if (cl) {
454
+ return $('.' + cl).first();
455
+ } else {
456
+ return $('body');
457
+ }
458
+ };
459
+
460
+ this.settings.$target = $sel();
461
+ },
462
+
463
+ scroll_to : function () {
464
+ var window_half, tipOffset;
465
+
466
+ window_half = $(window).height() / 2;
467
+ tipOffset = Math.ceil(this.settings.$target.offset().top - window_half + this.settings.$next_tip.outerHeight());
468
+
469
+ if (tipOffset != 0) {
470
+ $('html, body').stop().animate({
471
+ scrollTop: tipOffset
472
+ }, this.settings.scroll_speed, 'swing');
473
+ }
474
+ },
475
+
476
+ paused : function () {
477
+ return ($.inArray((this.settings.$li.index() + 1), this.settings.pause_after) === -1);
478
+ },
479
+
480
+ restart : function () {
481
+ this.hide();
482
+ this.settings.$li = undefined;
483
+ this.show('init');
484
+ },
485
+
486
+ pos_default : function (init) {
487
+ var $nub = this.settings.$next_tip.find('.joyride-nub'),
488
+ nub_width = Math.ceil($nub.outerWidth() / 2),
489
+ nub_height = Math.ceil($nub.outerHeight() / 2),
490
+ toggle = init || false;
491
+
492
+ // tip must not be "display: none" to calculate position
493
+ if (toggle) {
494
+ this.settings.$next_tip.css('visibility', 'hidden');
495
+ this.settings.$next_tip.show();
496
+ }
497
+
498
+ if (!/body/i.test(this.settings.$target.selector)) {
499
+ var topAdjustment = this.settings.tip_settings.tipAdjustmentY ? parseInt(this.settings.tip_settings.tipAdjustmentY) : 0,
500
+ leftAdjustment = this.settings.tip_settings.tipAdjustmentX ? parseInt(this.settings.tip_settings.tipAdjustmentX) : 0;
501
+
502
+ if (this.bottom()) {
503
+ if (this.rtl) {
504
+ this.settings.$next_tip.css({
505
+ top: (this.settings.$target.offset().top + nub_height + this.settings.$target.outerHeight() + topAdjustment),
506
+ left: this.settings.$target.offset().left + this.settings.$target.outerWidth() - this.settings.$next_tip.outerWidth() + leftAdjustment});
507
+ } else {
508
+ this.settings.$next_tip.css({
509
+ top: (this.settings.$target.offset().top + nub_height + this.settings.$target.outerHeight() + topAdjustment),
510
+ left: this.settings.$target.offset().left + leftAdjustment});
511
+ }
512
+
513
+ this.nub_position($nub, this.settings.tip_settings.nub_position, 'top');
514
+
515
+ } else if (this.top()) {
516
+ if (this.rtl) {
517
+ this.settings.$next_tip.css({
518
+ top: (this.settings.$target.offset().top - this.settings.$next_tip.outerHeight() - nub_height + topAdjustment),
519
+ left: this.settings.$target.offset().left + this.settings.$target.outerWidth() - this.settings.$next_tip.outerWidth()});
520
+ } else {
521
+ this.settings.$next_tip.css({
522
+ top: (this.settings.$target.offset().top - this.settings.$next_tip.outerHeight() - nub_height + topAdjustment),
523
+ left: this.settings.$target.offset().left + leftAdjustment});
524
+ }
525
+
526
+ this.nub_position($nub, this.settings.tip_settings.nub_position, 'bottom');
527
+
528
+ } else if (this.right()) {
529
+
530
+ this.settings.$next_tip.css({
531
+ top: this.settings.$target.offset().top + topAdjustment,
532
+ left: (this.settings.$target.outerWidth() + this.settings.$target.offset().left + nub_width + leftAdjustment)});
533
+
534
+ this.nub_position($nub, this.settings.tip_settings.nub_position, 'left');
535
+
536
+ } else if (this.left()) {
537
+
538
+ this.settings.$next_tip.css({
539
+ top: this.settings.$target.offset().top + topAdjustment,
540
+ left: (this.settings.$target.offset().left - this.settings.$next_tip.outerWidth() - nub_width + leftAdjustment)});
541
+
542
+ this.nub_position($nub, this.settings.tip_settings.nub_position, 'right');
543
+
544
+ }
545
+
546
+ if (!this.visible(this.corners(this.settings.$next_tip)) && this.settings.attempts < this.settings.tip_settings.tip_location_pattern.length) {
547
+
548
+ $nub.removeClass('bottom')
549
+ .removeClass('top')
550
+ .removeClass('right')
551
+ .removeClass('left');
552
+
553
+ this.settings.tip_settings.tip_location = this.settings.tip_settings.tip_location_pattern[this.settings.attempts];
554
+
555
+ this.settings.attempts++;
556
+
557
+ this.pos_default();
558
+
559
+ }
560
+
561
+ } else if (this.settings.$li.length) {
562
+
563
+ this.pos_modal($nub);
564
+
565
+ }
566
+
567
+ if (toggle) {
568
+ this.settings.$next_tip.hide();
569
+ this.settings.$next_tip.css('visibility', 'visible');
570
+ }
571
+
572
+ },
573
+
574
+ pos_phone : function (init) {
575
+ var tip_height = this.settings.$next_tip.outerHeight(),
576
+ tip_offset = this.settings.$next_tip.offset(),
577
+ target_height = this.settings.$target.outerHeight(),
578
+ $nub = $('.joyride-nub', this.settings.$next_tip),
579
+ nub_height = Math.ceil($nub.outerHeight() / 2),
580
+ toggle = init || false;
581
+
582
+ $nub.removeClass('bottom')
583
+ .removeClass('top')
584
+ .removeClass('right')
585
+ .removeClass('left');
586
+
587
+ if (toggle) {
588
+ this.settings.$next_tip.css('visibility', 'hidden');
589
+ this.settings.$next_tip.show();
590
+ }
591
+
592
+ if (!/body/i.test(this.settings.$target.selector)) {
593
+
594
+ if (this.top()) {
595
+
596
+ this.settings.$next_tip.offset({top: this.settings.$target.offset().top - tip_height - nub_height});
597
+ $nub.addClass('bottom');
598
+
599
+ } else {
600
+
601
+ this.settings.$next_tip.offset({top: this.settings.$target.offset().top + target_height + nub_height});
602
+ $nub.addClass('top');
603
+
604
+ }
605
+
606
+ } else if (this.settings.$li.length) {
607
+ this.pos_modal($nub);
608
+ }
609
+
610
+ if (toggle) {
611
+ this.settings.$next_tip.hide();
612
+ this.settings.$next_tip.css('visibility', 'visible');
613
+ }
614
+ },
615
+
616
+ pos_modal : function ($nub) {
617
+ this.center();
618
+ $nub.hide();
619
+
620
+ this.show_modal();
621
+ },
622
+
623
+ show_modal : function () {
624
+ if (!this.settings.$next_tip.data('closed')) {
625
+ var joyridemodalbg = $('.joyride-modal-bg');
626
+ if (joyridemodalbg.length < 1) {
627
+ var joyridemodalbg = $(this.settings.template.modal);
628
+ joyridemodalbg.appendTo('body');
629
+ }
630
+
631
+ if (/pop/i.test(this.settings.tip_animation)) {
632
+ joyridemodalbg.show();
633
+ } else {
634
+ joyridemodalbg.fadeIn(this.settings.tip_animation_fade_speed);
635
+ }
636
+ }
637
+ },
638
+
639
+ expose : function () {
640
+ var expose,
641
+ exposeCover,
642
+ el,
643
+ origCSS,
644
+ origClasses,
645
+ randId = 'expose-' + this.random_str(6);
646
+
647
+ if (arguments.length > 0 && arguments[0] instanceof $) {
648
+ el = arguments[0];
649
+ } else if(this.settings.$target && !/body/i.test(this.settings.$target.selector)){
650
+ el = this.settings.$target;
651
+ } else {
652
+ return false;
653
+ }
654
+
655
+ if(el.length < 1){
656
+ if(window.console){
657
+ console.error('element not valid', el);
658
+ }
659
+ return false;
660
+ }
661
+
662
+ expose = $(this.settings.template.expose);
663
+ this.settings.$body.append(expose);
664
+ expose.css({
665
+ top: el.offset().top,
666
+ left: el.offset().left,
667
+ width: el.outerWidth(true),
668
+ height: el.outerHeight(true)
669
+ });
670
+
671
+ exposeCover = $(this.settings.template.expose_cover);
672
+
673
+ origCSS = {
674
+ zIndex: el.css('z-index'),
675
+ position: el.css('position')
676
+ };
677
+
678
+ origClasses = el.attr('class') == null ? '' : el.attr('class');
679
+
680
+ el.css('z-index',parseInt(expose.css('z-index'))+1);
681
+
682
+ if (origCSS.position == 'static') {
683
+ el.css('position','relative');
684
+ }
685
+
686
+ el.data('expose-css',origCSS);
687
+ el.data('orig-class', origClasses);
688
+ el.attr('class', origClasses + ' ' + this.settings.expose_add_class);
689
+
690
+ exposeCover.css({
691
+ top: el.offset().top,
692
+ left: el.offset().left,
693
+ width: el.outerWidth(true),
694
+ height: el.outerHeight(true)
695
+ });
696
+
697
+ if (this.settings.modal) this.show_modal();
698
+
699
+ this.settings.$body.append(exposeCover);
700
+ expose.addClass(randId);
701
+ exposeCover.addClass(randId);
702
+ el.data('expose', randId);
703
+ this.settings.post_expose_callback(this.settings.$li.index(), this.settings.$next_tip, el);
704
+ this.add_exposed(el);
705
+ },
706
+
707
+ un_expose : function () {
708
+ var exposeId,
709
+ el,
710
+ expose ,
711
+ origCSS,
712
+ origClasses,
713
+ clearAll = false;
714
+
715
+ if (arguments.length > 0 && arguments[0] instanceof $) {
716
+ el = arguments[0];
717
+ } else if(this.settings.$target && !/body/i.test(this.settings.$target.selector)){
718
+ el = this.settings.$target;
719
+ } else {
720
+ return false;
721
+ }
722
+
723
+ if(el.length < 1){
724
+ if (window.console) {
725
+ console.error('element not valid', el);
726
+ }
727
+ return false;
728
+ }
729
+
730
+ exposeId = el.data('expose');
731
+ expose = $('.' + exposeId);
732
+
733
+ if (arguments.length > 1) {
734
+ clearAll = arguments[1];
735
+ }
736
+
737
+ if (clearAll === true) {
738
+ $('.joyride-expose-wrapper,.joyride-expose-cover').remove();
739
+ } else {
740
+ expose.remove();
741
+ }
742
+
743
+ origCSS = el.data('expose-css');
744
+
745
+ if (origCSS.zIndex == 'auto') {
746
+ el.css('z-index', '');
747
+ } else {
748
+ el.css('z-index', origCSS.zIndex);
749
+ }
750
+
751
+ if (origCSS.position != el.css('position')) {
752
+ if(origCSS.position == 'static') {// this is default, no need to set it.
753
+ el.css('position', '');
754
+ } else {
755
+ el.css('position', origCSS.position);
756
+ }
757
+ }
758
+
759
+ origClasses = el.data('orig-class');
760
+ el.attr('class', origClasses);
761
+ el.removeData('orig-classes');
762
+
763
+ el.removeData('expose');
764
+ el.removeData('expose-z-index');
765
+ this.remove_exposed(el);
766
+ },
767
+
768
+ add_exposed: function(el){
769
+ this.settings.exposed = this.settings.exposed || [];
770
+ if (el instanceof $ || typeof el === 'object') {
771
+ this.settings.exposed.push(el[0]);
772
+ } else if (typeof el == 'string') {
773
+ this.settings.exposed.push(el);
774
+ }
775
+ },
776
+
777
+ remove_exposed: function(el){
778
+ var search, i;
779
+ if (el instanceof $) {
780
+ search = el[0]
781
+ } else if (typeof el == 'string'){
782
+ search = el;
783
+ }
784
+
785
+ this.settings.exposed = this.settings.exposed || [];
786
+ i = this.settings.exposed.length;
787
+
788
+ while (i--) {
789
+ if (this.settings.exposed[i] == search) {
790
+ this.settings.exposed.splice(i, 1);
791
+ return;
792
+ }
793
+ }
794
+ },
795
+
796
+ center : function () {
797
+ var $w = $(window);
798
+
799
+ this.settings.$next_tip.css({
800
+ top : ((($w.height() - this.settings.$next_tip.outerHeight()) / 2) + $w.scrollTop()),
801
+ left : ((($w.width() - this.settings.$next_tip.outerWidth()) / 2) + $w.scrollLeft())
802
+ });
803
+
804
+ return true;
805
+ },
806
+
807
+ bottom : function () {
808
+ return /bottom/i.test(this.settings.tip_settings.tip_location);
809
+ },
810
+
811
+ top : function () {
812
+ return /top/i.test(this.settings.tip_settings.tip_location);
813
+ },
814
+
815
+ right : function () {
816
+ return /right/i.test(this.settings.tip_settings.tip_location);
817
+ },
818
+
819
+ left : function () {
820
+ return /left/i.test(this.settings.tip_settings.tip_location);
821
+ },
822
+
823
+ corners : function (el) {
824
+ var w = $(window),
825
+ window_half = w.height() / 2,
826
+ //using this to calculate since scroll may not have finished yet.
827
+ tipOffset = Math.ceil(this.settings.$target.offset().top - window_half + this.settings.$next_tip.outerHeight()),
828
+ right = w.width() + w.scrollLeft(),
829
+ offsetBottom = w.height() + tipOffset,
830
+ bottom = w.height() + w.scrollTop(),
831
+ top = w.scrollTop();
832
+
833
+ if (tipOffset < top) {
834
+ if (tipOffset < 0) {
835
+ top = 0;
836
+ } else {
837
+ top = tipOffset;
838
+ }
839
+ }
840
+
841
+ if (offsetBottom > bottom) {
842
+ bottom = offsetBottom;
843
+ }
844
+
845
+ return [
846
+ el.offset().top < top,
847
+ right < el.offset().left + el.outerWidth(),
848
+ bottom < el.offset().top + el.outerHeight(),
849
+ w.scrollLeft() > el.offset().left
850
+ ];
851
+ },
852
+
853
+ visible : function (hidden_corners) {
854
+ var i = hidden_corners.length;
855
+
856
+ while (i--) {
857
+ if (hidden_corners[i]) return false;
858
+ }
859
+
860
+ return true;
861
+ },
862
+
863
+ nub_position : function (nub, pos, def) {
864
+ if (pos === 'auto') {
865
+ nub.addClass(def);
866
+ } else {
867
+ nub.addClass(pos);
868
+ }
869
+ },
870
+
871
+ startTimer : function () {
872
+ if (this.settings.$li.length) {
873
+ this.settings.automate = setTimeout(function () {
874
+ this.hide();
875
+ this.show();
876
+ this.startTimer();
877
+ }.bind(this), this.settings.timer);
878
+ } else {
879
+ clearTimeout(this.settings.automate);
880
+ }
881
+ },
882
+
883
+ end : function (abort) {
884
+ if (this.settings.cookie_monster) {
885
+ $.cookie(this.settings.cookie_name, 'ridden', { expires: this.settings.cookie_expires, domain: this.settings.cookie_domain });
886
+ }
887
+
888
+ if (this.settings.timer > 0) {
889
+ clearTimeout(this.settings.automate);
890
+ }
891
+
892
+ if (this.settings.modal && this.settings.expose) {
893
+ this.un_expose();
894
+ }
895
+
896
+ // Unplug keystrokes listener
897
+ $(this.scope).off('keyup.joyride')
898
+
899
+ this.settings.$next_tip.data('closed', true);
900
+ this.settings.riding = false;
901
+
902
+ $('.joyride-modal-bg').hide();
903
+ this.settings.$current_tip.hide();
904
+
905
+ if (typeof abort === 'undefined' || abort === false) {
906
+ this.settings.post_step_callback(this.settings.$li.index(), this.settings.$current_tip);
907
+ this.settings.post_ride_callback(this.settings.$li.index(), this.settings.$current_tip);
908
+ }
909
+
910
+ $('.joyride-tip-guide').remove();
911
+ },
912
+
913
+ off : function () {
914
+ $(this.scope).off('.joyride');
915
+ $(window).off('.joyride');
916
+ $('.joyride-close-tip, .joyride-next-tip, .joyride-modal-bg').off('.joyride');
917
+ $('.joyride-tip-guide, .joyride-modal-bg').remove();
918
+ clearTimeout(this.settings.automate);
919
+ this.settings = {};
920
+ },
921
+
922
+ reflow : function () {}
923
+ };
924
+ }(jQuery, window, window.document));