vendor: 6,751 bytes, lines 1-229
1/*! npm.im/object-fit-images 3.2.4 */ 2var OFI = 'bfred-it:object-fit-images'; 3var propRegex = /(object-fit|object-position)\s*:\s*([-.\w\s%]+)/g; 4var testImg = typeof Image === 'undefined' ? {style: {'object-position': 1}} : new Image(); 5var supportsObjectFit = 'object-fit' in testImg.style; 6var supportsObjectPosition = 'object-position' in testImg.style; 7var supportsOFI = 'background-size' in testImg.style; 8var supportsCurrentSrc = typeof testImg.currentSrc === 'string'; 9var nativeGetAttribute = testImg.getAttribute; 10var nativeSetAttribute = testImg.setAttribute; 11var autoModeEnabled = false; 12 13function createPlaceholder(w, h) { 14 return ("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='" + w + "' height='" + h + "'%3E%3C/svg%3E"); 15} 16 17function polyfillCurrentSrc(el) { 18 if (el.srcset && !supportsCurrentSrc && window.picturefill) { 19 var pf = window.picturefill._; 20 // parse srcset with picturefill where currentSrc isn't available 21 if (!el[pf.ns] || !el[pf.ns].evaled) { 22 // force synchronous srcset parsing 23 pf.fillImg(el, {reselect: true}); 24 } 25 26 if (!el[pf.ns].curSrc) { 27 // force picturefill to parse srcset 28 el[pf.ns].supported = false; 29 pf.fillImg(el, {reselect: true}); 30 } 31 32 // retrieve parsed currentSrc, if any 33 el.currentSrc = el[pf.ns].curSrc || el.src; 34 } 35} 36 37function getStyle(el) { 38 var style = getComputedStyle(el).fontFamily; 39 var parsed; 40 var props = {}; 41 while ((parsed = propRegex.exec(style)) !== null) { 42 props[parsed[1]] = parsed[2]; 43 } 44 return props; 45} 46 47function setPlaceholder(img, width, height) { 48 // Default: fill width, no height 49 var placeholder = createPlaceholder(width || 1, height || 0); 50 51 // Only set placeholder if it's different 52 if (nativeGetAttribute.call(img, 'src') !== placeholder) { 53 nativeSetAttribute.call(img, 'src', placeholder); 54 } 55} 56 57function onImageReady(img, callback) { 58 // naturalWidth is only available when the image headers are loaded, 59 // this loop will poll it every 100ms. 60 if (img.naturalWidth) { 61 callback(img); 62 } else { 63 setTimeout(onImageReady, 100, img, callback); 64 } 65} 66 67function fixOne(el) { 68 var style = getStyle(el); 69 var ofi = el[OFI]; 70 style['object-fit'] = style['object-fit'] || 'fill'; // default value 71 72 // Avoid running where unnecessary, unless OFI had already done its deed 73 if (!ofi.img) { 74 // fill is the default behavior so no action is necessary 75 if (style['object-fit'] === 'fill') { 76 return; 77 } 78 79 // Where object-fit is supported and object-position isn't (Safari < 10) 80 if ( 81 !ofi.skipTest && // unless user wants to apply regardless of browser support 82 supportsObjectFit && // if browser already supports object-fit 83 !style['object-position'] // unless object-position is used 84 ) { 85 return; 86 } 87 } 88 89 // keep a clone in memory while resetting the original to a blank 90 if (!ofi.img) { 91 ofi.img = new Image(el.width, el.height); 92 ofi.img.srcset = nativeGetAttribute.call(el, "data-ofi-srcset") || el.srcset; 93 ofi.img.src = nativeGetAttribute.call(el, "data-ofi-src") || el.src; 94 95 // preserve for any future cloneNode calls 96 // https://github.com/bfred-it/object-fit-images/issues/53 97 nativeSetAttribute.call(el, "data-ofi-src", el.src); 98 if (el.srcset) { 99 nativeSetAttribute.call(el, "data-ofi-srcset", el.srcset); 100 } 101 102 setPlaceholder(el, el.naturalWidth || el.width, el.naturalHeight || el.height); 103 104 // remove srcset because it overrides src 105 if (el.srcset) { 106 el.srcset = ''; 107 } 108 try { 109 keepSrcUsable(el); 110 } catch (err) { 111 if (window.console) { 112 console.warn('https://bit.ly/ofi-old-browser'); 113 } 114 } 115 } 116 117 polyfillCurrentSrc(ofi.img); 118 119 el.style.backgroundImage = "url(\"" + ((ofi.img.currentSrc || ofi.img.src).replace(/"/g, '\\"')) + "\")"; 120 el.style.backgroundPosition = style['object-position'] || 'center'; 121 el.style.backgroundRepeat = 'no-repeat'; 122 el.style.backgroundOrigin = 'content-box'; 123 124 if (/scale-down/.test(style['object-fit'])) { 125 onImageReady(ofi.img, function () { 126 if (ofi.img.naturalWidth > el.width || ofi.img.naturalHeight > el.height) { 127 el.style.backgroundSize = 'contain'; 128 } else { 129 el.style.backgroundSize = 'auto'; 130 } 131 }); 132 } else { 133 el.style.backgroundSize = style['object-fit'].replace('none', 'auto').replace('fill', '100% 100%'); 134 } 135 136 onImageReady(ofi.img, function (img) { 137 setPlaceholder(el, img.naturalWidth, img.naturalHeight); 138 }); 139} 140 141function keepSrcUsable(el) { 142 var descriptors = { 143 get: function get(prop) { 144 return el[OFI].img[prop ? prop : 'src']; 145 }, 146 set: function set(value, prop) { 147 el[OFI].img[prop ? prop : 'src'] = value; 148 nativeSetAttribute.call(el, ("data-ofi-" + prop), value); // preserve for any future cloneNode 149 fixOne(el); 150 return value; 151 } 152 }; 153 Object.defineProperty(el, 'src', descriptors); 154 Object.defineProperty(el, 'currentSrc', { 155 get: function () { return descriptors.get('currentSrc'); } 156 }); 157 Object.defineProperty(el, 'srcset', { 158 get: function () { return descriptors.get('srcset'); }, 159 set: function (ss) { return descriptors.set(ss, 'srcset'); } 160 }); 161} 162 163function hijackAttributes() { 164 function getOfiImageMaybe(el, name) { 165 return el[OFI] && el[OFI].img && (name === 'src' || name === 'srcset') ? el[OFI].img : el; 166 } 167 if (!supportsObjectPosition) { 168 HTMLImageElement.prototype.getAttribute = function (name) { 169 return nativeGetAttribute.call(getOfiImageMaybe(this, name), name); 170 }; 171 172 HTMLImageElement.prototype.setAttribute = function (name, value) { 173 return nativeSetAttribute.call(getOfiImageMaybe(this, name), name, String(value)); 174 }; 175 } 176} 177 178function fix(imgs, opts) { 179 var startAutoMode = !autoModeEnabled && !imgs; 180 opts = opts || {}; 181 imgs = imgs || 'img'; 182 183 if ((supportsObjectPosition && !opts.skipTest) || !supportsOFI) { 184 return false; 185 } 186 187 // use imgs as a selector or just select all images 188 if (imgs === 'img') { 189 imgs = document.getElementsByTagName('img'); 190 } else if (typeof imgs === 'string') { 191 imgs = document.querySelectorAll(imgs); 192 } else if (!('length' in imgs)) { 193 imgs = [imgs]; 194 } 195 196 // apply fix to all 197 for (var i = 0; i < imgs.length; i++) { 198 imgs[i][OFI] = imgs[i][OFI] || { 199 skipTest: opts.skipTest 200 }; 201 fixOne(imgs[i]); 202 } 203 204 if (startAutoMode) { 205 document.body.addEventListener('load', function (e) { 206 if (e.target.tagName === 'IMG') { 207 fix(e.target, { 208 skipTest: opts.skipTest 209 }); 210 } 211 }, true); 212 autoModeEnabled = true; 213 imgs = 'img'; // reset to a generic selector for watchMQ 214 } 215 216 // if requested, watch media queries for object-fit change 217 if (opts.watchMQ) { 218 window.addEventListener('resize', fix.bind(null, imgs, { 219 skipTest: opts.skipTest 220 })); 221 } 222} 223 224fix.supportsObjectFit = supportsObjectFit; 225fix.supportsObjectPosition = supportsObjectPosition; 226 227hijackAttributes(); 228 229export default fix;
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.