Skip to content

Commit

Permalink
included srcset assets and test and updated readme
Browse files Browse the repository at this point in the history
  • Loading branch information
kristianmandrup committed Aug 29, 2012
1 parent 2bf1727 commit d59d93b
Show file tree
Hide file tree
Showing 10 changed files with 947 additions and 2 deletions.
48 changes: 46 additions & 2 deletions README.md
@@ -1,5 +1,11 @@
# Picturefill View helpers for Rails # Picturefill View helpers for Rails


This gem provides polyfills for 3 wys to render responsive images:

* picturefill
* jquery-picture
* srcset

[picturefill](https://github.com/scottjehl/picturefill) is currently the best way for rendering [Responsive Images](http://5by5.tv/webahead/25) on a web page. [picturefill](https://github.com/scottjehl/picturefill) is currently the best way for rendering [Responsive Images](http://5by5.tv/webahead/25) on a web page.


*picturefill-rails* provides nice view helper methods to render the picturefill. *picturefill-rails* provides nice view helper methods to render the picturefill.
Expand Down Expand Up @@ -64,7 +70,7 @@ A number of specs are included which all pass and should ensure that the view he


## TODO ## TODO


The `#picture_src` method works, but could use some heavy refactoring! I don't like methods of more than 10 lines! Is a bad sign. Reponsibilities should be off-loaded to other methods (or classes) The `#picture_src` method works, but could use some heavy refactoring! I don't like methods of more than 10 lines! Reponsibilities should be off-loaded to other methods (or classes)


Currently the gem only supports Ruby 1.9+ and has only been tested on 1.9.3. Currently the gem only supports Ruby 1.9+ and has only been tested on 1.9.3.


Expand Down Expand Up @@ -107,10 +113,48 @@ $(function(){
}); });
``` ```


## Random Notes *Arcticles*


[critique of picturefill](http://oscargodson.com/posts/picturefill-needs-to-die.html) [critique of picturefill](http://oscargodson.com/posts/picturefill-needs-to-die.html)


## Img SrcSet Polyfill

See [the specification][spec] for the reference algorithm.

See [repo]: https://github.com/borismus/srcset-polyfill

### Usage

Use the `srcset` attribute of `<img>` elements. For example:

<img alt="The Breakfast Combo"
src="banner.jpeg"
srcset="banner-HD.jpeg 2x, banner-phone.jpeg 100w,
banner-phone-HD.jpeg 100w 2x"/>


Include `srcset.min.js` in your page.

`= img_srcset ...`

TODO: Implement the Rails View Helper method!

### Assets

The gem includes srcset javascript assets that are automatically available for the asset pipeline. In your `application.js` manifest file require:

* `srcset.min.js` (prod)
* `srcset.js` (dev/test)

### Open questions

- How to reliably check for srcset support in the browser (so as to not
attempt to polyfill if it's not necessary?)
- Is it safe to use `-webkit-transform` to scale things?
- Is it worth falling back to `-webkit-image-set` if available?

[spec]: http://www.whatwg.org/specs/web-apps/current-work/multipage/embedded-content-1.html#processing-the-image-candidates

## Contributing to picturefill-rails ## Contributing to picturefill-rails


* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet. * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
Expand Down
Binary file added spec/srcset/banner-HD.jpeg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added spec/srcset/banner-phone-HD.jpeg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added spec/srcset/banner-phone.jpeg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added spec/srcset/banner.jpeg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 16 additions & 0 deletions spec/srcset/index.html
@@ -0,0 +1,16 @@
<!doctype html>
<html>
<head>
<title>Srcset Polyfill Demo</title>
<script src="../../vendor/assets/javascripts/srcset.js"></script>
<style>
body { background: gray; }
</style>
</head>

<div id="container"><img alt="The Breakfast Combo"
src="banner.jpeg"
srcset="banner-HD.jpeg 2x, banner-phone.jpeg 100w, banner-phone-HD.jpeg 100w 2x"></div>
</body>
</html>

29 changes: 29 additions & 0 deletions spec/srcset/tests/index.html
@@ -0,0 +1,29 @@
<!doctype html>
<html>
<head>
<title>Srcset Polyfill Unit tests</title>
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
<script src="../../../vendor/assets/javascripts/srcset.js"></script>
<script src="srcset-tests.js"></script>
</head>

<h1><img alt="The Breakfast Combo"
src="banner.jpeg"
srcset="banner-HD.jpeg 2x, banner-phone.jpeg 100w, banner-phone-HD.jpeg 100w 2x"></h1>


<body>
<h1 id="qunit-header">Srcset Polyfill Unit Tests</h1>
<h2 id="qunit-banner"></h2>
<div id="qunit-testrunner-toolbar"></div>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol>
<div id="qunit-fixture">test markup, will be hidden</div>

<div id="test">
</div>
</body>
</html>

100 changes: 100 additions & 0 deletions spec/srcset/tests/srcset-tests.js
@@ -0,0 +1,100 @@
module('srcset validation');

test('valid image candidate strings validate', function() {
var s1 = new SrcsetInfo({src: 'pear.jpeg', srcset: 'pear-mobile.jpeg'});
ok(s1.isValid, 'simple image candidates without descriptors understood.');
var s2 = new SrcsetInfo({src: 'pear.jpeg', srcset: 'pear-mobile.jpeg 720w'});
ok(s2.isValid, 'simple image candidates understood.');
var s3 = new SrcsetInfo({srcset: 'pear-mobile.jpeg 1.1x'});
ok(s3.isValid, 'simple image candidates understood.');
var s4 = new SrcsetInfo({srcset: 'pear-mobile.jpeg 720w, pear-tablet.jpeg 1280w'});
ok(s4.isValid, 'compound image candidates understood.');
var s5 = new SrcsetInfo({srcset: 'pear-mobile.jpeg 720w, pear-tablet.jpeg 1280w, pear-desktop.jpeg 1x'});
ok(s5.isValid, 'complex compound image candidates understood.');
});

test('invalid image candidate strings do not validate', function() {
var s1 = new SrcsetInfo({srcset: 'pear-mobile.jpeg 720k, pear-tablet.jpeg 1280w'});
ok(!s1.isValid, 'unknown descriptor units rejected');
var s2 = new SrcsetInfo({srcset: 'pear-mobile.jpeg 7.2w, pear-tablet.jpeg 1280w'});
ok(!s2.isValid, 'non-integer widths rejected.');
});

module('srcset parsing');

test('single image declarations set to the right defaults', function() {
var s1 = new SrcsetInfo({srcset: 'pear-mobile.jpeg'});
var img = s1.imageCandidates[0];
equal(img.x, 1, 'default density set');
equal(img.w, Infinity, 'default width set');
equal(img.h, Infinity, 'default height set');
});

test('single image declarations parse correctly', function() {
var s1 = new SrcsetInfo({srcset: 'pear-mobile.jpeg 720w'});
var img = s1.imageCandidates[0];
equal(img.src, 'pear-mobile.jpeg', 'image src validates');
equal(img.w, 720, 'width set');
});

test('multiple image candidates parse correctly', function() {
var s1 = new SrcsetInfo({srcset: 'pear-mobile.jpeg 720w, pear-tablet.jpeg 1280w, pear-desktop.jpeg 1.5x'});
equal(s1.imageCandidates.length, 3, '3 image candidates found');
var img = s1.imageCandidates[2];
equal(img.x, 1.5, 'last image candidate density is 1.5');
});

test('repeated values for image candidates are ignored', function() {
var s1 = new SrcsetInfo({srcset: 'pear-mobile.jpeg 720w, pear-tablet.jpeg 720w'});
equal(s1.imageCandidates.length, 1, '1 image candidate found');
var img = s1.imageCandidates[0];
equal(img.src, 'pear-mobile.jpeg', 'last candidate ignored.');
});


module('image candidate selection');

test('simple srcset picks correct image candidate', function() {
var old = new ViewportInfo();
old.setForTesting({w: 2000, h: 1000, x: 1});
var s1 = new SrcsetInfo({src: 'banner.jpeg', srcset: 'banner-HD.jpeg 2x'});
var img = old.getBestImage(s1);
equal(img.src, 'banner.jpeg', 'picked right image');
var hd = new ViewportInfo();
hd.setForTesting({w: 2000, h: 1000, x: 2});
var img = hd.getBestImage(s1);
equal(img.src, 'banner-HD.jpeg', 'picked right image');
});

test('ambiguous srcset picks best image candidate', function() {
var vp = new ViewportInfo();
vp.setForTesting({w: 500, h: 500});
var s1 = new SrcsetInfo({src: 'banner.jpeg',
srcset: 'banner-wide.jpeg 300w 1000h, banner-tall.jpeg 1000w 300h, banner.jpeg'});
var img = vp.getBestImage(s1);
equal(img.src, 'banner.jpeg', 'makes sense.');
});

test('complex srcset picks best image candidate', function() {
var mobile = new ViewportInfo();
mobile.setForTesting({w: 320, h: 480, x: 2});
var s1 = new SrcsetInfo({src: 'banner.jpeg', srcset: 'banner-HD.jpeg 2x, banner-phone.jpeg 400w, banner-phone-HD.jpeg 400w 2x'});
var img = mobile.getBestImage(s1);
equal(img.src, 'banner-phone-HD.jpeg', 'picked best image for phone');
var desktop = new ViewportInfo();
desktop.setForTesting({w: 1440, h: 1280, x: 2});
var img = desktop.getBestImage(s1);
equal(img.src, 'banner-HD.jpeg', 'picked best image for desktop');
var old = new ViewportInfo();
old.setForTesting({w: 320, h: 480, x: 1});
var img = old.getBestImage(s1);
equal(img.src, 'banner-phone.jpeg', 'picked best image for desktop');
});

test('john mellor test', function() {
var mobile = new ViewportInfo();
mobile.setForTesting({w: 320, h: 480, x: 2.1});
var s1 = new SrcsetInfo({srcset: 'ipad1.jpg 1024w, iphone4.jpg 320w 2x'});
var img = mobile.getBestImage(s1);
equal(img.src, 'iphone4.jpg', 'picked best image for phone');
});

0 comments on commit d59d93b

Please sign in to comment.