// packages/block-editor/src/components/use-paste-styles/index.js
import { useCallback } from "@wordpress/element";
import { getBlockType, parse } from "@wordpress/blocks";
import { useDispatch, useRegistry } from "@wordpress/data";
import { store as noticesStore } from "@wordpress/notices";
import { __, sprintf } from "@wordpress/i18n";
import { store as blockEditorStore } from "../../store";
import {
  hasAlignSupport,
  hasBorderSupport,
  hasBackgroundColorSupport,
  hasTextAlignSupport,
  hasTextColorSupport,
  hasGradientSupport,
  hasCustomClassNameSupport,
  hasFontFamilySupport,
  hasFontSizeSupport,
  hasLayoutSupport,
  hasStyleSupport
} from "../../hooks/supports";
function hasSerializedBlocks(text) {
  try {
    const blocks = parse(text, {
      __unstableSkipMigrationLogs: true,
      __unstableSkipAutop: true
    });
    if (blocks.length === 1 && blocks[0].name === "core/freeform") {
      return false;
    }
    return true;
  } catch (err) {
    return false;
  }
}
var STYLE_ATTRIBUTES = {
  align: hasAlignSupport,
  borderColor: (nameOrType) => hasBorderSupport(nameOrType, "color"),
  backgroundColor: hasBackgroundColorSupport,
  textAlign: hasTextAlignSupport,
  textColor: hasTextColorSupport,
  gradient: hasGradientSupport,
  className: hasCustomClassNameSupport,
  fontFamily: hasFontFamilySupport,
  fontSize: hasFontSizeSupport,
  layout: hasLayoutSupport,
  style: hasStyleSupport
};
function getStyleAttributes(sourceBlock, targetBlock) {
  return Object.entries(STYLE_ATTRIBUTES).reduce(
    (attributes, [attributeKey, hasSupport]) => {
      if (hasSupport(sourceBlock.name) && hasSupport(targetBlock.name)) {
        attributes[attributeKey] = sourceBlock.attributes[attributeKey];
      }
      return attributes;
    },
    {}
  );
}
function recursivelyUpdateBlockAttributes(targetBlocks, sourceBlocks, updateBlockAttributes) {
  for (let index = 0; index < Math.min(sourceBlocks.length, targetBlocks.length); index += 1) {
    updateBlockAttributes(
      targetBlocks[index].clientId,
      getStyleAttributes(sourceBlocks[index], targetBlocks[index])
    );
    recursivelyUpdateBlockAttributes(
      targetBlocks[index].innerBlocks,
      sourceBlocks[index].innerBlocks,
      updateBlockAttributes
    );
  }
}
function usePasteStyles() {
  const registry = useRegistry();
  const { updateBlockAttributes } = useDispatch(blockEditorStore);
  const { createSuccessNotice, createWarningNotice, createErrorNotice } = useDispatch(noticesStore);
  return useCallback(
    async (targetBlocks) => {
      let html = "";
      try {
        if (!window.navigator.clipboard) {
          createErrorNotice(
            __(
              "Unable to paste styles. This feature is only available on secure (https) sites in supporting browsers."
            ),
            { type: "snackbar" }
          );
          return;
        }
        html = await window.navigator.clipboard.readText();
      } catch (error) {
        createErrorNotice(
          __(
            "Unable to paste styles. Please allow browser clipboard permissions before continuing."
          ),
          {
            type: "snackbar"
          }
        );
        return;
      }
      if (!html || !hasSerializedBlocks(html)) {
        createWarningNotice(
          __(
            "Unable to paste styles. Block styles couldn't be found within the copied content."
          ),
          {
            type: "snackbar"
          }
        );
        return;
      }
      const copiedBlocks = parse(html);
      if (copiedBlocks.length === 1) {
        registry.batch(() => {
          recursivelyUpdateBlockAttributes(
            targetBlocks,
            targetBlocks.map(() => copiedBlocks[0]),
            updateBlockAttributes
          );
        });
      } else {
        registry.batch(() => {
          recursivelyUpdateBlockAttributes(
            targetBlocks,
            copiedBlocks,
            updateBlockAttributes
          );
        });
      }
      if (targetBlocks.length === 1) {
        const title = getBlockType(targetBlocks[0].name)?.title;
        createSuccessNotice(
          sprintf(
            // Translators: %s: Name of the block being pasted, e.g. "Paragraph".
            __("Pasted styles to %s."),
            title
          ),
          { type: "snackbar" }
        );
      } else {
        createSuccessNotice(
          sprintf(
            // Translators: %d: The number of the blocks.
            __("Pasted styles to %d blocks."),
            targetBlocks.length
          ),
          { type: "snackbar" }
        );
      }
    },
    [
      registry.batch,
      updateBlockAttributes,
      createSuccessNotice,
      createWarningNotice,
      createErrorNotice
    ]
  );
}
export {
  usePasteStyles as default
};
//# sourceMappingURL=index.js.map
