"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.useBlockCommands = void 0;
var _i18n = require("@wordpress/i18n");
var _blocks = require("@wordpress/blocks");
var _data = require("@wordpress/data");
var _commands = require("@wordpress/commands");
var _icons = require("@wordpress/icons");
var _blockIcon = _interopRequireDefault(require("../block-icon"));
var _store = require("../../store");
var _jsxRuntime = require("react/jsx-runtime");
/**
 * WordPress dependencies
 */

/**
 * Internal dependencies
 */

const getTransformCommands = () => function useTransformCommands() {
  const {
    replaceBlocks,
    multiSelect
  } = (0, _data.useDispatch)(_store.store);
  const {
    blocks,
    clientIds,
    canRemove,
    possibleBlockTransformations,
    invalidSelection
  } = (0, _data.useSelect)(select => {
    const {
      getBlockRootClientId,
      getBlockTransformItems,
      getSelectedBlockClientIds,
      getBlocksByClientId,
      canRemoveBlocks
    } = select(_store.store);
    const selectedBlockClientIds = getSelectedBlockClientIds();
    const selectedBlocks = getBlocksByClientId(selectedBlockClientIds);

    // selectedBlocks can have `null`s when something tries to call `selectBlock` with an inexistent clientId.
    // These nulls will cause fatal errors down the line.
    // In order to prevent discrepancies between selectedBlockClientIds and selectedBlocks, we effectively treat the entire selection as invalid.
    // @see https://github.com/WordPress/gutenberg/pull/59410#issuecomment-2006304536
    if (selectedBlocks.filter(block => !block).length > 0) {
      return {
        invalidSelection: true
      };
    }
    const rootClientId = getBlockRootClientId(selectedBlockClientIds[0]);
    return {
      blocks: selectedBlocks,
      clientIds: selectedBlockClientIds,
      possibleBlockTransformations: getBlockTransformItems(selectedBlocks, rootClientId),
      canRemove: canRemoveBlocks(selectedBlockClientIds),
      invalidSelection: false
    };
  }, []);
  if (invalidSelection) {
    return {
      isLoading: false,
      commands: []
    };
  }
  const isTemplate = blocks.length === 1 && (0, _blocks.isTemplatePart)(blocks[0]);
  function selectForMultipleBlocks(insertedBlocks) {
    if (insertedBlocks.length > 1) {
      multiSelect(insertedBlocks[0].clientId, insertedBlocks[insertedBlocks.length - 1].clientId);
    }
  }

  // Simple block tranformation based on the `Block Transforms` API.
  function onBlockTransform(name) {
    const newBlocks = (0, _blocks.switchToBlockType)(blocks, name);
    replaceBlocks(clientIds, newBlocks);
    selectForMultipleBlocks(newBlocks);
  }

  /**
   * The `isTemplate` check is a stopgap solution here.
   * Ideally, the Transforms API should handle this
   * by allowing to exclude blocks from wildcard transformations.
   */
  const hasPossibleBlockTransformations = !!possibleBlockTransformations.length && canRemove && !isTemplate;
  if (!clientIds || clientIds.length < 1 || !hasPossibleBlockTransformations) {
    return {
      isLoading: false,
      commands: []
    };
  }
  const commands = possibleBlockTransformations.map(transformation => {
    const {
      name,
      title,
      icon
    } = transformation;
    return {
      name: 'core/block-editor/transform-to-' + name.replace('/', '-'),
      /* translators: %s: Block or block variation name. */
      label: (0, _i18n.sprintf)((0, _i18n.__)('Transform to %s'), title),
      icon: /*#__PURE__*/(0, _jsxRuntime.jsx)(_blockIcon.default, {
        icon: icon
      }),
      callback: ({
        close
      }) => {
        onBlockTransform(name);
        close();
      }
    };
  });
  return {
    isLoading: false,
    commands
  };
};
const getQuickActionsCommands = () => function useQuickActionsCommands() {
  const {
    clientIds,
    isUngroupable,
    isGroupable
  } = (0, _data.useSelect)(select => {
    const {
      getSelectedBlockClientIds,
      isUngroupable: _isUngroupable,
      isGroupable: _isGroupable
    } = select(_store.store);
    const selectedBlockClientIds = getSelectedBlockClientIds();
    return {
      clientIds: selectedBlockClientIds,
      isUngroupable: _isUngroupable(),
      isGroupable: _isGroupable()
    };
  }, []);
  const {
    canInsertBlockType,
    getBlockRootClientId,
    getBlocksByClientId,
    canRemoveBlocks
  } = (0, _data.useSelect)(_store.store);
  const {
    getDefaultBlockName,
    getGroupingBlockName
  } = (0, _data.useSelect)(_blocks.store);
  const blocks = getBlocksByClientId(clientIds);
  const {
    removeBlocks,
    replaceBlocks,
    duplicateBlocks,
    insertAfterBlock,
    insertBeforeBlock
  } = (0, _data.useDispatch)(_store.store);
  const onGroup = () => {
    if (!blocks.length) {
      return;
    }
    const groupingBlockName = getGroupingBlockName();

    // Activate the `transform` on `core/group` which does the conversion.
    const newBlocks = (0, _blocks.switchToBlockType)(blocks, groupingBlockName);
    if (!newBlocks) {
      return;
    }
    replaceBlocks(clientIds, newBlocks);
  };
  const onUngroup = () => {
    if (!blocks.length) {
      return;
    }
    const innerBlocks = blocks[0].innerBlocks;
    if (!innerBlocks.length) {
      return;
    }
    replaceBlocks(clientIds, innerBlocks);
  };
  if (!clientIds || clientIds.length < 1) {
    return {
      isLoading: false,
      commands: []
    };
  }
  const rootClientId = getBlockRootClientId(clientIds[0]);
  const canInsertDefaultBlock = canInsertBlockType(getDefaultBlockName(), rootClientId);
  const canDuplicate = blocks.every(block => {
    return !!block && (0, _blocks.hasBlockSupport)(block.name, 'multiple', true) && canInsertBlockType(block.name, rootClientId);
  });
  const canRemove = canRemoveBlocks(clientIds);
  const commands = [];
  if (canDuplicate) {
    commands.push({
      name: 'duplicate',
      label: (0, _i18n.__)('Duplicate'),
      callback: () => duplicateBlocks(clientIds, true),
      icon: _icons.copy
    });
  }
  if (canInsertDefaultBlock) {
    commands.push({
      name: 'add-before',
      label: (0, _i18n.__)('Add before'),
      callback: () => {
        const clientId = Array.isArray(clientIds) ? clientIds[0] : clientId;
        insertBeforeBlock(clientId);
      },
      icon: _icons.plus
    }, {
      name: 'add-after',
      label: (0, _i18n.__)('Add after'),
      callback: () => {
        const clientId = Array.isArray(clientIds) ? clientIds[clientIds.length - 1] : clientId;
        insertAfterBlock(clientId);
      },
      icon: _icons.plus
    });
  }
  if (isGroupable) {
    commands.push({
      name: 'Group',
      label: (0, _i18n.__)('Group'),
      callback: onGroup,
      icon: _icons.group
    });
  }
  if (isUngroupable) {
    commands.push({
      name: 'ungroup',
      label: (0, _i18n.__)('Ungroup'),
      callback: onUngroup,
      icon: _icons.ungroup
    });
  }
  if (canRemove) {
    commands.push({
      name: 'remove',
      label: (0, _i18n.__)('Delete'),
      callback: () => removeBlocks(clientIds, true),
      icon: _icons.trash
    });
  }
  return {
    isLoading: false,
    commands: commands.map(command => ({
      ...command,
      name: 'core/block-editor/action-' + command.name,
      callback: ({
        close
      }) => {
        command.callback();
        close();
      }
    }))
  };
};
const useBlockCommands = () => {
  (0, _commands.useCommandLoader)({
    name: 'core/block-editor/blockTransforms',
    hook: getTransformCommands()
  });
  (0, _commands.useCommandLoader)({
    name: 'core/block-editor/blockQuickActions',
    hook: getQuickActionsCommands(),
    context: 'block-selection-edit'
  });
};
exports.useBlockCommands = useBlockCommands;
//# sourceMappingURL=index.js.map