'use strict';

// import { CSS_UTILITY } from './resources';
// export const getElementProp = (element: Element, prop: string, fallbackValue: any): any => {
//   const closest = element.closest(`[${prop}]`);
//   return closest ? closest.getAttribute(prop) : fallbackValue;
// };
const getRootNode = (element) => element.getRootNode();
const getHost = (root) => root.host || null;
// // Queries an element's rootNode and any ancestor rootNodes.
// // based on https://stackoverflow.com/q/54520554/194216
// export const queryElementsRoots = <T extends Element = Element>(element: Element, selector: string): T[] => {
//   // Gets the rootNode and any ancestor rootNodes (shadowRoot or document) of an element and queries them for a selector.
//   const queryFromAll = <T extends Element = Element>(element: Element, allResults: T[]): T[] => {
//     if (!element) return allResults;
//     if ((element as Slottable).assignedSlot) element = (element as Slottable).assignedSlot;
//     const rootNode = getRootNode(element);
//     const results = [...rootNode.querySelectorAll(selector)] as T[];
//     const uniqueResults = results.filter((result) => !allResults.includes(result));
//     allResults = [...allResults, ...uniqueResults];
//     const host = getHost(rootNode);
//     return host ? queryFromAll(host, allResults) : allResults;
//   };
//   return queryFromAll(element, []);
// };
// Queries element's rootNode and ancestor rootNodes.
// Based on https://stackoverflow.com/q/54520554/194216
const queryElementRoots = (element, selector) => {
  // Gets the rootNode and any ancestor rootNodes (shadowRoot or document) of an element and queries them for a selector.
  const queryFrom = (element) => {
    if (!element)
      return null;
    if (element.assignedSlot)
      element = element.assignedSlot;
    const rootNode = getRootNode(element);
    const found = rootNode.querySelector(selector);
    const host = getHost(rootNode);
    return found ? found : host ? queryFrom(host) : null;
  };
  return queryFrom(element);
};
const closestElementCrossShadowBoundary = (element, selector) => {
  // based on https://stackoverflow.com/q/54520554/194216
  const closestFrom = (element) => element ? element.closest(selector) || closestFrom(getHost(getRootNode(element))) : null;
  return closestFrom(element);
};

var ValidatorNames;
(function (ValidatorNames) {
  ValidatorNames["max"] = "max";
  ValidatorNames["maxLength"] = "maxLength";
  ValidatorNames["min"] = "min";
  ValidatorNames["minLength"] = "minLength";
  ValidatorNames["pattern"] = "pattern";
  ValidatorNames["required"] = "required";
})(ValidatorNames || (ValidatorNames = {}));
const defaultErrorMessagesConfig = {
  required: 'This entry is required',
};
/**  reducer callback: iterates through validators and returns the first one that fails it's validate function  */
function combineValidators(v1, v2) {
  const combined = {
    validate: (vParam) => {
      const result1 = v1.validate(vParam);
      const result2 = v2.validate(vParam);
      if (!result1)
        combined.errorMessage = v1.errorMessage;
      else if (!result2)
        combined.errorMessage = v2.errorMessage;
      return result1 && result2;
    },
  };
  return combined;
}
/** creates a list of ValidatorEntry objects from the ValidatorNames enum that exist on the component class
    example: [
      {name: 'required},
      {name: 'min', options: '5'}
    ]
  */
function composeValidatorList(componentClass) {
  const vList = Object.values(ValidatorNames)
    .filter((vname) => componentClass[vname] != null)
    .map((validatorEntry) => ({ name: validatorEntry, options: componentClass[validatorEntry] }));
  return getValidator(vList);
}
const defaultValidator = () => ({
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  validate: (_value) => true,
});
const getValidator = (list) => (list || [])
  .map((validator) => validatorFactory(validator.name))
  .reduce(combineValidators, defaultValidator());
const isRequiredValidator = () => ({
  errorMessage: defaultErrorMessagesConfig.required,
  validate: (inputElement) => inputElement && 'validity' in inputElement ? !inputElement.validity.valueMissing : true,
});
const validatorFactory = (name) => {
  switch (name) {
    case ValidatorNames.required:
      return isRequiredValidator();
    default:
      return defaultValidator();
  }
};

exports.closestElementCrossShadowBoundary = closestElementCrossShadowBoundary;
exports.composeValidatorList = composeValidatorList;
exports.defaultValidator = defaultValidator;
exports.queryElementRoots = queryElementRoots;

//# sourceMappingURL=validator-d497f649.js.map