spree_showcase 0.5.0 → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. data/.gitignore +11 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +9 -0
  4. data/Gemfile.lock +179 -0
  5. data/LICENSE +26 -0
  6. data/README.md +33 -0
  7. data/Rakefile +29 -0
  8. data/Versionfile +11 -0
  9. data/app/assets/images/store/bg_control_nav.png +0 -0
  10. data/app/assets/images/store/bg_direction_nav.png +0 -0
  11. data/app/assets/javascripts/admin/spree_showcase.js +1 -0
  12. data/app/assets/javascripts/store/spree_showcase.js +3 -0
  13. data/app/assets/stylesheets/admin/spree_showcase.css +3 -0
  14. data/app/assets/stylesheets/store/spree_showcase.css +4 -0
  15. data/app/controllers/spree/admin/showcase_settings_controller.rb +22 -0
  16. data/app/controllers/spree/admin/slides_controller.rb +25 -0
  17. data/app/models/spree/slide.rb +10 -0
  18. data/app/overrides/add_showcase_to_admin_configuration_menu.rb +9 -0
  19. data/app/overrides/add_showcase_to_admin_configurations_side_menu.rb +7 -0
  20. data/app/overrides/add_showcase_to_home_layout.rb +8 -0
  21. data/app/overrides/insert_slider_into_spree_application.rb +10 -0
  22. data/app/views/spree/admin/shared/_showcase_settings.html.erb +4 -0
  23. data/app/views/spree/admin/shared/_showcase_submenu.html.erb +6 -0
  24. data/app/views/spree/admin/showcase_settings/edit.html.erb +19 -0
  25. data/app/views/spree/admin/showcase_settings/show.html.erb +16 -0
  26. data/app/views/spree/admin/slides/_form.html.erb +28 -0
  27. data/app/views/spree/admin/slides/edit.html.erb +10 -0
  28. data/app/views/spree/admin/slides/index.html.erb +34 -0
  29. data/app/views/spree/admin/slides/new.html.erb +9 -0
  30. data/app/views/spree/admin/slides/show.html.erb +41 -0
  31. data/app/views/spree/slides/_content_insert.html.erb +5 -0
  32. data/app/views/spree/slides/_showcase.html.erb +28 -0
  33. data/config/locales/en.yml +5 -0
  34. data/config/routes.rb +14 -0
  35. data/db/migrate/20120506161852_create_slides.rb +17 -0
  36. data/db/migrate/20120507074922_add_position_to_slide.rb +9 -0
  37. data/lib/generators/spree_showcase/install/assets/javascripts/store/jquery.flexslider.js +563 -0
  38. data/lib/generators/spree_showcase/install/assets/javascripts/store/showcase.js +32 -0
  39. data/lib/generators/spree_showcase/install/assets/partials/_showcase.html.erb +28 -0
  40. data/lib/generators/spree_showcase/install/assets/stylesheets/store/flexslider.css +64 -0
  41. data/lib/generators/spree_showcase/install/assets/stylesheets/store/showcase.css.scss +26 -0
  42. data/lib/generators/spree_showcase/install/install_generator.rb +65 -0
  43. data/lib/spree/showcase_configuration.rb +8 -0
  44. data/lib/spree_showcase.rb +3 -0
  45. data/lib/spree_showcase/engine.rb +30 -0
  46. data/script/rails +7 -0
  47. data/spec/spec_helper.rb +43 -0
  48. data/spree_showcase-0.5.0.gem +0 -0
  49. data/spree_showcase-0.5.1.gem +0 -0
  50. data/spree_showcase.gemspec +26 -0
  51. metadata +118 -4
@@ -0,0 +1,19 @@
1
+ <%= render :partial => 'spree/admin/shared/configuration_menu' %>
2
+ <%= render :partial=>'spree/admin/shared/showcase_submenu'%>
3
+ <h1><%= t(:edit_showcase_settings) %></h1>
4
+
5
+ <%= form_tag admin_showcase_settings_path, :method => :put do %>
6
+ <fieldset id="preferences" data-hook>
7
+ <% @preferences.each do |key|
8
+ type = SpreeShowcase::Config.preference_type(key) %>
9
+ <%= label_tag(key, t(key) + ': ') + tag(:br) if type != :boolean %>
10
+ <%= preference_field_tag(key, SpreeShowcase::Config[key], :type => type) %>
11
+ <%= label_tag(key, t(key)) + tag(:br) if type == :boolean %>
12
+ <% end %>
13
+ </fieldset>
14
+ <p class="form-buttons" data-hook="buttons">
15
+ <%= button t(:update) %>
16
+ <%= t(:or) %> <%= link_to t(:cancel), admin_showcase_settings_url %>
17
+ </p>
18
+ <% end %>
19
+ <%= render :partial =>"spree/admin/shared/showcase_settings" %>
@@ -0,0 +1,16 @@
1
+ <%= render :partial => 'spree/admin/shared/configuration_menu' %>
2
+ <%= render :partial=>'spree/admin/shared/showcase_submenu'%>
3
+ <h1><%= t(:showcase_settings) %></h1>
4
+
5
+ <table data-hook="preferences">
6
+ <% @preferences.each do |key| %>
7
+ <tr>
8
+ <th scope="row"><%= t(key) %>:</th>
9
+ <td><%= SpreeShowcase::Config[key] %></td>
10
+ </tr>
11
+ <% end %>
12
+ </table>
13
+
14
+ <p><%= link_to_with_icon 'edit', t(:edit), edit_admin_showcase_settings_path, :id => 'admin_showcase_settings_link' %></p>
15
+
16
+ <%= render :partial =>"spree/admin/shared/showcase_settings" %>
@@ -0,0 +1,28 @@
1
+ <%= f.field_container :name do %>
2
+ <%= f.label :name, t(:name) %><br />
3
+ <%= f.text_field :name %>
4
+ <% end %>
5
+ <%= f.field_container :body do %>
6
+ <%= f.label :body, t(:body) %><br />
7
+ <%= f.text_area :body, {:cols => 60, :rows => 4, :class => 'fullwidth', :id=>:page_body} %>
8
+ <% end %>
9
+
10
+ <%= f.field_container :target_url do %>
11
+ <%= f.label :target_url, t(:target_url) %><br />
12
+ <%= f.text_field :target_url %>
13
+ <% end %>
14
+
15
+ <%= f.field_container :image do %>
16
+ <%= f.label :image, t(:image) %><br />
17
+ <%= f.file_field :image %>
18
+ <% end %>
19
+
20
+ <%= f.field_container :thumbnail_message do %>
21
+ <%= f.label "Thumb Message" %>
22
+ <%= f.text_field :thumbnail_message %>
23
+ <% end %>
24
+ <%= f.field_container :published do %>
25
+ <%= f.label :is_published, t(:published) %><br />
26
+ <%= f.check_box :published %>
27
+ <% end %>
28
+
@@ -0,0 +1,10 @@
1
+ <%= render :partial => 'spree/admin/shared/configuration_menu' %>
2
+ <%= render :partial=>'spree/admin/shared/showcase_submenu'%>
3
+ <h1>Editing Slide</h1>
4
+
5
+ <%= render 'spree/shared/error_messages', :target => @slide %>
6
+
7
+ <%= form_for [:admin, @slide], :html => { :multipart => true } do |f| %>
8
+ <%= render :partial => 'form', :locals => { :f => f } %>
9
+ <%= render :partial => 'spree/admin/shared/edit_resource_links' %>
10
+ <% end %>
@@ -0,0 +1,34 @@
1
+ <%= render :partial => 'spree/admin/shared/configuration_menu' %>
2
+ <%= render :partial=>'spree/admin/shared/showcase_submenu'%>
3
+ <div class="toolbar" data-hook="toolbar">
4
+ <ul class="actions">
5
+ <li>
6
+ <p><%= button_link_to 'New Slide', new_object_url, :icon => 'add', :id => 'admin_new_slide_link' %></p>
7
+ </li>
8
+ </ul>
9
+ <br class="clear" />
10
+ </div>
11
+
12
+ <h1>Showcase </h1>
13
+
14
+ <table class="index sortable" id="listing_slides" data-hook data-sortable-link="<%= update_positions_admin_slides_url %>">
15
+ <thead>
16
+ <tr data-hook="admin_slides_index_headers">
17
+ <th>Name</th>
18
+ <th data-hook="admin_slides_index_header_actions"></th>
19
+ </tr>
20
+ </thead>
21
+ <tbody>
22
+ <% @slides.each do |slide|%>
23
+ <tr id="<%= spree_dom_id slide %>" data-hook="admin_slides_index_rows">
24
+ <td width="350px" ><span class="handle" style="margin-right:5px"> </span> <%=link_to slide.name, object_url(slide) %></td>
25
+ <td data-hook="admin_slides_index_row_actions">
26
+ <%= link_to_edit slide, :class => 'edit' %> &nbsp;
27
+ <%= link_to_delete slide %>
28
+ </td>
29
+ </tr>
30
+ <% end %>
31
+ </tbody>
32
+ </table>
33
+
34
+ <p>Showcase is done by Damon Aw - @daemonsy</p>
@@ -0,0 +1,9 @@
1
+ <%= render :partial => 'spree/admin/shared/configuration_menu' %>
2
+ <%= render :partial=>'spree/admin/shared/showcase_submenu'%>
3
+ <h1>New Showcase Slide</h1>
4
+ <%= render 'spree/shared/error_messages', :target => @slide %>
5
+
6
+ <%= form_for [:admin, @slide] , :html => { :multipart => true } do |f| %>
7
+ <%= render :partial => 'form', :locals => { :f => f } %>
8
+ <p class="form-buttons" data-hook="buttons"><%= button t(:create) %></p>
9
+ <% end %>
@@ -0,0 +1,41 @@
1
+ <%= render :partial => 'spree/admin/shared/configuration_menu' %>
2
+ <%= render :partial=>'spree/admin/shared/showcase_submenu'%>
3
+ <h1><%= t(:slide) %></h1>
4
+
5
+ <table>
6
+ <tr data-hook="name">
7
+ <th><%= t(:name) %></th>
8
+ <td>
9
+ <%= @slide.name %>
10
+ </td>
11
+ </tr>
12
+ <tr data-hook="body">
13
+ <th><%= t(:body) %></th>
14
+ <td>
15
+ <%= @slide.body %>
16
+ </td>
17
+ </tr>
18
+ <tr data-hook="link_url">
19
+ <th><%= t(:target_url) %></th>
20
+ <td>
21
+ <%= @slide.target_url %>
22
+ </td>
23
+ </tr>
24
+ <tr data-hook="published">
25
+ <th><%= t(:published) %></th>
26
+ <td>
27
+ <%= @slide.published %>
28
+ </td>
29
+ </tr>
30
+ <tr data-hook="image_file_name">
31
+ <th><%= t(:image_file_name) %></th>
32
+ <td>
33
+ <%= @slide.image_file_name %>
34
+ </td>
35
+ </tr>
36
+ </table>
37
+
38
+ <p>
39
+ <%= link_to_edit @slide, :class => 'edit_slide' %> <%= t(:or) %>
40
+ <%= link_to t(:back), collection_url %>
41
+ </p>
@@ -0,0 +1,5 @@
1
+ <% if SpreeShowcase::Config.enabled %>
2
+ <% content_for :spree_showcase do %>
3
+ <%= render :partial => 'spree/slides/showcase' %>
4
+ <% end %>
5
+ <% end %>
@@ -0,0 +1,28 @@
1
+ <div class="flex-container">
2
+ <div class="row">
3
+ <div class="flexslider alpha omega sixteen columns">
4
+ <ul class="slides">
5
+ <% Spree::Slide.published.no_slides(SpreeShowcase::Config.number_of_slides_to_show).each do |slide| %>
6
+ <li>
7
+ <%= link_to(slide.target_url.present? ? slide.target_url : "#") do %>
8
+ <%= slide.image.present? ? image_tag(slide.image) : image_tag("http://www.placehold.it/#{SpreeShowcase::Config.preferences[:showcase_style].match(/\d{2,}x\d{2,}/)}&text=Spree%20Showcase%20by%20@daemonsy") %>
9
+ <% end %>
10
+ </li>
11
+ <% end %>
12
+ </ul>
13
+ </div>
14
+ </div>
15
+ <div class="row">
16
+ <div class="sixteen columns alpha omega">
17
+ <ul class="custom-controls">
18
+ <% Spree::Slide.published.no_slides(SpreeShowcase::Config.number_of_slides_to_show).each do |slide| %>
19
+ <li>
20
+ <%= link_to "#" do %>
21
+ <%=slide.image.present? ? image_tag(slide.image.url(:thumb),:class=>"alpha four columns") : image_tag("http://www.placehold.it/#{SpreeShowcase::Config.preferences[:thumbnail_style].match(/\d{2,}x\d{2,}/)}",:class=>"alpha four columns") %>
22
+ <% end %>
23
+ </li>
24
+ <% end %>
25
+ </ul>
26
+ </div>
27
+ </div>
28
+ </div>
@@ -0,0 +1,5 @@
1
+ # Sample localization file for English. Add more files in this directory for other locales.
2
+ # See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
3
+
4
+ en:
5
+ hello: "Hello world"
@@ -0,0 +1,14 @@
1
+ Spree::Core::Engine.routes.draw do
2
+ # Add your extension routes here
3
+ namespace :admin do
4
+ resources :slides do
5
+ collection do
6
+ post :update_positions
7
+ end
8
+ end
9
+ end
10
+ namespace :admin do
11
+ resource :showcase_settings
12
+ end
13
+ end
14
+
@@ -0,0 +1,17 @@
1
+ class CreateSlides < ActiveRecord::Migration
2
+ def change
3
+ create_table :spree_slides do |t|
4
+ t.string :name
5
+ t.text :body
6
+ t.string :thumbnail_message
7
+ t.string :target_url
8
+ t.boolean :published
9
+ t.string :image_file_name
10
+ t.string :image_content_type
11
+ t.integer :image_file_size
12
+ t.datetime :image_updated_at
13
+
14
+ t.timestamps
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,9 @@
1
+ class AddPositionToSlide < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :spree_slides, :position, :integer
4
+ end
5
+
6
+ def self.down
7
+ remove_column :spree_slides, :position
8
+ end
9
+ end
@@ -0,0 +1,563 @@
1
+ /*
2
+ * jQuery FlexSlider v1.8
3
+ * http://www.woothemes.com/flexslider/
4
+ *
5
+ * Copyright 2012 WooThemes
6
+ * Free to use under the MIT license.
7
+ * http://www.opensource.org/licenses/mit-license.php
8
+ *
9
+ * Contributing Author: Tyler Smith
10
+ */
11
+
12
+ ;(function ($) {
13
+
14
+ //FlexSlider: Object Instance
15
+ $.flexslider = function(el, options) {
16
+ var slider = $(el);
17
+
18
+ // slider DOM reference for use outside of the plugin
19
+ $.data(el, "flexslider", slider);
20
+
21
+ slider.init = function() {
22
+ slider.vars = $.extend({}, $.flexslider.defaults, options);
23
+ $.data(el, 'flexsliderInit', true);
24
+ slider.container = $('.slides', slider).first();
25
+ slider.slides = $('.slides:first > li', slider);
26
+ slider.count = slider.slides.length;
27
+ slider.animating = false;
28
+ slider.currentSlide = slider.vars.slideToStart;
29
+ slider.animatingTo = slider.currentSlide;
30
+ slider.atEnd = (slider.currentSlide == 0) ? true : false;
31
+ slider.eventType = ('ontouchstart' in document.documentElement) ? 'touchstart' : 'click';
32
+ slider.cloneCount = 0;
33
+ slider.cloneOffset = 0;
34
+ slider.manualPause = false;
35
+ slider.vertical = (slider.vars.slideDirection == "vertical");
36
+ slider.prop = (slider.vertical) ? "top" : "marginLeft";
37
+ slider.args = {};
38
+
39
+ //Test for webbkit CSS3 Animations
40
+ slider.transitions = "webkitTransition" in document.body.style;
41
+ if (slider.transitions) slider.prop = "-webkit-transform";
42
+
43
+ //Test for controlsContainer
44
+ if (slider.vars.controlsContainer != "") {
45
+ slider.controlsContainer = $(slider.vars.controlsContainer).eq($('.slides').index(slider.container));
46
+ slider.containerExists = slider.controlsContainer.length > 0;
47
+ }
48
+ //Test for manualControls
49
+ if (slider.vars.manualControls != "") {
50
+ slider.manualControls = $(slider.vars.manualControls, ((slider.containerExists) ? slider.controlsContainer : slider));
51
+ slider.manualExists = slider.manualControls.length > 0;
52
+ }
53
+
54
+ ///////////////////////////////////////////////////////////////////
55
+ // FlexSlider: Randomize Slides
56
+ if (slider.vars.randomize) {
57
+ slider.slides.sort(function() { return (Math.round(Math.random())-0.5); });
58
+ slider.container.empty().append(slider.slides);
59
+ }
60
+ ///////////////////////////////////////////////////////////////////
61
+
62
+ ///////////////////////////////////////////////////////////////////
63
+ // FlexSlider: Slider Animation Initialize
64
+ if (slider.vars.animation.toLowerCase() == "slide") {
65
+ if (slider.transitions) {
66
+ slider.setTransition(0);
67
+ }
68
+ slider.css({"overflow": "hidden"});
69
+ if (slider.vars.animationLoop) {
70
+ slider.cloneCount = 2;
71
+ slider.cloneOffset = 1;
72
+ slider.container.append(slider.slides.filter(':first').clone().addClass('clone')).prepend(slider.slides.filter(':last').clone().addClass('clone'));
73
+ }
74
+ //create newSlides to capture possible clones
75
+ slider.newSlides = $('.slides:first > li', slider);
76
+ var sliderOffset = (-1 * (slider.currentSlide + slider.cloneOffset));
77
+ if (slider.vertical) {
78
+ slider.newSlides.css({"display": "block", "width": "100%", "float": "left"});
79
+ slider.container.height((slider.count + slider.cloneCount) * 200 + "%").css("position", "absolute").width("100%");
80
+ //Timeout function to give browser enough time to get proper height initially
81
+ setTimeout(function() {
82
+ slider.css({"position": "relative"}).height(slider.slides.filter(':first').height());
83
+ slider.args[slider.prop] = (slider.transitions) ? "translate3d(0," + sliderOffset * slider.height() + "px,0)" : sliderOffset * slider.height() + "px";
84
+ slider.container.css(slider.args);
85
+ }, 100);
86
+
87
+ } else {
88
+ slider.args[slider.prop] = (slider.transitions) ? "translate3d(" + sliderOffset * slider.width() + "px,0,0)" : sliderOffset * slider.width() + "px";
89
+ slider.container.width((slider.count + slider.cloneCount) * 200 + "%").css(slider.args);
90
+ //Timeout function to give browser enough time to get proper width initially
91
+ setTimeout(function() {
92
+ slider.newSlides.width(slider.width()).css({"float": "left", "display": "block"});
93
+ }, 100);
94
+ }
95
+
96
+ } else { //Default to fade
97
+ //Not supporting fade CSS3 transitions right now
98
+ slider.transitions = false;
99
+ slider.slides.css({"width": "100%", "float": "left", "marginRight": "-100%"}).eq(slider.currentSlide).fadeIn(slider.vars.animationDuration);
100
+ }
101
+ ///////////////////////////////////////////////////////////////////
102
+
103
+ ///////////////////////////////////////////////////////////////////
104
+ // FlexSlider: Control Nav
105
+ if (slider.vars.controlNav) {
106
+ if (slider.manualExists) {
107
+ slider.controlNav = slider.manualControls;
108
+ } else {
109
+ var controlNavScaffold = $('<ol class="flex-control-nav"></ol>');
110
+ var j = 1;
111
+ for (var i = 0; i < slider.count; i++) {
112
+ controlNavScaffold.append('<li><a>' + j + '</a></li>');
113
+ j++;
114
+ }
115
+
116
+ if (slider.containerExists) {
117
+ $(slider.controlsContainer).append(controlNavScaffold);
118
+ slider.controlNav = $('.flex-control-nav li a', slider.controlsContainer);
119
+ } else {
120
+ slider.append(controlNavScaffold);
121
+ slider.controlNav = $('.flex-control-nav li a', slider);
122
+ }
123
+ }
124
+
125
+ slider.controlNav.eq(slider.currentSlide).addClass('active');
126
+
127
+ slider.controlNav.bind(slider.eventType, function(event) {
128
+ event.preventDefault();
129
+ if (!$(this).hasClass('active')) {
130
+ (slider.controlNav.index($(this)) > slider.currentSlide) ? slider.direction = "next" : slider.direction = "prev";
131
+ slider.flexAnimate(slider.controlNav.index($(this)), slider.vars.pauseOnAction);
132
+ }
133
+ });
134
+ }
135
+ ///////////////////////////////////////////////////////////////////
136
+
137
+ //////////////////////////////////////////////////////////////////
138
+ //FlexSlider: Direction Nav
139
+ if (slider.vars.directionNav) {
140
+ var directionNavScaffold = $('<ul class="flex-direction-nav"><li><a class="prev" href="#">' + slider.vars.prevText + '</a></li><li><a class="next" href="#">' + slider.vars.nextText + '</a></li></ul>');
141
+
142
+ if (slider.containerExists) {
143
+ $(slider.controlsContainer).append(directionNavScaffold);
144
+ slider.directionNav = $('.flex-direction-nav li a', slider.controlsContainer);
145
+ } else {
146
+ slider.append(directionNavScaffold);
147
+ slider.directionNav = $('.flex-direction-nav li a', slider);
148
+ }
149
+
150
+ //Set initial disable styles if necessary
151
+ if (!slider.vars.animationLoop) {
152
+ if (slider.currentSlide == 0) {
153
+ slider.directionNav.filter('.prev').addClass('disabled');
154
+ } else if (slider.currentSlide == slider.count - 1) {
155
+ slider.directionNav.filter('.next').addClass('disabled');
156
+ }
157
+ }
158
+
159
+ slider.directionNav.bind(slider.eventType, function(event) {
160
+ event.preventDefault();
161
+ var target = ($(this).hasClass('next')) ? slider.getTarget('next') : slider.getTarget('prev');
162
+
163
+ if (slider.canAdvance(target)) {
164
+ slider.flexAnimate(target, slider.vars.pauseOnAction);
165
+ }
166
+ });
167
+ }
168
+ //////////////////////////////////////////////////////////////////
169
+
170
+ //////////////////////////////////////////////////////////////////
171
+ //FlexSlider: Keyboard Nav
172
+ if (slider.vars.keyboardNav && $('ul.slides').length == 1) {
173
+ function keyboardMove(event) {
174
+ if (slider.animating) {
175
+ return;
176
+ } else if (event.keyCode != 39 && event.keyCode != 37){
177
+ return;
178
+ } else {
179
+ if (event.keyCode == 39) {
180
+ var target = slider.getTarget('next');
181
+ } else if (event.keyCode == 37){
182
+ var target = slider.getTarget('prev');
183
+ }
184
+
185
+ if (slider.canAdvance(target)) {
186
+ slider.flexAnimate(target, slider.vars.pauseOnAction);
187
+ }
188
+ }
189
+ }
190
+ $(document).bind('keyup', keyboardMove);
191
+ }
192
+ //////////////////////////////////////////////////////////////////
193
+
194
+ ///////////////////////////////////////////////////////////////////
195
+ // FlexSlider: Mousewheel interaction
196
+ if (slider.vars.mousewheel) {
197
+ slider.mousewheelEvent = (/Firefox/i.test(navigator.userAgent)) ? "DOMMouseScroll" : "mousewheel";
198
+ slider.bind(slider.mousewheelEvent, function(e) {
199
+ e.preventDefault();
200
+ e = e ? e : window.event;
201
+ var wheelData = e.detail ? e.detail * -1 : e.originalEvent.wheelDelta / 40,
202
+ target = (wheelData < 0) ? slider.getTarget('next') : slider.getTarget('prev');
203
+
204
+ if (slider.canAdvance(target)) {
205
+ slider.flexAnimate(target, slider.vars.pauseOnAction);
206
+ }
207
+ });
208
+ }
209
+ ///////////////////////////////////////////////////////////////////
210
+
211
+ //////////////////////////////////////////////////////////////////
212
+ //FlexSlider: Slideshow Setup
213
+ if (slider.vars.slideshow) {
214
+ //pauseOnHover
215
+ if (slider.vars.pauseOnHover && slider.vars.slideshow) {
216
+ slider.hover(function() {
217
+ slider.pause();
218
+ }, function() {
219
+ if (!slider.manualPause) {
220
+ slider.resume();
221
+ }
222
+ });
223
+ }
224
+
225
+ //Initialize animation
226
+ slider.animatedSlides = setInterval(slider.animateSlides, slider.vars.slideshowSpeed);
227
+ }
228
+ //////////////////////////////////////////////////////////////////
229
+
230
+ //////////////////////////////////////////////////////////////////
231
+ //FlexSlider: Pause/Play
232
+ if (slider.vars.pausePlay) {
233
+ var pausePlayScaffold = $('<div class="flex-pauseplay"><span></span></div>');
234
+
235
+ if (slider.containerExists) {
236
+ slider.controlsContainer.append(pausePlayScaffold);
237
+ slider.pausePlay = $('.flex-pauseplay span', slider.controlsContainer);
238
+ } else {
239
+ slider.append(pausePlayScaffold);
240
+ slider.pausePlay = $('.flex-pauseplay span', slider);
241
+ }
242
+
243
+ var pausePlayState = (slider.vars.slideshow) ? 'pause' : 'play';
244
+ slider.pausePlay.addClass(pausePlayState).text((pausePlayState == 'pause') ? slider.vars.pauseText : slider.vars.playText);
245
+
246
+ slider.pausePlay.bind(slider.eventType, function(event) {
247
+ event.preventDefault();
248
+ if ($(this).hasClass('pause')) {
249
+ slider.pause();
250
+ slider.manualPause = true;
251
+ } else {
252
+ slider.resume();
253
+ slider.manualPause = false;
254
+ }
255
+ });
256
+ }
257
+ //////////////////////////////////////////////////////////////////
258
+
259
+ //////////////////////////////////////////////////////////////////
260
+ //FlexSlider:Touch Swip Gestures
261
+ //Some brilliant concepts adapted from the following sources
262
+ //Source: TouchSwipe - http://www.netcu.de/jquery-touchwipe-iphone-ipad-library
263
+ //Source: SwipeJS - http://swipejs.com
264
+ if ('ontouchstart' in document.documentElement) {
265
+ //For brevity, variables are named for x-axis scrolling
266
+ //The variables are then swapped if vertical sliding is applied
267
+ //This reduces redundant code...I think :)
268
+ //If debugging, recognize variables are named for horizontal scrolling
269
+ var startX,
270
+ startY,
271
+ offset,
272
+ cwidth,
273
+ dx,
274
+ startT,
275
+ scrolling = false;
276
+
277
+ slider.each(function() {
278
+ if ('ontouchstart' in document.documentElement) {
279
+ this.addEventListener('touchstart', onTouchStart, false);
280
+ }
281
+ });
282
+
283
+ function onTouchStart(e) {
284
+ if (slider.animating) {
285
+ e.preventDefault();
286
+ } else if (e.touches.length == 1) {
287
+ slider.pause();
288
+ cwidth = (slider.vertical) ? slider.height() : slider.width();
289
+ startT = Number(new Date());
290
+ offset = (slider.vertical) ? (slider.currentSlide + slider.cloneOffset) * slider.height() : (slider.currentSlide + slider.cloneOffset) * slider.width();
291
+ startX = (slider.vertical) ? e.touches[0].pageY : e.touches[0].pageX;
292
+ startY = (slider.vertical) ? e.touches[0].pageX : e.touches[0].pageY;
293
+ slider.setTransition(0);
294
+
295
+ this.addEventListener('touchmove', onTouchMove, false);
296
+ this.addEventListener('touchend', onTouchEnd, false);
297
+ }
298
+ }
299
+
300
+ function onTouchMove(e) {
301
+ dx = (slider.vertical) ? startX - e.touches[0].pageY : startX - e.touches[0].pageX;
302
+ scrolling = (slider.vertical) ? (Math.abs(dx) < Math.abs(e.touches[0].pageX - startY)) : (Math.abs(dx) < Math.abs(e.touches[0].pageY - startY));
303
+
304
+ if (!scrolling) {
305
+ e.preventDefault();
306
+ if (slider.vars.animation == "slide" && slider.transitions) {
307
+ if (!slider.vars.animationLoop) {
308
+ dx = dx/((slider.currentSlide == 0 && dx < 0 || slider.currentSlide == slider.count - 1 && dx > 0) ? (Math.abs(dx)/cwidth+2) : 1);
309
+ }
310
+ slider.args[slider.prop] = (slider.vertical) ? "translate3d(0," + (-offset - dx) + "px,0)": "translate3d(" + (-offset - dx) + "px,0,0)";
311
+ slider.container.css(slider.args);
312
+ }
313
+ }
314
+ }
315
+
316
+ function onTouchEnd(e) {
317
+ slider.animating = false;
318
+ if (slider.animatingTo == slider.currentSlide && !scrolling && !(dx == null)) {
319
+ var target = (dx > 0) ? slider.getTarget('next') : slider.getTarget('prev');
320
+ if (slider.canAdvance(target) && Number(new Date()) - startT < 550 && Math.abs(dx) > 20 || Math.abs(dx) > cwidth/2) {
321
+ slider.flexAnimate(target, slider.vars.pauseOnAction);
322
+ } else {
323
+ slider.flexAnimate(slider.currentSlide, slider.vars.pauseOnAction);
324
+ }
325
+ }
326
+
327
+ //Finish the touch by undoing the touch session
328
+ this.removeEventListener('touchmove', onTouchMove, false);
329
+ this.removeEventListener('touchend', onTouchEnd, false);
330
+ startX = null;
331
+ startY = null;
332
+ dx = null;
333
+ offset = null;
334
+ }
335
+ }
336
+ //////////////////////////////////////////////////////////////////
337
+
338
+ //////////////////////////////////////////////////////////////////
339
+ //FlexSlider: Resize Functions (If necessary)
340
+ if (slider.vars.animation.toLowerCase() == "slide") {
341
+ $(window).resize(function(){
342
+ if (!slider.animating && slider.is(":visible")) {
343
+ if (slider.vertical) {
344
+ slider.height(slider.slides.filter(':first').height());
345
+ slider.args[slider.prop] = (-1 * (slider.currentSlide + slider.cloneOffset))* slider.slides.filter(':first').height() + "px";
346
+ if (slider.transitions) {
347
+ slider.setTransition(0);
348
+ slider.args[slider.prop] = (slider.vertical) ? "translate3d(0," + slider.args[slider.prop] + ",0)" : "translate3d(" + slider.args[slider.prop] + ",0,0)";
349
+ }
350
+ slider.container.css(slider.args);
351
+ } else {
352
+ slider.newSlides.width(slider.width());
353
+ slider.args[slider.prop] = (-1 * (slider.currentSlide + slider.cloneOffset))* slider.width() + "px";
354
+ if (slider.transitions) {
355
+ slider.setTransition(0);
356
+ slider.args[slider.prop] = (slider.vertical) ? "translate3d(0," + slider.args[slider.prop] + ",0)" : "translate3d(" + slider.args[slider.prop] + ",0,0)";
357
+ }
358
+ slider.container.css(slider.args);
359
+ }
360
+ }
361
+ });
362
+ }
363
+ //////////////////////////////////////////////////////////////////
364
+
365
+ //FlexSlider: start() Callback
366
+ slider.vars.start(slider);
367
+ }
368
+
369
+ //FlexSlider: Animation Actions
370
+ slider.flexAnimate = function(target, pause) {
371
+ if (!slider.animating && slider.is(":visible")) {
372
+ //Animating flag
373
+ slider.animating = true;
374
+
375
+ //FlexSlider: before() animation Callback
376
+ slider.animatingTo = target;
377
+ slider.vars.before(slider);
378
+
379
+ //Optional paramter to pause slider when making an anmiation call
380
+ if (pause) {
381
+ slider.pause();
382
+ }
383
+
384
+ //Update controlNav
385
+ if (slider.vars.controlNav) {
386
+ slider.controlNav.removeClass('active').eq(target).addClass('active');
387
+ }
388
+
389
+ //Is the slider at either end
390
+ slider.atEnd = (target == 0 || target == slider.count - 1) ? true : false;
391
+ if (!slider.vars.animationLoop && slider.vars.directionNav) {
392
+ if (target == 0) {
393
+ slider.directionNav.removeClass('disabled').filter('.prev').addClass('disabled');
394
+ } else if (target == slider.count - 1) {
395
+ slider.directionNav.removeClass('disabled').filter('.next').addClass('disabled');
396
+ } else {
397
+ slider.directionNav.removeClass('disabled');
398
+ }
399
+ }
400
+
401
+ if (!slider.vars.animationLoop && target == slider.count - 1) {
402
+ slider.pause();
403
+ //FlexSlider: end() of cycle Callback
404
+ slider.vars.end(slider);
405
+ }
406
+
407
+ if (slider.vars.animation.toLowerCase() == "slide") {
408
+ var dimension = (slider.vertical) ? slider.slides.filter(':first').height() : slider.slides.filter(':first').width();
409
+
410
+ if (slider.currentSlide == 0 && target == slider.count - 1 && slider.vars.animationLoop && slider.direction != "next") {
411
+ slider.slideString = "0px";
412
+ } else if (slider.currentSlide == slider.count - 1 && target == 0 && slider.vars.animationLoop && slider.direction != "prev") {
413
+ slider.slideString = (-1 * (slider.count + 1)) * dimension + "px";
414
+ } else {
415
+ slider.slideString = (-1 * (target + slider.cloneOffset)) * dimension + "px";
416
+ }
417
+ slider.args[slider.prop] = slider.slideString;
418
+
419
+ if (slider.transitions) {
420
+ slider.setTransition(slider.vars.animationDuration);
421
+ slider.args[slider.prop] = (slider.vertical) ? "translate3d(0," + slider.slideString + ",0)" : "translate3d(" + slider.slideString + ",0,0)";
422
+ slider.container.css(slider.args).one("webkitTransitionEnd transitionend", function(){
423
+ slider.wrapup(dimension);
424
+ });
425
+ } else {
426
+ slider.container.animate(slider.args, slider.vars.animationDuration, function(){
427
+ slider.wrapup(dimension);
428
+ });
429
+ }
430
+ } else { //Default to Fade
431
+ slider.slides.eq(slider.currentSlide).fadeOut(slider.vars.animationDuration);
432
+ slider.slides.eq(target).fadeIn(slider.vars.animationDuration, function() {
433
+ slider.wrapup();
434
+ });
435
+ }
436
+ }
437
+ }
438
+
439
+ //FlexSlider: Function to minify redundant animation actions
440
+ slider.wrapup = function(dimension) {
441
+ if (slider.vars.animation == "slide") {
442
+ //Jump the slider if necessary
443
+ if (slider.currentSlide == 0 && slider.animatingTo == slider.count - 1 && slider.vars.animationLoop) {
444
+ slider.args[slider.prop] = (-1 * slider.count) * dimension + "px";
445
+ if (slider.transitions) {
446
+ slider.setTransition(0);
447
+ slider.args[slider.prop] = (slider.vertical) ? "translate3d(0," + slider.args[slider.prop] + ",0)" : "translate3d(" + slider.args[slider.prop] + ",0,0)";
448
+ }
449
+ slider.container.css(slider.args);
450
+ } else if (slider.currentSlide == slider.count - 1 && slider.animatingTo == 0 && slider.vars.animationLoop) {
451
+ slider.args[slider.prop] = -1 * dimension + "px";
452
+ if (slider.transitions) {
453
+ slider.setTransition(0);
454
+ slider.args[slider.prop] = (slider.vertical) ? "translate3d(0," + slider.args[slider.prop] + ",0)" : "translate3d(" + slider.args[slider.prop] + ",0,0)";
455
+ }
456
+ slider.container.css(slider.args);
457
+ }
458
+ }
459
+ slider.animating = false;
460
+ slider.currentSlide = slider.animatingTo;
461
+ //FlexSlider: after() animation Callback
462
+ slider.vars.after(slider);
463
+ }
464
+
465
+ //FlexSlider: Automatic Slideshow
466
+ slider.animateSlides = function() {
467
+ if (!slider.animating) {
468
+ slider.flexAnimate(slider.getTarget("next"));
469
+ }
470
+ }
471
+
472
+ //FlexSlider: Automatic Slideshow Pause
473
+ slider.pause = function() {
474
+ clearInterval(slider.animatedSlides);
475
+ if (slider.vars.pausePlay) {
476
+ slider.pausePlay.removeClass('pause').addClass('play').text(slider.vars.playText);
477
+ }
478
+ }
479
+
480
+ //FlexSlider: Automatic Slideshow Start/Resume
481
+ slider.resume = function() {
482
+ slider.animatedSlides = setInterval(slider.animateSlides, slider.vars.slideshowSpeed);
483
+ if (slider.vars.pausePlay) {
484
+ slider.pausePlay.removeClass('play').addClass('pause').text(slider.vars.pauseText);
485
+ }
486
+ }
487
+
488
+ //FlexSlider: Helper function for non-looping sliders
489
+ slider.canAdvance = function(target) {
490
+ if (!slider.vars.animationLoop && slider.atEnd) {
491
+ if (slider.currentSlide == 0 && target == slider.count - 1 && slider.direction != "next") {
492
+ return false;
493
+ } else if (slider.currentSlide == slider.count - 1 && target == 0 && slider.direction == "next") {
494
+ return false;
495
+ } else {
496
+ return true;
497
+ }
498
+ } else {
499
+ return true;
500
+ }
501
+ }
502
+
503
+ //FlexSlider: Helper function to determine animation target
504
+ slider.getTarget = function(dir) {
505
+ slider.direction = dir;
506
+ if (dir == "next") {
507
+ return (slider.currentSlide == slider.count - 1) ? 0 : slider.currentSlide + 1;
508
+ } else {
509
+ return (slider.currentSlide == 0) ? slider.count - 1 : slider.currentSlide - 1;
510
+ }
511
+ }
512
+
513
+ //FlexSlider: Helper function to set CSS3 transitions
514
+ slider.setTransition = function(dur) {
515
+ slider.container.css({'-webkit-transition-duration': (dur/1000) + "s"});
516
+ }
517
+
518
+ //FlexSlider: Initialize
519
+ slider.init();
520
+ }
521
+
522
+ //FlexSlider: Default Settings
523
+ $.flexslider.defaults = {
524
+ animation: "fade", //String: Select your animation type, "fade" or "slide"
525
+ slideDirection: "horizontal", //String: Select the sliding direction, "horizontal" or "vertical"
526
+ slideshow: true, //Boolean: Animate slider automatically
527
+ slideshowSpeed: 7000, //Integer: Set the speed of the slideshow cycling, in milliseconds
528
+ animationDuration: 600, //Integer: Set the speed of animations, in milliseconds
529
+ directionNav: true, //Boolean: Create navigation for previous/next navigation? (true/false)
530
+ controlNav: true, //Boolean: Create navigation for paging control of each clide? Note: Leave true for manualControls usage
531
+ keyboardNav: true, //Boolean: Allow slider navigating via keyboard left/right keys
532
+ mousewheel: false, //Boolean: Allow slider navigating via mousewheel
533
+ prevText: "Previous", //String: Set the text for the "previous" directionNav item
534
+ nextText: "Next", //String: Set the text for the "next" directionNav item
535
+ pausePlay: false, //Boolean: Create pause/play dynamic element
536
+ pauseText: 'Pause', //String: Set the text for the "pause" pausePlay item
537
+ playText: 'Play', //String: Set the text for the "play" pausePlay item
538
+ randomize: false, //Boolean: Randomize slide order
539
+ slideToStart: 0, //Integer: The slide that the slider should start on. Array notation (0 = first slide)
540
+ animationLoop: true, //Boolean: Should the animation loop? If false, directionNav will received "disable" classes at either end
541
+ pauseOnAction: true, //Boolean: Pause the slideshow when interacting with control elements, highly recommended.
542
+ pauseOnHover: false, //Boolean: Pause the slideshow when hovering over slider, then resume when no longer hovering
543
+ controlsContainer: "", //Selector: Declare which container the navigation elements should be appended too. Default container is the flexSlider element. Example use would be ".flexslider-container", "#container", etc. If the given element is not found, the default action will be taken.
544
+ manualControls: "", //Selector: Declare custom control navigation. Example would be ".flex-control-nav li" or "#tabs-nav li img", etc. The number of elements in your controlNav should match the number of slides/tabs.
545
+ start: function(){}, //Callback: function(slider) - Fires when the slider loads the first slide
546
+ before: function(){}, //Callback: function(slider) - Fires asynchronously with each slider animation
547
+ after: function(){}, //Callback: function(slider) - Fires after each slider animation completes
548
+ end: function(){} //Callback: function(slider) - Fires when the slider reaches the last slide (asynchronous)
549
+ }
550
+
551
+ //FlexSlider: Plugin Function
552
+ $.fn.flexslider = function(options) {
553
+ return this.each(function() {
554
+ if ($(this).find('.slides > li').length == 1) {
555
+ $(this).find('.slides > li').fadeIn(400);
556
+ }
557
+ else if ($(this).data('flexsliderInit') != true) {
558
+ new $.flexslider(this, options);
559
+ }
560
+ });
561
+ }
562
+
563
+ })(jQuery);