wp/wp-includes/js/dist/vendor/wp-polyfill-object-fit.js
changeset 18 be944660c56a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/wp/wp-includes/js/dist/vendor/wp-polyfill-object-fit.js	Wed Sep 21 18:19:35 2022 +0200
@@ -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;
+})();