diff --git a/core/modules/picture/picture.module b/core/modules/picture/picture.module index 7dbbaee..1b0b8fd 100644 --- a/core/modules/picture/picture.module +++ b/core/modules/picture/picture.module @@ -89,10 +89,11 @@ function picture_library_info() { 'website' => 'http://drupal.org/node/1775530', 'version' => VERSION, 'js' => array( - drupal_get_path('module', 'picture') . '/picturefill/picturefill.js' => array('type' => 'file', 'weight' => -10, 'group' => JS_DEFAULT), + drupal_get_path('module', 'picture') . '/picturefill/picturefill.js' => array('weight' => -10, 'group' => JS_DEFAULT), ), 'dependencies' => array( array('system', 'matchmedia'), + array('system', 'domready'), ), ); return $libraries; @@ -286,10 +287,10 @@ function theme_picture($variables) { $attributes = array(); foreach (array('alt', 'title') as $key) { if (isset($variables[$key])) { - $attributes[$key] = $variables[$key]; + $attributes['data-' . $key] = $variables[$key]; } } - $output[] = ''; + $output[] = ''; // Add source tags to the output. foreach ($sources as $source) { @@ -298,7 +299,7 @@ function theme_picture($variables) { // Output the fallback image. $output[] = ''; - $output[] = ''; + $output[] = ''; return implode("\n", $output); } } @@ -319,19 +320,24 @@ function theme_picture($variables) { */ function theme_picture_source($variables) { $output = array(); + + // Convert dimensions to data-width and data-height + $attributes = array(); + foreach (array('width', 'height') as $key) { + if (isset($variables['dimensions'][$key])) { + $attributes['data-' . $key] = $variables['dimensions'][$key]; + } + } if (isset($variables['media']) && !empty($variables['media'])) { if (!isset($variables['srcset'])) { - $output[] = ''; - $output[] = ''; + $output[] = ''; } elseif (!isset($variables['src'])) { - $output[] = ''; - $output[] = ''; + $output[] = ''; } } else { - $output[] = ''; - $output[] = ''; + $output[] = ''; } return implode("\n", $output); } diff --git a/core/modules/picture/picturefill/picturefill.js b/core/modules/picture/picturefill/picturefill.js index 8df8eb9..9fb6b27 100644 --- a/core/modules/picture/picturefill/picturefill.js +++ b/core/modules/picture/picturefill/picturefill.js @@ -1,48 +1,42 @@ /*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 ){ +(function (w, domready) { // Enable strict mode. "use strict"; - // Test if `` is supported natively, if so, exit. - if (!!(w.document.createElement('picture') && w.document.createElement('source') && w.HTMLPictureElement)) { - return; - } - - w.picturefill = function() { + w.picturefill = function (parent) { // 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'); + function _copyAttributes (src, tar) { + var width = src.getAttribute('data-width'); + var height = src.getAttribute('data-height'); + if (width && height) { + tar.width = width; + tar.height = height; + } + else { + tar.removeAttribute('width'); + tar.removeAttribute('height'); } } // Get all picture tags. - var ps = w.document.getElementsByTagName('picture'); + if (!parent || !parent.querySelectorAll) { + parent = w.document; + } + var ps = parent.querySelectorAll('span[data-picture]'); // Loop the pictures. - for (var i = 0, il = ps.length; i < il; i++ ) { - var sources = ps[i].getElementsByTagName('source'); - var picImg = null; + for (var i = 0, il = ps.length; i < il; i++) { + var pic = ps[i]; 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(/]+>/gmi); - - frag.innerHTML = srcs.join(''); - sources = frag.getElementsByTagName('div'); - } + var sources = pic.querySelectorAll('span'); + var img = pic.querySelector('img'); // See which sources match. - for (var j = 0, jl = sources.length; j < jl; j++ ) { - var media = sources[j].getAttribute('media'); + for (var j = 0, jl = sources.length; j < jl; j++) { + var media = sources[j].getAttribute('data-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]); @@ -52,75 +46,31 @@ if (matches.length) { // Grab the most appropriate (last) match. var match = matches.pop(); - var srcset = match.getAttribute('srcset'); + var picImg = img; - // 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) { + if (!img) { + // Add a new img element. picImg = w.document.createElement('img'); - picImg.alt = ps[i].getAttribute('alt'); - ps[i].appendChild(picImg); + picImg.alt = pic.getAttribute('data-alt') || ''; + picImg.title = pic.getAttribute('data-title') || ''; } - // 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 - // original’s 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); - } - // We’ve 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. + var dataSrc = match.getAttribute('data-src'); + // Set the source if it's different. + if (picImg.src !== dataSrc) { + picImg.src = dataSrc; _copyAttributes(match, picImg); } + if (!img) { + pic.appendChild(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); + domready(w.picturefill); + +})(window, domready);