// packages/block-editor/src/hooks/style.js
import { useMemo } from "@wordpress/element";
import { addFilter } from "@wordpress/hooks";
import {
  getBlockSupport,
  hasBlockSupport,
  __EXPERIMENTAL_ELEMENTS as ELEMENTS
} from "@wordpress/blocks";
import { useInstanceId } from "@wordpress/compose";
import { getCSSRules, compileCSS } from "@wordpress/style-engine";
import { BACKGROUND_SUPPORT_KEY, BackgroundImagePanel } from "./background";
import { BORDER_SUPPORT_KEY, BorderPanel, SHADOW_SUPPORT_KEY } from "./border";
import { COLOR_SUPPORT_KEY, ColorEdit } from "./color";
import {
  TypographyPanel,
  TYPOGRAPHY_SUPPORT_KEY,
  TYPOGRAPHY_SUPPORT_KEYS
} from "./typography";
import {
  DIMENSIONS_SUPPORT_KEY,
  SPACING_SUPPORT_KEY,
  DimensionsPanel
} from "./dimensions";
import {
  shouldSkipSerialization,
  useStyleOverride,
  useBlockSettings
} from "./utils";
import { scopeSelector } from "../components/global-styles/utils";
import { useBlockEditingMode } from "../components/block-editing-mode";
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
var styleSupportKeys = [
  ...TYPOGRAPHY_SUPPORT_KEYS,
  BORDER_SUPPORT_KEY,
  COLOR_SUPPORT_KEY,
  DIMENSIONS_SUPPORT_KEY,
  BACKGROUND_SUPPORT_KEY,
  SPACING_SUPPORT_KEY,
  SHADOW_SUPPORT_KEY
];
var hasStyleSupport = (nameOrType) => styleSupportKeys.some((key) => hasBlockSupport(nameOrType, key));
function getInlineStyles(styles = {}) {
  const output = {};
  getCSSRules(styles).forEach((rule) => {
    output[rule.key] = rule.value;
  });
  return output;
}
function addAttribute(settings) {
  if (!hasStyleSupport(settings)) {
    return settings;
  }
  if (!settings.attributes.style) {
    Object.assign(settings.attributes, {
      style: {
        type: "object"
      }
    });
  }
  return settings;
}
var skipSerializationPathsEdit = {
  [`${BORDER_SUPPORT_KEY}.__experimentalSkipSerialization`]: ["border"],
  [`${COLOR_SUPPORT_KEY}.__experimentalSkipSerialization`]: [
    COLOR_SUPPORT_KEY
  ],
  [`${TYPOGRAPHY_SUPPORT_KEY}.__experimentalSkipSerialization`]: [
    TYPOGRAPHY_SUPPORT_KEY
  ],
  [`${DIMENSIONS_SUPPORT_KEY}.__experimentalSkipSerialization`]: [
    DIMENSIONS_SUPPORT_KEY
  ],
  [`${SPACING_SUPPORT_KEY}.__experimentalSkipSerialization`]: [
    SPACING_SUPPORT_KEY
  ],
  [`${SHADOW_SUPPORT_KEY}.__experimentalSkipSerialization`]: [
    SHADOW_SUPPORT_KEY
  ]
};
var skipSerializationPathsSave = {
  ...skipSerializationPathsEdit,
  [`${DIMENSIONS_SUPPORT_KEY}.aspectRatio`]: [
    `${DIMENSIONS_SUPPORT_KEY}.aspectRatio`
  ],
  // Skip serialization of aspect ratio in save mode.
  [`${BACKGROUND_SUPPORT_KEY}`]: [BACKGROUND_SUPPORT_KEY]
  // Skip serialization of background support in save mode.
};
var skipSerializationPathsSaveChecks = {
  [`${DIMENSIONS_SUPPORT_KEY}.aspectRatio`]: true,
  [`${BACKGROUND_SUPPORT_KEY}`]: true
};
var renamedFeatures = { gradients: "gradient" };
function omitStyle(style, paths, preserveReference = false) {
  if (!style) {
    return style;
  }
  let newStyle = style;
  if (!preserveReference) {
    newStyle = JSON.parse(JSON.stringify(style));
  }
  if (!Array.isArray(paths)) {
    paths = [paths];
  }
  paths.forEach((path) => {
    if (!Array.isArray(path)) {
      path = path.split(".");
    }
    if (path.length > 1) {
      const [firstSubpath, ...restPath] = path;
      omitStyle(newStyle[firstSubpath], [restPath], true);
    } else if (path.length === 1) {
      delete newStyle[path[0]];
    }
  });
  return newStyle;
}
function addSaveProps(props, blockNameOrType, attributes, skipPaths = skipSerializationPathsSave) {
  if (!hasStyleSupport(blockNameOrType)) {
    return props;
  }
  let { style } = attributes;
  Object.entries(skipPaths).forEach(([indicator, path]) => {
    const skipSerialization = skipSerializationPathsSaveChecks[indicator] || getBlockSupport(blockNameOrType, indicator);
    if (skipSerialization === true) {
      style = omitStyle(style, path);
    }
    if (Array.isArray(skipSerialization)) {
      skipSerialization.forEach((featureName) => {
        const feature = renamedFeatures[featureName] || featureName;
        style = omitStyle(style, [[...path, feature]]);
      });
    }
  });
  props.style = {
    ...getInlineStyles(style),
    ...props.style
  };
  return props;
}
function BlockStyleControls({
  clientId,
  name,
  setAttributes,
  __unstableParentLayout
}) {
  const settings = useBlockSettings(name, __unstableParentLayout);
  const blockEditingMode = useBlockEditingMode();
  const passedProps = {
    clientId,
    name,
    setAttributes,
    settings: {
      ...settings,
      typography: {
        ...settings.typography,
        // The text alignment UI for individual blocks is rendered in
        // the block toolbar, so disable it here.
        textAlign: false
      }
    }
  };
  if (blockEditingMode !== "default") {
    return null;
  }
  return /* @__PURE__ */ jsxs(Fragment, { children: [
    /* @__PURE__ */ jsx(ColorEdit, { ...passedProps }),
    /* @__PURE__ */ jsx(BackgroundImagePanel, { ...passedProps }),
    /* @__PURE__ */ jsx(TypographyPanel, { ...passedProps }),
    /* @__PURE__ */ jsx(BorderPanel, { ...passedProps }),
    /* @__PURE__ */ jsx(DimensionsPanel, { ...passedProps })
  ] });
}
var style_default = {
  edit: BlockStyleControls,
  hasSupport: hasStyleSupport,
  addSaveProps,
  attributeKeys: ["style"],
  useBlockProps
};
var elementTypes = [
  { elementType: "button" },
  { elementType: "link", pseudo: [":hover"] },
  {
    elementType: "heading",
    elements: ["h1", "h2", "h3", "h4", "h5", "h6"]
  }
];
var STYLE_BLOCK_PROPS_REFERENCE = {};
function useBlockProps({ name, style }) {
  const blockElementsContainerIdentifier = useInstanceId(
    STYLE_BLOCK_PROPS_REFERENCE,
    "wp-elements"
  );
  const baseElementSelector = `.${blockElementsContainerIdentifier}`;
  const blockElementStyles = style?.elements;
  const styles = useMemo(() => {
    if (!blockElementStyles) {
      return;
    }
    const elementCSSRules = [];
    elementTypes.forEach(({ elementType, pseudo, elements }) => {
      const skipSerialization = shouldSkipSerialization(
        name,
        COLOR_SUPPORT_KEY,
        elementType
      );
      if (skipSerialization) {
        return;
      }
      const elementStyles = blockElementStyles?.[elementType];
      if (elementStyles) {
        const selector = scopeSelector(
          baseElementSelector,
          ELEMENTS[elementType]
        );
        elementCSSRules.push(
          compileCSS(elementStyles, { selector })
        );
        if (pseudo) {
          pseudo.forEach((pseudoSelector) => {
            if (elementStyles[pseudoSelector]) {
              elementCSSRules.push(
                compileCSS(elementStyles[pseudoSelector], {
                  selector: scopeSelector(
                    baseElementSelector,
                    `${ELEMENTS[elementType]}${pseudoSelector}`
                  )
                })
              );
            }
          });
        }
      }
      if (elements) {
        elements.forEach((element) => {
          if (blockElementStyles[element]) {
            elementCSSRules.push(
              compileCSS(blockElementStyles[element], {
                selector: scopeSelector(
                  baseElementSelector,
                  ELEMENTS[element]
                )
              })
            );
          }
        });
      }
    });
    return elementCSSRules.length > 0 ? elementCSSRules.join("") : void 0;
  }, [baseElementSelector, blockElementStyles, name]);
  useStyleOverride({ css: styles });
  return addSaveProps(
    { className: blockElementsContainerIdentifier },
    name,
    { style },
    skipSerializationPathsEdit
  );
}
addFilter(
  "blocks.registerBlockType",
  "core/style/addAttribute",
  addAttribute
);
export {
  addSaveProps,
  style_default as default,
  getInlineStyles,
  omitStyle
};
//# sourceMappingURL=style.js.map
