"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.COLOR_SUPPORT_KEY = void 0;
exports.ColorEdit = ColorEdit;
exports.addSaveProps = addSaveProps;
exports.addTransforms = addTransforms;
exports.default = void 0;
var _clsx = _interopRequireDefault(require("clsx"));
var _hooks = require("@wordpress/hooks");
var _blocks = require("@wordpress/blocks");
var _element = require("@wordpress/element");
var _data = require("@wordpress/data");
var _colors = require("../components/colors");
var _gradients = require("../components/gradients");
var _utils = require("./utils");
var _background = require("./background");
var _useSettings = require("../components/use-settings");
var _inspectorControls = _interopRequireDefault(require("../components/inspector-controls"));
var _colorPanel = _interopRequireWildcard(require("../components/global-styles/color-panel"));
var _contrastChecker = _interopRequireDefault(require("./contrast-checker"));
var _store = require("../store");
var _jsxRuntime = require("react/jsx-runtime");
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
/**
 * External dependencies
 */

/**
 * WordPress dependencies
 */

/**
 * Internal dependencies
 */

const COLOR_SUPPORT_KEY = exports.COLOR_SUPPORT_KEY = 'color';
const hasColorSupport = blockNameOrType => {
  const colorSupport = (0, _blocks.getBlockSupport)(blockNameOrType, COLOR_SUPPORT_KEY);
  return colorSupport && (colorSupport.link === true || colorSupport.gradient === true || colorSupport.background !== false || colorSupport.text !== false);
};
const hasLinkColorSupport = blockType => {
  if (_element.Platform.OS !== 'web') {
    return false;
  }
  const colorSupport = (0, _blocks.getBlockSupport)(blockType, COLOR_SUPPORT_KEY);
  return colorSupport !== null && typeof colorSupport === 'object' && !!colorSupport.link;
};
const hasGradientSupport = blockNameOrType => {
  const colorSupport = (0, _blocks.getBlockSupport)(blockNameOrType, COLOR_SUPPORT_KEY);
  return colorSupport !== null && typeof colorSupport === 'object' && !!colorSupport.gradients;
};
const hasBackgroundColorSupport = blockType => {
  const colorSupport = (0, _blocks.getBlockSupport)(blockType, COLOR_SUPPORT_KEY);
  return colorSupport && colorSupport.background !== false;
};
const hasTextColorSupport = blockType => {
  const colorSupport = (0, _blocks.getBlockSupport)(blockType, COLOR_SUPPORT_KEY);
  return colorSupport && colorSupport.text !== false;
};

/**
 * Filters registered block settings, extending attributes to include
 * `backgroundColor` and `textColor` attribute.
 *
 * @param {Object} settings Original block settings.
 *
 * @return {Object} Filtered block settings.
 */
function addAttributes(settings) {
  if (!hasColorSupport(settings)) {
    return settings;
  }

  // Allow blocks to specify their own attribute definition with default values if needed.
  if (!settings.attributes.backgroundColor) {
    Object.assign(settings.attributes, {
      backgroundColor: {
        type: 'string'
      }
    });
  }
  if (!settings.attributes.textColor) {
    Object.assign(settings.attributes, {
      textColor: {
        type: 'string'
      }
    });
  }
  if (hasGradientSupport(settings) && !settings.attributes.gradient) {
    Object.assign(settings.attributes, {
      gradient: {
        type: 'string'
      }
    });
  }
  return settings;
}

/**
 * Override props assigned to save component to inject colors classnames.
 *
 * @param {Object}        props           Additional props applied to save element.
 * @param {Object|string} blockNameOrType Block type.
 * @param {Object}        attributes      Block attributes.
 *
 * @return {Object} Filtered props applied to save element.
 */
function addSaveProps(props, blockNameOrType, attributes) {
  if (!hasColorSupport(blockNameOrType) || (0, _utils.shouldSkipSerialization)(blockNameOrType, COLOR_SUPPORT_KEY)) {
    return props;
  }
  const hasGradient = hasGradientSupport(blockNameOrType);

  // I'd have preferred to avoid the "style" attribute usage here
  const {
    backgroundColor,
    textColor,
    gradient,
    style
  } = attributes;
  const shouldSerialize = feature => !(0, _utils.shouldSkipSerialization)(blockNameOrType, COLOR_SUPPORT_KEY, feature);

  // Primary color classes must come before the `has-text-color`,
  // `has-background` and `has-link-color` classes to maintain backwards
  // compatibility and avoid block invalidations.
  const textClass = shouldSerialize('text') ? (0, _colors.getColorClassName)('color', textColor) : undefined;
  const gradientClass = shouldSerialize('gradients') ? (0, _gradients.__experimentalGetGradientClass)(gradient) : undefined;
  const backgroundClass = shouldSerialize('background') ? (0, _colors.getColorClassName)('background-color', backgroundColor) : undefined;
  const serializeHasBackground = shouldSerialize('background') || shouldSerialize('gradients');
  const hasBackground = backgroundColor || style?.color?.background || hasGradient && (gradient || style?.color?.gradient);
  const newClassName = (0, _clsx.default)(props.className, textClass, gradientClass, {
    // Don't apply the background class if there's a custom gradient.
    [backgroundClass]: (!hasGradient || !style?.color?.gradient) && !!backgroundClass,
    'has-text-color': shouldSerialize('text') && (textColor || style?.color?.text),
    'has-background': serializeHasBackground && hasBackground,
    'has-link-color': shouldSerialize('link') && style?.elements?.link?.color
  });
  props.className = newClassName ? newClassName : undefined;
  return props;
}
function styleToAttributes(style) {
  const textColorValue = style?.color?.text;
  const textColorSlug = textColorValue?.startsWith('var:preset|color|') ? textColorValue.substring('var:preset|color|'.length) : undefined;
  const backgroundColorValue = style?.color?.background;
  const backgroundColorSlug = backgroundColorValue?.startsWith('var:preset|color|') ? backgroundColorValue.substring('var:preset|color|'.length) : undefined;
  const gradientValue = style?.color?.gradient;
  const gradientSlug = gradientValue?.startsWith('var:preset|gradient|') ? gradientValue.substring('var:preset|gradient|'.length) : undefined;
  const updatedStyle = {
    ...style
  };
  updatedStyle.color = {
    ...updatedStyle.color,
    text: textColorSlug ? undefined : textColorValue,
    background: backgroundColorSlug ? undefined : backgroundColorValue,
    gradient: gradientSlug ? undefined : gradientValue
  };
  return {
    style: (0, _utils.cleanEmptyObject)(updatedStyle),
    textColor: textColorSlug,
    backgroundColor: backgroundColorSlug,
    gradient: gradientSlug
  };
}
function attributesToStyle(attributes) {
  return {
    ...attributes.style,
    color: {
      ...attributes.style?.color,
      text: attributes.textColor ? 'var:preset|color|' + attributes.textColor : attributes.style?.color?.text,
      background: attributes.backgroundColor ? 'var:preset|color|' + attributes.backgroundColor : attributes.style?.color?.background,
      gradient: attributes.gradient ? 'var:preset|gradient|' + attributes.gradient : attributes.style?.color?.gradient
    }
  };
}
function ColorInspectorControl({
  children,
  resetAllFilter
}) {
  const attributesResetAllFilter = (0, _element.useCallback)(attributes => {
    const existingStyle = attributesToStyle(attributes);
    const updatedStyle = resetAllFilter(existingStyle);
    return {
      ...attributes,
      ...styleToAttributes(updatedStyle)
    };
  }, [resetAllFilter]);
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_inspectorControls.default, {
    group: "color",
    resetAllFilter: attributesResetAllFilter,
    children: children
  });
}
function ColorEdit({
  clientId,
  name,
  setAttributes,
  settings
}) {
  const isEnabled = (0, _colorPanel.useHasColorPanel)(settings);
  function selector(select) {
    const {
      style,
      textColor,
      backgroundColor,
      gradient
    } = select(_store.store).getBlockAttributes(clientId) || {};
    return {
      style,
      textColor,
      backgroundColor,
      gradient
    };
  }
  const {
    style,
    textColor,
    backgroundColor,
    gradient
  } = (0, _data.useSelect)(selector, [clientId]);
  const value = (0, _element.useMemo)(() => {
    return attributesToStyle({
      style,
      textColor,
      backgroundColor,
      gradient
    });
  }, [style, textColor, backgroundColor, gradient]);
  const onChange = newStyle => {
    setAttributes(styleToAttributes(newStyle));
  };
  if (!isEnabled) {
    return null;
  }
  const defaultControls = (0, _blocks.getBlockSupport)(name, [COLOR_SUPPORT_KEY, '__experimentalDefaultControls']);
  const enableContrastChecking = _element.Platform.OS === 'web' && !value?.color?.gradient && (settings?.color?.text || settings?.color?.link) &&
  // Contrast checking is enabled by default.
  // Deactivating it requires `enableContrastChecker` to have
  // an explicit value of `false`.
  false !== (0, _blocks.getBlockSupport)(name, [COLOR_SUPPORT_KEY, 'enableContrastChecker']);
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_colorPanel.default, {
    as: ColorInspectorControl,
    panelId: clientId,
    settings: settings,
    value: value,
    onChange: onChange,
    defaultControls: defaultControls,
    enableContrastChecker: false !== (0, _blocks.getBlockSupport)(name, [COLOR_SUPPORT_KEY, 'enableContrastChecker']),
    children: enableContrastChecking && /*#__PURE__*/(0, _jsxRuntime.jsx)(_contrastChecker.default, {
      clientId: clientId
    })
  });
}
function useBlockProps({
  name,
  backgroundColor,
  textColor,
  gradient,
  style
}) {
  const [userPalette, themePalette, defaultPalette] = (0, _useSettings.useSettings)('color.palette.custom', 'color.palette.theme', 'color.palette.default');
  const colors = (0, _element.useMemo)(() => [...(userPalette || []), ...(themePalette || []), ...(defaultPalette || [])], [userPalette, themePalette, defaultPalette]);
  if (!hasColorSupport(name) || (0, _utils.shouldSkipSerialization)(name, COLOR_SUPPORT_KEY)) {
    return {};
  }
  const extraStyles = {};
  if (textColor && !(0, _utils.shouldSkipSerialization)(name, COLOR_SUPPORT_KEY, 'text')) {
    extraStyles.color = (0, _colors.getColorObjectByAttributeValues)(colors, textColor)?.color;
  }
  if (backgroundColor && !(0, _utils.shouldSkipSerialization)(name, COLOR_SUPPORT_KEY, 'background')) {
    extraStyles.backgroundColor = (0, _colors.getColorObjectByAttributeValues)(colors, backgroundColor)?.color;
  }
  const saveProps = addSaveProps({
    style: extraStyles
  }, name, {
    textColor,
    backgroundColor,
    gradient,
    style
  });
  const hasBackgroundValue = backgroundColor || style?.color?.background || gradient || style?.color?.gradient;
  return {
    ...saveProps,
    className: (0, _clsx.default)(saveProps.className,
    // Add background image classes in the editor, if not already handled by background color values.
    !hasBackgroundValue && (0, _background.getBackgroundImageClasses)(style))
  };
}
var _default = exports.default = {
  useBlockProps,
  addSaveProps,
  attributeKeys: ['backgroundColor', 'textColor', 'gradient', 'style'],
  hasSupport: hasColorSupport
};
const MIGRATION_PATHS = {
  linkColor: [['style', 'elements', 'link', 'color', 'text']],
  textColor: [['textColor'], ['style', 'color', 'text']],
  backgroundColor: [['backgroundColor'], ['style', 'color', 'background']],
  gradient: [['gradient'], ['style', 'color', 'gradient']]
};
function addTransforms(result, source, index, results) {
  const destinationBlockType = result.name;
  const activeSupports = {
    linkColor: hasLinkColorSupport(destinationBlockType),
    textColor: hasTextColorSupport(destinationBlockType),
    backgroundColor: hasBackgroundColorSupport(destinationBlockType),
    gradient: hasGradientSupport(destinationBlockType)
  };
  return (0, _utils.transformStyles)(activeSupports, MIGRATION_PATHS, result, source, index, results);
}
(0, _hooks.addFilter)('blocks.registerBlockType', 'core/color/addAttribute', addAttributes);
(0, _hooks.addFilter)('blocks.switchToBlockType.transformedBlock', 'core/color/addTransforms', addTransforms);
//# sourceMappingURL=color.js.map