diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2b54990 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +\#* +*~ +.#* +.DS_Store +.idea +.project +tmp +nbproject +*.swp +spec/dummy diff --git a/.rspec b/.rspec new file mode 100644 index 0000000..53607ea --- /dev/null +++ b/.rspec @@ -0,0 +1 @@ +--colour diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..1122a8b --- /dev/null +++ b/Gemfile @@ -0,0 +1,9 @@ +source 'http://rubygems.org' + +if RUBY_VERSION < '1.9' + gem 'ruby-debug' +else + gem 'ruby-debug19' +end + +gemspec diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..b96241c --- /dev/null +++ b/LICENSE @@ -0,0 +1,26 @@ +Copyright (c) 2012 [name of plugin creator] +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name Spree nor the names of its contributors may be used to + endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..3b60870 --- /dev/null +++ b/README.md @@ -0,0 +1,21 @@ +SpreeProductZoom +================ + +Introduction goes here. + + +Example +======= + +Example goes here. + +Testing +------- + +Be sure to bundle your dependencies and then create a dummy test app for the specs to run against. + + $ bundle + $ bundle exec rake test_app + $ bundle exec rspec spec + +Copyright (c) 2012 [name of extension creator], released under the New BSD License diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..c8e808f --- /dev/null +++ b/Rakefile @@ -0,0 +1,29 @@ +require 'rake' +require 'rake/testtask' +require 'rake/packagetask' +require 'rubygems/package_task' +require 'rspec/core/rake_task' +require 'spree/core/testing_support/common_rake' + +RSpec::Core::RakeTask.new + +task :default => [:spec] + +spec = eval(File.read('spree_product_zoom.gemspec')) + +Gem::PackageTask.new(spec) do |p| + p.gem_spec = spec +end + +desc 'Release to gemcutter' +task :release => :package do + require 'rake/gemcutter' + Rake::Gemcutter::Tasks.new(spec).define + Rake::Task['gem:push'].invoke +end + +desc 'Generates a dummy app for testing' +task :test_app do + ENV['LIB_NAME'] = 'spree_product_zoom' + Rake::Task['common:test_app'].invoke +end diff --git a/Versionfile b/Versionfile new file mode 100644 index 0000000..5db83aa --- /dev/null +++ b/Versionfile @@ -0,0 +1,11 @@ +# This file is used to designate compatibilty with different versions of Spree +# Please see http://spreecommerce.com/documentation/extensions.html#versionfile for details + +# Examples +# +# '1.2.x' => { :branch => 'master' } +# '1.1.x' => { :branch => '1-1-stable' } +# '1.0.x' => { :branch => '1-0-stable' } +# '0.70.x' => { :branch => '0-70-stable' } +# '0.40.x' => { :tag => 'v1.0.0', :version => '1.0.0' } + diff --git a/app/assets/javascripts/admin/spree_product_zoom.js b/app/assets/javascripts/admin/spree_product_zoom.js new file mode 100644 index 0000000..a3b2c53 --- /dev/null +++ b/app/assets/javascripts/admin/spree_product_zoom.js @@ -0,0 +1 @@ +//= require admin/spree_core diff --git a/app/assets/javascripts/store/spree_product_zoom.js b/app/assets/javascripts/store/spree_product_zoom.js new file mode 100644 index 0000000..2dd78f2 --- /dev/null +++ b/app/assets/javascripts/store/spree_product_zoom.js @@ -0,0 +1,2 @@ +//= require store/spree_core +//= require fancybox diff --git a/app/assets/stylesheets/admin/spree_product_zoom.css b/app/assets/stylesheets/admin/spree_product_zoom.css new file mode 100644 index 0000000..21ef02a --- /dev/null +++ b/app/assets/stylesheets/admin/spree_product_zoom.css @@ -0,0 +1,3 @@ +/* + *= require admin/spree_core +*/ diff --git a/app/assets/stylesheets/store/spree_product_zoom.css b/app/assets/stylesheets/store/spree_product_zoom.css new file mode 100644 index 0000000..2e0fb7b --- /dev/null +++ b/app/assets/stylesheets/store/spree_product_zoom.css @@ -0,0 +1,4 @@ +/* + *= require store/spree_core + *= require fancybox +*/ diff --git a/config/locales/en.yml b/config/locales/en.yml new file mode 100644 index 0000000..179c14c --- /dev/null +++ b/config/locales/en.yml @@ -0,0 +1,5 @@ +# Sample localization file for English. Add more files in this directory for other locales. +# See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points. + +en: + hello: "Hello world" diff --git a/config/routes.rb b/config/routes.rb new file mode 100644 index 0000000..53e2eeb --- /dev/null +++ b/config/routes.rb @@ -0,0 +1,3 @@ +Spree::Core::Engine.routes.draw do + # Add your extension routes here +end diff --git a/lib/generators/spree_product_zoom/install/install_generator.rb b/lib/generators/spree_product_zoom/install/install_generator.rb new file mode 100644 index 0000000..a7590f4 --- /dev/null +++ b/lib/generators/spree_product_zoom/install/install_generator.rb @@ -0,0 +1,14 @@ +module SpreeProductZoom + module Generators + class InstallGenerator < Rails::Generators::Base + + def add_javascripts + append_file 'app/assets/javascripts/store/all.js', "//= require store/spree_product_zoom\n" + end + + def add_stylesheets + inject_into_file 'app/assets/stylesheets/store/all.css', " *= require store/spree_product_zoom\n", :before => /\*\//, :verbose => true + end + end + end +end diff --git a/lib/spree_product_zoom.rb b/lib/spree_product_zoom.rb new file mode 100644 index 0000000..1f1da9a --- /dev/null +++ b/lib/spree_product_zoom.rb @@ -0,0 +1,2 @@ +require 'spree_core' +require 'spree_product_zoom/engine' diff --git a/lib/spree_product_zoom/engine.rb b/lib/spree_product_zoom/engine.rb new file mode 100644 index 0000000..7df431b --- /dev/null +++ b/lib/spree_product_zoom/engine.rb @@ -0,0 +1,22 @@ +module SpreeProductZoom + class Engine < Rails::Engine + require 'spree/core' + isolate_namespace Spree + engine_name 'spree_product_zoom' + + config.autoload_paths += %W(#{config.root}/lib) + + # use rspec for tests + config.generators do |g| + g.test_framework :rspec + end + + def self.activate + Dir.glob(File.join(File.dirname(__FILE__), '../../app/**/*_decorator*.rb')) do |c| + Rails.configuration.cache_classes ? require(c) : load(c) + end + end + + config.to_prepare &method(:activate).to_proc + end +end diff --git a/script/rails b/script/rails new file mode 100644 index 0000000..cd9185c --- /dev/null +++ b/script/rails @@ -0,0 +1,7 @@ +# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. + +ENGINE_ROOT = File.expand_path('../..', __FILE__) +ENGINE_PATH = File.expand_path('../../lib/spree_product_zoom/engine', __FILE__) + +require 'rails/all' +require 'rails/engine/commands' diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000..8d6355d --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,44 @@ +# Configure Rails Environment +ENV['RAILS_ENV'] = 'test' + +require File.expand_path('../dummy/config/environment.rb', __FILE__) + +require 'rspec/rails' +require 'ffaker' + +# Requires supporting ruby files with custom matchers and macros, etc, +# in spec/support/ and its subdirectories. +Dir[File.join(File.dirname(__FILE__), 'support/**/*.rb')].each { |f| require f } + +# Requires factories defined in spree_core +require 'spree/core/testing_support/factories' +require 'spree/core/url_helpers' + +RSpec.configure do |config| + config.include FactoryGirl::Syntax::Methods + + # == URL Helpers + # + # Allows access to Spree's routes in specs: + # + # visit spree.admin_path + # current_path.should eql(spree.products_path) + config.include Spree::Core::UrlHelpers + + # == Mock Framework + # + # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line: + # + # config.mock_with :mocha + # config.mock_with :flexmock + # config.mock_with :rr + config.mock_with :rspec + + # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures + config.fixture_path = "#{::Rails.root}/spec/fixtures" + + # If you're not using ActiveRecord, or you'd prefer not to run each of your + # examples within a transaction, remove the following line or assign false + # instead of true. + config.use_transactional_fixtures = true +end diff --git a/spree_product_zoom.gemspec b/spree_product_zoom.gemspec new file mode 100644 index 0000000..3abb43d --- /dev/null +++ b/spree_product_zoom.gemspec @@ -0,0 +1,26 @@ +# encoding: UTF-8 +Gem::Specification.new do |s| + s.platform = Gem::Platform::RUBY + s.name = 'spree_product_zoom' + s.version = '1.1.2' + s.summary = 'TODO: Add gem summary here' + s.description = 'TODO: Add (optional) gem description here' + s.required_ruby_version = '>= 1.8.7' + + # s.author = 'You' + # s.email = 'you@example.com' + # s.homepage = 'http://www.spreecommerce.com' + + #s.files = `git ls-files`.split("\n") + #s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") + s.require_path = 'lib' + s.requirements << 'none' + + s.add_dependency 'spree_core', '~> 1.1.2' + + s.add_development_dependency 'capybara', '1.0.1' + s.add_development_dependency 'factory_girl', '~> 2.6.4' + s.add_development_dependency 'ffaker' + s.add_development_dependency 'rspec-rails', '~> 2.9' + s.add_development_dependency 'sqlite3' +end diff --git a/vendor/assets/images/blank.gif b/vendor/assets/images/blank.gif new file mode 100755 index 0000000..35d42e8 Binary files /dev/null and b/vendor/assets/images/blank.gif differ diff --git a/vendor/assets/images/fancybox_buttons.png b/vendor/assets/images/fancybox_buttons.png new file mode 100755 index 0000000..e0e1ea8 Binary files /dev/null and b/vendor/assets/images/fancybox_buttons.png differ diff --git a/vendor/assets/images/fancybox_loading.gif b/vendor/assets/images/fancybox_loading.gif new file mode 100755 index 0000000..0158617 Binary files /dev/null and b/vendor/assets/images/fancybox_loading.gif differ diff --git a/vendor/assets/images/fancybox_sprite.png b/vendor/assets/images/fancybox_sprite.png new file mode 100755 index 0000000..a1aae1a Binary files /dev/null and b/vendor/assets/images/fancybox_sprite.png differ diff --git a/vendor/assets/javascripts/fancybox.js b/vendor/assets/javascripts/fancybox.js new file mode 100644 index 0000000..228dc6f --- /dev/null +++ b/vendor/assets/javascripts/fancybox.js @@ -0,0 +1,4 @@ +//= require jquery.fancybox +//= require jquery.fancybox-buttons +//= require jquery.fancybox-thumbs +//= require jquery.fancybox-media diff --git a/vendor/assets/javascripts/jquery.fancybox-buttons.js b/vendor/assets/javascripts/jquery.fancybox-buttons.js new file mode 100755 index 0000000..e116e38 --- /dev/null +++ b/vendor/assets/javascripts/jquery.fancybox-buttons.js @@ -0,0 +1,115 @@ + /*! + * Buttons helper for fancyBox + * version: 1.0.2 + * @requires fancyBox v2.0 or later + * + * Usage: + * $(".fancybox").fancybox({ + * buttons: { + * position : 'top' + * } + * }); + * + * Options: + * tpl - HTML template + * position - 'top' or 'bottom' + * + */ +(function ($) { + //Shortcut for fancyBox object + var F = $.fancybox; + + //Add helper object + F.helpers.buttons = { + tpl: '
', + list: null, + buttons: {}, + + update: function () { + var toggle = this.buttons.toggle.removeClass('btnDisabled btnToggleOn'); + + //Size toggle button + if (F.current.canShrink) { + toggle.addClass('btnToggleOn'); + + } else if (!F.current.canExpand) { + toggle.addClass('btnDisabled'); + } + }, + + beforeLoad: function (opts) { + //Remove self if gallery do not have at least two items + if (F.group.length < 2) { + F.coming.helpers.buttons = false; + F.coming.closeBtn = true; + + return; + } + + //Increase top margin to give space for buttons + F.coming.margin[ opts.position === 'bottom' ? 2 : 0 ] += 30; + }, + + onPlayStart: function () { + if (this.list) { + this.buttons.play.attr('title', 'Pause slideshow').addClass('btnPlayOn'); + } + }, + + onPlayEnd: function () { + if (this.list) { + this.buttons.play.attr('title', 'Start slideshow').removeClass('btnPlayOn'); + } + }, + + afterShow: function (opts) { + var buttons; + + if (!this.list) { + this.list = $(opts.tpl || this.tpl).addClass(opts.position || 'top').appendTo('body'); + + this.buttons = { + prev : this.list.find('.btnPrev').click( F.prev ), + next : this.list.find('.btnNext').click( F.next ), + play : this.list.find('.btnPlay').click( F.play ), + toggle : this.list.find('.btnToggle').click( F.toggle ) + } + } + + buttons = this.buttons; + + //Prev + if (F.current.index > 0 || F.current.loop) { + buttons.prev.removeClass('btnDisabled'); + } else { + buttons.prev.addClass('btnDisabled'); + } + + //Next / Play + if (F.current.loop || F.current.index < F.group.length - 1) { + buttons.next.removeClass('btnDisabled'); + buttons.play.removeClass('btnDisabled'); + + } else { + buttons.next.addClass('btnDisabled'); + buttons.play.addClass('btnDisabled'); + } + + this.update(); + }, + + onUpdate: function () { + this.update(); + }, + + beforeClose: function () { + if (this.list) { + this.list.remove(); + } + + this.list = null; + this.buttons = {}; + } + }; + +}(jQuery)); \ No newline at end of file diff --git a/vendor/assets/javascripts/jquery.fancybox-media.js b/vendor/assets/javascripts/jquery.fancybox-media.js new file mode 100755 index 0000000..be5f586 --- /dev/null +++ b/vendor/assets/javascripts/jquery.fancybox-media.js @@ -0,0 +1,85 @@ + /*! + * Media helper for fancyBox + * version: 1.0.0 + * @requires fancyBox v2.0 or later + * + * Usage: + * $(".fancybox").fancybox({ + * media: {} + * }); + * + * Supports: + * Youtube + * http://www.youtube.com/watch?v=opj24KnzrWo + * http://youtu.be/opj24KnzrWo + * Vimeo + * http://vimeo.com/25634903 + * Metacafe + * http://www.metacafe.com/watch/7635964/dr_seuss_the_lorax_movie_trailer/ + * http://www.metacafe.com/watch/7635964/ + * Dailymotion + * http://www.dailymotion.com/video/xoytqh_dr-seuss-the-lorax-premiere_people + * Twitvid + * http://twitvid.com/QY7MD + * Twitpic + * http://twitpic.com/7p93st + * Instagram + * http://instagr.am/p/IejkuUGxQn/ + * http://instagram.com/p/IejkuUGxQn/ + * Google maps + * http://maps.google.com/maps?q=Eiffel+Tower,+Avenue+Gustave+Eiffel,+Paris,+France&t=h&z=17 + * http://maps.google.com/?ll=48.857995,2.294297&spn=0.007666,0.021136&t=m&z=16 + * http://maps.google.com/?ll=48.859463,2.292626&spn=0.000965,0.002642&t=m&z=19&layer=c&cbll=48.859524,2.292532&panoid=YJ0lq28OOy3VT2IqIuVY0g&cbp=12,151.58,,0,-15.56 + */ +(function ($) { + //Shortcut for fancyBox object + var F = $.fancybox; + + //Add helper object + F.helpers.media = { + beforeLoad : function(opts, obj) { + var href = obj.href || '', + type = false, + rez; + + if ((rez = href.match(/(youtube\.com|youtu\.be)\/(v\/|u\/|embed\/|watch\?v=)?([^#\&\?]*).*/i))) { + href = '//www.youtube.com/embed/' + rez[3] + '?autoplay=1&autohide=1&fs=1&rel=0&enablejsapi=1'; + type = 'iframe'; + + } else if ((rez = href.match(/vimeo.com\/(\d+)\/?(.*)/))) { + href = '//player.vimeo.com/video/' + rez[1] + '?hd=1&autoplay=1&show_title=1&show_byline=1&show_portrait=0&color=&fullscreen=1'; + type = 'iframe'; + + } else if ((rez = href.match(/metacafe.com\/watch\/(\d+)\/?(.*)/))) { + href = '//www.metacafe.com/fplayer/' + rez[1] + '/.swf?playerVars=autoPlay=yes'; + type = 'swf'; + + } else if ((rez = href.match(/dailymotion.com\/video\/(.*)\/?(.*)/))) { + href = '//www.dailymotion.com/swf/video/' + rez[1] + '?additionalInfos=0&autoStart=1'; + type = 'swf'; + + } else if ((rez = href.match(/twitvid\.com\/([a-zA-Z0-9_\-\?\=]+)/i))) { + href = '//www.twitvid.com/embed.php?autoplay=0&guid=' + rez[1]; + type = 'iframe'; + + } else if ((rez = href.match(/twitpic\.com\/(?!(?:place|photos|events)\/)([a-zA-Z0-9\?\=\-]+)/i))) { + href = '//twitpic.com/show/full/' + rez[1]; + type = 'image'; + + } else if ((rez = href.match(/(instagr\.am|instagram\.com)\/p\/([a-zA-Z0-9_\-]+)\/?/i))) { + href = '//' + rez[1] + '/p/' + rez[2] + '/media/?size=l'; + type = 'image'; + + } else if ((rez = href.match(/maps\.google\.com\/(\?ll=|maps\/?\?q=)(.*)/i))) { + href = '//maps.google.com/' + rez[1] + '' + rez[2] + '&output=' + (rez[2].indexOf('layer=c') ? 'svembed' : 'embed'); + type = 'iframe'; + } + + if (type) { + obj.href = href; + obj.type = type; + } + } + } + +}(jQuery)); \ No newline at end of file diff --git a/vendor/assets/javascripts/jquery.fancybox-thumbs.js b/vendor/assets/javascripts/jquery.fancybox-thumbs.js new file mode 100755 index 0000000..a1b2bb7 --- /dev/null +++ b/vendor/assets/javascripts/jquery.fancybox-thumbs.js @@ -0,0 +1,157 @@ + /*! + * Thumbnail helper for fancyBox + * version: 1.0.4 + * @requires fancyBox v2.0 or later + * + * Usage: + * $(".fancybox").fancybox({ + * thumbs: { + * width : 50, + * height : 50 + * } + * }); + * + * Options: + * width - thumbnail width + * height - thumbnail height + * source - function to obtain the URL of the thumbnail image + * position - 'top' or 'bottom' + * + */ +(function ($) { + //Shortcut for fancyBox object + var F = $.fancybox; + + //Add helper object + F.helpers.thumbs = { + wrap: null, + list: null, + width: 0, + + //Default function to obtain the URL of the thumbnail image + source: function (el) { + var img; + + if ($.type(el) === 'string') { + return el; + } + + img = $(el).find('img'); + + return img.length ? img.attr('src') : el.href; + }, + + init: function (opts) { + var that = this, + list, + thumbWidth = opts.width || 50, + thumbHeight = opts.height || 50, + thumbSource = opts.source || this.source; + + //Build list structure + list = ''; + + for (var n = 0; n < F.group.length; n++) { + list += 'The requested content cannot be loaded.
Please try again later.