drupal/core/assets/vendor/picturefill/picturefill.js

127 lines
4.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/*jshint loopfunc: true, browser: true, curly: true, eqeqeq: true, expr: true, forin: true, latedef: true, newcap: true, noarg: true, trailing: true, undef: true, unused: true */
/*! Picturefill - Author: Scott Jehl, 2012 | License: MIT/GPLv2 */
(function (w) {
// Enable strict mode.
"use strict";
// Test if `<picture>` is supported natively, if so, exit.
if (!!(w.document.createElement('picture') && w.document.createElement('source') && w.HTMLPictureElement)) {
return;
}
w.picturefill = function () {
// Copy attributes from the source to the destination.
function _copyAttributes(src, tar) {
if (src.getAttribute('width') && src.getAttribute('height')) {
tar.width = src.getAttribute('width');
tar.height = src.getAttribute('height');
}
}
// Get all picture tags.
var ps = w.document.getElementsByTagName('picture');
// Loop the pictures.
for (var i = 0, il = ps.length; i < il; i++) {
var sources = ps[i].getElementsByTagName('source');
var picImg = null;
var matches = [];
// If no sources are found, they're likely erased from the DOM.
// Try finding them inside comments.
if (!sources.length) {
var picText = ps[i].innerHTML;
var frag = w.document.createElement('div');
// For IE9, convert the source elements to divs.
var srcs = picText.replace(/(<)source([^>]+>)/gmi, '$1div$2').match(/<div[^>]+>/gmi);
frag.innerHTML = srcs.join('');
sources = frag.getElementsByTagName('div');
}
// See which sources match.
for (var j = 0, jl = sources.length; j < jl; j++) {
var media = sources[j].getAttribute('media');
// If there's no media specified or the media query matches, add it.
if (!media || (w.matchMedia && w.matchMedia(media).matches)) {
matches.push(sources[j]);
}
}
if (matches.length) {
// Grab the most appropriate (last) match.
var match = matches.pop();
var srcset = match.getAttribute('srcset');
// Find any existing img element in the picture element.
picImg = ps[i].getElementsByTagName('img')[0];
// Add a new img element if one doesn't exists.
if (!picImg) {
picImg = w.document.createElement('img');
picImg.alt = ps[i].getAttribute('alt');
ps[i].appendChild(picImg);
}
// Source element uses a srcset.
if (srcset) {
var screenRes = w.devicePixelRatio || 1;
// Split comma-separated `srcset` sources into an array.
sources = srcset.split(', ');
// Loop through each source/resolution in srcset.
for (var res = sources.length, r = res - 1; r >= 0; r--) {
// Remove any leading whitespace, then split on spaces.
var source = sources[ r ].replace(/^\s*/, '').replace(/\s*$/, '').split(' ');
// Parse out the resolution for each source in `srcset`.
var resMatch = parseFloat(source[1], 10);
if (screenRes >= resMatch) {
if (picImg.getAttribute('src') !== source[0]) {
var newImg = document.createElement('img');
newImg.src = source[0];
// When the image is loaded, set a width equal to that of the
// originals intrinsic width divided by the screen resolution.
newImg.onload = function () {
// Clone the original image into memory so the width is
// unaffected by page styles.
var w = this.cloneNode(true).width;
if (w > 0) {
this.width = (w / resMatch);
}
};
// Copy width and height from the source tag to the img element.
_copyAttributes(match, newImg);
picImg.parentNode.replaceChild(newImg, picImg);
}
// Weve matched, so bail out of the loop here.
break;
}
}
} else {
// No srcset used, so just use the 'src' value.
picImg.src = match.getAttribute('src');
// Copy width and height from the source tag to the img element.
_copyAttributes(match, picImg);
}
}
}
};
// Run on resize and domready (w.load as a fallback)
if (w.addEventListener) {
w.addEventListener('resize', w.picturefill, false);
w.addEventListener('DOMContentLoaded', function () {
w.picturefill();
// Run once only.
w.removeEventListener('load', w.picturefill, false);
}, false);
w.addEventListener('load', w.picturefill, false);
}
else if (w.attachEvent) {
w.attachEvent('onload', w.picturefill);
}
})(this);