summaryrefslogtreecommitdiffstats
path: root/wp-includes/js/dist/vendor/wp-polyfill-object-fit.js
diff options
context:
space:
mode:
Diffstat (limited to 'wp-includes/js/dist/vendor/wp-polyfill-object-fit.js')
-rw-r--r--wp-includes/js/dist/vendor/wp-polyfill-object-fit.js304
1 files changed, 304 insertions, 0 deletions
diff --git a/wp-includes/js/dist/vendor/wp-polyfill-object-fit.js b/wp-includes/js/dist/vendor/wp-polyfill-object-fit.js
new file mode 100644
index 0000000..7f6e5db
--- /dev/null
+++ b/wp-includes/js/dist/vendor/wp-polyfill-object-fit.js
@@ -0,0 +1,304 @@
+/*----------------------------------------
+ * objectFitPolyfill 2.3.5
+ *
+ * Made by Constance Chen
+ * Released under the ISC license
+ *
+ * https://github.com/constancecchen/object-fit-polyfill
+ *--------------------------------------*/
+
+(function() {
+ 'use strict';
+
+ // if the page is being rendered on the server, don't continue
+ if (typeof window === 'undefined') return;
+
+ // Workaround for Edge 16-18, which only implemented object-fit for <img> tags
+ var edgeMatch = window.navigator.userAgent.match(/Edge\/(\d{2})\./);
+ var edgeVersion = edgeMatch ? parseInt(edgeMatch[1], 10) : null;
+ var edgePartialSupport = edgeVersion
+ ? edgeVersion >= 16 && edgeVersion <= 18
+ : false;
+
+ // If the browser does support object-fit, we don't need to continue
+ var hasSupport = 'objectFit' in document.documentElement.style !== false;
+ if (hasSupport && !edgePartialSupport) {
+ window.objectFitPolyfill = function() {
+ return false;
+ };
+ return;
+ }
+
+ /**
+ * Check the container's parent element to make sure it will
+ * correctly handle and clip absolutely positioned children
+ *
+ * @param {node} $container - parent element
+ */
+ var checkParentContainer = function($container) {
+ var styles = window.getComputedStyle($container, null);
+ var position = styles.getPropertyValue('position');
+ var overflow = styles.getPropertyValue('overflow');
+ var display = styles.getPropertyValue('display');
+
+ if (!position || position === 'static') {
+ $container.style.position = 'relative';
+ }
+ if (overflow !== 'hidden') {
+ $container.style.overflow = 'hidden';
+ }
+ // Guesstimating that people want the parent to act like full width/height wrapper here.
+ // Mostly attempts to target <picture> elements, which default to inline.
+ if (!display || display === 'inline') {
+ $container.style.display = 'block';
+ }
+ if ($container.clientHeight === 0) {
+ $container.style.height = '100%';
+ }
+
+ // Add a CSS class hook, in case people need to override styles for any reason.
+ if ($container.className.indexOf('object-fit-polyfill') === -1) {
+ $container.className = $container.className + ' object-fit-polyfill';
+ }
+ };
+
+ /**
+ * Check for pre-set max-width/height, min-width/height,
+ * positioning, or margins, which can mess up image calculations
+ *
+ * @param {node} $media - img/video element
+ */
+ var checkMediaProperties = function($media) {
+ var styles = window.getComputedStyle($media, null);
+ var constraints = {
+ 'max-width': 'none',
+ 'max-height': 'none',
+ 'min-width': '0px',
+ 'min-height': '0px',
+ top: 'auto',
+ right: 'auto',
+ bottom: 'auto',
+ left: 'auto',
+ 'margin-top': '0px',
+ 'margin-right': '0px',
+ 'margin-bottom': '0px',
+ 'margin-left': '0px',
+ };
+
+ for (var property in constraints) {
+ var constraint = styles.getPropertyValue(property);
+
+ if (constraint !== constraints[property]) {
+ $media.style[property] = constraints[property];
+ }
+ }
+ };
+
+ /**
+ * Calculate & set object-position
+ *
+ * @param {string} axis - either "x" or "y"
+ * @param {node} $media - img or video element
+ * @param {string} objectPosition - e.g. "50% 50%", "top left"
+ */
+ var setPosition = function(axis, $media, objectPosition) {
+ var position, other, start, end, side;
+ objectPosition = objectPosition.split(' ');
+
+ if (objectPosition.length < 2) {
+ objectPosition[1] = objectPosition[0];
+ }
+
+ /* istanbul ignore else */
+ if (axis === 'x') {
+ position = objectPosition[0];
+ other = objectPosition[1];
+ start = 'left';
+ end = 'right';
+ side = $media.clientWidth;
+ } else if (axis === 'y') {
+ position = objectPosition[1];
+ other = objectPosition[0];
+ start = 'top';
+ end = 'bottom';
+ side = $media.clientHeight;
+ } else {
+ return; // Neither x or y axis specified
+ }
+
+ if (position === start || other === start) {
+ $media.style[start] = '0';
+ return;
+ }
+
+ if (position === end || other === end) {
+ $media.style[end] = '0';
+ return;
+ }
+
+ if (position === 'center' || position === '50%') {
+ $media.style[start] = '50%';
+ $media.style['margin-' + start] = side / -2 + 'px';
+ return;
+ }
+
+ // Percentage values (e.g., 30% 10%)
+ if (position.indexOf('%') >= 0) {
+ position = parseInt(position, 10);
+
+ if (position < 50) {
+ $media.style[start] = position + '%';
+ $media.style['margin-' + start] = side * (position / -100) + 'px';
+ } else {
+ position = 100 - position;
+ $media.style[end] = position + '%';
+ $media.style['margin-' + end] = side * (position / -100) + 'px';
+ }
+
+ return;
+ }
+ // Length-based values (e.g. 10px / 10em)
+ else {
+ $media.style[start] = position;
+ }
+ };
+
+ /**
+ * Calculate & set object-fit
+ *
+ * @param {node} $media - img/video/picture element
+ */
+ var objectFit = function($media) {
+ // IE 10- data polyfill
+ var fit = $media.dataset
+ ? $media.dataset.objectFit
+ : $media.getAttribute('data-object-fit');
+ var position = $media.dataset
+ ? $media.dataset.objectPosition
+ : $media.getAttribute('data-object-position');
+
+ // Default fallbacks
+ fit = fit || 'cover';
+ position = position || '50% 50%';
+
+ // If necessary, make the parent container work with absolutely positioned elements
+ var $container = $media.parentNode;
+ checkParentContainer($container);
+
+ // Check for any pre-set CSS which could mess up image calculations
+ checkMediaProperties($media);
+
+ // Reset any pre-set width/height CSS and handle fit positioning
+ $media.style.position = 'absolute';
+ $media.style.width = 'auto';
+ $media.style.height = 'auto';
+
+ // `scale-down` chooses either `none` or `contain`, whichever is smaller
+ if (fit === 'scale-down') {
+ if (
+ $media.clientWidth < $container.clientWidth &&
+ $media.clientHeight < $container.clientHeight
+ ) {
+ fit = 'none';
+ } else {
+ fit = 'contain';
+ }
+ }
+
+ // `none` (width/height auto) and `fill` (100%) and are straightforward
+ if (fit === 'none') {
+ setPosition('x', $media, position);
+ setPosition('y', $media, position);
+ return;
+ }
+
+ if (fit === 'fill') {
+ $media.style.width = '100%';
+ $media.style.height = '100%';
+ setPosition('x', $media, position);
+ setPosition('y', $media, position);
+ return;
+ }
+
+ // `cover` and `contain` must figure out which side needs covering, and add CSS positioning & centering
+ $media.style.height = '100%';
+
+ if (
+ (fit === 'cover' && $media.clientWidth > $container.clientWidth) ||
+ (fit === 'contain' && $media.clientWidth < $container.clientWidth)
+ ) {
+ $media.style.top = '0';
+ $media.style.marginTop = '0';
+ setPosition('x', $media, position);
+ } else {
+ $media.style.width = '100%';
+ $media.style.height = 'auto';
+ $media.style.left = '0';
+ $media.style.marginLeft = '0';
+ setPosition('y', $media, position);
+ }
+ };
+
+ /**
+ * Initialize plugin
+ *
+ * @param {node} media - Optional specific DOM node(s) to be polyfilled
+ */
+ var objectFitPolyfill = function(media) {
+ if (typeof media === 'undefined' || media instanceof Event) {
+ // If left blank, or a default event, all media on the page will be polyfilled.
+ media = document.querySelectorAll('[data-object-fit]');
+ } else if (media && media.nodeName) {
+ // If it's a single node, wrap it in an array so it works.
+ media = [media];
+ } else if (typeof media === 'object' && media.length && media[0].nodeName) {
+ // If it's an array of DOM nodes (e.g. a jQuery selector), it's fine as-is.
+ media = media;
+ } else {
+ // Otherwise, if it's invalid or an incorrect type, return false to let people know.
+ return false;
+ }
+
+ for (var i = 0; i < media.length; i++) {
+ if (!media[i].nodeName) continue;
+
+ var mediaType = media[i].nodeName.toLowerCase();
+
+ if (mediaType === 'img') {
+ if (edgePartialSupport) continue; // Edge supports object-fit for images (but nothing else), so no need to polyfill
+
+ if (media[i].complete) {
+ objectFit(media[i]);
+ } else {
+ media[i].addEventListener('load', function() {
+ objectFit(this);
+ });
+ }
+ } else if (mediaType === 'video') {
+ if (media[i].readyState > 0) {
+ objectFit(media[i]);
+ } else {
+ media[i].addEventListener('loadedmetadata', function() {
+ objectFit(this);
+ });
+ }
+ } else {
+ objectFit(media[i]);
+ }
+ }
+
+ return true;
+ };
+
+ if (document.readyState === 'loading') {
+ // Loading hasn't finished yet
+ document.addEventListener('DOMContentLoaded', objectFitPolyfill);
+ } else {
+ // `DOMContentLoaded` has already fired
+ objectFitPolyfill();
+ }
+
+ window.addEventListener('resize', objectFitPolyfill);
+
+ window.objectFitPolyfill = objectFitPolyfill;
+})();