// Object.assign polyfill for IE 11- support
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign#Browser_compatibility
import 'mdn-polyfills/Object.assign';
"use strict";
// Check if the browser requires this polyfill (IE 11-)
// https://philipnewcomer.net/2014/04/target-internet-explorer-10-11-css/
const needsPolyfill =
document.documentElement.className.indexOf("old-ie") > -1 ||
window.matchMedia("(-ms-high-contrast: none), (-ms-high-contrast: active)").matches;
/**
* Rounding function that accounts for floating point errors
* @param {number} value - Number to round
* @param {number} decimals - Decimals places to round to
*/
// http://www.jacklmoore.com/notes/rounding-in-javascript/
// https://stackoverflow.com/a/29101013/673457
// http://floating-point-gui.de
function round(value, decimals) {
return Number(Math.round(value + "e" + decimals) + "e-" + decimals);
}
/**
* Preserve the aspect ratio of fluid-width SVGs in IE 11 and below
* @param {HTMLElement} el - SVG element
* @param {Object} opts - Options
* @param {string} [opts.classes=""] - Class(es) to add to the wrapper or iframe (depends on wrap option)
*/
export default function(el, opts) {
if (!needsPolyfill) {
return false;
}
// Make sure element is an SVG
if (el.tagName.toLowerCase() !== "svg") {
console.warn("fluidSVGPolyfill() only works on SVG elements", el);
return false;
}
// Use Object.assign() to merge “opts” object with default values in “options”
// Note: There’s only one option for now, but this approach makes it easy to add others in the future.
const options = Object.assign(
{},
{
moveClasses: false, // move classes from SVG to wrapper
svgClass: false, // optional class string added to SVG
wrapperClass: false // optional class string added to wrapper
},
opts
);
var aspectRatioPadding = null;
// Check if SVG has a “viewBox” attribute
if (el.hasAttribute("viewBox")) {
var viewBox = el.getAttribute("viewBox").split(" "); // => [0, 0, width, height]
// Calculate aspect ratio
// Note: JS will automatically convert number strings to integers
// http://2ality.com/2013/04/quirk-implicit-conversion.html
aspectRatioPadding = viewBox[3] / viewBox[2] * 100;
} else if (el.getAttribute("height") && el.getAttribute("width")) {
// If no “viewBox”, check for height/width attributes to calculate aspect ratio
aspectRatioPadding =
el.getAttribute("height") / el.getAttribute("width") * 100;
} else {
console.warn("Couldn’t determine SVG’s aspect ratio", el);
return false;
}
// Wrap SVG in div
var wrapper = document.createElement("div");
// Move SVG classes to wrapper
if (options.moveClasses) {
wrapper.className = el.getAttribute("class");
// Remove classes from SVG
el.removeAttribute("class");
}
// Add custom SVG class
// Note: If we want to drop IE 9 support, we could use classList.add() instead
if (options.svgClass) {
el.className.baseVal += (el.className.baseVal.length ? " " : "") + options.svgClass;
}
// Add custom wrapper class
if (options.wrapperClass) {
wrapper.className = options.wrapperClass;
}
wrapper.style.paddingTop = round(aspectRatioPadding, 3) + "%";
wrapper.style.position = "relative";
wrapper.style.width = "100%";
// Wrap SVG with the div
el.parentNode.insertBefore(wrapper, el);
wrapper.appendChild(el);
// Stretch SVG to fill parent
// Merge any existing inline styles https://stackoverflow.com/a/34490573/673457
Object.assign(el.style, {
height: "100%",
left: "0",
position: "absolute",
top: "0",
width: "100%"
});
}