Skip to content

Commit

Permalink
Merge pull request scottjehl#436 from aFarkas/setintrinsicdimensions
Browse files Browse the repository at this point in the history
Alternative proposal for setInherent/IntrinsicSize
  • Loading branch information
Alexander Farkas committed Feb 10, 2015
2 parents 4c01243 + cf50e35 commit ad306a9
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 51 deletions.
95 changes: 61 additions & 34 deletions src/picturefill.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,18 @@
return str.trim ? str.trim() : str.replace( /^\s+|\s+$/g, "" );
};

// just a string endsWith workaround
pf.endsWith = function( str, suffix ) {
return str.endsWith ? str.endsWith( suffix ) : str.indexOf( suffix, str.length - suffix.length ) !== -1;
};
/**
* Gets a string and returns the absolute URL
* @param src
* @returns {String} absolute URL
*/
pf.makeUrl = (function() {
var anchor = doc.createElement( "a" );
return function(src) {
anchor.href = src;
return anchor.href;
};
})();

/**
* Shortcut method for https://w3c.github.io/webappsec/specs/mixedcontent/#restricts-mixed-content ( for easy overriding in tests )
Expand Down Expand Up @@ -361,25 +369,38 @@
}
};

pf.setInherentSize = function( res, picImg, readyState ) {
var ready = readyState !== undefined ? readyState : picImg.complete,
widthPreset = !ready && picImg.getAttribute && picImg.getAttribute( "width" ) !== null,
setWidth = function( res, picImg ) {
if ( picImg.setAttribute ) {
picImg.setAttribute( "width", picImg.naturalWidth / res );
}
},
widthInterval;
pf.setIntrinsicSize = (function() {
var urlCache = {};
var setSize = function( picImg, width, res ) {
picImg.setAttribute( "width", parseInt(width / res, 10) );
};
return function( picImg, bestCandidate ) {
var img;
if ( !picImg[ pf.ns ] ) {
return;
}
if ( picImg[ pf.ns ].dims === undefined ) {
picImg[ pf.ns].dims = picImg.getAttribute("width") || picImg.getAttribute("height");
}
if ( picImg[ pf.ns].dims ) { return; }

if ( ready && res && !widthPreset ) {
setWidth( res, picImg );
}
if ( !ready ) {
widthInterval = setTimeout(function() {
pf.setInherentSize( res, picImg, picImg.complete );
}, 250);
}
};
if ( urlCache[bestCandidate.url] ) {
setSize( picImg, urlCache[bestCandidate.url], bestCandidate.resolution );
} else {
img = doc.createElement( "img" );
img.onload = function() {
urlCache[bestCandidate.url] = img.width;
if ( picImg.src === bestCandidate.url ) {
setSize( picImg, urlCache[bestCandidate.url], bestCandidate.resolution );
}
picImg = null;
img.onload = null;
img = null;
};
img.src = bestCandidate.url;
}
};
})();

pf.applyBestCandidate = function( candidates, picImg ) {
var candidate,
Expand All @@ -399,20 +420,26 @@
}
}

if ( bestCandidate && !pf.endsWith( picImg.src, bestCandidate.url ) ) {
if ( pf.restrictsMixedContent() && bestCandidate.url.substr(0, "http:".length).toLowerCase() === "http:" ) {
if ( window.console !== undefined ) {
console.warn( "Blocked mixed content image " + bestCandidate.url );
}
} else {
picImg.src = bestCandidate.url;
// currentSrc attribute and property to match
// http://picture.responsiveimages.org/#the-img-element
picImg.currentSrc = picImg.src;
if ( bestCandidate ) {

bestCandidate.url = pf.makeUrl( bestCandidate.url );

if ( picImg.src !== bestCandidate.url ) {
if ( pf.restrictsMixedContent() && bestCandidate.url.substr(0, "http:".length).toLowerCase() === "http:" ) {
if ( window.console !== undefined ) {
console.warn( "Blocked mixed content image " + bestCandidate.url );
}
} else {
picImg.src = bestCandidate.url;
// currentSrc attribute and property to match
// http://picture.responsiveimages.org/#the-img-element
picImg.currentSrc = picImg.src;

pf.backfaceVisibilityFix( picImg );
pf.setInherentSize( bestCandidate.resolution, picImg );
pf.backfaceVisibilityFix( picImg );
}
}

pf.setIntrinsicSize(picImg, bestCandidate);
}
};

Expand Down
53 changes: 36 additions & 17 deletions tests/tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,20 +71,39 @@
equal(width, 500, "returns 500 when match media returns false");
});

test("setInherentSize", function() {
var fakeImg = document.createElement( "img" );
asyncTest("setIntrinsicSize", function() {
var imgInitialHeight = document.createElement( "img" );
var imgInitialWidth = document.createElement( "img" );
var imgWithoutDimensions = document.createElement( "img" );
var candidate = {
url: pf.makeUrl( "../examples/images/small.jpg" ),
resolution: 2
};

imgWithoutDimensions.onload = function() {
ok( !imgInitialHeight.getAttribute("width"), "No natural width calculation is performed if a `height` attribute already exists." );

equal( imgInitialWidth.width, 10, "No natural width calculation is performed if a `width` attribute already exists." );

fakeImg.src = "../examples/images/small.jpg";
equal( imgWithoutDimensions.width, 90, "width attribute is set to `naturalWidth / resolution`" );
start();
};

imgInitialHeight.src = candidate.url;
imgInitialWidth.src = candidate.url;
imgWithoutDimensions.src = candidate.url;

fakeImg.setAttribute( "width", 10 );
imgInitialHeight[ pf.ns ] = {};
imgInitialWidth[ pf.ns ] = {};
imgWithoutDimensions[ pf.ns ] = {};

pf.setInherentSize( 2, fakeImg, false );
deepEqual( fakeImg.width, 10, "No natural width calculation is performed if a `width` attribute already exists." );
imgInitialHeight.setAttribute( "height", 10 );
imgInitialWidth.setAttribute( "width", 10 );

fakeImg.removeAttribute( "width" );
pf.setIntrinsicSize(imgInitialHeight, candidate );
pf.setIntrinsicSize(imgInitialWidth, candidate );
pf.setIntrinsicSize(imgWithoutDimensions, candidate );

pf.setInherentSize( 2, fakeImg, true );
deepEqual( fakeImg.width, 90, "width attribute is set to `naturalWidth / resolution`" );
});

test("parseSize", function() {
Expand Down Expand Up @@ -422,9 +441,9 @@
var image, candidates;

candidates = [
{ resolution: 100, url: "100" },
{ resolution: 200, url: "200" },
{ resolution: 300, url: "300" }
{ resolution: 100, url: "data:100" },
{ resolution: 200, url: "data:200" },
{ resolution: 300, url: "data:300" }
];

image = {
Expand All @@ -440,13 +459,13 @@
deepEqual(image.src, candidates[2].url, "uses the url from the best px fit" );
deepEqual(image.currentSrc, candidates[2].url, "uses the url from the best px fit" );

image.src = "foo300";
image.currentSrc = "foo300";
image.src = "data:300";
image.currentSrc = "data:300";

pf.applyBestCandidate( candidates, image );

deepEqual(image.src, "foo300", "src left alone when matched" );
deepEqual(image.currentSrc, "foo300", "currentSrc left alone when matched" );
deepEqual(image.src, "data:300", "src left alone when matched" );
deepEqual(image.currentSrc, "data:300", "currentSrc left alone when matched" );
});

test( "removeVideoShim", function() {
Expand Down Expand Up @@ -591,5 +610,5 @@

assert.equal( img.currentSrc || img.src, "data:img" );
});

})( window, jQuery );

0 comments on commit ad306a9

Please sign in to comment.