luneta 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. data/.gitignore +4 -0
  2. data/Gemfile +4 -0
  3. data/Rakefile +9 -0
  4. data/bin/luneta +2 -0
  5. data/lib/luneta.rb +11 -0
  6. data/lib/luneta/builder.rb +11 -0
  7. data/lib/luneta/layout.rb +13 -0
  8. data/lib/luneta/park.rb +73 -0
  9. data/lib/luneta/template.rb +13 -0
  10. data/lib/luneta/version.rb +3 -0
  11. data/luneta.gemspec +26 -0
  12. data/spec/.DS_Store +0 -0
  13. data/spec/layout_spec.rb +23 -0
  14. data/spec/luneta_spec.rb +40 -0
  15. data/spec/sample-site/.DS_Store +0 -0
  16. data/spec/sample-site/app.rb +33 -0
  17. data/spec/sample-site/config.ru +4 -0
  18. data/spec/sample-site/humans.txt +8 -0
  19. data/spec/sample-site/images/foundation/orbit/bullets.jpg +0 -0
  20. data/spec/sample-site/images/foundation/orbit/left-arrow-small.png +0 -0
  21. data/spec/sample-site/images/foundation/orbit/left-arrow.png +0 -0
  22. data/spec/sample-site/images/foundation/orbit/loading.gif +0 -0
  23. data/spec/sample-site/images/foundation/orbit/mask-black.png +0 -0
  24. data/spec/sample-site/images/foundation/orbit/pause-black.png +0 -0
  25. data/spec/sample-site/images/foundation/orbit/right-arrow-small.png +0 -0
  26. data/spec/sample-site/images/foundation/orbit/right-arrow.png +0 -0
  27. data/spec/sample-site/images/foundation/orbit/rotator-black.png +0 -0
  28. data/spec/sample-site/images/foundation/orbit/timer-black.png +0 -0
  29. data/spec/sample-site/index.html.erb +180 -0
  30. data/spec/sample-site/javascripts/app.js +38 -0
  31. data/spec/sample-site/javascripts/foundation.min.js +98 -0
  32. data/spec/sample-site/javascripts/jquery.foundation.accordion.js +34 -0
  33. data/spec/sample-site/javascripts/jquery.foundation.alerts.js +20 -0
  34. data/spec/sample-site/javascripts/jquery.foundation.buttons.js +74 -0
  35. data/spec/sample-site/javascripts/jquery.foundation.clearing.js +468 -0
  36. data/spec/sample-site/javascripts/jquery.foundation.forms.js +486 -0
  37. data/spec/sample-site/javascripts/jquery.foundation.joyride.js +639 -0
  38. data/spec/sample-site/javascripts/jquery.foundation.magellan.js +85 -0
  39. data/spec/sample-site/javascripts/jquery.foundation.mediaQueryToggle.js +27 -0
  40. data/spec/sample-site/javascripts/jquery.foundation.navigation.js +55 -0
  41. data/spec/sample-site/javascripts/jquery.foundation.orbit.js +897 -0
  42. data/spec/sample-site/javascripts/jquery.foundation.reveal.js +794 -0
  43. data/spec/sample-site/javascripts/jquery.foundation.tabs.js +43 -0
  44. data/spec/sample-site/javascripts/jquery.foundation.tooltips.js +193 -0
  45. data/spec/sample-site/javascripts/jquery.foundation.topbar.js +152 -0
  46. data/spec/sample-site/javascripts/jquery.js +9440 -0
  47. data/spec/sample-site/javascripts/jquery.placeholder.js +157 -0
  48. data/spec/sample-site/javascripts/modernizr.foundation.js +4 -0
  49. data/spec/sample-site/layout.erb +38 -0
  50. data/spec/sample-site/robots.txt +4 -0
  51. data/spec/sample-site/simple-layout.erb +10 -0
  52. data/spec/sample-site/simple-layout.rb +3 -0
  53. data/spec/sample-site/simple-test-with-params.haml +1 -0
  54. data/spec/sample-site/simple-test.erb +3 -0
  55. data/spec/sample-site/simple-test.haml +1 -0
  56. data/spec/sample-site/store.html +253 -0
  57. data/spec/sample-site/stylesheets/app.css +29 -0
  58. data/spec/sample-site/stylesheets/foundation.css +1213 -0
  59. data/spec/sample-site/stylesheets/foundation.min.css +1 -0
  60. data/spec/spec_helper.rb +10 -0
  61. data/spec/template_spec.rb +36 -0
  62. metadata +200 -0
@@ -0,0 +1,85 @@
1
+ /*
2
+ * jQuery Foundation Magellan 0.0.1
3
+ * http://foundation.zurb.com
4
+ * Copyright 2012, ZURB
5
+ * Free to use under the MIT license.
6
+ * http://www.opensource.org/licenses/mit-license.php
7
+ */
8
+
9
+ /*jslint unparam: true, browser: true, indent: 2 */
10
+
11
+ ;(function ($, window, undefined) {
12
+ 'use strict';
13
+
14
+ $.fn.foundationMagellan = function(options) {
15
+ var defaults = {
16
+ threshold: 25,
17
+ activeClass: 'active'
18
+ },
19
+
20
+ options = $.extend({}, defaults, options);
21
+
22
+ // Indicate we have arrived at a destination
23
+ $(document).on('magellan.arrival', '[data-magellan-arrival]', function(e) {
24
+ var $expedition = $(this).closest('[data-magellan-expedition]'),
25
+ activeClass = $expedition.attr('data-magellan-active-class') || options.activeClass;
26
+ $(this)
27
+ .closest('[data-magellan-expedition]')
28
+ .find('[data-magellan-arrival]')
29
+ .not(this)
30
+ .removeClass(activeClass);
31
+ $(this).addClass(activeClass);
32
+ });
33
+
34
+ // Set starting point as the current destination
35
+ var $expedition = $('[data-magellan-expedition]');
36
+ $expedition.find('[data-magellan-arrival]:first')
37
+ .addClass($expedition.attr('data-magellan-active-class') || options.activeClass);
38
+
39
+ // Update fixed position
40
+ $('[data-magellan-expedition=fixed]').on('magellan.update-position', function(){
41
+ var $el = $(this);
42
+ $el.data("magellan-fixed-position","");
43
+ $el.data("magellan-top-offset", "");
44
+ });
45
+
46
+ $('[data-magellan-expedition=fixed]').trigger('magellan.update-position');
47
+
48
+ $(window).on('resize.magellan', function() {
49
+ $('[data-magellan-expedition=fixed]').trigger('magellan.update-position');
50
+ });
51
+
52
+ $(window).on('scroll.magellan', function() {
53
+ var windowScrollTop = $(window).scrollTop();
54
+ $('[data-magellan-expedition=fixed]').each(function() {
55
+ var $expedition = $(this);
56
+ if ($expedition.data("magellan-top-offset") === "") {
57
+ $expedition.data("magellan-top-offset", $expedition.offset().top);
58
+ }
59
+ var fixed_position = (windowScrollTop + options.threshold) > $expedition.data("magellan-top-offset");
60
+ if ($expedition.data("magellan-fixed-position") != fixed_position) {
61
+ $expedition.data("magellan-fixed-position", fixed_position);
62
+ if (fixed_position) {
63
+ $expedition.css({position:"fixed", top:0});
64
+ } else {
65
+ $expedition.css({position:"", top:""});
66
+ }
67
+ }
68
+ });
69
+ });
70
+
71
+ // Determine when a destination has been reached, ah0y!
72
+ $(window).on('scroll.magellan', function(e){
73
+ var windowScrollTop = $(window).scrollTop();
74
+ $('[data-magellan-destination]').each(function(){
75
+ var $destination = $(this),
76
+ destination_name = $destination.attr('data-magellan-destination'),
77
+ topOffset = $destination.offset().top - windowScrollTop;
78
+ if (topOffset <= options.threshold) {
79
+ $('[data-magellan-arrival=' + destination_name + ']')
80
+ .trigger('magellan.arrival');
81
+ }
82
+ });
83
+ });
84
+ };
85
+ }(jQuery, this));
@@ -0,0 +1,27 @@
1
+ ;(function ($, window, undefined) {
2
+ 'use strict';
3
+
4
+ $.fn.foundationMediaQueryViewer = function (options) {
5
+ var settings = $.extend(options,{toggleKey:77}), // Press 'M'
6
+ $doc = $(document);
7
+
8
+ $doc.on("keyup.mediaQueryViewer", ":input", function (e){
9
+ if (e.which === settings.toggleKey) {
10
+ e.stopPropagation();
11
+ }
12
+ });
13
+ $doc.on("keyup.mediaQueryViewer", function (e) {
14
+ var $mqViewer = $('#fqv');
15
+
16
+ if (e.which === settings.toggleKey) {
17
+ if ($mqViewer.length > 0) {
18
+ $mqViewer.remove();
19
+ } else {
20
+ $('body').prepend('<div id="fqv" style="position:fixed;top:4px;left:4px;z-index:999;color:#fff;"><p style="font-size:12px;background:rgba(0,0,0,0.75);padding:5px;margin-bottom:1px;line-height:1.2;"><span class="left">Media:</span> <span style="font-weight:bold;" class="show-for-xlarge">Extra Large</span><span style="font-weight:bold;" class="show-for-large">Large</span><span style="font-weight:bold;" class="show-for-medium">Medium</span><span style="font-weight:bold;" class="show-for-small">Small</span><span style="font-weight:bold;" class="show-for-landscape">Landscape</span><span style="font-weight:bold;" class="show-for-portrait">Portrait</span><span style="font-weight:bold;" class="show-for-touch">Touch</span></p></div>');
21
+ }
22
+ }
23
+ });
24
+
25
+ };
26
+
27
+ })(jQuery, this);
@@ -0,0 +1,55 @@
1
+ ;(function ($, window, undefined) {
2
+ 'use strict';
3
+
4
+ $.fn.foundationNavigation = function (options) {
5
+
6
+ var lockNavBar = false;
7
+ // Windows Phone, sadly, does not register touch events :(
8
+ if (Modernizr.touch || navigator.userAgent.match(/Windows Phone/i)) {
9
+ $(document).on('click.fndtn touchstart.fndtn', '.nav-bar a.flyout-toggle', function (e) {
10
+ e.preventDefault();
11
+ var flyout = $(this).siblings('.flyout').first();
12
+ if (lockNavBar === false) {
13
+ $('.nav-bar .flyout').not(flyout).slideUp(500);
14
+ flyout.slideToggle(500, function () {
15
+ lockNavBar = false;
16
+ });
17
+ }
18
+ lockNavBar = true;
19
+ });
20
+ $('.nav-bar>li.has-flyout', this).addClass('is-touch');
21
+ } else {
22
+ $('.nav-bar>li.has-flyout', this).on('mouseenter mouseleave', function (e) {
23
+ if (e.type == 'mouseenter') {
24
+ $('.nav-bar').find('.flyout').hide();
25
+ $(this).children('.flyout').show();
26
+ }
27
+
28
+ if (e.type == 'mouseleave') {
29
+ var flyout = $(this).children('.flyout'),
30
+ inputs = flyout.find('input'),
31
+ hasFocus = function (inputs) {
32
+ var focus;
33
+ if (inputs.length > 0) {
34
+ inputs.each(function () {
35
+ if ($(this).is(":focus")) {
36
+ focus = true;
37
+ }
38
+ });
39
+ return focus;
40
+ }
41
+
42
+ return false;
43
+ };
44
+
45
+ if (!hasFocus(inputs)) {
46
+ $(this).children('.flyout').hide();
47
+ }
48
+ }
49
+
50
+ });
51
+ }
52
+
53
+ };
54
+
55
+ })( jQuery, this );
@@ -0,0 +1,897 @@
1
+ /*
2
+ * jQuery Orbit Plugin 1.4.0
3
+ * www.ZURB.com/playground
4
+ * Copyright 2010, ZURB
5
+ * Free to use under the MIT license.
6
+ * http://www.opensource.org/licenses/mit-license.php
7
+ */
8
+
9
+
10
+ (function ($) {
11
+ 'use strict';
12
+
13
+ $.fn.findFirstImage = function () {
14
+ return this.first()
15
+ .find('img')
16
+ .andSelf().filter('img')
17
+ .first();
18
+ };
19
+
20
+ var ORBIT = {
21
+
22
+ defaults: {
23
+ animation: 'horizontal-push', // fade, horizontal-slide, vertical-slide, horizontal-push, vertical-push
24
+ animationSpeed: 600, // how fast animations are
25
+ timer: true, // display timer?
26
+ advanceSpeed: 4000, // if timer is enabled, time between transitions
27
+ pauseOnHover: false, // if you hover pauses the slider
28
+ startClockOnMouseOut: false, // if clock should start on MouseOut
29
+ startClockOnMouseOutAfter: 1000, // how long after MouseOut should the timer start again
30
+ directionalNav: true, // manual advancing directional navs
31
+ directionalNavRightText: 'Right', // text of right directional element for accessibility
32
+ directionalNavLeftText: 'Left', // text of left directional element for accessibility
33
+ captions: true, // do you want captions?
34
+ captionAnimation: 'fade', // fade, slideOpen, none
35
+ captionAnimationSpeed: 600, // if so how quickly should they animate in
36
+ resetTimerOnClick: false, // true resets the timer instead of pausing slideshow progress on manual navigation
37
+ bullets: false, // true or false to activate the bullet navigation
38
+ bulletThumbs: false, // thumbnails for the bullets
39
+ bulletThumbLocation: '', // relative path to thumbnails from this file
40
+ afterSlideChange: $.noop, // callback to execute after slide changes
41
+ afterLoadComplete: $.noop, // callback to execute after everything has been loaded
42
+ fluid: true,
43
+ centerBullets: true, // center bullet nav with js, turn this off if you want to position the bullet nav manually
44
+ singleCycle: false, // cycles through orbit slides only once
45
+ slideNumber: false, // display slide numbers?
46
+ stackOnSmall: false // stack slides on small devices (i.e. phones)
47
+ },
48
+
49
+ activeSlide: 0,
50
+ numberSlides: 0,
51
+ orbitWidth: null,
52
+ orbitHeight: null,
53
+ locked: null,
54
+ timerRunning: null,
55
+ degrees: 0,
56
+ wrapperHTML: '<div class="orbit-wrapper" />',
57
+ timerHTML: '<div class="timer"><span class="mask"><span class="rotator"></span></span><span class="pause"></span></div>',
58
+ captionHTML: '<div class="orbit-caption"></div>',
59
+ directionalNavHTML: '<div class="slider-nav hide-for-small"><span class="right"></span><span class="left"></span></div>',
60
+ bulletHTML: '<ul class="orbit-bullets"></ul>',
61
+ slideNumberHTML: '<span class="orbit-slide-counter"></span>',
62
+
63
+ init: function (element, options) {
64
+ var $imageSlides,
65
+ imagesLoadedCount = 0,
66
+ self = this;
67
+
68
+ // Bind functions to correct context
69
+ this.clickTimer = $.proxy(this.clickTimer, this);
70
+ this.addBullet = $.proxy(this.addBullet, this);
71
+ this.resetAndUnlock = $.proxy(this.resetAndUnlock, this);
72
+ this.stopClock = $.proxy(this.stopClock, this);
73
+ this.startTimerAfterMouseLeave = $.proxy(this.startTimerAfterMouseLeave, this);
74
+ this.clearClockMouseLeaveTimer = $.proxy(this.clearClockMouseLeaveTimer, this);
75
+ this.rotateTimer = $.proxy(this.rotateTimer, this);
76
+
77
+ this.options = $.extend({}, this.defaults, options);
78
+ if (this.options.timer === 'false') this.options.timer = false;
79
+ if (this.options.captions === 'false') this.options.captions = false;
80
+ if (this.options.directionalNav === 'false') this.options.directionalNav = false;
81
+
82
+ this.$element = $(element);
83
+ this.$wrapper = this.$element.wrap(this.wrapperHTML).parent();
84
+ this.$slides = this.$element.children('img, a, div, figure');
85
+
86
+ this.$element.on('movestart', function(e) {
87
+ // If the movestart is heading off in an upwards or downwards
88
+ // direction, prevent it so that the browser scrolls normally.
89
+ if ((e.distX > e.distY && e.distX < -e.distY) ||
90
+ (e.distX < e.distY && e.distX > -e.distY)) {
91
+ e.preventDefault();
92
+ }
93
+ });
94
+
95
+ this.$element.bind('orbit.next swipeleft', function () {
96
+ self.shift('next');
97
+ });
98
+
99
+ this.$element.bind('orbit.prev swiperight', function () {
100
+ self.shift('prev');
101
+ });
102
+
103
+ this.$element.bind('orbit.goto', function (event, index) {
104
+ self.shift(index);
105
+ });
106
+
107
+ this.$element.bind('orbit.start', function (event, index) {
108
+ self.startClock();
109
+ });
110
+
111
+ this.$element.bind('orbit.stop', function (event, index) {
112
+ self.stopClock();
113
+ });
114
+
115
+ $imageSlides = this.$slides.filter('img');
116
+
117
+ if ($imageSlides.length === 0) {
118
+ this.loaded();
119
+ } else {
120
+ $imageSlides.bind('imageready', function () {
121
+ imagesLoadedCount += 1;
122
+ if (imagesLoadedCount === $imageSlides.length) {
123
+ self.loaded();
124
+ }
125
+ });
126
+ }
127
+ },
128
+
129
+ loaded: function () {
130
+ this.$element
131
+ .addClass('orbit')
132
+ .css({width: '1px', height: '1px'});
133
+
134
+ if (this.options.stackOnSmall) {
135
+ this.$element.addClass('orbit-stack-on-small');
136
+ }
137
+
138
+ this.$slides.addClass('orbit-slide');
139
+
140
+ this.setDimentionsFromLargestSlide();
141
+ this.updateOptionsIfOnlyOneSlide();
142
+ this.setupFirstSlide();
143
+ this.notifySlideChange();
144
+
145
+ if (this.options.timer) {
146
+ this.setupTimer();
147
+ this.startClock();
148
+ }
149
+
150
+ if (this.options.captions) {
151
+ this.setupCaptions();
152
+ }
153
+
154
+ if (this.options.directionalNav) {
155
+ this.setupDirectionalNav();
156
+ }
157
+
158
+ if (this.options.bullets) {
159
+ this.setupBulletNav();
160
+ this.setActiveBullet();
161
+ }
162
+
163
+ this.options.afterLoadComplete.call(this);
164
+ Holder.run();
165
+ },
166
+
167
+ currentSlide: function () {
168
+ return this.$slides.eq(this.activeSlide);
169
+ },
170
+
171
+ notifySlideChange: function() {
172
+ if (this.options.slideNumber) {
173
+ var txt = (this.activeSlide+1) + ' of ' + this.$slides.length;
174
+ this.$element.trigger("orbit.change", {slideIndex: this.activeSlide, slideCount: this.$slides.length});
175
+ if (this.$counter === undefined) {
176
+ var $counter = $(this.slideNumberHTML).html(txt);
177
+ this.$counter = $counter;
178
+ this.$wrapper.append(this.$counter);
179
+ } else {
180
+ this.$counter.html(txt);
181
+ }
182
+ }
183
+ },
184
+
185
+ setDimentionsFromLargestSlide: function () {
186
+ //Collect all slides and set slider size of largest image
187
+ var self = this,
188
+ $fluidPlaceholder;
189
+
190
+ self.$element.add(self.$wrapper).width(this.$slides.first().outerWidth());
191
+ self.$element.add(self.$wrapper).height(this.$slides.first().height());
192
+ self.orbitWidth = this.$slides.first().outerWidth();
193
+ self.orbitHeight = this.$slides.first().height();
194
+ $fluidPlaceholder = this.$slides.first().findFirstImage().clone();
195
+
196
+
197
+ this.$slides.each(function () {
198
+ var slide = $(this),
199
+ slideWidth = slide.outerWidth(),
200
+ slideHeight = slide.height();
201
+
202
+ if (slideWidth > self.$element.outerWidth()) {
203
+ self.$element.add(self.$wrapper).width(slideWidth);
204
+ self.orbitWidth = self.$element.outerWidth();
205
+ }
206
+ if (slideHeight > self.$element.height()) {
207
+ self.$element.add(self.$wrapper).height(slideHeight);
208
+ self.orbitHeight = self.$element.height();
209
+ $fluidPlaceholder = $(this).findFirstImage().clone();
210
+ }
211
+ self.numberSlides += 1;
212
+ });
213
+
214
+ if (this.options.fluid) {
215
+ if (typeof this.options.fluid === "string") {
216
+ // $fluidPlaceholder = $("<img>").attr("src", "http://placehold.it/" + this.options.fluid);
217
+ $fluidPlaceholder = $("<img>").attr("data-src", "holder.js/" + this.options.fluid);
218
+ //var inner = $("<div/>").css({"display":"inline-block", "width":"2px", "height":"2px"});
219
+ //$fluidPlaceholder = $("<div/>").css({"float":"left"});
220
+ //$fluidPlaceholder.wrapInner(inner);
221
+
222
+ //$fluidPlaceholder = $("<div/>").css({"height":"1px", "width":"2px"});
223
+ //$fluidPlaceholder = $("<div style='display:inline-block;width:2px;height:1px;'></div>");
224
+ }
225
+
226
+ self.$element.prepend($fluidPlaceholder);
227
+ $fluidPlaceholder.addClass('fluid-placeholder');
228
+ self.$element.add(self.$wrapper).css({width: 'inherit'});
229
+ self.$element.add(self.$wrapper).css({height: 'inherit'});
230
+
231
+ $(window).bind('resize', function () {
232
+ self.orbitWidth = self.$element.outerWidth();
233
+ self.orbitHeight = self.$element.height();
234
+ });
235
+ }
236
+ },
237
+
238
+ //Animation locking functions
239
+ lock: function () {
240
+ this.locked = true;
241
+ },
242
+
243
+ unlock: function () {
244
+ this.locked = false;
245
+ },
246
+
247
+ updateOptionsIfOnlyOneSlide: function () {
248
+ if(this.$slides.length === 1) {
249
+ this.options.directionalNav = false;
250
+ this.options.timer = false;
251
+ this.options.bullets = false;
252
+ }
253
+ },
254
+
255
+ setupFirstSlide: function () {
256
+ //Set initial front photo z-index and fades it in
257
+ var self = this;
258
+ this.$slides.first()
259
+ .css({"z-index" : 3, "opacity" : 1})
260
+ .fadeIn(function() {
261
+ //brings in all other slides IF css declares a display: none
262
+ self.$slides.css({"display":"block"})
263
+ });
264
+ },
265
+
266
+ startClock: function () {
267
+ var self = this;
268
+
269
+ if(!this.options.timer) {
270
+ return false;
271
+ }
272
+
273
+ if (this.$timer.is(':hidden')) {
274
+ this.clock = setInterval(function () {
275
+ self.$element.trigger('orbit.next');
276
+ }, this.options.advanceSpeed);
277
+ } else {
278
+ this.timerRunning = true;
279
+ this.$pause.removeClass('active');
280
+ this.clock = setInterval(this.rotateTimer, this.options.advanceSpeed / 180, false);
281
+ }
282
+ },
283
+
284
+ rotateTimer: function (reset) {
285
+ var degreeCSS = "rotate(" + this.degrees + "deg)";
286
+ this.degrees += 2;
287
+ this.$rotator.css({
288
+ "-webkit-transform": degreeCSS,
289
+ "-moz-transform": degreeCSS,
290
+ "-o-transform": degreeCSS,
291
+ "-ms-transform": degreeCSS
292
+ });
293
+ if(this.degrees > 180) {
294
+ this.$rotator.addClass('move');
295
+ this.$mask.addClass('move');
296
+ }
297
+ if(this.degrees > 360 || reset) {
298
+ this.$rotator.removeClass('move');
299
+ this.$mask.removeClass('move');
300
+ this.degrees = 0;
301
+ this.$element.trigger('orbit.next');
302
+ }
303
+ },
304
+
305
+ stopClock: function () {
306
+ if (!this.options.timer) {
307
+ return false;
308
+ } else {
309
+ this.timerRunning = false;
310
+ clearInterval(this.clock);
311
+ this.$pause.addClass('active');
312
+ }
313
+ },
314
+
315
+ setupTimer: function () {
316
+ this.$timer = $(this.timerHTML);
317
+ this.$wrapper.append(this.$timer);
318
+
319
+ this.$rotator = this.$timer.find('.rotator');
320
+ this.$mask = this.$timer.find('.mask');
321
+ this.$pause = this.$timer.find('.pause');
322
+
323
+ this.$timer.click(this.clickTimer);
324
+
325
+ if (this.options.startClockOnMouseOut) {
326
+ this.$wrapper.mouseleave(this.startTimerAfterMouseLeave);
327
+ this.$wrapper.mouseenter(this.clearClockMouseLeaveTimer);
328
+ }
329
+
330
+ if (this.options.pauseOnHover) {
331
+ this.$wrapper.mouseenter(this.stopClock);
332
+ }
333
+ },
334
+
335
+ startTimerAfterMouseLeave: function () {
336
+ var self = this;
337
+
338
+ this.outTimer = setTimeout(function() {
339
+ if(!self.timerRunning){
340
+ self.startClock();
341
+ }
342
+ }, this.options.startClockOnMouseOutAfter)
343
+ },
344
+
345
+ clearClockMouseLeaveTimer: function () {
346
+ clearTimeout(this.outTimer);
347
+ },
348
+
349
+ clickTimer: function () {
350
+ if(!this.timerRunning) {
351
+ this.startClock();
352
+ } else {
353
+ this.stopClock();
354
+ }
355
+ },
356
+
357
+ setupCaptions: function () {
358
+ this.$caption = $(this.captionHTML);
359
+ this.$wrapper.append(this.$caption);
360
+ this.setCaption();
361
+ },
362
+
363
+ setCaption: function () {
364
+ var captionLocation = this.currentSlide().attr('data-caption'),
365
+ captionHTML;
366
+
367
+ if (!this.options.captions) {
368
+ return false;
369
+ }
370
+
371
+ //Set HTML for the caption if it exists
372
+ if (captionLocation) {
373
+ //if caption text is blank, don't show captions
374
+ if ($.trim($(captionLocation).text()).length < 1){
375
+ return false;
376
+ }
377
+ captionHTML = $(captionLocation).html(); //get HTML from the matching HTML entity
378
+ this.$caption
379
+ .attr('id', captionLocation) // Add ID caption TODO why is the id being set?
380
+ .html(captionHTML); // Change HTML in Caption
381
+ //Animations for Caption entrances
382
+ switch (this.options.captionAnimation) {
383
+ case 'none':
384
+ this.$caption.show();
385
+ break;
386
+ case 'fade':
387
+ this.$caption.fadeIn(this.options.captionAnimationSpeed);
388
+ break;
389
+ case 'slideOpen':
390
+ this.$caption.slideDown(this.options.captionAnimationSpeed);
391
+ break;
392
+ }
393
+ } else {
394
+ //Animations for Caption exits
395
+ switch (this.options.captionAnimation) {
396
+ case 'none':
397
+ this.$caption.hide();
398
+ break;
399
+ case 'fade':
400
+ this.$caption.fadeOut(this.options.captionAnimationSpeed);
401
+ break;
402
+ case 'slideOpen':
403
+ this.$caption.slideUp(this.options.captionAnimationSpeed);
404
+ break;
405
+ }
406
+ }
407
+ },
408
+
409
+ setupDirectionalNav: function () {
410
+ var self = this,
411
+ $directionalNav = $(this.directionalNavHTML);
412
+
413
+ $directionalNav.find('.right').html(this.options.directionalNavRightText);
414
+ $directionalNav.find('.left').html(this.options.directionalNavLeftText);
415
+
416
+ this.$wrapper.append($directionalNav);
417
+
418
+ this.$wrapper.find('.left').click(function () {
419
+ self.stopClock();
420
+ if (self.options.resetTimerOnClick) {
421
+ self.rotateTimer(true);
422
+ self.startClock();
423
+ }
424
+ self.$element.trigger('orbit.prev');
425
+ });
426
+
427
+ this.$wrapper.find('.right').click(function () {
428
+ self.stopClock();
429
+ if (self.options.resetTimerOnClick) {
430
+ self.rotateTimer(true);
431
+ self.startClock();
432
+ }
433
+ self.$element.trigger('orbit.next');
434
+ });
435
+ },
436
+
437
+ setupBulletNav: function () {
438
+ this.$bullets = $(this.bulletHTML);
439
+ this.$wrapper.append(this.$bullets);
440
+ this.$slides.each(this.addBullet);
441
+ this.$element.addClass('with-bullets');
442
+ if (this.options.centerBullets) this.$bullets.css('margin-left', -this.$bullets.outerWidth() / 2);
443
+ },
444
+
445
+ addBullet: function (index, slide) {
446
+ var position = index + 1,
447
+ $li = $('<li>' + (position) + '</li>'),
448
+ thumbName,
449
+ self = this;
450
+
451
+ if (this.options.bulletThumbs) {
452
+ thumbName = $(slide).attr('data-thumb');
453
+ if (thumbName) {
454
+ $li
455
+ .addClass('has-thumb')
456
+ .css({background: "url(" + this.options.bulletThumbLocation + thumbName + ") no-repeat"});;
457
+ }
458
+ }
459
+ this.$bullets.append($li);
460
+ $li.data('index', index);
461
+ $li.click(function () {
462
+ self.stopClock();
463
+ if (self.options.resetTimerOnClick) {
464
+ self.rotateTimer(true);
465
+ self.startClock();
466
+ }
467
+ self.$element.trigger('orbit.goto', [$li.data('index')])
468
+ });
469
+ },
470
+
471
+ setActiveBullet: function () {
472
+ if(!this.options.bullets) { return false; } else {
473
+ this.$bullets.find('li')
474
+ .removeClass('active')
475
+ .eq(this.activeSlide)
476
+ .addClass('active');
477
+ }
478
+ },
479
+
480
+ resetAndUnlock: function () {
481
+ this.$slides
482
+ .eq(this.prevActiveSlide)
483
+ .css({"z-index" : 1});
484
+ this.unlock();
485
+ this.options.afterSlideChange.call(this, this.$slides.eq(this.prevActiveSlide), this.$slides.eq(this.activeSlide));
486
+ },
487
+
488
+ shift: function (direction) {
489
+ var slideDirection = direction;
490
+
491
+ //remember previous activeSlide
492
+ this.prevActiveSlide = this.activeSlide;
493
+
494
+ //exit function if bullet clicked is same as the current image
495
+ if (this.prevActiveSlide == slideDirection) { return false; }
496
+
497
+ if (this.$slides.length == "1") { return false; }
498
+ if (!this.locked) {
499
+ this.lock();
500
+ //deduce the proper activeImage
501
+ if (direction == "next") {
502
+ this.activeSlide++;
503
+ if (this.activeSlide == this.numberSlides) {
504
+ this.activeSlide = 0;
505
+ }
506
+ } else if (direction == "prev") {
507
+ this.activeSlide--
508
+ if (this.activeSlide < 0) {
509
+ this.activeSlide = this.numberSlides - 1;
510
+ }
511
+ } else {
512
+ this.activeSlide = direction;
513
+ if (this.prevActiveSlide < this.activeSlide) {
514
+ slideDirection = "next";
515
+ } else if (this.prevActiveSlide > this.activeSlide) {
516
+ slideDirection = "prev"
517
+ }
518
+ }
519
+
520
+ //set to correct bullet
521
+ this.setActiveBullet();
522
+ this.notifySlideChange();
523
+
524
+ //set previous slide z-index to one below what new activeSlide will be
525
+ this.$slides
526
+ .eq(this.prevActiveSlide)
527
+ .css({"z-index" : 2});
528
+
529
+ //fade
530
+ if (this.options.animation == "fade") {
531
+ this.$slides
532
+ .eq(this.activeSlide)
533
+ .css({"opacity" : 0, "z-index" : 3})
534
+ .animate({"opacity" : 1}, this.options.animationSpeed, this.resetAndUnlock);
535
+ this.$slides
536
+ .eq(this.prevActiveSlide)
537
+ .animate({"opacity":0}, this.options.animationSpeed);
538
+ }
539
+
540
+ //horizontal-slide
541
+ if (this.options.animation == "horizontal-slide") {
542
+ if (slideDirection == "next") {
543
+ this.$slides
544
+ .eq(this.activeSlide)
545
+ .css({"left": this.orbitWidth, "z-index" : 3})
546
+ .css("opacity", 1)
547
+ .animate({"left" : 0}, this.options.animationSpeed, this.resetAndUnlock);
548
+ }
549
+ if (slideDirection == "prev") {
550
+ this.$slides
551
+ .eq(this.activeSlide)
552
+ .css({"left": -this.orbitWidth, "z-index" : 3})
553
+ .css("opacity", 1)
554
+ .animate({"left" : 0}, this.options.animationSpeed, this.resetAndUnlock);
555
+ }
556
+ this.$slides
557
+ .eq(this.prevActiveSlide)
558
+ .css("opacity", 0);
559
+ }
560
+
561
+ //vertical-slide
562
+ if (this.options.animation == "vertical-slide") {
563
+ if (slideDirection == "prev") {
564
+ this.$slides
565
+ .eq(this.activeSlide)
566
+ .css({"top": this.orbitHeight, "z-index" : 3})
567
+ .css("opacity", 1)
568
+ .animate({"top" : 0}, this.options.animationSpeed, this.resetAndUnlock);
569
+ this.$slides
570
+ .eq(this.prevActiveSlide)
571
+ .css("opacity", 0);
572
+ }
573
+ if (slideDirection == "next") {
574
+ this.$slides
575
+ .eq(this.activeSlide)
576
+ .css({"top": -this.orbitHeight, "z-index" : 3})
577
+ .css("opacity", 1)
578
+ .animate({"top" : 0}, this.options.animationSpeed, this.resetAndUnlock);
579
+ }
580
+ this.$slides
581
+ .eq(this.prevActiveSlide)
582
+ .css("opacity", 0);
583
+ }
584
+
585
+ //horizontal-push
586
+ if (this.options.animation == "horizontal-push") {
587
+ if (slideDirection == "next") {
588
+ this.$slides
589
+ .eq(this.activeSlide)
590
+ .css({"left": this.orbitWidth, "z-index" : 3})
591
+ .animate({"left" : 0, "opacity" : 1}, this.options.animationSpeed, this.resetAndUnlock);
592
+ this.$slides
593
+ .eq(this.prevActiveSlide)
594
+ .animate({"left" : -this.orbitWidth}, this.options.animationSpeed, "", function(){
595
+ $(this).css({"opacity" : 0});
596
+ });
597
+ }
598
+ if (slideDirection == "prev") {
599
+ this.$slides
600
+ .eq(this.activeSlide)
601
+ .css({"left": -this.orbitWidth, "z-index" : 3})
602
+ .animate({"left" : 0, "opacity" : 1}, this.options.animationSpeed, this.resetAndUnlock);
603
+ this.$slides
604
+ .eq(this.prevActiveSlide)
605
+ .animate({"left" : this.orbitWidth}, this.options.animationSpeed, "", function(){
606
+ $(this).css({"opacity" : 0});
607
+ });
608
+ }
609
+ }
610
+
611
+ //vertical-push
612
+ if (this.options.animation == "vertical-push") {
613
+ if (slideDirection == "next") {
614
+ this.$slides
615
+ .eq(this.activeSlide)
616
+ .css({top: -this.orbitHeight, "z-index" : 3})
617
+ .css("opacity", 1)
618
+ .animate({top : 0, "opacity":1}, this.options.animationSpeed, this.resetAndUnlock);
619
+ this.$slides
620
+ .eq(this.prevActiveSlide)
621
+ .css("opacity", 0)
622
+ .animate({top : this.orbitHeight}, this.options.animationSpeed, "");
623
+ }
624
+ if (slideDirection == "prev") {
625
+ this.$slides
626
+ .eq(this.activeSlide)
627
+ .css({top: this.orbitHeight, "z-index" : 3})
628
+ .css("opacity", 1)
629
+ .animate({top : 0}, this.options.animationSpeed, this.resetAndUnlock);
630
+ this.$slides
631
+ .eq(this.prevActiveSlide)
632
+ .css("opacity", 0)
633
+ .animate({top : -this.orbitHeight}, this.options.animationSpeed);
634
+ }
635
+ }
636
+
637
+ this.setCaption();
638
+ }
639
+
640
+ if (this.$slides.last() && this.options.singleCycle) {
641
+ this.stopClock();
642
+ }
643
+ }
644
+ };
645
+
646
+ $.fn.orbit = function (options) {
647
+ return this.each(function () {
648
+ var orbit = $.extend({}, ORBIT);
649
+ orbit.init(this, options);
650
+ });
651
+ };
652
+
653
+ })(jQuery);
654
+
655
+ /*!
656
+ * jQuery imageready Plugin
657
+ * http://www.zurb.com/playground/
658
+ *
659
+ * Copyright 2011, ZURB
660
+ * Released under the MIT License
661
+ */
662
+ (function ($) {
663
+
664
+ var options = {};
665
+
666
+ $.event.special.imageready = {
667
+
668
+ setup: function (data, namespaces, eventHandle) {
669
+ options = data || options;
670
+ },
671
+
672
+ add: function (handleObj) {
673
+ var $this = $(this),
674
+ src;
675
+
676
+ if ( this.nodeType === 1 && this.tagName.toLowerCase() === 'img' && this.src !== '' ) {
677
+ if (options.forceLoad) {
678
+ src = $this.attr('src');
679
+ $this.attr('src', '');
680
+ bindToLoad(this, handleObj.handler);
681
+ $this.attr('src', src);
682
+ } else if ( this.complete || this.readyState === 4 ) {
683
+ handleObj.handler.apply(this, arguments);
684
+ } else {
685
+ bindToLoad(this, handleObj.handler);
686
+ }
687
+ }
688
+ },
689
+
690
+ teardown: function (namespaces) {
691
+ $(this).unbind('.imageready');
692
+ }
693
+ };
694
+
695
+ function bindToLoad(element, callback) {
696
+ var $this = $(element);
697
+
698
+ $this.bind('load.imageready', function () {
699
+ callback.apply(element, arguments);
700
+ $this.unbind('load.imageready');
701
+ });
702
+ }
703
+
704
+ }(jQuery));
705
+
706
+ /*
707
+
708
+ Holder - 1.3 - client side image placeholders
709
+ (c) 2012 Ivan Malopinsky / http://imsky.co
710
+
711
+ Provided under the Apache 2.0 License: http://www.apache.org/licenses/LICENSE-2.0
712
+ Commercial use requires attribution.
713
+
714
+ */
715
+
716
+ var Holder = Holder || {};
717
+ (function (app, win) {
718
+
719
+ var preempted = false,
720
+ fallback = false,
721
+ canvas = document.createElement('canvas');
722
+
723
+ //http://javascript.nwbox.com/ContentLoaded by Diego Perini with modifications
724
+ function contentLoaded(n,t){var l="complete",s="readystatechange",u=!1,h=u,c=!0,i=n.document,a=i.documentElement,e=i.addEventListener?"addEventListener":"attachEvent",v=i.addEventListener?"removeEventListener":"detachEvent",f=i.addEventListener?"":"on",r=function(e){(e.type!=s||i.readyState==l)&&((e.type=="load"?n:i)[v](f+e.type,r,u),!h&&(h=!0)&&t.call(n,null))},o=function(){try{a.doScroll("left")}catch(n){setTimeout(o,50);return}r("poll")};if(i.readyState==l)t.call(n,"lazy");else{if(i.createEventObject&&a.doScroll){try{c=!n.frameElement}catch(y){}c&&o()}i[e](f+"DOMContentLoaded",r,u),i[e](f+s,r,u),n[e](f+"load",r,u)}};
725
+
726
+ //https://gist.github.com/991057 by Jed Schmidt with modifications
727
+ function selector(a){
728
+ a=a.match(/^(\W)?(.*)/);var b=document["getElement"+(a[1]?a[1]=="#"?"ById":"sByClassName":"sByTagName")](a[2]);
729
+ var ret=[]; b!=null&&(b.length?ret=b:b.length==0?ret=b:ret=[b]); return ret;
730
+ }
731
+
732
+ //shallow object property extend
733
+ function extend(a,b){var c={};for(var d in a)c[d]=a[d];for(var e in b)c[e]=b[e];return c}
734
+
735
+ function draw(ctx, dimensions, template) {
736
+ var dimension_arr = [dimensions.height, dimensions.width].sort();
737
+ var maxFactor = Math.round(dimension_arr[1] / 16),
738
+ minFactor = Math.round(dimension_arr[0] / 16);
739
+ var text_height = Math.max(template.size, maxFactor);
740
+ canvas.width = dimensions.width;
741
+ canvas.height = dimensions.height;
742
+ ctx.textAlign = "center";
743
+ ctx.textBaseline = "middle";
744
+ ctx.fillStyle = template.background;
745
+ ctx.fillRect(0, 0, dimensions.width, dimensions.height);
746
+ ctx.fillStyle = template.foreground;
747
+ ctx.font = "bold " + text_height + "px sans-serif";
748
+ var text = template.text ? template.text : (dimensions.width + "x" + dimensions.height);
749
+ if (Math.round(ctx.measureText(text).width) / dimensions.width > 1) {
750
+ text_height = Math.max(minFactor, template.size);
751
+ }
752
+ ctx.font = "bold " + text_height + "px sans-serif";
753
+ ctx.fillText(text, (dimensions.width / 2), (dimensions.height / 2), dimensions.width);
754
+ return canvas.toDataURL("image/png");
755
+ }
756
+
757
+ if (!canvas.getContext) {
758
+ fallback = true;
759
+ } else {
760
+ if (canvas.toDataURL("image/png").indexOf("data:image/png") < 0) {
761
+ //Android doesn't support data URI
762
+ fallback = true;
763
+ } else {
764
+ var ctx = canvas.getContext("2d");
765
+ }
766
+ }
767
+
768
+ var settings = {
769
+ domain: "holder.js",
770
+ images: "img",
771
+ themes: {
772
+ "gray": {
773
+ background: "#eee",
774
+ foreground: "#aaa",
775
+ size: 12
776
+ },
777
+ "social": {
778
+ background: "#3a5a97",
779
+ foreground: "#fff",
780
+ size: 12
781
+ },
782
+ "industrial": {
783
+ background: "#434A52",
784
+ foreground: "#C2F200",
785
+ size: 12
786
+ }
787
+ }
788
+ };
789
+
790
+
791
+
792
+ app.flags = {
793
+ dimensions: {
794
+ regex: /([0-9]+)x([0-9]+)/,
795
+ output: function(val){
796
+ var exec = this.regex.exec(val);
797
+ return {
798
+ width: +exec[1],
799
+ height: +exec[2]
800
+ }
801
+ }
802
+ },
803
+ colors: {
804
+ regex: /#([0-9a-f]{3,})\:#([0-9a-f]{3,})/i,
805
+ output: function(val){
806
+ var exec = this.regex.exec(val);
807
+ return {
808
+ size: settings.themes.gray.size,
809
+ foreground: "#" + exec[2],
810
+ background: "#" + exec[1]
811
+ }
812
+ }
813
+ },
814
+ text: {
815
+ regex: /text\:(.*)/,
816
+ output: function(val){
817
+ return this.regex.exec(val)[1];
818
+ }
819
+ }
820
+ }
821
+
822
+ for(var flag in app.flags){
823
+ app.flags[flag].match = function (val){
824
+ return val.match(this.regex)
825
+ }
826
+ }
827
+
828
+ app.add_theme = function (name, theme) {
829
+ name != null && theme != null && (settings.themes[name] = theme);
830
+ return app;
831
+ };
832
+
833
+ app.add_image = function (src, el) {
834
+ var node = selector(el);
835
+ if (node.length) {
836
+ for (var i = 0, l = node.length; i < l; i++) {
837
+ var img = document.createElement("img")
838
+ img.setAttribute("data-src", src);
839
+ node[i].appendChild(img);
840
+ }
841
+ }
842
+ return app;
843
+ };
844
+
845
+ app.run = function (o) {
846
+ var options = extend(settings, o),
847
+ images = selector(options.images),
848
+ preempted = true;
849
+
850
+ for (var l = images.length, i = 0; i < l; i++) {
851
+ var theme = settings.themes.gray;
852
+ var src = images[i].getAttribute("data-src") || images[i].getAttribute("src");
853
+ if ( !! ~src.indexOf(options.domain)) {
854
+ var render = false,
855
+ dimensions = null,
856
+ text = null;
857
+ var flags = src.substr(src.indexOf(options.domain) + options.domain.length + 1).split("/");
858
+ for (sl = flags.length, j = 0; j < sl; j++) {
859
+ if (app.flags.dimensions.match(flags[j])) {
860
+ render = true;
861
+ dimensions = app.flags.dimensions.output(flags[j]);
862
+ } else if (app.flags.colors.match(flags[j])) {
863
+ theme = app.flags.colors.output(flags[j]);
864
+ } else if (options.themes[flags[j]]) {
865
+ //If a theme is specified, it will override custom colors
866
+ theme = options.themes[flags[j]];
867
+ } else if (app.flags.text.match(flags[j])) {
868
+ text = app.flags.text.output(flags[j]);
869
+ }
870
+ }
871
+ if (render) {
872
+ images[i].setAttribute("data-src", src);
873
+ var dimensions_caption = dimensions.width + "x" + dimensions.height;
874
+ images[i].setAttribute("alt", text ? text : theme.text ? theme.text + " [" + dimensions_caption + "]" : dimensions_caption);
875
+
876
+ // Fallback
877
+ // images[i].style.width = dimensions.width + "px";
878
+ // images[i].style.height = dimensions.height + "px";
879
+ images[i].style.backgroundColor = theme.background;
880
+
881
+ var theme = (text ? extend(theme, {
882
+ text: text
883
+ }) : theme);
884
+
885
+ if (!fallback) {
886
+ images[i].setAttribute("src", draw(ctx, dimensions, theme));
887
+ }
888
+ }
889
+ }
890
+ }
891
+ return app;
892
+ };
893
+ contentLoaded(win, function () {
894
+ preempted || app.run()
895
+ })
896
+
897
+ })(Holder, window);