').show();
502 | }
503 |
504 | if (/pop/i.test(settings.tipAnimation)) {
505 | $('.joyride-modal-bg').show();
506 | } else {
507 | $('.joyride-modal-bg').fadeIn(settings.tipAnimationFadeSpeed);
508 | }
509 | },
510 |
511 | center : function () {
512 | var $w = settings.$window;
513 |
514 | settings.$next_tip.css({
515 | top : ((($w.height() - settings.$next_tip.outerHeight()) / 2) + $w.scrollTop()),
516 | left : ((($w.width() - settings.$next_tip.outerWidth()) / 2) + $w.scrollLeft())
517 | });
518 |
519 | return true;
520 | },
521 |
522 | bottom : function () {
523 | return /bottom/i.test(settings.tipSettings.tipLocation);
524 | },
525 |
526 | top : function () {
527 | return /top/i.test(settings.tipSettings.tipLocation);
528 | },
529 |
530 | right : function () {
531 | return /right/i.test(settings.tipSettings.tipLocation);
532 | },
533 |
534 | left : function () {
535 | return /left/i.test(settings.tipSettings.tipLocation);
536 | },
537 |
538 | corners : function (el) {
539 | var w = settings.$window,
540 | right = w.width() + w.scrollLeft(),
541 | bottom = w.width() + w.scrollTop();
542 |
543 | return [
544 | el.offset().top <= w.scrollTop(),
545 | right <= el.offset().left + el.outerWidth(),
546 | bottom <= el.offset().top + el.outerHeight(),
547 | w.scrollLeft() >= el.offset().left
548 | ];
549 | },
550 |
551 | visible : function (hidden_corners) {
552 | var i = hidden_corners.length;
553 |
554 | while (i--) {
555 | if (hidden_corners[i]) return false;
556 | }
557 |
558 | return true;
559 | },
560 |
561 | nub_position : function (nub, pos, def) {
562 | if (pos === 'auto') {
563 | nub.addClass(def);
564 | } else {
565 | nub.addClass(pos);
566 | }
567 | },
568 |
569 | startTimer : function () {
570 | if (settings.$li.length) {
571 | settings.automate = setTimeout(function () {
572 | methods.hide();
573 | methods.show();
574 | methods.startTimer();
575 | }, settings.timer);
576 | } else {
577 | clearTimeout(settings.automate);
578 | }
579 | },
580 |
581 | end : function () {
582 | if (settings.cookieMonster) {
583 | $.cookie(settings.cookieName, 'ridden', { expires: 365, domain: settings.cookieDomain });
584 | }
585 |
586 | if (settings.timer > 0) {
587 | clearTimeout(settings.automate);
588 | }
589 |
590 | $('.joyride-modal-bg').hide();
591 | settings.$current_tip.hide();
592 | settings.postStepCallback(settings.$li.index(), settings.$current_tip);
593 | settings.postRideCallback(settings.$li.index(), settings.$current_tip);
594 | },
595 |
596 | jquery_check : function () {
597 | // define on() and off() for older jQuery
598 | if (!$.isFunction($.fn.on)) {
599 |
600 | $.fn.on = function (types, sel, fn) {
601 |
602 | return this.delegate(sel, types, fn);
603 |
604 | };
605 |
606 | $.fn.off = function (types, sel, fn) {
607 |
608 | return this.undelegate(sel, types, fn);
609 |
610 | };
611 |
612 | return false;
613 | }
614 |
615 | return true;
616 | },
617 |
618 | outerHTML : function (el) {
619 | // support FireFox < 11
620 | return el.outerHTML || new XMLSerializer().serializeToString(el);
621 | },
622 |
623 | version : function () {
624 | return settings.version;
625 | }
626 |
627 | };
628 |
629 | $.fn.joyride = function (method) {
630 | if (methods[method]) {
631 | return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
632 | } else if (typeof method === 'object' || !method) {
633 | return methods.init.apply(this, arguments);
634 | } else {
635 | $.error('Method ' + method + ' does not exist on jQuery.joyride');
636 | }
637 | };
638 |
639 | }(jQuery, this));
640 |
--------------------------------------------------------------------------------
/views/javascripts/jquery.foundation.reveal.js:
--------------------------------------------------------------------------------
1 | /*
2 | * jQuery Reveal Plugin 1.1
3 | * www.ZURB.com
4 | * Copyright 2010, ZURB
5 | * Free to use under the MIT license.
6 | * http://www.opensource.org/licenses/mit-license.php
7 | */
8 | /*globals jQuery */
9 |
10 | (function ($) {
11 | 'use strict';
12 | //
13 | // Global variable.
14 | // Helps us determine if the current modal is being queued for display.
15 | //
16 | var modalQueued = false;
17 |
18 | //
19 | // Bind the live 'click' event to all anchor elemnets with the data-reveal-id attribute.
20 | //
21 | $(document).on('click', 'a[data-reveal-id]', function ( event ) {
22 | //
23 | // Prevent default action of the event.
24 | //
25 | event.preventDefault();
26 | //
27 | // Get the clicked anchor data-reveal-id attribute value.
28 | //
29 | var modalLocation = $( this ).attr( 'data-reveal-id' );
30 | //
31 | // Find the element with that modalLocation id and call the reveal plugin.
32 | //
33 | $( '#' + modalLocation ).reveal( $( this ).data() );
34 |
35 | });
36 |
37 | /**
38 | * @module reveal
39 | * @property {Object} [options] Reveal options
40 | */
41 | $.fn.reveal = function ( options ) {
42 | /*
43 | * Cache the document object.
44 | */
45 | var $doc = $( document ),
46 | /*
47 | * Default property values.
48 | */
49 | defaults = {
50 | /**
51 | * Possible options: fade, fadeAndPop, none
52 | *
53 | * @property animation
54 | * @type {String}
55 | * @default fadeAndPop
56 | */
57 | animation: 'fadeAndPop',
58 | /**
59 | * Speed at which the reveal should show. How fast animtions are.
60 | *
61 | * @property animationSpeed
62 | * @type {Integer}
63 | * @default 300
64 | */
65 | animationSpeed: 300,
66 | /**
67 | * Should the modal close when the background is clicked?
68 | *
69 | * @property closeOnBackgroundClick
70 | * @type {Boolean}
71 | * @default true
72 | */
73 | closeOnBackgroundClick: true,
74 | /**
75 | * Specify a class name for the 'close modal' element.
76 | * This element will close an open modal.
77 | *
78 | @example
79 |
Close Me
80 | *
81 | * @property dismissModalClass
82 | * @type {String}
83 | * @default close-reveal-modal
84 | */
85 | dismissModalClass: 'close-reveal-modal',
86 | /**
87 | * Specify a callback function that triggers 'before' the modal opens.
88 | *
89 | * @property open
90 | * @type {Function}
91 | * @default function(){}
92 | */
93 | open: $.noop,
94 | /**
95 | * Specify a callback function that triggers 'after' the modal is opened.
96 | *
97 | * @property opened
98 | * @type {Function}
99 | * @default function(){}
100 | */
101 | opened: $.noop,
102 | /**
103 | * Specify a callback function that triggers 'before' the modal prepares to close.
104 | *
105 | * @property close
106 | * @type {Function}
107 | * @default function(){}
108 | */
109 | close: $.noop,
110 | /**
111 | * Specify a callback function that triggers 'after' the modal is closed.
112 | *
113 | * @property closed
114 | * @type {Function}
115 | * @default function(){}
116 | */
117 | closed: $.noop
118 | }
119 | ;
120 | //
121 | // Extend the default options.
122 | // This replaces the passed in option (options) values with default values.
123 | //
124 | options = $.extend( {}, defaults, options );
125 |
126 | //
127 | // Apply the plugin functionality to each element in the jQuery collection.
128 | //
129 | return this.not('.reveal-modal.open').each( function () {
130 | //
131 | // Cache the modal element
132 | //
133 | var modal = $( this ),
134 | //
135 | // Get the current css 'top' property value in decimal format.
136 | //
137 | topMeasure = parseInt( modal.css( 'top' ), 10 ),
138 | //
139 | // Calculate the top offset.
140 | //
141 | topOffset = modal.height() + topMeasure,
142 | //
143 | // Helps determine if the modal is locked.
144 | // This way we keep the modal from triggering while it's in the middle of animating.
145 | //
146 | locked = false,
147 | //
148 | // Get the modal background element.
149 | //
150 | modalBg = $( '.reveal-modal-bg' ),
151 | //
152 | // Show modal properties
153 | //
154 | cssOpts = {
155 | //
156 | // Used, when we show the modal.
157 | //
158 | open : {
159 | //
160 | // Set the 'top' property to the document scroll minus the calculated top offset.
161 | //
162 | 'top': 0,
163 | //
164 | // Opacity gets set to 0.
165 | //
166 | 'opacity': 0,
167 | //
168 | // Show the modal
169 | //
170 | 'visibility': 'visible',
171 | //
172 | // Ensure it's displayed as a block element.
173 | //
174 | 'display': 'block'
175 | },
176 | //
177 | // Used, when we hide the modal.
178 | //
179 | close : {
180 | //
181 | // Set the default 'top' property value.
182 | //
183 | 'top': topMeasure,
184 | //
185 | // Has full opacity.
186 | //
187 | 'opacity': 1,
188 | //
189 | // Hide the modal
190 | //
191 | 'visibility': 'hidden',
192 | //
193 | // Ensure the elment is hidden.
194 | //
195 | 'display': 'none'
196 | }
197 |
198 | },
199 | //
200 | // Initial closeButton variable.
201 | //
202 | $closeButton
203 | ;
204 |
205 | //
206 | // Do we have a modal background element?
207 | //
208 | if ( modalBg.length === 0 ) {
209 | //
210 | // No we don't. So, let's create one.
211 | //
212 | modalBg = $( '
', { 'class' : 'reveal-modal-bg' } )
213 | //
214 | // Then insert it after the modal element.
215 | //
216 | .insertAfter( modal );
217 | //
218 | // Now, fade it out a bit.
219 | //
220 | modalBg.fadeTo( 'fast', 0.8 );
221 | }
222 |
223 | //
224 | // Helper Methods
225 | //
226 |
227 | /**
228 | * Unlock the modal for animation.
229 | *
230 | * @method unlockModal
231 | */
232 | function unlockModal() {
233 | locked = false;
234 | }
235 |
236 | /**
237 | * Lock the modal to prevent further animation.
238 | *
239 | * @method lockModal
240 | */
241 | function lockModal() {
242 | locked = true;
243 | }
244 |
245 | /**
246 | * Closes all open modals.
247 | *
248 | * @method closeOpenModal
249 | */
250 | function closeOpenModals() {
251 | //
252 | // Get all reveal-modal elements with the .open class.
253 | //
254 | var $openModals = $( ".reveal-modal.open" );
255 | //
256 | // Do we have modals to close?
257 | //
258 | if ( $openModals.length === 1 ) {
259 | //
260 | // Set the modals for animation queuing.
261 | //
262 | modalQueued = true;
263 | //
264 | // Trigger the modal close event.
265 | //
266 | $openModals.trigger( "reveal:close" );
267 | }
268 |
269 | }
270 | /**
271 | * Animates the modal opening.
272 | * Handles the modal 'open' event.
273 | *
274 | * @method openAnimation
275 | */
276 | function openAnimation() {
277 | //
278 | // First, determine if we're in the middle of animation.
279 | //
280 | if ( !locked ) {
281 | //
282 | // We're not animating, let's lock the modal for animation.
283 | //
284 | lockModal();
285 | //
286 | // Close any opened modals.
287 | //
288 | closeOpenModals();
289 | //
290 | // Now, add the open class to this modal.
291 | //
292 | modal.addClass( "open" );
293 |
294 | //
295 | // Are we executing the 'fadeAndPop' animation?
296 | //
297 | if ( options.animation === "fadeAndPop" ) {
298 | //
299 | // Yes, we're doing the 'fadeAndPop' animation.
300 | // Okay, set the modal css properties.
301 | //
302 | //
303 | // Set the 'top' property to the document scroll minus the calculated top offset.
304 | //
305 | cssOpts.open.top = $doc.scrollTop() - topOffset;
306 | //
307 | // Flip the opacity to 0.
308 | //
309 | cssOpts.open.opacity = 0;
310 | //
311 | // Set the css options.
312 | //
313 | modal.css( cssOpts.open );
314 | //
315 | // Fade in the background element, at half the speed of the modal element.
316 | // So, faster than the modal element.
317 | //
318 | modalBg.fadeIn( options.animationSpeed / 2 );
319 |
320 | //
321 | // Let's delay the next animation queue.
322 | // We'll wait until the background element is faded in.
323 | //
324 | modal.delay( options.animationSpeed / 2 )
325 | //
326 | // Animate the following css properties.
327 | //
328 | .animate( {
329 | //
330 | // Set the 'top' property to the document scroll plus the calculated top measure.
331 | //
332 | "top": $doc.scrollTop() + topMeasure + 'px',
333 | //
334 | // Set it to full opacity.
335 | //
336 | "opacity": 1
337 |
338 | },
339 | /*
340 | * Fade speed.
341 | */
342 | options.animationSpeed,
343 | /*
344 | * End of animation callback.
345 | */
346 | function () {
347 | //
348 | // Trigger the modal reveal:opened event.
349 | // This should trigger the functions set in the options.opened property.
350 | //
351 | modal.trigger( 'reveal:opened' );
352 |
353 | }); // end of animate.
354 |
355 | } // end if 'fadeAndPop'
356 |
357 | //
358 | // Are executing the 'fade' animation?
359 | //
360 | if ( options.animation === "fade" ) {
361 | //
362 | // Yes, were executing 'fade'.
363 | // Okay, let's set the modal properties.
364 | //
365 | cssOpts.open.top = $doc.scrollTop() + topMeasure;
366 | //
367 | // Flip the opacity to 0.
368 | //
369 | cssOpts.open.opacity = 0;
370 | //
371 | // Set the css options.
372 | //
373 | modal.css( cssOpts.open );
374 | //
375 | // Fade in the modal background at half the speed of the modal.
376 | // So, faster than modal.
377 | //
378 | modalBg.fadeIn( options.animationSpeed / 2 );
379 |
380 | //
381 | // Delay the modal animation.
382 | // Wait till the modal background is done animating.
383 | //
384 | modal.delay( options.animationSpeed / 2 )
385 | //
386 | // Now animate the modal.
387 | //
388 | .animate( {
389 | //
390 | // Set to full opacity.
391 | //
392 | "opacity": 1
393 | },
394 |
395 | /*
396 | * Animation speed.
397 | */
398 | options.animationSpeed,
399 |
400 | /*
401 | * End of animation callback.
402 | */
403 | function () {
404 | //
405 | // Trigger the modal reveal:opened event.
406 | // This should trigger the functions set in the options.opened property.
407 | //
408 | modal.trigger( 'reveal:opened' );
409 |
410 | });
411 |
412 | } // end if 'fade'
413 |
414 | //
415 | // Are we not animating?
416 | //
417 | if ( options.animation === "none" ) {
418 | //
419 | // We're not animating.
420 | // Okay, let's set the modal css properties.
421 | //
422 | //
423 | // Set the top property.
424 | //
425 | cssOpts.open.top = $doc.scrollTop() + topMeasure;
426 | //
427 | // Set the opacity property to full opacity, since we're not fading (animating).
428 | //
429 | cssOpts.open.opacity = 1;
430 | //
431 | // Set the css property.
432 | //
433 | modal.css( cssOpts.open );
434 | //
435 | // Show the modal Background.
436 | //
437 | modalBg.css( { "display": "block" } );
438 | //
439 | // Trigger the modal opened event.
440 | //
441 | modal.trigger( 'reveal:opened' );
442 |
443 | } // end if animating 'none'
444 |
445 | }// end if !locked
446 |
447 | }// end openAnimation
448 |
449 |
450 | function openVideos() {
451 | var video = modal.find('.flex-video'),
452 | iframe = video.find('iframe');
453 | if (iframe.length > 0) {
454 | iframe.attr("src", iframe.data("src"));
455 | video.fadeIn(100);
456 | }
457 | }
458 |
459 | //
460 | // Bind the reveal 'open' event.
461 | // When the event is triggered, openAnimation is called
462 | // along with any function set in the options.open property.
463 | //
464 | modal.bind( 'reveal:open.reveal', openAnimation );
465 | modal.bind( 'reveal:open.reveal', openVideos);
466 |
467 | /**
468 | * Closes the modal element(s)
469 | * Handles the modal 'close' event.
470 | *
471 | * @method closeAnimation
472 | */
473 | function closeAnimation() {
474 | //
475 | // First, determine if we're in the middle of animation.
476 | //
477 | if ( !locked ) {
478 | //
479 | // We're not animating, let's lock the modal for animation.
480 | //
481 | lockModal();
482 | //
483 | // Clear the modal of the open class.
484 | //
485 | modal.removeClass( "open" );
486 |
487 | //
488 | // Are we using the 'fadeAndPop' animation?
489 | //
490 | if ( options.animation === "fadeAndPop" ) {
491 | //
492 | // Yes, okay, let's set the animation properties.
493 | //
494 | modal.animate( {
495 | //
496 | // Set the top property to the document scrollTop minus calculated topOffset.
497 | //
498 | "top": $doc.scrollTop() - topOffset + 'px',
499 | //
500 | // Fade the modal out, by using the opacity property.
501 | //
502 | "opacity": 0
503 |
504 | },
505 | /*
506 | * Fade speed.
507 | */
508 | options.animationSpeed / 2,
509 | /*
510 | * End of animation callback.
511 | */
512 | function () {
513 | //
514 | // Set the css hidden options.
515 | //
516 | modal.css( cssOpts.close );
517 |
518 | });
519 | //
520 | // Is the modal animation queued?
521 | //
522 | if ( !modalQueued ) {
523 | //
524 | // Oh, the modal(s) are mid animating.
525 | // Let's delay the animation queue.
526 | //
527 | modalBg.delay( options.animationSpeed )
528 | //
529 | // Fade out the modal background.
530 | //
531 | .fadeOut(
532 | /*
533 | * Animation speed.
534 | */
535 | options.animationSpeed,
536 | /*
537 | * End of animation callback.
538 | */
539 | function () {
540 | //
541 | // Trigger the modal 'closed' event.
542 | // This should trigger any method set in the options.closed property.
543 | //
544 | modal.trigger( 'reveal:closed' );
545 |
546 | });
547 |
548 | } else {
549 | //
550 | // We're not mid queue.
551 | // Trigger the modal 'closed' event.
552 | // This should trigger any method set in the options.closed propety.
553 | //
554 | modal.trigger( 'reveal:closed' );
555 |
556 | } // end if !modalQueued
557 |
558 | } // end if animation 'fadeAndPop'
559 |
560 | //
561 | // Are we using the 'fade' animation.
562 | //
563 | if ( options.animation === "fade" ) {
564 | //
565 | // Yes, we're using the 'fade' animation.
566 | //
567 | modal.animate( { "opacity" : 0 },
568 | /*
569 | * Animation speed.
570 | */
571 | options.animationSpeed,
572 | /*
573 | * End of animation callback.
574 | */
575 | function () {
576 | //
577 | // Set the css close options.
578 | //
579 | modal.css( cssOpts.close );
580 |
581 | }); // end animate
582 |
583 | //
584 | // Are we mid animating the modal(s)?
585 | //
586 | if ( !modalQueued ) {
587 | //
588 | // Oh, the modal(s) are mid animating.
589 | // Let's delay the animation queue.
590 | //
591 | modalBg.delay( options.animationSpeed )
592 | //
593 | // Let's fade out the modal background element.
594 | //
595 | .fadeOut(
596 | /*
597 | * Animation speed.
598 | */
599 | options.animationSpeed,
600 | /*
601 | * End of animation callback.
602 | */
603 | function () {
604 | //
605 | // Trigger the modal 'closed' event.
606 | // This should trigger any method set in the options.closed propety.
607 | //
608 | modal.trigger( 'reveal:closed' );
609 |
610 | }); // end fadeOut
611 |
612 | } else {
613 | //
614 | // We're not mid queue.
615 | // Trigger the modal 'closed' event.
616 | // This should trigger any method set in the options.closed propety.
617 | //
618 | modal.trigger( 'reveal:closed' );
619 |
620 | } // end if !modalQueued
621 |
622 | } // end if animation 'fade'
623 |
624 | //
625 | // Are we not animating?
626 | //
627 | if ( options.animation === "none" ) {
628 | //
629 | // We're not animating.
630 | // Set the modal close css options.
631 | //
632 | modal.css( cssOpts.close );
633 | //
634 | // Is the modal in the middle of an animation queue?
635 | //
636 | if ( !modalQueued ) {
637 | //
638 | // It's not mid queueu. Just hide it.
639 | //
640 | modalBg.css( { 'display': 'none' } );
641 | }
642 | //
643 | // Trigger the modal 'closed' event.
644 | // This should trigger any method set in the options.closed propety.
645 | //
646 | modal.trigger( 'reveal:closed' );
647 |
648 | } // end if not animating
649 | //
650 | // Reset the modalQueued variable.
651 | //
652 | modalQueued = false;
653 | } // end if !locked
654 |
655 | } // end closeAnimation
656 |
657 | /**
658 | * Destroys the modal and it's events.
659 | *
660 | * @method destroy
661 | */
662 | function destroy() {
663 | //
664 | // Unbind all .reveal events from the modal.
665 | //
666 | modal.unbind( '.reveal' );
667 | //
668 | // Unbind all .reveal events from the modal background.
669 | //
670 | modalBg.unbind( '.reveal' );
671 | //
672 | // Unbind all .reveal events from the modal 'close' button.
673 | //
674 | $closeButton.unbind( '.reveal' );
675 | //
676 | // Unbind all .reveal events from the body.
677 | //
678 | $( 'body' ).unbind( '.reveal' );
679 |
680 | }
681 |
682 | function closeVideos() {
683 | var video = modal.find('.flex-video'),
684 | iframe = video.find('iframe');
685 | if (iframe.length > 0) {
686 | iframe.data("src", iframe.attr("src"));
687 | iframe.attr("src", "");
688 | video.fadeOut(100);
689 | }
690 | }
691 |
692 | //
693 | // Bind the modal 'close' event
694 | //
695 | modal.bind( 'reveal:close.reveal', closeAnimation );
696 | modal.bind( 'reveal:closed.reveal', closeVideos );
697 | //
698 | // Bind the modal 'opened' + 'closed' event
699 | // Calls the unlockModal method.
700 | //
701 | modal.bind( 'reveal:opened.reveal reveal:closed.reveal', unlockModal );
702 | //
703 | // Bind the modal 'closed' event.
704 | // Calls the destroy method.
705 | //
706 | modal.bind( 'reveal:closed.reveal', destroy );
707 | //
708 | // Bind the modal 'open' event
709 | // Handled by the options.open property function.
710 | //
711 | modal.bind( 'reveal:open.reveal', options.open );
712 | //
713 | // Bind the modal 'opened' event.
714 | // Handled by the options.opened property function.
715 | //
716 | modal.bind( 'reveal:opened.reveal', options.opened );
717 | //
718 | // Bind the modal 'close' event.
719 | // Handled by the options.close property function.
720 | //
721 | modal.bind( 'reveal:close.reveal', options.close );
722 | //
723 | // Bind the modal 'closed' event.
724 | // Handled by the options.closed property function.
725 | //
726 | modal.bind( 'reveal:closed.reveal', options.closed );
727 |
728 | //
729 | // We're running this for the first time.
730 | // Trigger the modal 'open' event.
731 | //
732 | modal.trigger( 'reveal:open' );
733 |
734 | //
735 | // Get the closeButton variable element(s).
736 | //
737 | $closeButton = $( '.' + options.dismissModalClass )
738 | //
739 | // Bind the element 'click' event and handler.
740 | //
741 | .bind( 'click.reveal', function () {
742 | //
743 | // Trigger the modal 'close' event.
744 | //
745 | modal.trigger( 'reveal:close' );
746 |
747 | });
748 |
749 | //
750 | // Should we close the modal background on click?
751 | //
752 | if ( options.closeOnBackgroundClick ) {
753 | //
754 | // Yes, close the modal background on 'click'
755 | // Set the modal background css 'cursor' propety to pointer.
756 | // Adds a pointer symbol when you mouse over the modal background.
757 | //
758 | modalBg.css( { "cursor": "pointer" } );
759 | //
760 | // Bind a 'click' event handler to the modal background.
761 | //
762 | modalBg.bind( 'click.reveal', function () {
763 | //
764 | // Trigger the modal 'close' event.
765 | //
766 | modal.trigger( 'reveal:close' );
767 |
768 | });
769 |
770 | }
771 |
772 | //
773 | // Bind keyup functions on the body element.
774 | // We'll want to close the modal when the 'escape' key is hit.
775 | //
776 | $( 'body' ).bind( 'keyup.reveal', function ( event ) {
777 | //
778 | // Did the escape key get triggered?
779 | //
780 | if ( event.which === 27 ) { // 27 is the keycode for the Escape key
781 | //
782 | // Escape key was triggered.
783 | // Trigger the modal 'close' event.
784 | //
785 | modal.trigger( 'reveal:close' );
786 | }
787 |
788 | }); // end $(body)
789 |
790 | }); // end this.each
791 |
792 | }; // end $.fn
793 |
794 | } ( jQuery ) );
795 |
--------------------------------------------------------------------------------
/views/javascripts/jquery.foundation.orbit.js:
--------------------------------------------------------------------------------
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 | bulletThumbsHideOnSmall: true, // hide thumbs on small devices
41 | afterSlideChange: $.noop, // callback to execute after slide changes
42 | afterLoadComplete: $.noop, // callback to execute after everything has been loaded
43 | fluid: true,
44 | centerBullets: true, // center bullet nav with js, turn this off if you want to position the bullet nav manually
45 | singleCycle: false, // cycles through orbit slides only once
46 | slideNumber: false, // display slide numbers?
47 | stackOnSmall: false // stack slides on small devices (i.e. phones)
48 | },
49 |
50 | activeSlide: 0,
51 | numberSlides: 0,
52 | orbitWidth: null,
53 | orbitHeight: null,
54 | locked: null,
55 | timerRunning: null,
56 | degrees: 0,
57 | wrapperHTML: '
',
58 | timerHTML: '
',
59 | captionHTML: '
',
60 | directionalNavHTML: '
',
61 | bulletHTML: '
',
62 | slideNumberHTML: '
',
63 |
64 | init: function (element, options) {
65 | var $imageSlides,
66 | imagesLoadedCount = 0,
67 | self = this;
68 |
69 | // Bind functions to correct context
70 | this.clickTimer = $.proxy(this.clickTimer, this);
71 | this.addBullet = $.proxy(this.addBullet, this);
72 | this.resetAndUnlock = $.proxy(this.resetAndUnlock, this);
73 | this.stopClock = $.proxy(this.stopClock, this);
74 | this.startTimerAfterMouseLeave = $.proxy(this.startTimerAfterMouseLeave, this);
75 | this.clearClockMouseLeaveTimer = $.proxy(this.clearClockMouseLeaveTimer, this);
76 | this.rotateTimer = $.proxy(this.rotateTimer, this);
77 |
78 | this.options = $.extend({}, this.defaults, options);
79 | if (this.options.timer === 'false') this.options.timer = false;
80 | if (this.options.captions === 'false') this.options.captions = false;
81 | if (this.options.directionalNav === 'false') this.options.directionalNav = false;
82 |
83 | this.$element = $(element);
84 | this.$wrapper = this.$element.wrap(this.wrapperHTML).parent();
85 | this.$slides = this.$element.children('img, a, div, figure, li');
86 |
87 | this.$element.on('movestart', function(e) {
88 | // If the movestart is heading off in an upwards or downwards
89 | // direction, prevent it so that the browser scrolls normally.
90 | if ((e.distX > e.distY && e.distX < -e.distY) ||
91 | (e.distX < e.distY && e.distX > -e.distY)) {
92 | e.preventDefault();
93 | }
94 | });
95 |
96 | this.$element.bind('orbit.next', function () {
97 | self.shift('next');
98 | });
99 |
100 | this.$element.bind('orbit.prev', function () {
101 | self.shift('prev');
102 | });
103 |
104 | this.$element.bind('swipeleft', function () {
105 | $(this).trigger('orbit.next');
106 | });
107 |
108 | this.$element.bind('swiperight', function () {
109 | $(this).trigger('orbit.prev');
110 | });
111 |
112 | this.$element.bind('orbit.goto', function (event, index) {
113 | self.shift(index);
114 | });
115 |
116 | this.$element.bind('orbit.start', function (event, index) {
117 | self.startClock();
118 | });
119 |
120 | this.$element.bind('orbit.stop', function (event, index) {
121 | self.stopClock();
122 | });
123 |
124 | $imageSlides = this.$slides.filter('img');
125 |
126 | if ($imageSlides.length === 0) {
127 | this.loaded();
128 | } else {
129 | $imageSlides.bind('imageready', function () {
130 | imagesLoadedCount += 1;
131 | if (imagesLoadedCount === $imageSlides.length) {
132 | self.loaded();
133 | }
134 | });
135 | }
136 | },
137 |
138 | loaded: function () {
139 | this.$element
140 | .addClass('orbit')
141 | .css({width: '1px', height: '1px'});
142 |
143 | if (this.options.stackOnSmall) {
144 | this.$element.addClass('orbit-stack-on-small');
145 | }
146 |
147 | this.$slides.addClass('orbit-slide').css({"opacity" : 0});
148 |
149 | this.setDimentionsFromLargestSlide();
150 | this.updateOptionsIfOnlyOneSlide();
151 | this.setupFirstSlide();
152 | this.notifySlideChange();
153 |
154 | if (this.options.timer) {
155 | this.setupTimer();
156 | this.startClock();
157 | }
158 |
159 | if (this.options.captions) {
160 | this.setupCaptions();
161 | }
162 |
163 | if (this.options.directionalNav) {
164 | this.setupDirectionalNav();
165 | }
166 |
167 | if (this.options.bullets) {
168 | this.setupBulletNav();
169 | this.setActiveBullet();
170 | }
171 |
172 | this.options.afterLoadComplete.call(this);
173 | Holder.run();
174 | },
175 |
176 | currentSlide: function () {
177 | return this.$slides.eq(this.activeSlide);
178 | },
179 |
180 | notifySlideChange: function() {
181 | if (this.options.slideNumber) {
182 | var txt = (this.activeSlide+1) + ' of ' + this.$slides.length;
183 | this.$element.trigger("orbit.change", {slideIndex: this.activeSlide, slideCount: this.$slides.length});
184 | if (this.$counter === undefined) {
185 | var $counter = $(this.slideNumberHTML).html(txt);
186 | this.$counter = $counter;
187 | this.$wrapper.append(this.$counter);
188 | } else {
189 | this.$counter.html(txt);
190 | }
191 | }
192 | },
193 |
194 | setDimentionsFromLargestSlide: function () {
195 | //Collect all slides and set slider size of largest image
196 | var self = this,
197 | $fluidPlaceholder;
198 |
199 | self.$element.add(self.$wrapper).width(this.$slides.first().outerWidth());
200 | self.$element.add(self.$wrapper).height(this.$slides.first().height());
201 | self.orbitWidth = this.$slides.first().outerWidth();
202 | self.orbitHeight = this.$slides.first().height();
203 | $fluidPlaceholder = this.$slides.first().findFirstImage().clone();
204 |
205 |
206 | this.$slides.each(function () {
207 | var slide = $(this),
208 | slideWidth = slide.outerWidth(),
209 | slideHeight = slide.height();
210 |
211 | if (slideWidth > self.$element.outerWidth()) {
212 | self.$element.add(self.$wrapper).width(slideWidth);
213 | self.orbitWidth = self.$element.outerWidth();
214 | }
215 | if (slideHeight > self.$element.height()) {
216 | self.$element.add(self.$wrapper).height(slideHeight);
217 | self.orbitHeight = self.$element.height();
218 | $fluidPlaceholder = $(this).findFirstImage().clone();
219 | }
220 | self.numberSlides += 1;
221 | });
222 |
223 | if (this.options.fluid) {
224 | if (typeof this.options.fluid === "string") {
225 | // $fluidPlaceholder = $("
![]()
").attr("src", "http://placehold.it/" + this.options.fluid);
226 | $fluidPlaceholder = $("
![]()
").attr("data-src", "holder.js/" + this.options.fluid);
227 | //var inner = $("
").css({"display":"inline-block", "width":"2px", "height":"2px"});
228 | //$fluidPlaceholder = $("
").css({"float":"left"});
229 | //$fluidPlaceholder.wrapInner(inner);
230 |
231 | //$fluidPlaceholder = $("
").css({"height":"1px", "width":"2px"});
232 | //$fluidPlaceholder = $("
");
233 | }
234 |
235 | self.$element.prepend($fluidPlaceholder);
236 | $fluidPlaceholder.addClass('fluid-placeholder');
237 | self.$element.add(self.$wrapper).css({width: 'inherit'});
238 | self.$element.add(self.$wrapper).css({height: 'inherit'});
239 |
240 | $(window).bind('resize', function () {
241 | self.orbitWidth = self.$element.outerWidth();
242 | self.orbitHeight = self.$element.height();
243 | });
244 | }
245 | },
246 |
247 | //Animation locking functions
248 | lock: function () {
249 | this.locked = true;
250 | },
251 |
252 | unlock: function () {
253 | this.locked = false;
254 | },
255 |
256 | updateOptionsIfOnlyOneSlide: function () {
257 | if(this.$slides.length === 1) {
258 | this.options.directionalNav = false;
259 | this.options.timer = false;
260 | this.options.bullets = false;
261 | }
262 | },
263 |
264 | setupFirstSlide: function () {
265 | //Set initial front photo z-index and fades it in
266 | var self = this;
267 | this.$slides.first()
268 | .css({"z-index" : 3, "opacity" : 1})
269 | .fadeIn(function() {
270 | //brings in all other slides IF css declares a display: none
271 | self.$slides.css({"display":"block"})
272 | });
273 | },
274 |
275 | startClock: function () {
276 | var self = this;
277 |
278 | if(!this.options.timer) {
279 | return false;
280 | }
281 |
282 | if (this.$timer.is(':hidden')) {
283 | this.clock = setInterval(function () {
284 | self.$element.trigger('orbit.next');
285 | }, this.options.advanceSpeed);
286 | } else {
287 | this.timerRunning = true;
288 | this.$pause.removeClass('active');
289 | this.clock = setInterval(this.rotateTimer, this.options.advanceSpeed / 180, false);
290 | }
291 | },
292 |
293 | rotateTimer: function (reset) {
294 | var degreeCSS = "rotate(" + this.degrees + "deg)";
295 | this.degrees += 2;
296 | this.$rotator.css({
297 | "-webkit-transform": degreeCSS,
298 | "-moz-transform": degreeCSS,
299 | "-o-transform": degreeCSS,
300 | "-ms-transform": degreeCSS
301 | });
302 | if (reset) {
303 | this.degrees = 0;
304 | this.$rotator.removeClass('move');
305 | this.$mask.removeClass('move');
306 | }
307 | if(this.degrees > 180) {
308 | this.$rotator.addClass('move');
309 | this.$mask.addClass('move');
310 | }
311 | if(this.degrees > 360) {
312 | this.$rotator.removeClass('move');
313 | this.$mask.removeClass('move');
314 | this.degrees = 0;
315 | this.$element.trigger('orbit.next');
316 | }
317 | },
318 |
319 | stopClock: function () {
320 | if (!this.options.timer) {
321 | return false;
322 | } else {
323 | this.timerRunning = false;
324 | clearInterval(this.clock);
325 | this.$pause.addClass('active');
326 | }
327 | },
328 |
329 | setupTimer: function () {
330 | this.$timer = $(this.timerHTML);
331 | this.$wrapper.append(this.$timer);
332 |
333 | this.$rotator = this.$timer.find('.rotator');
334 | this.$mask = this.$timer.find('.mask');
335 | this.$pause = this.$timer.find('.pause');
336 |
337 | this.$timer.click(this.clickTimer);
338 |
339 | if (this.options.startClockOnMouseOut) {
340 | this.$wrapper.mouseleave(this.startTimerAfterMouseLeave);
341 | this.$wrapper.mouseenter(this.clearClockMouseLeaveTimer);
342 | }
343 |
344 | if (this.options.pauseOnHover) {
345 | this.$wrapper.mouseenter(this.stopClock);
346 | }
347 | },
348 |
349 | startTimerAfterMouseLeave: function () {
350 | var self = this;
351 |
352 | this.outTimer = setTimeout(function() {
353 | if(!self.timerRunning){
354 | self.startClock();
355 | }
356 | }, this.options.startClockOnMouseOutAfter)
357 | },
358 |
359 | clearClockMouseLeaveTimer: function () {
360 | clearTimeout(this.outTimer);
361 | },
362 |
363 | clickTimer: function () {
364 | if(!this.timerRunning) {
365 | this.startClock();
366 | } else {
367 | this.stopClock();
368 | }
369 | },
370 |
371 | setupCaptions: function () {
372 | this.$caption = $(this.captionHTML);
373 | this.$wrapper.append(this.$caption);
374 | this.setCaption();
375 | },
376 |
377 | setCaption: function () {
378 | var captionLocation = this.currentSlide().attr('data-caption'),
379 | captionHTML;
380 |
381 | if (!this.options.captions) {
382 | return false;
383 | }
384 |
385 | //Set HTML for the caption if it exists
386 | if (captionLocation) {
387 | //if caption text is blank, don't show captions
388 | if ($.trim($(captionLocation).text()).length < 1){
389 | return false;
390 | }
391 |
392 | // if location selector starts with '#', remove it so we don't see id="#selector"
393 | if (captionLocation.charAt(0) == '#') {
394 | captionLocation = captionLocation.substring(1, captionLocation.length);
395 | }
396 | captionHTML = $('#' + captionLocation).html(); //get HTML from the matching HTML entity
397 | this.$caption
398 | .attr('id', captionLocation) // Add ID caption TODO why is the id being set?
399 | .html(captionHTML); // Change HTML in Caption
400 | //Animations for Caption entrances
401 | switch (this.options.captionAnimation) {
402 | case 'none':
403 | this.$caption.show();
404 | break;
405 | case 'fade':
406 | this.$caption.fadeIn(this.options.captionAnimationSpeed);
407 | break;
408 | case 'slideOpen':
409 | this.$caption.slideDown(this.options.captionAnimationSpeed);
410 | break;
411 | }
412 | } else {
413 | //Animations for Caption exits
414 | switch (this.options.captionAnimation) {
415 | case 'none':
416 | this.$caption.hide();
417 | break;
418 | case 'fade':
419 | this.$caption.fadeOut(this.options.captionAnimationSpeed);
420 | break;
421 | case 'slideOpen':
422 | this.$caption.slideUp(this.options.captionAnimationSpeed);
423 | break;
424 | }
425 | }
426 | },
427 |
428 | setupDirectionalNav: function () {
429 | var self = this,
430 | $directionalNav = $(this.directionalNavHTML);
431 |
432 | $directionalNav.find('.right').html(this.options.directionalNavRightText);
433 | $directionalNav.find('.left').html(this.options.directionalNavLeftText);
434 |
435 | this.$wrapper.append($directionalNav);
436 |
437 | this.$wrapper.find('.left').click(function () {
438 | self.stopClock();
439 | if (self.options.resetTimerOnClick) {
440 | self.rotateTimer(true);
441 | self.startClock();
442 | }
443 | self.$element.trigger('orbit.prev');
444 | });
445 |
446 | this.$wrapper.find('.right').click(function () {
447 | self.stopClock();
448 | if (self.options.resetTimerOnClick) {
449 | self.rotateTimer(true);
450 | self.startClock();
451 | }
452 | self.$element.trigger('orbit.next');
453 | });
454 | },
455 |
456 | setupBulletNav: function () {
457 | this.$bullets = $(this.bulletHTML);
458 | this.$wrapper.append(this.$bullets);
459 | this.$slides.each(this.addBullet);
460 | this.$element.addClass('with-bullets');
461 | if (this.options.centerBullets) this.$bullets.css('margin-left', -this.$bullets.outerWidth() / 2);
462 | if (this.options.bulletThumbsHideOnSmall) this.$bullets.addClass('hide-for-small');
463 | },
464 |
465 | addBullet: function (index, slide) {
466 | var position = index + 1,
467 | $li = $('
' + (position) + ''),
468 | thumbName,
469 | self = this;
470 |
471 | if (this.options.bulletThumbs) {
472 | thumbName = $(slide).attr('data-thumb');
473 | if (thumbName) {
474 | $li
475 | .addClass('has-thumb')
476 | .css({background: "url(" + this.options.bulletThumbLocation + thumbName + ") no-repeat"});;
477 | }
478 | }
479 | this.$bullets.append($li);
480 | $li.data('index', index);
481 | $li.click(function () {
482 | self.stopClock();
483 | if (self.options.resetTimerOnClick) {
484 | self.rotateTimer(true);
485 | self.startClock();
486 | }
487 | self.$element.trigger('orbit.goto', [$li.data('index')])
488 | });
489 | },
490 |
491 | setActiveBullet: function () {
492 | if(!this.options.bullets) { return false; } else {
493 | this.$bullets.find('li')
494 | .removeClass('active')
495 | .eq(this.activeSlide)
496 | .addClass('active');
497 | }
498 | },
499 |
500 | resetAndUnlock: function () {
501 | this.$slides
502 | .eq(this.prevActiveSlide)
503 | .css({"z-index" : 1});
504 | this.unlock();
505 | this.options.afterSlideChange.call(this, this.$slides.eq(this.prevActiveSlide), this.$slides.eq(this.activeSlide));
506 | },
507 |
508 | shift: function (direction) {
509 | var slideDirection = direction;
510 |
511 | //remember previous activeSlide
512 | this.prevActiveSlide = this.activeSlide;
513 |
514 | //exit function if bullet clicked is same as the current image
515 | if (this.prevActiveSlide == slideDirection) { return false; }
516 |
517 | if (this.$slides.length == "1") { return false; }
518 | if (!this.locked) {
519 | this.lock();
520 | //deduce the proper activeImage
521 | if (direction == "next") {
522 | this.activeSlide++;
523 | if (this.activeSlide == this.numberSlides) {
524 | this.activeSlide = 0;
525 | }
526 | } else if (direction == "prev") {
527 | this.activeSlide--
528 | if (this.activeSlide < 0) {
529 | this.activeSlide = this.numberSlides - 1;
530 | }
531 | } else {
532 | this.activeSlide = direction;
533 | if (this.prevActiveSlide < this.activeSlide) {
534 | slideDirection = "next";
535 | } else if (this.prevActiveSlide > this.activeSlide) {
536 | slideDirection = "prev"
537 | }
538 | }
539 |
540 | //set to correct bullet
541 | this.setActiveBullet();
542 | this.notifySlideChange();
543 |
544 | //set previous slide z-index to one below what new activeSlide will be
545 | this.$slides
546 | .eq(this.prevActiveSlide)
547 | .css({"z-index" : 2});
548 |
549 | //fade
550 | if (this.options.animation == "fade") {
551 | this.$slides
552 | .eq(this.activeSlide)
553 | .css({"opacity" : 0, "z-index" : 3})
554 | .animate({"opacity" : 1}, this.options.animationSpeed, this.resetAndUnlock);
555 | this.$slides
556 | .eq(this.prevActiveSlide)
557 | .animate({"opacity":0}, this.options.animationSpeed);
558 | }
559 |
560 | //horizontal-slide
561 | if (this.options.animation == "horizontal-slide") {
562 | if (slideDirection == "next") {
563 | this.$slides
564 | .eq(this.activeSlide)
565 | .css({"left": this.orbitWidth, "z-index" : 3})
566 | .css("opacity", 1)
567 | .animate({"left" : 0}, this.options.animationSpeed, this.resetAndUnlock);
568 | }
569 | if (slideDirection == "prev") {
570 | this.$slides
571 | .eq(this.activeSlide)
572 | .css({"left": -this.orbitWidth, "z-index" : 3})
573 | .css("opacity", 1)
574 | .animate({"left" : 0}, this.options.animationSpeed, this.resetAndUnlock);
575 | }
576 | this.$slides
577 | .eq(this.prevActiveSlide)
578 | .css("opacity", 0);
579 | }
580 |
581 | //vertical-slide
582 | if (this.options.animation == "vertical-slide") {
583 | if (slideDirection == "prev") {
584 | this.$slides
585 | .eq(this.activeSlide)
586 | .css({"top": this.orbitHeight, "z-index" : 3})
587 | .css("opacity", 1)
588 | .animate({"top" : 0}, this.options.animationSpeed, this.resetAndUnlock);
589 | this.$slides
590 | .eq(this.prevActiveSlide)
591 | .css("opacity", 0);
592 | }
593 | if (slideDirection == "next") {
594 | this.$slides
595 | .eq(this.activeSlide)
596 | .css({"top": -this.orbitHeight, "z-index" : 3})
597 | .css("opacity", 1)
598 | .animate({"top" : 0}, this.options.animationSpeed, this.resetAndUnlock);
599 | }
600 | this.$slides
601 | .eq(this.prevActiveSlide)
602 | .css("opacity", 0);
603 | }
604 |
605 | //horizontal-push
606 | if (this.options.animation == "horizontal-push") {
607 | if (slideDirection == "next") {
608 | this.$slides
609 | .eq(this.activeSlide)
610 | .css({"left": this.orbitWidth, "z-index" : 3})
611 | .animate({"left" : 0, "opacity" : 1}, this.options.animationSpeed, this.resetAndUnlock);
612 | this.$slides
613 | .eq(this.prevActiveSlide)
614 | .animate({"left" : -this.orbitWidth}, this.options.animationSpeed, "", function(){
615 | $(this).css({"opacity" : 0});
616 | });
617 | }
618 | if (slideDirection == "prev") {
619 | this.$slides
620 | .eq(this.activeSlide)
621 | .css({"left": -this.orbitWidth, "z-index" : 3})
622 | .animate({"left" : 0, "opacity" : 1}, this.options.animationSpeed, this.resetAndUnlock);
623 | this.$slides
624 | .eq(this.prevActiveSlide)
625 | .animate({"left" : this.orbitWidth}, this.options.animationSpeed, "", function(){
626 | $(this).css({"opacity" : 0});
627 | });
628 | }
629 | }
630 |
631 | //vertical-push
632 | if (this.options.animation == "vertical-push") {
633 | if (slideDirection == "next") {
634 | this.$slides
635 | .eq(this.activeSlide)
636 | .css({top: -this.orbitHeight, "z-index" : 3})
637 | .css("opacity", 1)
638 | .animate({top : 0, "opacity":1}, this.options.animationSpeed, this.resetAndUnlock);
639 | this.$slides
640 | .eq(this.prevActiveSlide)
641 | .css("opacity", 0)
642 | .animate({top : this.orbitHeight}, this.options.animationSpeed, "");
643 | }
644 | if (slideDirection == "prev") {
645 | this.$slides
646 | .eq(this.activeSlide)
647 | .css({top: this.orbitHeight, "z-index" : 3})
648 | .css("opacity", 1)
649 | .animate({top : 0}, this.options.animationSpeed, this.resetAndUnlock);
650 | this.$slides
651 | .eq(this.prevActiveSlide)
652 | .css("opacity", 0)
653 | .animate({top : -this.orbitHeight}, this.options.animationSpeed);
654 | }
655 | }
656 |
657 | this.setCaption();
658 | }
659 |
660 | // if on last slide and singleCycle is true, don't loop through slides again
661 | // .length is zero based so must minus 1 to match activeSlide index
662 | if (this.activeSlide === this.$slides.length-1 && this.options.singleCycle) {
663 | this.stopClock();
664 | }
665 | }
666 | };
667 |
668 | $.fn.orbit = function (options) {
669 | return this.each(function () {
670 | var orbit = $.extend({}, ORBIT);
671 | orbit.init(this, options);
672 | });
673 | };
674 |
675 | })(jQuery);
676 |
677 | /*!
678 | * jQuery imageready Plugin
679 | * http://www.zurb.com/playground/
680 | *
681 | * Copyright 2011, ZURB
682 | * Released under the MIT License
683 | */
684 | (function ($) {
685 |
686 | var options = {};
687 |
688 | $.event.special.imageready = {
689 |
690 | setup: function (data, namespaces, eventHandle) {
691 | options = data || options;
692 | },
693 |
694 | add: function (handleObj) {
695 | var $this = $(this),
696 | src;
697 |
698 | if ( this.nodeType === 1 && this.tagName.toLowerCase() === 'img' && this.src !== '' ) {
699 | if (options.forceLoad) {
700 | src = $this.attr('src');
701 | $this.attr('src', '');
702 | bindToLoad(this, handleObj.handler);
703 | $this.attr('src', src);
704 | } else if ( this.complete || this.readyState === 4 ) {
705 | handleObj.handler.apply(this, arguments);
706 | } else {
707 | bindToLoad(this, handleObj.handler);
708 | }
709 | }
710 | },
711 |
712 | teardown: function (namespaces) {
713 | $(this).unbind('.imageready');
714 | }
715 | };
716 |
717 | function bindToLoad(element, callback) {
718 | var $this = $(element);
719 |
720 | $this.bind('load.imageready', function () {
721 | callback.apply(element, arguments);
722 | $this.unbind('load.imageready');
723 | });
724 | }
725 |
726 | }(jQuery));
727 |
728 | /*
729 |
730 | Holder - 1.3 - client side image placeholders
731 | (c) 2012 Ivan Malopinsky / http://imsky.co
732 |
733 | Provided under the Apache 2.0 License: http://www.apache.org/licenses/LICENSE-2.0
734 | Commercial use requires attribution.
735 |
736 | */
737 |
738 | var Holder = Holder || {};
739 | (function (app, win) {
740 |
741 | var preempted = false,
742 | fallback = false,
743 | canvas = document.createElement('canvas');
744 |
745 | //http://javascript.nwbox.com/ContentLoaded by Diego Perini with modifications
746 | 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)}};
747 |
748 | //https://gist.github.com/991057 by Jed Schmidt with modifications
749 | function selector(a){
750 | a=a.match(/^(\W)?(.*)/);var b=document["getElement"+(a[1]?a[1]=="#"?"ById":"sByClassName":"sByTagName")](a[2]);
751 | var ret=[]; b!=null&&(b.length?ret=b:b.length==0?ret=b:ret=[b]); return ret;
752 | }
753 |
754 | //shallow object property extend
755 | 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}
756 |
757 | function draw(ctx, dimensions, template) {
758 | var dimension_arr = [dimensions.height, dimensions.width].sort();
759 | var maxFactor = Math.round(dimension_arr[1] / 16),
760 | minFactor = Math.round(dimension_arr[0] / 16);
761 | var text_height = Math.max(template.size, maxFactor);
762 | canvas.width = dimensions.width;
763 | canvas.height = dimensions.height;
764 | ctx.textAlign = "center";
765 | ctx.textBaseline = "middle";
766 | ctx.fillStyle = template.background;
767 | ctx.fillRect(0, 0, dimensions.width, dimensions.height);
768 | ctx.fillStyle = template.foreground;
769 | ctx.font = "bold " + text_height + "px sans-serif";
770 | var text = template.text ? template.text : (dimensions.width + "x" + dimensions.height);
771 | if (Math.round(ctx.measureText(text).width) / dimensions.width > 1) {
772 | text_height = Math.max(minFactor, template.size);
773 | }
774 | ctx.font = "bold " + text_height + "px sans-serif";
775 | ctx.fillText(text, (dimensions.width / 2), (dimensions.height / 2), dimensions.width);
776 | return canvas.toDataURL("image/png");
777 | }
778 |
779 | if (!canvas.getContext) {
780 | fallback = true;
781 | } else {
782 | if (canvas.toDataURL("image/png").indexOf("data:image/png") < 0) {
783 | //Android doesn't support data URI
784 | fallback = true;
785 | } else {
786 | var ctx = canvas.getContext("2d");
787 | }
788 | }
789 |
790 | var settings = {
791 | domain: "holder.js",
792 | images: "img",
793 | themes: {
794 | "gray": {
795 | background: "#eee",
796 | foreground: "#aaa",
797 | size: 12
798 | },
799 | "social": {
800 | background: "#3a5a97",
801 | foreground: "#fff",
802 | size: 12
803 | },
804 | "industrial": {
805 | background: "#434A52",
806 | foreground: "#C2F200",
807 | size: 12
808 | }
809 | }
810 | };
811 |
812 |
813 |
814 | app.flags = {
815 | dimensions: {
816 | regex: /([0-9]+)x([0-9]+)/,
817 | output: function(val){
818 | var exec = this.regex.exec(val);
819 | return {
820 | width: +exec[1],
821 | height: +exec[2]
822 | }
823 | }
824 | },
825 | colors: {
826 | regex: /#([0-9a-f]{3,})\:#([0-9a-f]{3,})/i,
827 | output: function(val){
828 | var exec = this.regex.exec(val);
829 | return {
830 | size: settings.themes.gray.size,
831 | foreground: "#" + exec[2],
832 | background: "#" + exec[1]
833 | }
834 | }
835 | },
836 | text: {
837 | regex: /text\:(.*)/,
838 | output: function(val){
839 | return this.regex.exec(val)[1];
840 | }
841 | }
842 | }
843 |
844 | for(var flag in app.flags){
845 | app.flags[flag].match = function (val){
846 | return val.match(this.regex)
847 | }
848 | }
849 |
850 | app.add_theme = function (name, theme) {
851 | name != null && theme != null && (settings.themes[name] = theme);
852 | return app;
853 | };
854 |
855 | app.add_image = function (src, el) {
856 | var node = selector(el);
857 | if (node.length) {
858 | for (var i = 0, l = node.length; i < l; i++) {
859 | var img = document.createElement("img")
860 | img.setAttribute("data-src", src);
861 | node[i].appendChild(img);
862 | }
863 | }
864 | return app;
865 | };
866 |
867 | app.run = function (o) {
868 | var options = extend(settings, o),
869 | images = selector(options.images),
870 | preempted = true;
871 |
872 | for (var l = images.length, i = 0; i < l; i++) {
873 | var theme = settings.themes.gray;
874 | var src = images[i].getAttribute("data-src") || images[i].getAttribute("src");
875 | if (src && !! ~src.indexOf(options.domain)) {
876 | var render = false,
877 | dimensions = null,
878 | text = null;
879 | var flags = src.substr(src.indexOf(options.domain) + options.domain.length + 1).split("/");
880 | for (sl = flags.length, j = 0; j < sl; j++) {
881 | if (app.flags.dimensions.match(flags[j])) {
882 | render = true;
883 | dimensions = app.flags.dimensions.output(flags[j]);
884 | } else if (app.flags.colors.match(flags[j])) {
885 | theme = app.flags.colors.output(flags[j]);
886 | } else if (options.themes[flags[j]]) {
887 | //If a theme is specified, it will override custom colors
888 | theme = options.themes[flags[j]];
889 | } else if (app.flags.text.match(flags[j])) {
890 | text = app.flags.text.output(flags[j]);
891 | }
892 | }
893 | if (render) {
894 | images[i].setAttribute("data-src", src);
895 | var dimensions_caption = dimensions.width + "x" + dimensions.height;
896 | images[i].setAttribute("alt", text ? text : theme.text ? theme.text + " [" + dimensions_caption + "]" : dimensions_caption);
897 |
898 | // Fallback
899 | // images[i].style.width = dimensions.width + "px";
900 | // images[i].style.height = dimensions.height + "px";
901 | images[i].style.backgroundColor = theme.background;
902 |
903 | var theme = (text ? extend(theme, {
904 | text: text
905 | }) : theme);
906 |
907 | if (!fallback) {
908 | images[i].setAttribute("src", draw(ctx, dimensions, theme));
909 | }
910 | }
911 | }
912 | }
913 | return app;
914 | };
915 | contentLoaded(win, function () {
916 | preempted || app.run()
917 | })
918 |
919 | })(Holder, window);
920 |
--------------------------------------------------------------------------------