'use strict';

const globalSlimmerRegistry = require('./global-slimmer-registry-b3bce7e0.js');

const exemptionClasses = [
  'vega-flex-grow',
  'vega-flex-shrink',
  'vega-flex-grow-0',
  'vega-flex-shrink-0',
  'vega-flex-basis-0',
  'v-flex-1',
  'v-min-w-min',
  'disabled',
  'v-text-black',
  'v-text-white',
  'v-hidden',
  'vega-page-notification-fade-out',
  'v-h-full',
  'v-h-screen',
];
/**
 * Sanitize the vega component rendered output hostElement with the following procedures:
 * 1. Catch any external passed-in classes e.g. <vega-flex class="<culprit_class>"></vega-flex>
 *    and log error message
 * 2. Persist the verified classes into DOM element dataset['verifiedClasses'] for the next time verification
 * 3. Catch any data-shrink='0' attribute e.g. <vega-flex><div data-shrink='0'></div></vega-flex> and log error message
 *
 * @typedef T type of vega component
 * @param {T} renderedOutput renderedOutput generated internally by vega-component runtime
 * @param {HTMLStencilElement} hostElement the external-facing element reference for hosting the vega component renderedOutput
 * @returns {T} processed vega component
 */
function sanitizeVegaComponent(renderedOutput, hostElement) {
  checkIfInAllowedClassList(renderedOutput, hostElement);
  checkIfUseDataShrink(hostElement);
  return renderedOutput;
}
/**
 * It checks if the classes added to the host element are allowed
 *
 * @param {T} renderedOutput - T - The output of the render method of the component
 * @param {HTMLStencilElement} hostElement - HTMLStencilElement - the host element of the component
 */
function checkIfInAllowedClassList(renderedOutput, hostElement) {
  var _a, _b, _c;
  // Get classes passed from vega component render method
  const componentDefinedClasses = ['hydrated'].concat(((_b = (_a = renderedOutput['$attrs$']) === null || _a === void 0 ? void 0 : _a['class']) === null || _b === void 0 ? void 0 : _b.split(/\s+/).filter(Boolean)) || []);
  // Get previously verified (and rendered in DOM tree) classes
  const previousVerifiedClasses = ((_c = hostElement.dataset['verifiedClasses']) === null || _c === void 0 ? void 0 : _c.split(' ')) || [];
  // Construct the classes allowlist
  const allowlistClassSet = new Set([
    ...componentDefinedClasses,
    ...previousVerifiedClasses,
    ...exemptionClasses,
  ]);
  // Get the culprit classes
  const culpritClassTokens = Array.from(hostElement.classList)
    .filter(Boolean)
    //Exclude the classes with breakpoint prefixes (M:vega-flex-shrink for example) from the culprit list
    .filter((classStr) => {
    const classStrWithoutBreakpoint = classStr.replace(/(S|M|L|XL):/, '');
    return !allowlistClassSet.has(classStrWithoutBreakpoint);
  })
    //Exclude the classes added by the framework (Angular for example) from the culprit list
    .filter((classStr) => !classStr.startsWith('ng-'));
  if (culpritClassTokens.length) {
    // For now, we will show a warning instead of erasing the culprit classes
    globalSlimmerRegistry.LogUtility.warn(`Found class(es) ${culpritClassTokens} added to component:`, hostElement, ' which is anti vega design pattern and we will forbid this behavior in the future release.', ' for more details, please refer to: https://heartlandpayments.github.io/Vega/?path=/docs/best-practice--page');
    // hostElement.classList.remove(...culpritClassTokens);
  }
  // Persist the verified classes for the next time verification
  if (componentDefinedClasses.join() !== 'hydrated') {
    hostElement.dataset['verifiedClasses'] = componentDefinedClasses.join(' ');
  }
}
/**
 * It checks if the host element has any children with the attribute data-shrink. If it does, it logs an error
 *
 * @param {HTMLStencilElement} hostElement - HTMLStencilElement - the host element of the component
 */
function checkIfUseDataShrink(hostElement) {
  if (hostElement.children) {
    const children = Array.from(hostElement.children);
    children.forEach((child) => {
      if (child.hasAttribute('data-shrink')) {
        globalSlimmerRegistry.LogUtility.warn(`Found attribute [data-shrink='0'] inside component:`, hostElement, ' which will be deprecated, please use classes of vega-flex-shrink, vega-flex-grow, vega-flex-shrink-0, vega-flex-grow-0, vega-flex-basis-0 instead.');
      }
    });
  }
}
/* istanbul ignore next */
/**
 * The function `getActiveElement` returns the active element within a shadow root or the
 * document.
 *
 * @param {Document | ShadowRoot} root - The `root` parameter is the root element from which to start
 * searching for the active element. It can be either a `Document` or a `ShadowRoot`. If no `root` is
 * provided, it defaults to the `document` object.
 * @returns {Nullable<Element>} The function `getActiveElementInShadow` returns an `Element` if there is an active element
 * in the given `root` (either a `Document` or a `ShadowRoot`). If there is no active element, it
 * returns `null`.
 */
// eslint-disable-next-line no-restricted-globals
const getActiveElement = (root = document) => {
  const activeEl = root.activeElement;
  if (activeEl === null || activeEl === void 0 ? void 0 : activeEl.shadowRoot) {
    return getActiveElement(activeEl.shadowRoot);
  }
  else if (activeEl) {
    return activeEl;
  }
  else {
    return null;
  }
};

exports.getActiveElement = getActiveElement;
exports.sanitizeVegaComponent = sanitizeVegaComponent;
