forked from a64f7bb4-7358-4778-9fbe-3b882c34cc1d/v1
145 lines
3.7 KiB
JavaScript
145 lines
3.7 KiB
JavaScript
/**
|
|
* @file
|
|
* Provides a few disposable polyfills till IE is gone from planet earth.
|
|
*
|
|
* Supports for webp is landed at D9.2. This file relies on core/picturefill
|
|
* which is always included as core/responsive_image polifyll as per 2022/2.
|
|
* This file is a client-side solution, with advantage clean native image markup
|
|
* since it doesn't change IMG into PICTURE till required by old browsers, as
|
|
* alt for HTML/ server-side solutions:
|
|
* - https://www.drupal.org/project/webp
|
|
* - https://www.drupal.org/project/imageapi_optimize_webp
|
|
*
|
|
* @see https://www.drupal.org/node/3171135
|
|
* @see https://www.drupal.org/project/drupal/issues/3213491
|
|
* @todo remove if picturefill suffices. FWIW, IE9 works fine with picturefill
|
|
* w/o this fallback. Not tested against other oldies, Safari, etc. So included,
|
|
* but can be ditched as usual via Blazy UI if not needed at all.
|
|
*/
|
|
|
|
(function ($, _win, _doc) {
|
|
|
|
'use strict';
|
|
|
|
if ($.webp) {
|
|
return;
|
|
}
|
|
|
|
var _key = 'bwebp';
|
|
var _dataSrcset = 'data-srcset';
|
|
var _picture = 'picture';
|
|
var _mimeWebp = 'image/webp';
|
|
var _source = 'source';
|
|
var pf = _win.picturefill;
|
|
|
|
function isSupported() {
|
|
var support = true;
|
|
|
|
// Ensures not locked down when Responsive image is not present, yet.
|
|
// @todo use $.decode for better async.
|
|
if (pf) {
|
|
var check = $.storage(_key);
|
|
|
|
if (!$.isNull(check)) {
|
|
return check === 'true';
|
|
}
|
|
|
|
// Undefined means supported, due to !pf.supPicture check.
|
|
support = $.isUnd(pf._.supportsType(_mimeWebp));
|
|
$.storage(_key, support);
|
|
}
|
|
|
|
return support;
|
|
}
|
|
|
|
function markup(img, webps, nowebps, dataset) {
|
|
if (!$.isElm(img)) {
|
|
return false;
|
|
}
|
|
var picture = $.create(_picture);
|
|
var source = $.create(_source);
|
|
var sizes = $.attr(img, 'sizes');
|
|
var webpSrc = webps.join(',').trim();
|
|
var nowebpSrc = nowebps.join(',').trim();
|
|
var check = $.find(picture, _source);
|
|
|
|
if (!$.isElm(check)) {
|
|
if (dataset) {
|
|
$.attr(source, _dataSrcset, webpSrc);
|
|
$.attr(img, _dataSrcset, nowebpSrc);
|
|
}
|
|
else {
|
|
source.srcset = webpSrc;
|
|
img.srcset = nowebpSrc;
|
|
}
|
|
|
|
if (sizes) {
|
|
source.sizes = sizes;
|
|
}
|
|
|
|
source.type = _mimeWebp;
|
|
|
|
$.append(picture, source);
|
|
$.append(picture, img);
|
|
}
|
|
|
|
return picture;
|
|
}
|
|
|
|
function convert(el) {
|
|
var img = _doc.importNode(el, true);
|
|
var webps = [];
|
|
var nowebps = [];
|
|
var dataset = $.attr(img, _dataSrcset);
|
|
var scrset = $.attr(img, 'srcset');
|
|
|
|
if (scrset.length || dataset.length) {
|
|
scrset = scrset.length ? scrset : dataset;
|
|
|
|
if (scrset.length) {
|
|
$.each(scrset.split(','), function (src) {
|
|
if ($.contains(src, '.webp')) {
|
|
webps.push(src);
|
|
}
|
|
else {
|
|
nowebps.push(src);
|
|
}
|
|
});
|
|
|
|
if (webps.length) {
|
|
return markup(img, webps, nowebps, dataset.length);
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
$.webp = {
|
|
isSupported: isSupported,
|
|
|
|
run: function (elms) {
|
|
if (isSupported() || !elms.length) {
|
|
return;
|
|
}
|
|
|
|
$.each(elms, function (el) {
|
|
var isImg = $.equal(el, 'img');
|
|
var pic = $.closest(el, _picture);
|
|
|
|
if (isImg && $.isNull(pic)) {
|
|
var parent = $.closest(el, '.media') || el.parentNode;
|
|
var picture = convert(el, true);
|
|
|
|
if (picture) {
|
|
// Cannot use parent.replaceWith because this is for old browsers.
|
|
// Nor parent.replaceChild(picture, el); due to various features.
|
|
$.append(parent, picture);
|
|
$.remove(el);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
};
|
|
|
|
})(dBlazy, this, this.document);
|