├── .gitignore ├── .rspec ├── CHANGELOG ├── Gemfile ├── LICENSE ├── README.md ├── Rakefile ├── app └── views │ └── gallery │ ├── _galleria.html.haml │ ├── _responsive.html.haml │ ├── _slideshow.html.haml │ └── template │ └── _responsive.html.haml ├── config └── locales │ └── rails_gallery.yml ├── lib ├── rails-gallery.rb └── rails-gallery │ ├── engine.rb │ ├── photo_validation.rb │ ├── rgallery.rb │ ├── rgallery │ ├── page.rb │ ├── pages.rb │ ├── photo.rb │ ├── photo_config.rb │ └── photos.rb │ ├── version.rb │ ├── view_helper.rb │ └── view_helper │ ├── galleria.rb │ ├── responsive.rb │ ├── slideshow.rb │ └── touch_touch.rb ├── rails-gallery.gemspec ├── spec ├── galleria_snippet.html ├── galleria_snippet.html.haml ├── images │ ├── photo_gallery │ │ ├── icons │ │ │ ├── IconsByGentleface.txt │ │ │ ├── grid.png │ │ │ ├── loading.gif │ │ │ ├── next.png │ │ │ ├── next_thumb.png │ │ │ ├── pause.png │ │ │ ├── play.png │ │ │ ├── prev.png │ │ │ ├── prev_thumb.png │ │ │ └── up.png │ │ └── images │ │ │ ├── 1.jpg │ │ │ ├── 10.jpg │ │ │ ├── 11.jpg │ │ │ ├── 12.jpg │ │ │ ├── 2.jpg │ │ │ ├── 3.jpg │ │ │ ├── 4.jpg │ │ │ ├── 5.jpg │ │ │ ├── 6.jpg │ │ │ ├── 7.jpg │ │ │ ├── 8.jpg │ │ │ ├── 9.jpg │ │ │ ├── ImagesByTibchris.txt │ │ │ └── thumbs │ │ │ ├── 1.jpg │ │ │ ├── 10.jpg │ │ │ ├── 11.jpg │ │ │ ├── 12.jpg │ │ │ ├── 2.jpg │ │ │ ├── 3.jpg │ │ │ ├── 4.jpg │ │ │ ├── 5.jpg │ │ │ ├── 6.jpg │ │ │ ├── 7.jpg │ │ │ ├── 8.jpg │ │ │ └── 9.jpg │ ├── property │ │ ├── 1.jpg │ │ ├── 2.jpg │ │ ├── 3.jpg │ │ ├── 4.jpg │ │ ├── 5.jpg │ │ ├── 6.jpg │ │ ├── 7.jpg │ │ ├── ads │ │ │ ├── ad1.jpg │ │ │ ├── ad2.jpg │ │ │ └── ad3.jpg │ │ └── thumbs │ │ │ ├── 1.jpg │ │ │ ├── 2.jpg │ │ │ ├── 3.jpg │ │ │ ├── 4.jpg │ │ │ ├── 5.jpg │ │ │ ├── 6.jpg │ │ │ └── 7.jpg │ └── responsive-gallery │ │ ├── icons │ │ ├── ajax-loader.gif │ │ ├── black.png │ │ ├── nav.png │ │ ├── nav_thumbs.png │ │ ├── pattern.png │ │ └── views.png │ │ └── images │ │ ├── 1.jpg │ │ ├── 10.jpg │ │ ├── 11.jpg │ │ ├── 12.jpg │ │ ├── 13.jpg │ │ ├── 14.jpg │ │ ├── 15.jpg │ │ ├── 16.jpg │ │ ├── 17.jpg │ │ ├── 18.jpg │ │ ├── 19.jpg │ │ ├── 2.jpg │ │ ├── 20.jpg │ │ ├── 21.jpg │ │ ├── 22.jpg │ │ ├── 23.jpg │ │ ├── 24.jpg │ │ ├── 3.jpg │ │ ├── 4.jpg │ │ ├── 5.jpg │ │ ├── 6.jpg │ │ ├── 7.jpg │ │ ├── 8.jpg │ │ ├── 9.jpg │ │ └── thumbs │ │ ├── 1.jpg │ │ ├── 10.jpg │ │ ├── 11.jpg │ │ ├── 12.jpg │ │ ├── 13.jpg │ │ ├── 14.jpg │ │ ├── 15.jpg │ │ ├── 16.jpg │ │ ├── 17.jpg │ │ ├── 18.jpg │ │ ├── 19.jpg │ │ ├── 2.jpg │ │ ├── 20.jpg │ │ ├── 21.jpg │ │ ├── 22.jpg │ │ ├── 23.jpg │ │ ├── 24.jpg │ │ ├── 3.jpg │ │ ├── 4.jpg │ │ ├── 5.jpg │ │ ├── 6.jpg │ │ ├── 7.jpg │ │ ├── 8.jpg │ │ └── 9.jpg ├── rails-gallery │ └── view_helper_spec.rb ├── rgallery │ ├── photos_spec.rb │ └── property_photo.rb └── spec_helper.rb └── vendor └── assets ├── images └── gallery │ ├── galleria │ └── classic │ │ ├── loader.gif │ │ └── map.png │ ├── responsive │ └── icons │ │ ├── ajax-loader.gif │ │ ├── black.png │ │ ├── nav.png │ │ ├── nav_thumbs.png │ │ ├── pattern.png │ │ └── views.png │ ├── slideshow │ └── icons │ │ ├── grid.png │ │ ├── loading.gif │ │ ├── next.png │ │ ├── next_thumb.png │ │ ├── pause.png │ │ ├── play.png │ │ ├── prev.png │ │ ├── prev_thumb.png │ │ └── up.png │ └── touch_touch │ ├── arrows.png │ └── preloader.gif ├── javascripts ├── gallery │ ├── galleria.js │ ├── galleria │ │ ├── classic.js │ │ └── classic.min.js │ ├── responsive.js │ ├── slideshow.js │ └── touch_touch.js └── jquery │ ├── jquery.easing-1.3.js │ ├── jquery.elastislide.js │ └── jquery.tmpl.min.js └── stylesheets └── gallery ├── galleria └── classic.css ├── responsive.css ├── responsive └── elastislide.css ├── slideshow.css └── touch_touch.css /.gitignore: -------------------------------------------------------------------------------- 1 | .bundle/ 2 | log/*.log 3 | pkg/ 4 | spec/dummy/logs 5 | spec/dummy/public 6 | spec/dummy/temp 7 | 8 | *.gem 9 | 10 | Gemfile.lock 11 | .DS_Store 12 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --color --format nested 2 | -------------------------------------------------------------------------------- /CHANGELOG: -------------------------------------------------------------------------------- 1 | ## CHANGELOG 2 | 3 | ### 0.3.2 4 | 5 | - Using bundler for gem management :) -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "http://rubygems.org" 2 | 3 | gemspec 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 Kristian Mandrup 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Photo Gallery components for Rails 2 | 3 | Popular Javascript Photo galleries/carousels ready to use with Rails 3+. 4 | 5 | ## Usage 6 | 7 | `gem 'rails-gallery'` 8 | 9 | ## Galleries included 10 | 11 | * slideshow 12 | * responsive 13 | * galleria 14 | * touch_touch 15 | 16 | Please add more using a similar convention as is used for these galleries ;) 17 | 18 | ## Configuration 19 | 20 | In `application.css` manifest file: 21 | 22 | ```css 23 | /* 24 | *= require gallery/responsive/elastislide 25 | *= require gallery/responsive 26 | *= require gallery/slideshow 27 | *= require gallery/galleria/classic 28 | *= require gallery/touch_touch 29 | */ 30 | ``` 31 | 32 | Using Compass, f.ex in `application.css.scss` 33 | 34 | ``` 35 | @import 'gallery/responsive/elastislide'; 36 | @import 'gallery/responsive'; 37 | @import 'gallery/slideshow'; 38 | @import 'gallery/galleria/classic'; 39 | @import 'gallery/touch_touch'; 40 | ``` 41 | 42 | In `application.js` manifest file: 43 | 44 | ```javascript 45 | //= require gallery/responsive 46 | //= require gallery/slideshow 47 | //= require gallery/galleria 48 | //= require gallery/galleria/classic 49 | //= require gallery/touch_touch 50 | 51 | //= require jquery/jquery.easing-1.3 52 | //= require jquery/jquery.elastislide 53 | //= require jquery/jquery.tmpl.min 54 | ``` 55 | 56 | Note: For galleria, you need to specify the theme to use. 57 | 58 | ## Touch-Touch 59 | 60 | ```javascript 61 | $(function(){ 62 | 63 | // Initialize the gallery 64 | $('#thumbs a').touchTouch(); 65 | 66 | }); 67 | ``` 68 | 69 | See [TouchTouch](http://tutorialzine.com/2012/04/mobile-touch-gallery/) and [github repo](https://github.com/martinaglv/touchTouch) 70 | 71 | ```haml 72 | = touchgal_image photo 73 | ``` 74 | 75 | ## Minimalistic Slideshow gallery 76 | 77 | See [minimalistic-slideshow-gallery](http://tympanus.net/codrops/2010/07/05/minimalistic-slideshow-gallery/) for more info. 78 | 79 | 80 | ### Customization 81 | 82 | Pls Fill in here ;) 83 | 84 | ## Responsive gallery 85 | 86 | See [responsive-image-gallery](http://tympanus.net/codrops/2011/09/20/responsive-image-gallery/) for more info. 87 | 88 | ### Customization 89 | 90 | *Remove thumbnails* 91 | 92 | Change `mode = 'carousel'` to `'fullview'` 93 | 94 | *Remove 'mode' bar* 95 | 96 | ```css 97 | .rg-view{ 98 | display: none; 99 | } 100 | 101 | .rg-thumbs { 102 | padding-top: 10px; 103 | } 104 | ``` 105 | 106 | *placement of thumbnails* 107 | 108 | To adjust placement of thumbnails, use: `prependTo` or `appendTo` in `gallery/responsive.js`: 109 | 110 | ```javascript 111 | _addImageWrapper= function() { 112 | 113 | // adds the structure for the large image and the navigation buttons (if total items > 1) 114 | // also initializes the navigation events 115 | $('#img-wrapper-tmpl').tmpl( {itemsCount : itemsCount} ).prependTo( $rgGallery ) 116 | ``` 117 | 118 | *Automatic slideshow* 119 | 120 | I wanted the same thing and I find a way to do it. 121 | In the file gallery.js, in the function `_initCarousel` add these lines after: 122 | 123 | `$esCarousel.elastislide( 'setCurrent', current );` 124 | 125 | ```javascript 126 | window.setInterval(function(){ 127 | _navigate( 'right' ); 128 | }, 5000); 129 | ``` 130 | 131 | You just have to change `5000` to the value you want (milliseconds). 132 | 133 | * Fancybox integration* 134 | 135 | First you have to include the js and the css file of fancybox in the file where you have the carousel. 136 | 137 | In the file `responsive.js`, replace this line: 138 | 139 | `$rgGallery.find('div.rg-image').empty().append('img src="' + largesrc + '"');` 140 | 141 | With this (which adds 'fancybox' class to all images): 142 | 143 | `$rgGallery.find('div.rg-image').empty().append('a class="fancybox" 144 | href="'+largesrc+ '" img src="' + largesrc + '" a');` 145 | 146 | In this line, don’t forget to add the `"` for the img and link tags. 147 | 148 | Then do the fancybox magic on any class with the `fancybox` class 149 | 150 | ```javascript 151 | $(document).ready(function() { 152 | $(“.fancybox”).fancybox(); 153 | }); 154 | ``` 155 | 156 | ## Galleria 157 | 158 | See [galleria.io](http://galleria.io) for more info. 159 | 160 | [quick start](http://galleria.io/docs/getting_started/quick_start/) 161 | 162 | ```css 163 | #galleria { 164 | width: 700px; 165 | height: 400px; 166 | background: white 167 | } 168 | ``` 169 | 170 | Important: You need to specify the width and height of the galleria container object in your CSS (here the `#galleria` DOM node). Otherwise you will get a trace error! 171 | 172 | ```javascript 173 | Galleria.loadTheme('gallery/galleria/classic.js'); 174 | 175 | // or simply 176 | Galleria.loadNamedTheme('classic'); 177 | 178 | // or for asset path 179 | Galleria.loadAssetTheme('classic'); 180 | 181 | // Then configure 182 | Galleria.configure({ 183 | imageCrop: true, 184 | transition: 'fade', 185 | log: true, 186 | // better handle image paths in assets folder! 187 | assets: true, 188 | // if pic can't be loaded use this one as fallback 189 | dummy: '/assets/photos/dummy.png' 190 | }); 191 | 192 | Galleria.run('#galleria'); 193 | ``` 194 | 195 | *Troubleshooting a javascript gallery* 196 | 197 | Many of the Javascript galleries don't play very well with Rails and the asset pipeline as they expect a pretty simple application file structure/setup. 198 | 199 | As an example, in order to make *galleria* work, I had to add a `normalizeSrc` method, which ensures that it looks for an image of the form `/assets/...` when configured with `assets: true` (See `Galleria.configure` options). 200 | 201 | You might well encounter similar troubles. Another potential problem is browser caching, where you might well have to add a timestamp to the image url. Something like: 202 | 203 | `my/image.png?235325325323232` 204 | 205 | In some cases you might wanna hide the image tags and only execute/initialize the gallery when the images have finished loading, fx via the `imagesLoaded` jQuery plugin. Good luck! 206 | 207 | ### Model Configuration 208 | 209 | The engine comes with a RGallery::Photos` model which can encapsulate your photos for display and allows you to group photos in multiple pages. 210 | The `RGallery::Photo` class is a base class for describing a photo. 211 | 212 | You should create your own Photo class that inherits from `RGallery::Photo` (or implements the API), which knows how to render and describe your photos. 213 | 214 | Here is a rough example: 215 | 216 | ```ruby 217 | class Property 218 | class Photo < RGallery::Photo 219 | def initialize property, options = {} 220 | super 221 | end 222 | alias_method :property, :obj 223 | 224 | def path 225 | File.join folder, super 226 | end 227 | 228 | # mogrify -path fullpathto/temp2 -resize 60x60% -quality 60 -format jpg *.png 229 | 230 | # this will take all png files in your current directory (temp), 231 | # resize to 60% (of largest dimension and keep aspect ratio), 232 | # set jpg quality to 60 and convert to jpg. 233 | def thumb 234 | File.join folder, 'thumbs', file_path 235 | end 236 | 237 | def folder 238 | 'gallery/images' 239 | end 240 | 241 | # Here we expect to create each photo with the 242 | # id being set to a Property object 243 | def property 244 | id 245 | end 246 | 247 | # The filename of the picture. 248 | # Here it assumes that the id assigned is a Property object, which has a 249 | # method 'picture' which returns the picture id. 250 | def filename 251 | "property-#{property.picture}" 252 | end 253 | 254 | def title 255 | property.title 256 | end 257 | 258 | def alt 259 | title 260 | end 261 | 262 | def self.extension 263 | :jpg 264 | end 265 | end 266 | end 267 | ``` 268 | 269 | See the `lib/rails-gallery/rgallery/photos.rb` for details on how to extend this class appropriately to fit your scenario. 270 | 271 | *debugging* 272 | 273 | In order to help debug the configuration of the photo class, you can use the view_helper methods: 274 | 275 | ```ruby 276 | = validate_gallery_photo photo # prints error msg if invalid 277 | - validate_gallery_photo! photo # raise error if invalid 278 | ``` 279 | 280 | Or you can include the `RailsGallery::PhotoValidation` module anywhere you want to leverage these methods! 281 | 282 | 283 | ## Rails engine usage 284 | 285 | The `RailsGallery::ViewHelper` is inluded into ActionView::Base by the engine. 286 | 287 | The following are the main methods exposed: 288 | 289 | * gallery_image type, photo 290 | * gallery_imageset type, photo 291 | 292 | Example usage: 293 | 294 | ```haml 295 | = gallery_image :responsive, photo` 296 | = gallery_imageset :galleria, photo` 297 | ``` 298 | 299 | The photo argument must be a kind of `RGallery::Photo:: 300 | 301 | ### Controller and partials 302 | 303 | Some *HAML* views (partials) are included in `app/views/gallery` 304 | 305 | ### Rails views usage 306 | 307 | First set up photos in your controller. 308 | 309 | ```ruby 310 | class PropertiesController < ApplicationController 311 | def show 312 | @property = property 313 | end 314 | 315 | protected 316 | 317 | def property 318 | Hashie::Mash.new title: 'A beautiful property', 319 | description: decription, 320 | photos: photos 321 | end 322 | 323 | def description 324 | %q{Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent mauris arcu, auctor ac rhoncus non, libero. Nulla dolor velit, volutpat a bibendum ut, hendrerit id mi. Pellentesque convallis erat in mi interdum rutrum. Phasellus interdum velit nulla. 325 | } 326 | end 327 | 328 | def photos 329 | @photos ||= RGallery::Photos.new nil, photo_class: Property::Photo 330 | 5.times do |n| 331 | # using a paginator to get a page of properties 332 | @photos.pages << Property.page(n) 333 | end 334 | @photos 335 | end 336 | end 337 | ``` 338 | 339 | In `property/show.html.haml`, render one of the partials of this gem, sending it the list of photos as a local variable `photo`: 340 | 341 | ```haml 342 | .gallery 343 | = render partial: 'gallery/gallery', locals: { photos: @property.photos} 344 | ``` 345 | 346 | *Responsive Gallery* 347 | 348 | In your `properties/show.html.haml`: 349 | 350 | ```haml 351 | = render partial: 'gallery/template/responsive' 352 | = render partial: 'gallery/responsive', locals: { photos: @property.photos } 353 | ``` 354 | 355 | Note :Currently only the *responsive* gallery uses a template, and thus requires rendering an extra partial. 356 | 357 | *Slideshow Gallery* 358 | 359 | ```haml 360 | = render partial: 'gallery/slideshow', locals: { photos: @property.photos } 361 | ``` 362 | 363 | *Galleria* 364 | 365 | ```haml 366 | = render partial: 'gallery/galleria', locals: { photos: @property.photos } 367 | ``` 368 | 369 | All galleries should follow this convention (or as close as possible) 370 | 371 | ## Labels 372 | 373 | Note that all gallery labels are rendered using Rails I18n `I18n.t`. 374 | You should include appropriate translations for the following keys under 'rgallery': 375 | 376 | * previous 377 | * next 378 | * photos_loading 379 | 380 | The engine includes a `config/locales/rails_gallery.yml` file, currently only with english translation mappings. Include a `config/locales/rails_gallery.yml` file in your Rails app and override or supply you additional translation mappings ;) 381 | 382 | ## View helpers 383 | 384 | There are some view helpers included in `rails-gallery/view_helper.rb` 385 | 386 | `= gallery_image type, photo` 387 | 388 | *Simple example:* 389 | 390 | Iterate all photos as a "single page". 391 | 392 | ```haml 393 | - photos.all.each do |photo| 394 | = gallery_image :responsive, photo` 395 | ``` 396 | 397 | *Pages example:* 398 | 399 | Iterate photos, one page at a time. 400 | 401 | ```haml 402 | - photos.pages.each do |photo| 403 | = gallery_image :responsive, photo` 404 | ``` 405 | 406 | *Advanced example:* 407 | 408 | Iterate photos, first page visible, then remaining pages invisible. 409 | 410 | ```haml 411 | .page.visible 412 | - photos.page(:first).photos.each do |photo| 413 | = gallery_image :responsive, photo` 414 | 415 | - photos.pages.remainder.each do |page| 416 | .page.hidden 417 | - page.photos.each do |photo| 418 | = gallery_image :responsive, photo` 419 | ``` 420 | 421 | ## Responsive gallery support 422 | 423 | The RGallery also supports multiple photo sources for responsive galleries: 424 | 425 | ```ruby 426 | @photos.pages.add_photo_w_sources 'banner' => [{src: 'banner-HD', sizing: '2x'}, {src: 'banner-phone', sizing: '100w'}] 427 | 428 | Note: See module `RGallery::Pages` class. 429 | 430 | # OR 431 | 432 | @photos.pages.add_photo_sources 'banner' => [{src: 'banner-HD', sizing: '2x'}], 'logo' => [{src: 'logo-HD', sizing: '2x'} 433 | 434 | # OR on individual pages 435 | 436 | @photos.page(:first).add_photo_sources 'banner' => [{src: 'banner-HD', sizing: '2x'}], 'logo' => [{src: 'logo-HD', sizing: '2x'} 437 | 438 | ``` 439 | 440 | ### Shortcuts for view helpers 441 | 442 | ```haml 443 | # galleria 444 | = riagal_image photo 445 | = riagal_imageset photo 446 | 447 | # slideshow 448 | = slidegal_image photo 449 | = slidegal_imageset photo 450 | 451 | # responsive 452 | = respgal_image photo 453 | = respgal_imageset photo 454 | 455 | # touchtouch 456 | = touchgal_image photo 457 | = touchgal_imageset photo 458 | ``` 459 | 460 | ## Responsive images via "image srcset" 461 | 462 | The View Helpers includes tag helpers to create image tags with [srcset](https://github.com/borismus/srcset-polyfill). This can be installed and used with [picturefill-rails](https://github.com/kristianmandrup/picturefill-rails) 463 | 464 | Example: 465 | 466 | ```haml 467 | - photos.pages.each do |photo| 468 | = gallery_imageset :responsive, photo` 469 | ``` 470 | 471 | Enjoy! 472 | 473 | ## Adding more galleries 474 | 475 | Simply follow the existing conventions (see the code). 476 | 477 | *ViewHelpers* 478 | 479 | Add the gallery name to the `#galleries` class method of the `ViewHelper` and create a module for that gallery with a `[name]_gallery_image(photo)` method. 480 | 481 | Then add gallery client-side pieces to the assets folder following conventions and make sure that your css files (and possible js files) references the icons used (and any other asset) correctly using `/assets/` in the path ;) 482 | 483 | ## TODO 484 | 485 | Would be nice to allow pages/albums to have info assigned, such as title and/or description, tags etc. 486 | 487 | ## Contributing to rails-gallery 488 | 489 | See [building gem with bundler](http://no-fucking-idea.com/blog/2012/04/11/building-gem-with-bundler/) 490 | 491 | Update `VERSION` referenced from .gemspec file in `lib/rails-gallery/version.rb` 492 | 493 | Build the new version of the gem: 494 | 495 | `$ gem build rails-gallery.gemspec` 496 | 497 | Generate rspec: 498 | 499 | `gem spec rails-gallery-0.3.3.gem` 500 | 501 | Push (publish) to rubygems: 502 | 503 | `gem push rails-gallery-0.3.3.gem` 504 | 505 | * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet. 506 | * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it. 507 | * Fork the project. 508 | * Start a feature/bugfix branch. 509 | * Commit and push until you are happy with your contribution. 510 | * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally. 511 | * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it. 512 | 513 | ## Copyright 514 | 515 | Copyright (c) 2012 Kristian Mandrup. See LICENSE.txt for 516 | further details. 517 | 518 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env rake 2 | require "bundler/gem_tasks" 3 | 4 | require 'rspec/core/rake_task' 5 | 6 | RSpec::Core::RakeTask.new('spec') 7 | 8 | task :default => :spec -------------------------------------------------------------------------------- /app/views/gallery/_galleria.html.haml: -------------------------------------------------------------------------------- 1 | #galleria.galleria 2 | - photos.all.each do |photo| 3 | = gallery_image :galleria, photo 4 | -------------------------------------------------------------------------------- /app/views/gallery/_responsive.html.haml: -------------------------------------------------------------------------------- 1 | #rg-gallery.rg-gallery 2 | .rg-thumbs 3 | // Elastislide Carousel Thumbnail Viewer 4 | .es-carousel-wrapper 5 | .es-nav 6 | %span.es-nav-prev 7 | = t('rgallery.previous') 8 | %span.es-nav-next 9 | = t('rgallery.next') 10 | .es-carousel 11 | %ul 12 | - photos.all.each do |photo| 13 | = gallery_image :responsive, photo, wrap: true 14 | -------------------------------------------------------------------------------- /app/views/gallery/_slideshow.html.haml: -------------------------------------------------------------------------------- 1 | // http://tympanus.net/codrops/2010/07/05/minimalistic-slideshow-gallery/ 2 | #msg_slideshow.msg_slideshow 3 | #msg_wrapper.msg_wrapper 4 | #msg_controls.msg_controls 5 | // right has to animate to 15px, default -110px 6 | %a#msg_grid.msg_grid{href: "#"} 7 | %a#msg_prev.msg_prev{href: "#"} 8 | %a#msg_pause_play.msg_pause{href: "#"} 9 | // has to change to msg_play if paused 10 | %a#msg_next.msg_next{href: "#"} 11 | #msg_thumbs.msg_thumbs 12 | // top has to animate to 0px, default -230px 13 | .msg_thumb_wrapper 14 | - photos.page(:first).photos.each do |photo| 15 | %a{href: "#"} 16 | = gallery_image :slideshow, photo 17 | - photos.pages.remainder.each do |page| 18 | .msg_thumb_wrapper{style: 'display:none'} 19 | - page.photos.each do |photo| 20 | %a{href: "#"} 21 | = gallery_image :slideshow, photo 22 | %a#msg_thumb_next.msg_thumb_next{href: '#'} 23 | %a#msg_thumb_prev.msg_thumb_prev{href: '#'} 24 | %a#msg_thumb_close.msg_thumb_close{href: '#'} 25 | %span.msg_loading 26 | = t('rgallery.photos_loading') 27 | -------------------------------------------------------------------------------- /app/views/gallery/template/_responsive.html.haml: -------------------------------------------------------------------------------- 1 | %script#img-wrapper-tmpl{style: "display:none;"} 2 | .rg-image-wrapper 3 | {{if itemsCount > 1}} 4 | .rg-image-nav 5 | %a.rg-image-nav-prev{href: "#"} 6 | = t('rgallery.previous') 7 | %a.rg-image-nav-next{href: "#"} 8 | = t('rgallery.next') 9 | {{/if}} 10 | .rg-image 11 | .rg-loading 12 | .rg-caption-wrapper 13 | .rg-caption{style: "display:none;"} 14 | %p 15 | -------------------------------------------------------------------------------- /config/locales/rails_gallery.yml: -------------------------------------------------------------------------------- 1 | en: 2 | rgallery: 3 | previous: Previous 4 | next: Next 5 | photos_loading: Loading photos... 6 | -------------------------------------------------------------------------------- /lib/rails-gallery.rb: -------------------------------------------------------------------------------- 1 | require 'rails-gallery/rgallery' 2 | require 'rails-gallery/photo_validation' 3 | require 'rails-gallery/view_helper' 4 | require 'rails-gallery/engine' if defined?(::Rails::Engine) -------------------------------------------------------------------------------- /lib/rails-gallery/engine.rb: -------------------------------------------------------------------------------- 1 | module RailsGallery 2 | module Rails 3 | class Engine < ::Rails::Engine 4 | initializer 'rails gallery' do 5 | # puts "Adding RailsGallery::ViewHelper" 6 | ActionView::Base.send :include, RailsGallery::ViewHelper 7 | end 8 | end 9 | end 10 | end -------------------------------------------------------------------------------- /lib/rails-gallery/photo_validation.rb: -------------------------------------------------------------------------------- 1 | module RailsGallery 2 | module PhotoValidation 3 | def validate_gallery_photo photo 4 | return "Photo must be a kind of RGallery::Photo, was: #{photo}" unless photo.kind_of?(RGallery::Photo) 5 | return 'Photo must have a #path method' unless photo.respond_to? :path 6 | return 'Photo must have a #title method' unless photo.respond_to? :title 7 | 8 | begin 9 | photo.filename 10 | photo.file_path 11 | rescue Exception => e 12 | return "filename or file_path could not be resolved for: #{photo}, cause: #{e}" 13 | end 14 | 15 | return "Photo must have a path: #{photo}" if photo.path.blank? 16 | return "Photo must have a title: #{photo}" if photo.title.blank? 17 | true 18 | end 19 | 20 | def validate_gallery_photo! photo 21 | raise ArgumentError, "Photo must be a kind of RGallery::Photo, was: #{photo}" unless photo.kind_of?(RGallery::Photo) 22 | raise ArgumentError, 'Photo must have a #path method' unless photo.respond_to? :path 23 | raise ArgumentError, 'Photo must have a #title method' unless photo.respond_to? :title 24 | 25 | begin 26 | photo.filename 27 | photo.file_path 28 | rescue Exception => e 29 | raise ::RailsGallery::ConfigurationError, "filename or file_path could not be resolved for: #{photo}, cause: #{e}" 30 | end 31 | 32 | raise ArgumentError, "Photo must have a path: #{photo}" if photo.path.blank? 33 | raise ArgumentError, "Photo must have a title: #{photo}" if photo.title.blank? 34 | true 35 | end 36 | end 37 | end -------------------------------------------------------------------------------- /lib/rails-gallery/rgallery.rb: -------------------------------------------------------------------------------- 1 | module RGallery 2 | autoload :Photos, 'rails-gallery/rgallery/photos' 3 | autoload :Pages, 'rails-gallery/rgallery/pages' 4 | autoload :Page, 'rails-gallery/rgallery/page' 5 | autoload :Photo, 'rails-gallery/rgallery/photo' 6 | autoload :PhotoConfig, 'rails-gallery/rgallery/photo_config' 7 | end -------------------------------------------------------------------------------- /lib/rails-gallery/rgallery/page.rb: -------------------------------------------------------------------------------- 1 | module RGallery 2 | class Page < PhotoConfig 3 | include Enumerable 4 | 5 | def initialize photo_objs = [], options = {} 6 | @photo_objs = photo_objs 7 | super options 8 | end 9 | 10 | # a source is a hash of the form: 11 | # 'banner' => [{src: 'banner-HD', sizing: '2x'}, {src: 'banner-phone', sizing: '100w'}] 12 | # see: add_photo_sources 13 | def self.from_source sources 14 | page = self.create sources.keys, options 15 | 16 | @photos ||= sources.map do |key, srclist| 17 | photo_class.new key, options.merge(:sources => srclist) 18 | end 19 | end 20 | 21 | def << photo_objs 22 | @photo_objs ||= [] 23 | @photo_objs += [photo_objs].flatten 24 | end 25 | 26 | def add_photo_sources sources_hash 27 | sources_hash.each do |source| 28 | add_photo_w_sources source 29 | end 30 | end 31 | 32 | def add_photo_w_sources source 33 | raise ArgumentError, "Must be a hash, was: #{source}" unless source.kind_of? Hash 34 | key = source.keys.first 35 | srclist = source.values.first 36 | raise ArgumentError, "Hash value must be an Array, was: #{srclist}" unless srclist.kind_of? Array 37 | 38 | self.send :<<, key 39 | @photos ||= [] 40 | @photos << photo_class.new(key, options.merge(:sources => srclist)) 41 | end 42 | 43 | def photo_objs 44 | @photo_objs ||= [] 45 | end 46 | 47 | def photos 48 | @photos ||= photo_objs.map {|obj| photo_class.new obj, options } 49 | end 50 | 51 | delegate :empty?, to: :photos 52 | 53 | def each &block 54 | photos.each {|photo| yield photo } 55 | end 56 | end 57 | end -------------------------------------------------------------------------------- /lib/rails-gallery/rgallery/pages.rb: -------------------------------------------------------------------------------- 1 | module RGallery 2 | class Pages < PhotoConfig 3 | include Enumerable 4 | 5 | def initialize photo_list = [], options = {} 6 | super options 7 | self.send(:<<, photo_list) unless photo_list.blank? 8 | end 9 | 10 | def each &block 11 | pages.each {|page| yield page } 12 | end 13 | 14 | def remainder 15 | pages[1..-1] || [] 16 | end 17 | 18 | def first 19 | pages.first || [] 20 | end 21 | 22 | def << photo_list 23 | pages << RGallery::Page.new(photo_list, options) 24 | end 25 | 26 | # a source is a hash of the form: 27 | # 'banner' => [{src: 'banner-HD', sizing: '2x'}, {src: 'banner-phone', sizing: '100w'}] 28 | def add_photo_w_sources source 29 | pages << RGallery::Page.from_source(source, options) 30 | end 31 | 32 | # a Hash where each element is a source of the form: 33 | # 'banner' => [{src: 'banner-HD', sizing: '2x'}, {src: 'banner-phone', sizing: '100w'}] 34 | def add_photo_sources sources_hash 35 | sources_hash.each do |source| 36 | pages.add_photo_w_sources source 37 | end 38 | end 39 | 40 | 41 | delegate :empty?, to: :pages 42 | 43 | protected 44 | 45 | def pages 46 | @pages ||= [] 47 | end 48 | end 49 | end -------------------------------------------------------------------------------- /lib/rails-gallery/rgallery/photo.rb: -------------------------------------------------------------------------------- 1 | module RGallery 2 | class Photo 3 | attr_reader :obj, :sizing, :sources, :options 4 | 5 | def initialize obj, options = {} 6 | @obj = obj 7 | self.sources = options.delete :sources 8 | @sizing = options.delete :sizing 9 | @options = options 10 | end 11 | 12 | alias_method :id, :obj 13 | 14 | # map [{src: 'banner-HD.jpeg', sizing: '2x'}, {src: 'banner-phone.jpeg', sizing: '100w'}] 15 | # into -> "banner-HD.jpeg 2x, banner-phone.jpeg 100w 16 | def srcset 17 | return '' unless sources_photos.kind_of? Array 18 | @srcset ||= source_photos.inject([]) do |res, photo| 19 | res << [photo.id, photo.sizing].join(' ') 20 | end.join(',') 21 | end 22 | 23 | def srcset? 24 | !srcset.blank? 25 | end 26 | 27 | # A photo can contain a source set of other photos! 28 | def source_photos 29 | return [] unless sources.kind_of? Array 30 | @source_photos ||= sources.map do |source| 31 | RGallery::Photo.new source.src, options.merge(:sizing => source.sizing) 32 | end 33 | end 34 | 35 | # make sure that sources are wrapped as Hashies to allow method access 36 | def sources= sources = [] 37 | return unless sources.kind_of? Array 38 | @sources = sources.map{|source| Hashie::Mash.new source } 39 | end 40 | 41 | def filename 42 | id 43 | end 44 | 45 | def file_path 46 | "#{filename}.#{extension}" 47 | end 48 | 49 | def path 50 | file_path 51 | end 52 | 53 | def thumb 54 | path 55 | end 56 | 57 | def title 58 | 'no title' 59 | end 60 | 61 | def alt 62 | 'no alt' 63 | end 64 | 65 | def description 66 | 'no description' 67 | end 68 | 69 | def extension 70 | options[:extension] || self.class.extension 71 | end 72 | 73 | class << self 74 | attr_writer :extension 75 | 76 | def extension 77 | @extension ||= :png 78 | end 79 | end 80 | end 81 | end -------------------------------------------------------------------------------- /lib/rails-gallery/rgallery/photo_config.rb: -------------------------------------------------------------------------------- 1 | module RGallery 2 | class PhotoConfig 3 | attr_writer :photo_class 4 | attr_reader :options 5 | 6 | def initialize options = {} 7 | options ||= {} 8 | @options = options 9 | @photo_class = options[:photo_class] if options[:photo_class] 10 | end 11 | 12 | protected 13 | 14 | def photo_class 15 | @photo_class ||= RGallery::Photo 16 | end 17 | end 18 | end -------------------------------------------------------------------------------- /lib/rails-gallery/rgallery/photos.rb: -------------------------------------------------------------------------------- 1 | require 'enumerator' 2 | 3 | module RGallery 4 | class Photos < PhotoConfig 5 | def initialize pages = nil, options = {} 6 | unless pages.nil? 7 | raise ArgumentError, "Must be a Photos::Pages or Array, was: #{pages}" unless valid_pages? pages 8 | pages = pages_class.new pages, options if pages.kind_of?(Array) 9 | @pages = pages 10 | end 11 | super options 12 | end 13 | 14 | def all 15 | pages.inject([]) {|res, page| res += page.photos }.flatten.compact 16 | end 17 | 18 | def pages 19 | @pages ||= pages_class.new nil, options 20 | end 21 | 22 | def page id 23 | raise ArgumentError, "Page id must be one #{valid_page_ids}, was: #{id}" unless valid_page_id? id 24 | pages.send(id) 25 | end 26 | 27 | protected 28 | 29 | def valid_page_id? id 30 | [:first].include? id.to_sym 31 | end 32 | 33 | def valid_page_ids 34 | [:first] 35 | end 36 | 37 | def valid_pages? pages 38 | pages.kind_of?(pages_class) || pages.kind_of?(Array) 39 | end 40 | 41 | def pages_class 42 | RGallery::Pages 43 | end 44 | end 45 | end -------------------------------------------------------------------------------- /lib/rails-gallery/version.rb: -------------------------------------------------------------------------------- 1 | module RailsGallery 2 | VERSION = '0.3.3' 3 | end -------------------------------------------------------------------------------- /lib/rails-gallery/view_helper.rb: -------------------------------------------------------------------------------- 1 | module RailsGallery 2 | class ConfigurationError < StandardError 3 | end 4 | 5 | module ViewHelper 6 | include RailsGallery::PhotoValidation 7 | 8 | def self.galleries 9 | %w{galleria responsive slideshow touch_touch} 10 | end 11 | 12 | def self.version 13 | '0.2.2' 14 | end 15 | 16 | # autoload all galleries when references 17 | galleries.each do |gallery| 18 | autoload gallery.camelize.to_sym, "rails-gallery/view_helper/#{gallery}" 19 | end 20 | 21 | def gallery_image type, photo, options = {} 22 | meth_name = "#{type}_gallery_image" 23 | validate_gallery_photo! photo 24 | unless respond_to? meth_name 25 | raise ArgumentError, "Gallery #{type} is not yet supported. Please add a View helper module for this gallery using the convention followed by the other galleries..." 26 | end 27 | send(meth_name, photo, options) 28 | end 29 | 30 | def gallery_imageset type, imageset, options = {} 31 | meth_name = "#{type}_gallery_imageset" 32 | # validate_gallery_imageset! imageset 33 | unless respond_to? meth_name 34 | raise ArgumentError, "Gallery #{type} is not yet supported for imageset. Please add a View helper module for this gallery using the convention followed by the other galleries..." 35 | end 36 | send(meth_name, imageset, options) 37 | end 38 | 39 | protected 40 | 41 | # include view helper modules for all galleries :) 42 | galleries.each do |gallery| 43 | include "RailsGallery::ViewHelper::#{gallery.camelize}".constantize 44 | end 45 | end 46 | end 47 | -------------------------------------------------------------------------------- /lib/rails-gallery/view_helper/galleria.rb: -------------------------------------------------------------------------------- 1 | module RailsGallery 2 | module ViewHelper 3 | module Galleria 4 | def riagal_image photo, options = {} 5 | content_tag :a, href: photo.path do 6 | options.merge! :"data-title" => photo.title, :"data-description" => photo.description 7 | image_tag photo.path, options 8 | end 9 | end 10 | 11 | def riagal_imageset photo, options = {} 12 | content_tag :a, href: photo.path do 13 | options.merge! :"data-title" => photo.title, :"data-description" => photo.description 14 | options.merge! :srcset => photo.srcset if photo.srcset? 15 | image_tag photo.path, options 16 | end 17 | end 18 | alias_method :galleria_gallery_image, :riagal_image 19 | alias_method :galleria_gallery_imageset, :riagal_imageset 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /lib/rails-gallery/view_helper/responsive.rb: -------------------------------------------------------------------------------- 1 | module RailsGallery 2 | module ViewHelper 3 | module Responsive 4 | def respgal_image photo, options = {} 5 | options.merge! :alt => photo.alt 6 | options.merge! :"data-large" => photo.path, :"data-description" => photo.title 7 | return image_tag photo.thumb, options unless options.delete :wrap 8 | 9 | content_tag :li do 10 | content_tag :a, href: '#' do 11 | image_tag(photo.thumb, options) 12 | end 13 | end 14 | end 15 | 16 | def respgal_imageset photo, options = {} 17 | options.merge! :alt => photo.alt 18 | options.merge! :"data-large" => photo.path, :"data-description" => photo.title 19 | options.merge! :srcset => srcset if photo.srcset? 20 | return imageset_tag photo.thumb, options unless options.delete :wrap 21 | 22 | content_tag :li do 23 | content_tag :a, href: '#' do 24 | imageset_tag(photo.thumb, options) 25 | end 26 | end 27 | end 28 | alias_method :responsive_gallery_image, :respgal_image 29 | alias_method :responsive_gallery_imageset, :respgal_imageset 30 | end 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /lib/rails-gallery/view_helper/slideshow.rb: -------------------------------------------------------------------------------- 1 | module RailsGallery 2 | module ViewHelper 3 | module Slideshow 4 | def slidegal_image photo, options = {} 5 | options.merge! alt: photo.path 6 | image_tag photo.thumb, options 7 | end 8 | 9 | def slidegal_imageset photo, options = {} 10 | options.merge! alt: photo.path 11 | options.merge! :srcset => photo.srcset if photo.srcset? 12 | imageset_tag photo.thumb, options 13 | end 14 | 15 | alias_method :slideshow_gallery_image, :slidegal_image 16 | alias_method :slideshow_gallery_imageset, :slidegal_imageset 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /lib/rails-gallery/view_helper/touch_touch.rb: -------------------------------------------------------------------------------- 1 | module RailsGallery 2 | module ViewHelper 3 | module TouchTouch 4 | def touchgal_image photo, options = {} 5 | content_tag :a, nil, options.merge(href: photo.path, title: photo.title) 6 | end 7 | alias_method :touch_gallery_image, :touchgal_image 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /rails-gallery.gemspec: -------------------------------------------------------------------------------- 1 | $:.push File.expand_path("../lib", __FILE__) 2 | 3 | # Maintain your gem's version: 4 | require "rails-gallery/version" 5 | 6 | Gem::Specification.new do |spec| 7 | spec.name = "rails-gallery" 8 | spec.version = RailsGallery::VERSION 9 | spec.authors = ["Kristian Mandrup"] 10 | spec.date = "2012-10-11" 11 | spec.summary = "Gallery functionality for Rails apps" 12 | spec.description = "Add photo galleries to your Rails apps :)" 13 | spec.email = "kmandrup@gmail.com" 14 | spec.homepage = "https://github.com/kristianmandrup/rails-gallery" 15 | spec.license = "MIT" 16 | 17 | spec.files = `git ls-files`.split($/) 18 | spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } 19 | spec.test_files = spec.files.grep(%r{^(test|spec|features)/}) 20 | spec.require_paths = ["lib"] 21 | 22 | spec.add_dependency 'rails', '>= 3.1' 23 | spec.add_dependency 'hashie', '>= 2.0.0' 24 | end 25 | -------------------------------------------------------------------------------- /spec/galleria_snippet.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 8 | 9 | 10 | 13 | 14 | 15 | 17 | 18 | 19 | 21 | 22 | 23 | 26 | 27 | 28 | 31 | 32 | 33 | 35 | 36 | 37 | 40 | 41 | 42 | 43 | 44 |
45 | 46 | 55 | -------------------------------------------------------------------------------- /spec/galleria_snippet.html.haml: -------------------------------------------------------------------------------- 1 | #galleria 2 | %a{href: "http://upload.wikimedia.org/wikipedia/commons/thumb/3/34/Locomotives-Roundhouse2.jpg/800px-Locomotives-Roundhouse2.jpg"} 3 | = image_tag "http://upload.wikimedia.org/wikipedia/commons/thumb/3/34/Locomotives-Roundhouse2.jpg/100px-Locomotives-Roundhouse2.jpg", :"data-title" => "Locomotives Roundhouse", :"data-description" => "Steam locomotives of the Chicago & North Western Railway." 4 | 5 | // Load the classic theme 6 | Galleria.loadTheme('gallery/galleria/classic.min.js'); 7 | 8 | // Initialize Galleria 9 | Galleria.run('#galleria'); 10 | -------------------------------------------------------------------------------- /spec/images/photo_gallery/icons/IconsByGentleface.txt: -------------------------------------------------------------------------------- 1 | http://www.gentleface.com/ -------------------------------------------------------------------------------- /spec/images/photo_gallery/icons/grid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/photo_gallery/icons/grid.png -------------------------------------------------------------------------------- /spec/images/photo_gallery/icons/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/photo_gallery/icons/loading.gif -------------------------------------------------------------------------------- /spec/images/photo_gallery/icons/next.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/photo_gallery/icons/next.png -------------------------------------------------------------------------------- /spec/images/photo_gallery/icons/next_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/photo_gallery/icons/next_thumb.png -------------------------------------------------------------------------------- /spec/images/photo_gallery/icons/pause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/photo_gallery/icons/pause.png -------------------------------------------------------------------------------- /spec/images/photo_gallery/icons/play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/photo_gallery/icons/play.png -------------------------------------------------------------------------------- /spec/images/photo_gallery/icons/prev.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/photo_gallery/icons/prev.png -------------------------------------------------------------------------------- /spec/images/photo_gallery/icons/prev_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/photo_gallery/icons/prev_thumb.png -------------------------------------------------------------------------------- /spec/images/photo_gallery/icons/up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/photo_gallery/icons/up.png -------------------------------------------------------------------------------- /spec/images/photo_gallery/images/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/photo_gallery/images/1.jpg -------------------------------------------------------------------------------- /spec/images/photo_gallery/images/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/photo_gallery/images/10.jpg -------------------------------------------------------------------------------- /spec/images/photo_gallery/images/11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/photo_gallery/images/11.jpg -------------------------------------------------------------------------------- /spec/images/photo_gallery/images/12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/photo_gallery/images/12.jpg -------------------------------------------------------------------------------- /spec/images/photo_gallery/images/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/photo_gallery/images/2.jpg -------------------------------------------------------------------------------- /spec/images/photo_gallery/images/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/photo_gallery/images/3.jpg -------------------------------------------------------------------------------- /spec/images/photo_gallery/images/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/photo_gallery/images/4.jpg -------------------------------------------------------------------------------- /spec/images/photo_gallery/images/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/photo_gallery/images/5.jpg -------------------------------------------------------------------------------- /spec/images/photo_gallery/images/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/photo_gallery/images/6.jpg -------------------------------------------------------------------------------- /spec/images/photo_gallery/images/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/photo_gallery/images/7.jpg -------------------------------------------------------------------------------- /spec/images/photo_gallery/images/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/photo_gallery/images/8.jpg -------------------------------------------------------------------------------- /spec/images/photo_gallery/images/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/photo_gallery/images/9.jpg -------------------------------------------------------------------------------- /spec/images/photo_gallery/images/ImagesByTibchris.txt: -------------------------------------------------------------------------------- 1 | tibchris Photostream on Flickr: 2 | 3 | http://www.flickr.com/photos/arcticpuppy/ 4 | -------------------------------------------------------------------------------- /spec/images/photo_gallery/images/thumbs/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/photo_gallery/images/thumbs/1.jpg -------------------------------------------------------------------------------- /spec/images/photo_gallery/images/thumbs/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/photo_gallery/images/thumbs/10.jpg -------------------------------------------------------------------------------- /spec/images/photo_gallery/images/thumbs/11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/photo_gallery/images/thumbs/11.jpg -------------------------------------------------------------------------------- /spec/images/photo_gallery/images/thumbs/12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/photo_gallery/images/thumbs/12.jpg -------------------------------------------------------------------------------- /spec/images/photo_gallery/images/thumbs/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/photo_gallery/images/thumbs/2.jpg -------------------------------------------------------------------------------- /spec/images/photo_gallery/images/thumbs/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/photo_gallery/images/thumbs/3.jpg -------------------------------------------------------------------------------- /spec/images/photo_gallery/images/thumbs/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/photo_gallery/images/thumbs/4.jpg -------------------------------------------------------------------------------- /spec/images/photo_gallery/images/thumbs/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/photo_gallery/images/thumbs/5.jpg -------------------------------------------------------------------------------- /spec/images/photo_gallery/images/thumbs/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/photo_gallery/images/thumbs/6.jpg -------------------------------------------------------------------------------- /spec/images/photo_gallery/images/thumbs/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/photo_gallery/images/thumbs/7.jpg -------------------------------------------------------------------------------- /spec/images/photo_gallery/images/thumbs/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/photo_gallery/images/thumbs/8.jpg -------------------------------------------------------------------------------- /spec/images/photo_gallery/images/thumbs/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/photo_gallery/images/thumbs/9.jpg -------------------------------------------------------------------------------- /spec/images/property/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/property/1.jpg -------------------------------------------------------------------------------- /spec/images/property/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/property/2.jpg -------------------------------------------------------------------------------- /spec/images/property/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/property/3.jpg -------------------------------------------------------------------------------- /spec/images/property/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/property/4.jpg -------------------------------------------------------------------------------- /spec/images/property/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/property/5.jpg -------------------------------------------------------------------------------- /spec/images/property/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/property/6.jpg -------------------------------------------------------------------------------- /spec/images/property/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/property/7.jpg -------------------------------------------------------------------------------- /spec/images/property/ads/ad1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/property/ads/ad1.jpg -------------------------------------------------------------------------------- /spec/images/property/ads/ad2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/property/ads/ad2.jpg -------------------------------------------------------------------------------- /spec/images/property/ads/ad3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/property/ads/ad3.jpg -------------------------------------------------------------------------------- /spec/images/property/thumbs/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/property/thumbs/1.jpg -------------------------------------------------------------------------------- /spec/images/property/thumbs/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/property/thumbs/2.jpg -------------------------------------------------------------------------------- /spec/images/property/thumbs/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/property/thumbs/3.jpg -------------------------------------------------------------------------------- /spec/images/property/thumbs/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/property/thumbs/4.jpg -------------------------------------------------------------------------------- /spec/images/property/thumbs/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/property/thumbs/5.jpg -------------------------------------------------------------------------------- /spec/images/property/thumbs/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/property/thumbs/6.jpg -------------------------------------------------------------------------------- /spec/images/property/thumbs/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/property/thumbs/7.jpg -------------------------------------------------------------------------------- /spec/images/responsive-gallery/icons/ajax-loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/icons/ajax-loader.gif -------------------------------------------------------------------------------- /spec/images/responsive-gallery/icons/black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/icons/black.png -------------------------------------------------------------------------------- /spec/images/responsive-gallery/icons/nav.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/icons/nav.png -------------------------------------------------------------------------------- /spec/images/responsive-gallery/icons/nav_thumbs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/icons/nav_thumbs.png -------------------------------------------------------------------------------- /spec/images/responsive-gallery/icons/pattern.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/icons/pattern.png -------------------------------------------------------------------------------- /spec/images/responsive-gallery/icons/views.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/icons/views.png -------------------------------------------------------------------------------- /spec/images/responsive-gallery/images/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/images/1.jpg -------------------------------------------------------------------------------- /spec/images/responsive-gallery/images/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/images/10.jpg -------------------------------------------------------------------------------- /spec/images/responsive-gallery/images/11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/images/11.jpg -------------------------------------------------------------------------------- /spec/images/responsive-gallery/images/12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/images/12.jpg -------------------------------------------------------------------------------- /spec/images/responsive-gallery/images/13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/images/13.jpg -------------------------------------------------------------------------------- /spec/images/responsive-gallery/images/14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/images/14.jpg -------------------------------------------------------------------------------- /spec/images/responsive-gallery/images/15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/images/15.jpg -------------------------------------------------------------------------------- /spec/images/responsive-gallery/images/16.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/images/16.jpg -------------------------------------------------------------------------------- /spec/images/responsive-gallery/images/17.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/images/17.jpg -------------------------------------------------------------------------------- /spec/images/responsive-gallery/images/18.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/images/18.jpg -------------------------------------------------------------------------------- /spec/images/responsive-gallery/images/19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/images/19.jpg -------------------------------------------------------------------------------- /spec/images/responsive-gallery/images/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/images/2.jpg -------------------------------------------------------------------------------- /spec/images/responsive-gallery/images/20.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/images/20.jpg -------------------------------------------------------------------------------- /spec/images/responsive-gallery/images/21.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/images/21.jpg -------------------------------------------------------------------------------- /spec/images/responsive-gallery/images/22.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/images/22.jpg -------------------------------------------------------------------------------- /spec/images/responsive-gallery/images/23.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/images/23.jpg -------------------------------------------------------------------------------- /spec/images/responsive-gallery/images/24.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/images/24.jpg -------------------------------------------------------------------------------- /spec/images/responsive-gallery/images/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/images/3.jpg -------------------------------------------------------------------------------- /spec/images/responsive-gallery/images/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/images/4.jpg -------------------------------------------------------------------------------- /spec/images/responsive-gallery/images/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/images/5.jpg -------------------------------------------------------------------------------- /spec/images/responsive-gallery/images/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/images/6.jpg -------------------------------------------------------------------------------- /spec/images/responsive-gallery/images/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/images/7.jpg -------------------------------------------------------------------------------- /spec/images/responsive-gallery/images/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/images/8.jpg -------------------------------------------------------------------------------- /spec/images/responsive-gallery/images/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/images/9.jpg -------------------------------------------------------------------------------- /spec/images/responsive-gallery/images/thumbs/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/images/thumbs/1.jpg -------------------------------------------------------------------------------- /spec/images/responsive-gallery/images/thumbs/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/images/thumbs/10.jpg -------------------------------------------------------------------------------- /spec/images/responsive-gallery/images/thumbs/11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/images/thumbs/11.jpg -------------------------------------------------------------------------------- /spec/images/responsive-gallery/images/thumbs/12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/images/thumbs/12.jpg -------------------------------------------------------------------------------- /spec/images/responsive-gallery/images/thumbs/13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/images/thumbs/13.jpg -------------------------------------------------------------------------------- /spec/images/responsive-gallery/images/thumbs/14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/images/thumbs/14.jpg -------------------------------------------------------------------------------- /spec/images/responsive-gallery/images/thumbs/15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/images/thumbs/15.jpg -------------------------------------------------------------------------------- /spec/images/responsive-gallery/images/thumbs/16.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/images/thumbs/16.jpg -------------------------------------------------------------------------------- /spec/images/responsive-gallery/images/thumbs/17.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/images/thumbs/17.jpg -------------------------------------------------------------------------------- /spec/images/responsive-gallery/images/thumbs/18.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/images/thumbs/18.jpg -------------------------------------------------------------------------------- /spec/images/responsive-gallery/images/thumbs/19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/images/thumbs/19.jpg -------------------------------------------------------------------------------- /spec/images/responsive-gallery/images/thumbs/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/images/thumbs/2.jpg -------------------------------------------------------------------------------- /spec/images/responsive-gallery/images/thumbs/20.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/images/thumbs/20.jpg -------------------------------------------------------------------------------- /spec/images/responsive-gallery/images/thumbs/21.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/images/thumbs/21.jpg -------------------------------------------------------------------------------- /spec/images/responsive-gallery/images/thumbs/22.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/images/thumbs/22.jpg -------------------------------------------------------------------------------- /spec/images/responsive-gallery/images/thumbs/23.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/images/thumbs/23.jpg -------------------------------------------------------------------------------- /spec/images/responsive-gallery/images/thumbs/24.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/images/thumbs/24.jpg -------------------------------------------------------------------------------- /spec/images/responsive-gallery/images/thumbs/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/images/thumbs/3.jpg -------------------------------------------------------------------------------- /spec/images/responsive-gallery/images/thumbs/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/images/thumbs/4.jpg -------------------------------------------------------------------------------- /spec/images/responsive-gallery/images/thumbs/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/images/thumbs/5.jpg -------------------------------------------------------------------------------- /spec/images/responsive-gallery/images/thumbs/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/images/thumbs/6.jpg -------------------------------------------------------------------------------- /spec/images/responsive-gallery/images/thumbs/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/images/thumbs/7.jpg -------------------------------------------------------------------------------- /spec/images/responsive-gallery/images/thumbs/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/images/thumbs/8.jpg -------------------------------------------------------------------------------- /spec/images/responsive-gallery/images/thumbs/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/spec/images/responsive-gallery/images/thumbs/9.jpg -------------------------------------------------------------------------------- /spec/rails-gallery/view_helper_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | class NoPathPhoto < RGallery::Photo 4 | def path 5 | nil 6 | end 7 | end 8 | 9 | class BadFilenamePhoto < RGallery::Photo 10 | def title 11 | 'my title' 12 | end 13 | 14 | # blip method unknown! 15 | def filename 16 | blip 17 | end 18 | end 19 | 20 | class NoTitlePhoto < RGallery::Photo 21 | def path 22 | 'abc' 23 | end 24 | 25 | def title 26 | nil 27 | end 28 | end 29 | 30 | class ValidPhoto < RGallery::Photo 31 | def path 32 | 'abc' 33 | end 34 | 35 | def title 36 | 'sdgds' 37 | end 38 | end 39 | 40 | describe RailsGallery::ConfigurationError do 41 | specify { RailsGallery::ConfigurationError.new.should be_a StandardError } 42 | end 43 | 44 | describe RailsGallery::ViewHelper do 45 | include ControllerTestHelpers, 46 | RailsGallery::ViewHelper 47 | 48 | let(:no_path_photo) { NoPathPhoto.new 1 } 49 | let(:no_title_photo) { NoTitlePhoto.new 2 } 50 | let(:bad_filename_photo) { BadFilenamePhoto.new 2 } 51 | let(:valid_photo) { ValidPhoto.new 2 } 52 | 53 | describe 'validate_gallery_photo! photo' do 54 | it 'should raise error on nil' do 55 | expect { validate_gallery_photo!(nil) }.to raise_error(ArgumentError) 56 | end 57 | 58 | it 'should raise error on no #path method' do 59 | expect { validate_gallery_photo!(no_path_photo) }.to raise_error(ArgumentError) 60 | end 61 | 62 | it 'should raise error on no #title method' do 63 | expect { validate_gallery_photo!(no_title_photo) }.to raise_error(ArgumentError) 64 | end 65 | 66 | it 'should raise error on bad filename method' do 67 | expect { validate_gallery_photo!(bad_filename_photo) }.to raise_error(::RailsGallery::ConfigurationError) 68 | end 69 | end 70 | 71 | describe 'validate_gallery_photo photo' do 72 | it 'should return nil error msg' do 73 | validate_gallery_photo(nil).should == "Photo must be a kind of RGallery::Photo, was: " 74 | end 75 | 76 | it 'should return no path error msg' do 77 | validate_gallery_photo(no_path_photo).should match /Photo must have a path:/ 78 | end 79 | 80 | it 'should return no title error msg' do 81 | validate_gallery_photo(no_title_photo).should match /Photo must have a title:/ 82 | end 83 | 84 | it 'should return bad filename method error' do 85 | validate_gallery_photo(bad_filename_photo).should match /filename or file_path could not be resolved for:/ 86 | end 87 | end 88 | 89 | describe 'gallery_image photo' do 90 | it 'should raise error on nil' do 91 | expect { gallery_image(nil) }.to raise_error(ArgumentError) 92 | end 93 | 94 | it 'should return error if valid type but nil photo' do 95 | expect { gallery_image(:galleria, nil) }.to raise_error(ArgumentError) 96 | end 97 | 98 | it 'should return error if invalid type and valid photo' do 99 | expect { gallery_image(:invalid, valid_photo) }.to raise_error(ArgumentError) 100 | end 101 | 102 | it "should no raise error for galleria image" do 103 | expect { gallery_image(:galleria, valid_photo) }.to_not raise_error 104 | end 105 | 106 | it "should render the image for galleria image" do 107 | gallery_image(:galleria, valid_photo).should == "" 108 | end 109 | 110 | %w{slideshow responsive}.each do |gallery_type| 111 | it "should not raise error for type: #{gallery_type}" do 112 | expect { gallery_image(gallery_type, valid_photo) }.to_not raise_error 113 | end 114 | 115 | it "should render the image for galleria image" do 116 | gallery_image(gallery_type, valid_photo).should match /img.*alt=.*src="\w+"/ 117 | end 118 | end 119 | end 120 | end -------------------------------------------------------------------------------- /spec/rgallery/photos_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | require 'rgallery/property_photo' 3 | 4 | describe RGallery::Photos do 5 | context 'New empty RGallery::Photos collection' do 6 | subject { RGallery::Photos.new } 7 | 8 | its(:pages) { should be_empty } 9 | its(:pages) { should be_a RGallery::Pages } 10 | 11 | describe '.page :first' do 12 | specify { subject.page(:first).should be_empty } 13 | end 14 | 15 | describe '.page :remainder' do 16 | specify { subject.pages.remainder.should be_empty } 17 | end 18 | end 19 | 20 | context 'Photos with one page' do 21 | subject { RGallery::Photos.new ['0'] } 22 | 23 | its(:pages) { should_not be_empty } 24 | its(:pages) { should be_a RGallery::Pages } 25 | 26 | describe '.page' do 27 | describe ':first' do 28 | specify { subject.page(:first).should_not be_empty } 29 | end 30 | 31 | describe ':remainder' do 32 | specify { subject.pages.remainder.should be_empty } 33 | end 34 | end 35 | 36 | describe '.all' do 37 | specify { subject.all.first.should be_a RGallery::Photo } 38 | 39 | specify { subject.all.first.id.should == '0' } 40 | 41 | specify { subject.all.first.path.should == '0.png' } 42 | end 43 | end 44 | 45 | context 'configure with custom Photo class' do 46 | subject { RGallery::Photos.new ['0'], photo_class: Property::Photo } 47 | 48 | specify { subject.all.first.should be_a Property::Photo } 49 | end 50 | end -------------------------------------------------------------------------------- /spec/rgallery/property_photo.rb: -------------------------------------------------------------------------------- 1 | class Property 2 | class Photo < RGallery::Photo 3 | def path 4 | File.join folder, super 5 | end 6 | 7 | # mogrify -path fullpathto/temp2 -resize 60x60% -quality 60 -format jpg *.png 8 | 9 | # this will take all png files in your current directory (temp), 10 | # resize to 60% (of largest dimension and keep aspect ratio), 11 | # set jpg quality to 60 and convert to jpg. 12 | def thumb 13 | File.join folder, 'thumbs', file_path 14 | end 15 | 16 | def folder 17 | 'responsive-gallery/images' 18 | end 19 | 20 | def title 21 | 'property title' 22 | end 23 | 24 | def alt 25 | 'property alt' 26 | end 27 | 28 | def self.extension 29 | :jpg 30 | end 31 | end 32 | end -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | require 'rubygems' 3 | require 'rails' 4 | require 'json' 5 | require 'active_support' 6 | require 'action_pack' 7 | require 'action_view' 8 | require 'action_controller' 9 | require 'action_view/template' 10 | 11 | require 'rspec' 12 | require 'rails-gallery' 13 | 14 | RSpec.configure do |config| 15 | 16 | end 17 | 18 | module ControllerTestHelpers 19 | 20 | def self.included(base) 21 | base.class_eval do 22 | 23 | include ActionView::Helpers, 24 | ActionView::Helpers::CaptureHelper, 25 | ActionView::Helpers::JavaScriptHelper, 26 | ActionView::Helpers::AssetTagHelper 27 | 28 | # allow tabs.create to run by stubbing an output_buffer 29 | attr_accessor :output_buffer 30 | @output_buffer = "" 31 | 32 | # stub content_for for testing 33 | def content_for(name, content = nil, &block) 34 | # this doesn't exist, and causes errors 35 | @_content_for = {} unless defined? @_content_for 36 | # we've got to initialize this, so we can concat to it 37 | @_content_for[name] = '' if @_content_for[name].nil? 38 | # now the rest is the same as in rails 39 | content = capture(&block) if block_given? 40 | @_content_for[name] << content if content 41 | @_content_for[name] unless content 42 | end 43 | 44 | def image_tag src, options = {} 45 | content_tag :img, nil, options.merge(src: src) 46 | end 47 | end 48 | end 49 | 50 | end 51 | -------------------------------------------------------------------------------- /vendor/assets/images/gallery/galleria/classic/loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/vendor/assets/images/gallery/galleria/classic/loader.gif -------------------------------------------------------------------------------- /vendor/assets/images/gallery/galleria/classic/map.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/vendor/assets/images/gallery/galleria/classic/map.png -------------------------------------------------------------------------------- /vendor/assets/images/gallery/responsive/icons/ajax-loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/vendor/assets/images/gallery/responsive/icons/ajax-loader.gif -------------------------------------------------------------------------------- /vendor/assets/images/gallery/responsive/icons/black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/vendor/assets/images/gallery/responsive/icons/black.png -------------------------------------------------------------------------------- /vendor/assets/images/gallery/responsive/icons/nav.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/vendor/assets/images/gallery/responsive/icons/nav.png -------------------------------------------------------------------------------- /vendor/assets/images/gallery/responsive/icons/nav_thumbs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/vendor/assets/images/gallery/responsive/icons/nav_thumbs.png -------------------------------------------------------------------------------- /vendor/assets/images/gallery/responsive/icons/pattern.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/vendor/assets/images/gallery/responsive/icons/pattern.png -------------------------------------------------------------------------------- /vendor/assets/images/gallery/responsive/icons/views.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/vendor/assets/images/gallery/responsive/icons/views.png -------------------------------------------------------------------------------- /vendor/assets/images/gallery/slideshow/icons/grid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/vendor/assets/images/gallery/slideshow/icons/grid.png -------------------------------------------------------------------------------- /vendor/assets/images/gallery/slideshow/icons/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/vendor/assets/images/gallery/slideshow/icons/loading.gif -------------------------------------------------------------------------------- /vendor/assets/images/gallery/slideshow/icons/next.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/vendor/assets/images/gallery/slideshow/icons/next.png -------------------------------------------------------------------------------- /vendor/assets/images/gallery/slideshow/icons/next_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/vendor/assets/images/gallery/slideshow/icons/next_thumb.png -------------------------------------------------------------------------------- /vendor/assets/images/gallery/slideshow/icons/pause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/vendor/assets/images/gallery/slideshow/icons/pause.png -------------------------------------------------------------------------------- /vendor/assets/images/gallery/slideshow/icons/play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/vendor/assets/images/gallery/slideshow/icons/play.png -------------------------------------------------------------------------------- /vendor/assets/images/gallery/slideshow/icons/prev.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/vendor/assets/images/gallery/slideshow/icons/prev.png -------------------------------------------------------------------------------- /vendor/assets/images/gallery/slideshow/icons/prev_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/vendor/assets/images/gallery/slideshow/icons/prev_thumb.png -------------------------------------------------------------------------------- /vendor/assets/images/gallery/slideshow/icons/up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/vendor/assets/images/gallery/slideshow/icons/up.png -------------------------------------------------------------------------------- /vendor/assets/images/gallery/touch_touch/arrows.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/vendor/assets/images/gallery/touch_touch/arrows.png -------------------------------------------------------------------------------- /vendor/assets/images/gallery/touch_touch/preloader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kristianmandrup/rails-gallery/cf02ca751ad1e51ed2f4b370baf4e34601c6f897/vendor/assets/images/gallery/touch_touch/preloader.gif -------------------------------------------------------------------------------- /vendor/assets/javascripts/gallery/galleria/classic.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Galleria Classic Theme 2012-08-08 3 | * http://galleria.io 4 | * 5 | * Licensed under the MIT license 6 | * https://raw.github.com/aino/galleria/master/LICENSE 7 | * 8 | */ 9 | 10 | (function($) { 11 | 12 | /*global jQuery, Galleria */ 13 | 14 | Galleria.addTheme({ 15 | name: 'classic', 16 | author: 'Galleria', 17 | css: 'classic.css', 18 | defaults: { 19 | transition: 'slide', 20 | thumbCrop: 'height', 21 | 22 | // set this to false if you want to show the caption all the time: 23 | _toggleInfo: true 24 | }, 25 | init: function(options) { 26 | 27 | Galleria.requires(1.28, 'This version of Classic theme requires Galleria 1.2.8 or later'); 28 | 29 | // add some elements 30 | this.addElement('info-link','info-close'); 31 | this.append({ 32 | 'info' : ['info-link','info-close'] 33 | }); 34 | 35 | // cache some stuff 36 | var info = this.$('info-link,info-close,info-text'), 37 | touch = Galleria.TOUCH, 38 | click = touch ? 'touchstart' : 'click'; 39 | 40 | // show loader & counter with opacity 41 | this.$('loader,counter').show().css('opacity', 0.4); 42 | 43 | // some stuff for non-touch browsers 44 | if (! touch ) { 45 | this.addIdleState( this.get('image-nav-left'), { left:-50 }); 46 | this.addIdleState( this.get('image-nav-right'), { right:-50 }); 47 | this.addIdleState( this.get('counter'), { opacity:0 }); 48 | } 49 | 50 | // toggle info 51 | if ( options._toggleInfo === true ) { 52 | info.bind( click, function() { 53 | info.toggle(); 54 | }); 55 | } else { 56 | info.show(); 57 | this.$('info-link, info-close').hide(); 58 | } 59 | 60 | // bind some stuff 61 | this.bind('thumbnail', function(e) { 62 | 63 | if (! touch ) { 64 | // fade thumbnails 65 | $(e.thumbTarget).css('opacity', 0.6).parent().hover(function() { 66 | $(this).not('.active').children().stop().fadeTo(100, 1); 67 | }, function() { 68 | $(this).not('.active').children().stop().fadeTo(400, 0.6); 69 | }); 70 | 71 | if ( e.index === this.getIndex() ) { 72 | $(e.thumbTarget).css('opacity',1); 73 | } 74 | } else { 75 | $(e.thumbTarget).css('opacity', this.getIndex() ? 1 : 0.6); 76 | } 77 | }); 78 | 79 | this.bind('loadstart', function(e) { 80 | if (!e.cached) { 81 | this.$('loader').show().fadeTo(200, 0.4); 82 | } 83 | 84 | this.$('info').toggle( this.hasInfo() ); 85 | 86 | $(e.thumbTarget).css('opacity',1).parent().siblings().children().css('opacity', 0.6); 87 | }); 88 | 89 | this.bind('loadfinish', function(e) { 90 | this.$('loader').fadeOut(200); 91 | }); 92 | } 93 | }); 94 | 95 | }(jQuery)); 96 | -------------------------------------------------------------------------------- /vendor/assets/javascripts/gallery/galleria/classic.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Galleria Classic Theme 2012-08-08 3 | * http://galleria.io 4 | * 5 | * Licensed under the MIT license 6 | * https://raw.github.com/aino/galleria/master/LICENSE 7 | * 8 | */(function(a){Galleria.addTheme({name:"classic",author:"Galleria",css:'classic.css',defaults:{transition:"slide",thumbCrop:"height",_toggleInfo:!0},init:function(b){Galleria.requires(1.28,"This version of Classic theme requires Galleria 1.2.8 or later"),this.addElement("info-link","info-close"),this.append({info:["info-link","info-close"]});var c=this.$("info-link,info-close,info-text"),d=Galleria.TOUCH,e=d?"touchstart":"click";this.$("loader,counter").show().css("opacity",.4),d||(this.addIdleState(this.get("image-nav-left"),{left:-50}),this.addIdleState(this.get("image-nav-right"),{right:-50}),this.addIdleState(this.get("counter"),{opacity:0})),b._toggleInfo===!0?c.bind(e,function(){c.toggle()}):(c.show(),this.$("info-link, info-close").hide()),this.bind("thumbnail",function(b){d?a(b.thumbTarget).css("opacity",this.getIndex()?1:.6):(a(b.thumbTarget).css("opacity",.6).parent().hover(function(){a(this).not(".active").children().stop().fadeTo(100,1)},function(){a(this).not(".active").children().stop().fadeTo(400,.6)}),b.index===this.getIndex()&&a(b.thumbTarget).css("opacity",1))}),this.bind("loadstart",function(b){b.cached||this.$("loader").show().fadeTo(200,.4),this.$("info").toggle(this.hasInfo()),a(b.thumbTarget).css("opacity",1).parent().siblings().children().css("opacity",.6)}),this.bind("loadfinish",function(a){this.$("loader").fadeOut(200)})}})})(jQuery); -------------------------------------------------------------------------------- /vendor/assets/javascripts/gallery/responsive.js: -------------------------------------------------------------------------------- 1 | $(function() { 2 | // ======================= imagesLoaded Plugin =============================== 3 | // https://github.com/desandro/imagesloaded 4 | 5 | // $('#my-container').imagesLoaded(myFunction) 6 | // execute a callback when all images have loaded. 7 | // needed because .load() doesn't work on cached images 8 | 9 | // callback function gets image collection as argument 10 | // this is the container 11 | 12 | // original: mit license. paul irish. 2010. 13 | // contributors: Oren Solomianik, David DeSandro, Yiannis Chatzikonstantinou 14 | 15 | $.fn.imagesLoaded = function( callback ) { 16 | var $images = this.find('img'), 17 | len = $images.length, 18 | _this = this, 19 | blank = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw=='; 20 | 21 | function triggerCallback() { 22 | callback.call( _this, $images ); 23 | } 24 | 25 | function imgLoaded() { 26 | if ( --len <= 0 && this.src !== blank ){ 27 | setTimeout( triggerCallback ); 28 | $images.off( 'load error', imgLoaded ); 29 | } 30 | } 31 | 32 | if ( !len ) { 33 | triggerCallback(); 34 | } 35 | 36 | $images.on( 'load error', imgLoaded ).each( function() { 37 | // cached images don't fire load sometimes, so we reset src. 38 | if (this.complete || this.complete === undefined){ 39 | var src = this.src; 40 | // webkit hack from http://groups.google.com/group/jquery-dev/browse_thread/thread/eee6ab7b2da50e1f 41 | // data uri bypasses webkit log warning (thx doug jones) 42 | this.src = blank; 43 | this.src = src; 44 | } 45 | }); 46 | 47 | return this; 48 | }; 49 | 50 | // gallery container 51 | var $rgGallery = $('#rg-gallery'), 52 | // carousel container 53 | $esCarousel = $rgGallery.find('div.es-carousel-wrapper'), 54 | // the carousel items 55 | $items = $esCarousel.find('ul > li'), 56 | // total number of items 57 | itemsCount = $items.length; 58 | 59 | Gallery = (function() { 60 | // index of the current item 61 | var current = 0, 62 | // mode : carousel || fullview 63 | mode = 'carousel', 64 | // control if one image is being loaded 65 | anim = false, 66 | init = function(config) { 67 | 68 | // (not necessary) preloading the images here... 69 | $items.add('').imagesLoaded( function() { 70 | // add options 71 | _addViewModes(); 72 | 73 | // add large image wrapper 74 | _addImageWrapper(); 75 | 76 | // show first image 77 | _showImage( $items.eq( current ) ); 78 | 79 | }); 80 | 81 | // initialize the carousel 82 | if( mode === 'carousel' ) 83 | _initCarousel(); 84 | 85 | }, 86 | _initCarousel = function() { 87 | 88 | // we are using the elastislide plugin: 89 | // http://tympanus.net/codrops/2011/09/12/elastislide-responsive-carousel/ 90 | $esCarousel.show().elastislide({ 91 | imageW : 65, 92 | onClick : function( $item ) { 93 | if( anim ) return false; 94 | anim = true; 95 | // on click show image 96 | _showImage($item); 97 | // change current 98 | current = $item.index(); 99 | } 100 | }); 101 | 102 | // set elastislide's current to current 103 | $esCarousel.elastislide( 'setCurrent', current ); 104 | 105 | }, 106 | _addViewModes = function() { 107 | 108 | // top right buttons: hide / show carousel 109 | 110 | var $viewfull = $(''), 111 | $viewthumbs = $(''); 112 | 113 | $rgGallery.prepend( $('
').append( $viewfull ).append( $viewthumbs ) ); 114 | 115 | $viewfull.on('click.rgGallery', function( event ) { 116 | if( mode === 'carousel' ) 117 | $esCarousel.elastislide( 'destroy' ); 118 | $esCarousel.hide(); 119 | $viewfull.addClass('rg-view-selected'); 120 | $viewthumbs.removeClass('rg-view-selected'); 121 | mode = 'fullview'; 122 | return false; 123 | }); 124 | 125 | $viewthumbs.on('click.rgGallery', function( event ) { 126 | _initCarousel(); 127 | $viewthumbs.addClass('rg-view-selected'); 128 | $viewfull.removeClass('rg-view-selected'); 129 | mode = 'carousel'; 130 | return false; 131 | }); 132 | 133 | if( mode === 'fullview' ) 134 | $viewfull.trigger('click'); 135 | 136 | }, 137 | _addImageWrapper= function() { 138 | 139 | try { 140 | // adds the structure for the large image and the navigation buttons (if total items > 1) 141 | // also initializes the navigation events 142 | $('#img-wrapper-tmpl').tmpl( {itemsCount : itemsCount} ).prependTo( $rgGallery ); 143 | } catch(e) { 144 | return; 145 | } 146 | 147 | // $('#img-wrapper-tmpl').tmpl( {itemsCount : itemsCount} ).appendTo( $rgGallery ); 148 | 149 | if( itemsCount > 1 ) { 150 | // addNavigation 151 | var $navPrev = $rgGallery.find('a.rg-image-nav-prev'), 152 | $navNext = $rgGallery.find('a.rg-image-nav-next'), 153 | $imgWrapper = $rgGallery.find('div.rg-image'); 154 | 155 | $navPrev.on('click.rgGallery', function( event ) { 156 | _navigate( 'left' ); 157 | return false; 158 | }); 159 | 160 | $navNext.on('click.rgGallery', function( event ) { 161 | _navigate( 'right' ); 162 | return false; 163 | }); 164 | 165 | // add touchwipe events on the large image wrapper 166 | $imgWrapper.touchwipe({ 167 | wipeLeft : function() { 168 | _navigate( 'right' ); 169 | }, 170 | wipeRight : function() { 171 | _navigate( 'left' ); 172 | }, 173 | preventDefaultEvents: false 174 | }); 175 | 176 | $(document).on('keyup.rgGallery', function( event ) { 177 | if (event.keyCode == 39) 178 | _navigate( 'right' ); 179 | else if (event.keyCode == 37) 180 | _navigate( 'left' ); 181 | }); 182 | 183 | } 184 | 185 | }, 186 | _navigate = function( dir ) { 187 | 188 | // navigate through the large images 189 | 190 | if( anim ) return false; 191 | anim = true; 192 | 193 | if( dir === 'right' ) { 194 | if( current + 1 >= itemsCount ) 195 | current = 0; 196 | else 197 | ++current; 198 | } 199 | else if( dir === 'left' ) { 200 | if( current - 1 < 0 ) 201 | current = itemsCount - 1; 202 | else 203 | --current; 204 | } 205 | 206 | _showImage( $items.eq( current ) ); 207 | 208 | }, 209 | _showImage = function( $item ) { 210 | 211 | // shows the large image that is associated to the $item 212 | 213 | var $loader = $rgGallery.find('div.rg-loading').show(); 214 | 215 | $items.removeClass('selected'); 216 | $item.addClass('selected'); 217 | 218 | var $thumb = $item.find('img'), 219 | largesrc = $thumb.data('large'), 220 | title = $thumb.data('description'); 221 | 222 | $('').load( function() { 223 | 224 | $rgGallery.find('div.rg-image').empty().append(''); 225 | 226 | if( title ) 227 | $rgGallery.find('div.rg-caption').show().children('p').empty().text( title ); 228 | 229 | $loader.hide(); 230 | 231 | if( mode === 'carousel' ) { 232 | $esCarousel.elastislide( 'reload' ); 233 | $esCarousel.elastislide( 'setCurrent', current ); 234 | } 235 | 236 | anim = false; 237 | 238 | }).attr( 'src', largesrc ); 239 | 240 | }, 241 | addItems = function( $new ) { 242 | 243 | $esCarousel.find('ul').append($new); 244 | $items = $items.add( $($new) ); 245 | itemsCount = $items.length; 246 | $esCarousel.elastislide( 'add', $new ); 247 | 248 | }; 249 | 250 | return { 251 | init : init, 252 | addItems : addItems 253 | }; 254 | 255 | })(); 256 | 257 | Gallery.init(); 258 | 259 | /* 260 | Example to add more items to the gallery: 261 | 262 | var $new = $('
  • image01
  • '); 263 | Gallery.addItems( $new ); 264 | */ 265 | }); -------------------------------------------------------------------------------- /vendor/assets/javascripts/gallery/slideshow.js: -------------------------------------------------------------------------------- 1 | $(function() { 2 | /** 3 | * interval : time between the display of images 4 | * playtime : the timeout for the setInterval function 5 | * current : number to control the current image 6 | * current_thumb : the index of the current thumbs wrapper 7 | * nmb_thumb_wrappers : total number of thumbs wrappers 8 | * nmb_images_wrapper : the number of images inside of each wrapper 9 | */ 10 | var interval = 4000; 11 | var playtime; 12 | var current = 0; 13 | var current_thumb = 0; 14 | var nmb_thumb_wrappers = $('#msg_thumbs .msg_thumb_wrapper').length; 15 | var nmb_images_wrapper = 6; 16 | /** 17 | * start the slideshow 18 | */ 19 | play(); 20 | 21 | /** 22 | * show the controls when 23 | * mouseover the main container 24 | */ 25 | slideshowMouseEvent(); 26 | function slideshowMouseEvent(){ 27 | $('#msg_slideshow').unbind('mouseenter') 28 | .bind('mouseenter',showControls) 29 | .andSelf() 30 | .unbind('mouseleave') 31 | .bind('mouseleave',hideControls); 32 | } 33 | 34 | /** 35 | * clicking the grid icon, 36 | * shows the thumbs view, pauses the slideshow, and hides the controls 37 | */ 38 | $('#msg_grid').bind('click',function(e){ 39 | hideControls(); 40 | $('#msg_slideshow').unbind('mouseenter').unbind('mouseleave'); 41 | pause(); 42 | $('#msg_thumbs').stop().animate({'top':'0px'},500); 43 | e.preventDefault(); 44 | }); 45 | 46 | /** 47 | * closing the thumbs view, 48 | * shows the controls 49 | */ 50 | $('#msg_thumb_close').bind('click',function(e){ 51 | showControls(); 52 | slideshowMouseEvent(); 53 | $('#msg_thumbs').stop().animate({'top':'-230px'},500); 54 | e.preventDefault(); 55 | }); 56 | 57 | /** 58 | * pause or play icons 59 | */ 60 | $('#msg_pause_play').bind('click',function(e){ 61 | var $this = $(this); 62 | if($this.hasClass('msg_play')) 63 | play(); 64 | else 65 | pause(); 66 | e.preventDefault(); 67 | }); 68 | 69 | /** 70 | * click controls next or prev, 71 | * pauses the slideshow, 72 | * and displays the next or prevoius image 73 | */ 74 | $('#msg_next').bind('click',function(e){ 75 | pause(); 76 | next(); 77 | e.preventDefault(); 78 | }); 79 | $('#msg_prev').bind('click',function(e){ 80 | pause(); 81 | prev(); 82 | e.preventDefault(); 83 | }); 84 | 85 | /** 86 | * show and hide controls functions 87 | */ 88 | function showControls(){ 89 | $('#msg_controls').stop().animate({'right':'15px'},500); 90 | } 91 | function hideControls(){ 92 | $('#msg_controls').stop().animate({'right':'-110px'},500); 93 | } 94 | 95 | /** 96 | * start the slideshow 97 | */ 98 | function play(){ 99 | next(); 100 | $('#msg_pause_play').addClass('msg_pause').removeClass('msg_play'); 101 | playtime = setInterval(next,interval) 102 | } 103 | 104 | /** 105 | * stops the slideshow 106 | */ 107 | function pause(){ 108 | $('#msg_pause_play').addClass('msg_play').removeClass('msg_pause'); 109 | clearTimeout(playtime); 110 | } 111 | 112 | /** 113 | * show the next image 114 | */ 115 | function next(){ 116 | ++current; 117 | showImage('r'); 118 | } 119 | 120 | /** 121 | * shows the previous image 122 | */ 123 | function prev(){ 124 | --current; 125 | showImage('l'); 126 | } 127 | 128 | /** 129 | * shows an image 130 | * dir : right or left 131 | */ 132 | function showImage(dir){ 133 | /** 134 | * the thumbs wrapper being shown, is always 135 | * the one containing the current image 136 | */ 137 | alternateThumbs(); 138 | 139 | /** 140 | * the thumb that will be displayed in full mode 141 | */ 142 | var $thumb = $('#msg_thumbs .msg_thumb_wrapper:nth-child('+current_thumb+')') 143 | .find('a:nth-child('+ parseInt(current - nmb_images_wrapper*(current_thumb -1)) +')') 144 | .find('img'); 145 | if($thumb.length){ 146 | var source = $thumb.attr('alt'); 147 | var $currentImage = $('#msg_wrapper').find('img'); 148 | if($currentImage.length){ 149 | // console.log('image src:', source); 150 | $currentImage.fadeOut(function(){ 151 | $(this).remove(); 152 | $('').load(function(){ 153 | var $image = $(this); 154 | resize($image); 155 | $image.hide(); 156 | $('#msg_wrapper').empty().append($image.fadeIn()); 157 | }).attr('src',source); 158 | }); 159 | } 160 | else{ 161 | $('').load(function(){ 162 | var $image = $(this); 163 | resize($image); 164 | $image.hide(); 165 | // console.log('resize image src:', source); 166 | $('#msg_wrapper').empty().append($image.fadeIn()); 167 | }).attr('src',source); 168 | } 169 | 170 | } 171 | else{ //this is actually not necessary since we have a circular slideshow 172 | if(dir == 'r') 173 | --current; 174 | else if(dir == 'l') 175 | ++current; 176 | alternateThumbs(); 177 | return; 178 | } 179 | } 180 | 181 | /** 182 | * the thumbs wrapper being shown, is always 183 | * the one containing the current image 184 | */ 185 | function alternateThumbs(){ 186 | $('#msg_thumbs').find('.msg_thumb_wrapper:nth-child('+current_thumb+')') 187 | .hide(); 188 | current_thumb = Math.ceil(current/nmb_images_wrapper); 189 | /** 190 | * if we reach the end, start from the beggining 191 | */ 192 | if(current_thumb > nmb_thumb_wrappers){ 193 | current_thumb = 1; 194 | current = 1; 195 | } 196 | /** 197 | * if we are at the beggining, go to the end 198 | */ 199 | else if(current_thumb == 0){ 200 | current_thumb = nmb_thumb_wrappers; 201 | current = current_thumb*nmb_images_wrapper; 202 | } 203 | 204 | $('#msg_thumbs').find('.msg_thumb_wrapper:nth-child('+current_thumb+')') 205 | .show(); 206 | } 207 | 208 | /** 209 | * click next or previous on the thumbs wrapper 210 | */ 211 | $('#msg_thumb_next').bind('click',function(e){ 212 | next_thumb(); 213 | e.preventDefault(); 214 | }); 215 | $('#msg_thumb_prev').bind('click',function(e){ 216 | prev_thumb(); 217 | e.preventDefault(); 218 | }); 219 | function next_thumb(){ 220 | var $next_wrapper = $('#msg_thumbs').find('.msg_thumb_wrapper:nth-child('+parseInt(current_thumb+1)+')'); 221 | if($next_wrapper.length){ 222 | $('#msg_thumbs').find('.msg_thumb_wrapper:nth-child('+current_thumb+')') 223 | .fadeOut(function(){ 224 | ++current_thumb; 225 | $next_wrapper.fadeIn(); 226 | }); 227 | } 228 | } 229 | function prev_thumb(){ 230 | var $prev_wrapper = $('#msg_thumbs').find('.msg_thumb_wrapper:nth-child('+parseInt(current_thumb-1)+')'); 231 | if($prev_wrapper.length){ 232 | $('#msg_thumbs').find('.msg_thumb_wrapper:nth-child('+current_thumb+')') 233 | .fadeOut(function(){ 234 | --current_thumb; 235 | $prev_wrapper.fadeIn(); 236 | }); 237 | } 238 | } 239 | 240 | /** 241 | * clicking on a thumb, displays the image (alt attribute of the thumb) 242 | */ 243 | $('#msg_thumbs .msg_thumb_wrapper > a').bind('click',function(e){ 244 | var $this = $(this); 245 | $('#msg_thumb_close').trigger('click'); 246 | var idx = $this.index(); 247 | var p_idx = $this.parent().index(); 248 | current = parseInt(p_idx*nmb_images_wrapper + idx + 1); 249 | showImage(); 250 | e.preventDefault(); 251 | }).bind('mouseenter',function(){ 252 | var $this = $(this); 253 | $this.stop().animate({'opacity':1}); 254 | }).bind('mouseleave',function(){ 255 | var $this = $(this); 256 | $this.stop().animate({'opacity':0.5}); 257 | }); 258 | 259 | /** 260 | * resize the image to fit in the container (400 x 400) 261 | */ 262 | function resize($image){ 263 | var theImage = new Image(); 264 | theImage.src = $image.attr("src"); 265 | var imgwidth = theImage.width; 266 | var imgheight = theImage.height; 267 | 268 | var containerwidth = 400; 269 | var containerheight = 400; 270 | 271 | if(imgwidth > containerwidth){ 272 | var newwidth = containerwidth; 273 | var ratio = imgwidth / containerwidth; 274 | var newheight = imgheight / ratio; 275 | if(newheight > containerheight){ 276 | var newnewheight = containerheight; 277 | var newratio = newheight/containerheight; 278 | var newnewwidth =newwidth/newratio; 279 | theImage.width = newnewwidth; 280 | theImage.height= newnewheight; 281 | } 282 | else{ 283 | theImage.width = newwidth; 284 | theImage.height= newheight; 285 | } 286 | } 287 | else if(imgheight > containerheight){ 288 | var newheight = containerheight; 289 | var ratio = imgheight / containerheight; 290 | var newwidth = imgwidth / ratio; 291 | if(newwidth > containerwidth){ 292 | var newnewwidth = containerwidth; 293 | var newratio = newwidth/containerwidth; 294 | var newnewheight =newheight/newratio; 295 | theImage.height = newnewheight; 296 | theImage.width= newnewwidth; 297 | } 298 | else{ 299 | theImage.width = newwidth; 300 | theImage.height= newheight; 301 | } 302 | } 303 | $image.css({ 304 | 'width' :theImage.width, 305 | 'height':theImage.height 306 | }); 307 | } 308 | }); -------------------------------------------------------------------------------- /vendor/assets/javascripts/gallery/touch_touch.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @name jQuery touchTouch plugin 3 | * @author Martin Angelov 4 | * @version 1.0 5 | * @url http://tutorialzine.com/2012/04/mobile-touch-gallery/ 6 | * @license MIT License 7 | */ 8 | 9 | (function(){ 10 | 11 | /* Private variables */ 12 | 13 | var overlay = $('
    '), 14 | slider = $('
    '), 15 | prevArrow = $(''), 16 | nextArrow = $(''), 17 | overlayVisible = false; 18 | 19 | 20 | /* Creating the plugin */ 21 | 22 | $.fn.touchTouch = function(){ 23 | 24 | var placeholders = $([]), 25 | index = 0, 26 | items = this; 27 | 28 | // Appending the markup to the page 29 | overlay.hide().appendTo('body'); 30 | slider.appendTo(overlay); 31 | 32 | // Creating a placeholder for each image 33 | items.each(function(){ 34 | placeholders = placeholders.add($('
    ')); 35 | }); 36 | 37 | // Hide the gallery if the background is touched / clicked 38 | slider.append(placeholders).on('click',function(e){ 39 | if(!$(e.target).is('img')){ 40 | hideOverlay(); 41 | } 42 | }); 43 | 44 | // Listen for touch events on the body and check if they 45 | // originated in #gallerySlider img - the images in the slider. 46 | $('body').on('touchstart', '#gallerySlider img', function(e){ 47 | 48 | var touch = e.originalEvent, 49 | startX = touch.changedTouches[0].pageX; 50 | 51 | slider.on('touchmove',function(e){ 52 | 53 | e.preventDefault(); 54 | 55 | touch = e.originalEvent.touches[0] || 56 | e.originalEvent.changedTouches[0]; 57 | 58 | if(touch.pageX - startX > 10){ 59 | slider.off('touchmove'); 60 | showPrevious(); 61 | } 62 | else if (touch.pageX - startX < -10){ 63 | slider.off('touchmove'); 64 | showNext(); 65 | } 66 | }); 67 | 68 | // Return false to prevent image 69 | // highlighting on Android 70 | return false; 71 | 72 | }).on('touchend',function(){ 73 | slider.off('touchmove'); 74 | }); 75 | 76 | // Listening for clicks on the thumbnails 77 | 78 | items.on('click', function(e){ 79 | e.preventDefault(); 80 | 81 | // Find the position of this image 82 | // in the collection 83 | 84 | index = items.index(this); 85 | showOverlay(index); 86 | showImage(index); 87 | 88 | // Preload the next image 89 | preload(index+1); 90 | 91 | // Preload the previous 92 | preload(index-1); 93 | 94 | }); 95 | 96 | // If the browser does not have support 97 | // for touch, display the arrows 98 | if ( !("ontouchstart" in window) ){ 99 | overlay.append(prevArrow).append(nextArrow); 100 | 101 | prevArrow.click(function(e){ 102 | e.preventDefault(); 103 | showPrevious(); 104 | }); 105 | 106 | nextArrow.click(function(e){ 107 | e.preventDefault(); 108 | showNext(); 109 | }); 110 | } 111 | 112 | // Listen for arrow keys 113 | $(window).bind('keydown', function(e){ 114 | 115 | if (e.keyCode == 37){ 116 | showPrevious(); 117 | } 118 | else if (e.keyCode==39){ 119 | showNext(); 120 | } 121 | 122 | }); 123 | 124 | 125 | /* Private functions */ 126 | 127 | 128 | function showOverlay(index){ 129 | 130 | // If the overlay is already shown, exit 131 | if (overlayVisible){ 132 | return false; 133 | } 134 | 135 | // Show the overlay 136 | overlay.show(); 137 | 138 | setTimeout(function(){ 139 | // Trigger the opacity CSS transition 140 | overlay.addClass('visible'); 141 | }, 100); 142 | 143 | // Move the slider to the correct image 144 | offsetSlider(index); 145 | 146 | // Raise the visible flag 147 | overlayVisible = true; 148 | } 149 | 150 | function hideOverlay(){ 151 | // If the overlay is not shown, exit 152 | if(!overlayVisible){ 153 | return false; 154 | } 155 | 156 | // Hide the overlay 157 | overlay.hide().removeClass('visible'); 158 | overlayVisible = false; 159 | } 160 | 161 | function offsetSlider(index){ 162 | // This will trigger a smooth css transition 163 | slider.css('left',(-index*100)+'%'); 164 | } 165 | 166 | // Preload an image by its index in the items array 167 | function preload(index){ 168 | setTimeout(function(){ 169 | showImage(index); 170 | }, 1000); 171 | } 172 | 173 | // Show image in the slider 174 | function showImage(index){ 175 | 176 | // If the index is outside the bonds of the array 177 | if(index < 0 || index >= items.length){ 178 | return false; 179 | } 180 | 181 | // Call the load function with the href attribute of the item 182 | loadImage(items.eq(index).attr('href'), function(){ 183 | placeholders.eq(index).html(this); 184 | }); 185 | } 186 | 187 | // Load the image and execute a callback function. 188 | // Returns a jQuery object 189 | 190 | function loadImage(src, callback){ 191 | var img = $('').on('load', function(){ 192 | callback.call(img); 193 | }); 194 | 195 | img.attr('src',src); 196 | } 197 | 198 | function showNext(){ 199 | 200 | // If this is not the last image 201 | if(index+1 < items.length){ 202 | index++; 203 | offsetSlider(index); 204 | preload(index+1); 205 | } 206 | else{ 207 | // Trigger the spring animation 208 | 209 | slider.addClass('rightSpring'); 210 | setTimeout(function(){ 211 | slider.removeClass('rightSpring'); 212 | },500); 213 | } 214 | } 215 | 216 | function showPrevious(){ 217 | 218 | // If this is not the first image 219 | if(index>0){ 220 | index--; 221 | offsetSlider(index); 222 | preload(index-1); 223 | } 224 | else{ 225 | // Trigger the spring animation 226 | 227 | slider.addClass('leftSpring'); 228 | setTimeout(function(){ 229 | slider.removeClass('leftSpring'); 230 | },500); 231 | } 232 | } 233 | }; 234 | 235 | })(jQuery); -------------------------------------------------------------------------------- /vendor/assets/javascripts/jquery/jquery.easing-1.3.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/ 3 | * 4 | * Uses the built in easing capabilities added In jQuery 1.1 5 | * to offer multiple easing options 6 | * 7 | * TERMS OF USE - jQuery Easing 8 | * 9 | * Open source under the BSD License. 10 | * 11 | * Copyright © 2008 George McGinley Smith 12 | * All rights reserved. 13 | * 14 | * Redistribution and use in source and binary forms, with or without modification, 15 | * are permitted provided that the following conditions are met: 16 | * 17 | * Redistributions of source code must retain the above copyright notice, this list of 18 | * conditions and the following disclaimer. 19 | * Redistributions in binary form must reproduce the above copyright notice, this list 20 | * of conditions and the following disclaimer in the documentation and/or other materials 21 | * provided with the distribution. 22 | * 23 | * Neither the name of the author nor the names of contributors may be used to endorse 24 | * or promote products derived from this software without specific prior written permission. 25 | * 26 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 27 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 28 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 29 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 30 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 31 | * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 32 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 33 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 34 | * OF THE POSSIBILITY OF SUCH DAMAGE. 35 | * 36 | */ 37 | 38 | // t: current time, b: begInnIng value, c: change In value, d: duration 39 | jQuery.easing['jswing'] = jQuery.easing['swing']; 40 | 41 | jQuery.extend( jQuery.easing, 42 | { 43 | def: 'easeOutQuad', 44 | swing: function (x, t, b, c, d) { 45 | //alert(jQuery.easing.default); 46 | return jQuery.easing[jQuery.easing.def](x, t, b, c, d); 47 | }, 48 | easeInQuad: function (x, t, b, c, d) { 49 | return c*(t/=d)*t + b; 50 | }, 51 | easeOutQuad: function (x, t, b, c, d) { 52 | return -c *(t/=d)*(t-2) + b; 53 | }, 54 | easeInOutQuad: function (x, t, b, c, d) { 55 | if ((t/=d/2) < 1) return c/2*t*t + b; 56 | return -c/2 * ((--t)*(t-2) - 1) + b; 57 | }, 58 | easeInCubic: function (x, t, b, c, d) { 59 | return c*(t/=d)*t*t + b; 60 | }, 61 | easeOutCubic: function (x, t, b, c, d) { 62 | return c*((t=t/d-1)*t*t + 1) + b; 63 | }, 64 | easeInOutCubic: function (x, t, b, c, d) { 65 | if ((t/=d/2) < 1) return c/2*t*t*t + b; 66 | return c/2*((t-=2)*t*t + 2) + b; 67 | }, 68 | easeInQuart: function (x, t, b, c, d) { 69 | return c*(t/=d)*t*t*t + b; 70 | }, 71 | easeOutQuart: function (x, t, b, c, d) { 72 | return -c * ((t=t/d-1)*t*t*t - 1) + b; 73 | }, 74 | easeInOutQuart: function (x, t, b, c, d) { 75 | if ((t/=d/2) < 1) return c/2*t*t*t*t + b; 76 | return -c/2 * ((t-=2)*t*t*t - 2) + b; 77 | }, 78 | easeInQuint: function (x, t, b, c, d) { 79 | return c*(t/=d)*t*t*t*t + b; 80 | }, 81 | easeOutQuint: function (x, t, b, c, d) { 82 | return c*((t=t/d-1)*t*t*t*t + 1) + b; 83 | }, 84 | easeInOutQuint: function (x, t, b, c, d) { 85 | if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b; 86 | return c/2*((t-=2)*t*t*t*t + 2) + b; 87 | }, 88 | easeInSine: function (x, t, b, c, d) { 89 | return -c * Math.cos(t/d * (Math.PI/2)) + c + b; 90 | }, 91 | easeOutSine: function (x, t, b, c, d) { 92 | return c * Math.sin(t/d * (Math.PI/2)) + b; 93 | }, 94 | easeInOutSine: function (x, t, b, c, d) { 95 | return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b; 96 | }, 97 | easeInExpo: function (x, t, b, c, d) { 98 | return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b; 99 | }, 100 | easeOutExpo: function (x, t, b, c, d) { 101 | return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b; 102 | }, 103 | easeInOutExpo: function (x, t, b, c, d) { 104 | if (t==0) return b; 105 | if (t==d) return b+c; 106 | if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b; 107 | return c/2 * (-Math.pow(2, -10 * --t) + 2) + b; 108 | }, 109 | easeInCirc: function (x, t, b, c, d) { 110 | return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b; 111 | }, 112 | easeOutCirc: function (x, t, b, c, d) { 113 | return c * Math.sqrt(1 - (t=t/d-1)*t) + b; 114 | }, 115 | easeInOutCirc: function (x, t, b, c, d) { 116 | if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b; 117 | return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b; 118 | }, 119 | easeInElastic: function (x, t, b, c, d) { 120 | var s=1.70158;var p=0;var a=c; 121 | if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; 122 | if (a < Math.abs(c)) { a=c; var s=p/4; } 123 | else var s = p/(2*Math.PI) * Math.asin (c/a); 124 | return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b; 125 | }, 126 | easeOutElastic: function (x, t, b, c, d) { 127 | var s=1.70158;var p=0;var a=c; 128 | if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; 129 | if (a < Math.abs(c)) { a=c; var s=p/4; } 130 | else var s = p/(2*Math.PI) * Math.asin (c/a); 131 | return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b; 132 | }, 133 | easeInOutElastic: function (x, t, b, c, d) { 134 | var s=1.70158;var p=0;var a=c; 135 | if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5); 136 | if (a < Math.abs(c)) { a=c; var s=p/4; } 137 | else var s = p/(2*Math.PI) * Math.asin (c/a); 138 | if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b; 139 | return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b; 140 | }, 141 | easeInBack: function (x, t, b, c, d, s) { 142 | if (s == undefined) s = 1.70158; 143 | return c*(t/=d)*t*((s+1)*t - s) + b; 144 | }, 145 | easeOutBack: function (x, t, b, c, d, s) { 146 | if (s == undefined) s = 1.70158; 147 | return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b; 148 | }, 149 | easeInOutBack: function (x, t, b, c, d, s) { 150 | if (s == undefined) s = 1.70158; 151 | if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b; 152 | return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b; 153 | }, 154 | easeInBounce: function (x, t, b, c, d) { 155 | return c - jQuery.easing.easeOutBounce (x, d-t, 0, c, d) + b; 156 | }, 157 | easeOutBounce: function (x, t, b, c, d) { 158 | if ((t/=d) < (1/2.75)) { 159 | return c*(7.5625*t*t) + b; 160 | } else if (t < (2/2.75)) { 161 | return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b; 162 | } else if (t < (2.5/2.75)) { 163 | return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b; 164 | } else { 165 | return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b; 166 | } 167 | }, 168 | easeInOutBounce: function (x, t, b, c, d) { 169 | if (t < d/2) return jQuery.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b; 170 | return jQuery.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b; 171 | } 172 | }); 173 | 174 | /* 175 | * 176 | * TERMS OF USE - EASING EQUATIONS 177 | * 178 | * Open source under the BSD License. 179 | * 180 | * Copyright © 2001 Robert Penner 181 | * All rights reserved. 182 | * 183 | * Redistribution and use in source and binary forms, with or without modification, 184 | * are permitted provided that the following conditions are met: 185 | * 186 | * Redistributions of source code must retain the above copyright notice, this list of 187 | * conditions and the following disclaimer. 188 | * Redistributions in binary form must reproduce the above copyright notice, this list 189 | * of conditions and the following disclaimer in the documentation and/or other materials 190 | * provided with the distribution. 191 | * 192 | * Neither the name of the author nor the names of contributors may be used to endorse 193 | * or promote products derived from this software without specific prior written permission. 194 | * 195 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 196 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 197 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 198 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 199 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 200 | * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 201 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 202 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 203 | * OF THE POSSIBILITY OF SUCH DAMAGE. 204 | * 205 | */ -------------------------------------------------------------------------------- /vendor/assets/javascripts/jquery/jquery.elastislide.js: -------------------------------------------------------------------------------- 1 | (function( window, $, undefined ) { 2 | 3 | // http://www.netcu.de/jquery-touchwipe-iphone-ipad-library 4 | $.fn.touchwipe = function(settings) { 5 | 6 | var config = { 7 | min_move_x: 20, 8 | min_move_y: 20, 9 | wipeLeft: function() { }, 10 | wipeRight: function() { }, 11 | wipeUp: function() { }, 12 | wipeDown: function() { }, 13 | preventDefaultEvents: true 14 | }; 15 | 16 | if (settings) $.extend(config, settings); 17 | 18 | this.each(function() { 19 | var startX; 20 | var startY; 21 | var isMoving = false; 22 | 23 | function cancelTouch() { 24 | this.removeEventListener('touchmove', onTouchMove); 25 | startX = null; 26 | isMoving = false; 27 | } 28 | 29 | function onTouchMove(e) { 30 | if(config.preventDefaultEvents) { 31 | e.preventDefault(); 32 | } 33 | if(isMoving) { 34 | var x = e.touches[0].pageX; 35 | var y = e.touches[0].pageY; 36 | var dx = startX - x; 37 | var dy = startY - y; 38 | if(Math.abs(dx) >= config.min_move_x) { 39 | cancelTouch(); 40 | if(dx > 0) { 41 | config.wipeLeft(); 42 | } 43 | else { 44 | config.wipeRight(); 45 | } 46 | } 47 | else if(Math.abs(dy) >= config.min_move_y) { 48 | cancelTouch(); 49 | if(dy > 0) { 50 | config.wipeDown(); 51 | } 52 | else { 53 | config.wipeUp(); 54 | } 55 | } 56 | } 57 | } 58 | 59 | function onTouchStart(e) 60 | { 61 | if (e.touches.length == 1) { 62 | startX = e.touches[0].pageX; 63 | startY = e.touches[0].pageY; 64 | isMoving = true; 65 | this.addEventListener('touchmove', onTouchMove, false); 66 | } 67 | } 68 | if ('ontouchstart' in document.documentElement) { 69 | this.addEventListener('touchstart', onTouchStart, false); 70 | } 71 | }); 72 | 73 | return this; 74 | }; 75 | 76 | $.elastislide = function( options, element ) { 77 | this.$el = $( element ); 78 | this._init( options ); 79 | }; 80 | 81 | $.elastislide.defaults = { 82 | speed : 450, // animation speed 83 | easing : '', // animation easing effect 84 | imageW : 190, // the images width 85 | margin : 3, // image margin right 86 | border : 2, // image border 87 | minItems : 1, // the minimum number of items to show. 88 | // when we resize the window, this will make sure minItems are always shown 89 | // (unless of course minItems is higher than the total number of elements) 90 | current : 0, // index of the current item 91 | // when we resize the window, the carousel will make sure this item is visible 92 | onClick : function() { return false; } // click item callback 93 | }; 94 | 95 | $.elastislide.prototype = { 96 | _init : function( options ) { 97 | 98 | this.options = $.extend( true, {}, $.elastislide.defaults, options ); 99 | 100 | //