"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.BlockSettingsDropdown = BlockSettingsDropdown;
exports.default = void 0;
var _blocks = require("@wordpress/blocks");
var _components = require("@wordpress/components");
var _data = require("@wordpress/data");
var _icons = require("@wordpress/icons");
var _element = require("@wordpress/element");
var _i18n = require("@wordpress/i18n");
var _keycodes = require("@wordpress/keycodes");
var _keyboardShortcuts = require("@wordpress/keyboard-shortcuts");
var _compose = require("@wordpress/compose");
var _blockActions = _interopRequireDefault(require("../block-actions"));
var _blockCommentIconSlot = _interopRequireDefault(require("../../components/collab/block-comment-icon-slot"));
var _blockHtmlConvertButton = _interopRequireDefault(require("./block-html-convert-button"));
var _blockSettingsMenuFirstItem = _interopRequireDefault(require("./block-settings-menu-first-item"));
var _blockSettingsMenuControls = _interopRequireDefault(require("../block-settings-menu-controls"));
var _blockParentSelectorMenuItem = _interopRequireDefault(require("./block-parent-selector-menu-item"));
var _store = require("../../store");
var _lockUnlock = require("../../lock-unlock");
var _jsxRuntime = require("react/jsx-runtime");
/**
 * WordPress dependencies
 */

/**
 * Internal dependencies
 */

const POPOVER_PROPS = {
  className: 'block-editor-block-settings-menu__popover',
  placement: 'bottom-start'
};
function CopyMenuItem({
  clientIds,
  onCopy,
  label,
  shortcut
}) {
  const {
    getBlocksByClientId
  } = (0, _data.useSelect)(_store.store);
  const ref = (0, _compose.useCopyToClipboard)(() => (0, _blocks.serialize)(getBlocksByClientId(clientIds)), onCopy);
  const copyMenuItemLabel = label ? label : (0, _i18n.__)('Copy');
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.MenuItem, {
    ref: ref,
    shortcut: shortcut,
    children: copyMenuItemLabel
  });
}
function BlockSettingsDropdown({
  block,
  clientIds,
  children,
  __experimentalSelectBlock,
  ...props
}) {
  // Get the client id of the current block for this menu, if one is set.
  const currentClientId = block?.clientId;
  const count = clientIds.length;
  const firstBlockClientId = clientIds[0];
  const {
    firstParentClientId,
    parentBlockType,
    previousBlockClientId,
    selectedBlockClientIds,
    openedBlockSettingsMenu,
    isContentOnly
  } = (0, _data.useSelect)(select => {
    const {
      getBlockName,
      getBlockRootClientId,
      getPreviousBlockClientId,
      getSelectedBlockClientIds,
      getBlockAttributes,
      getOpenedBlockSettingsMenu,
      getBlockEditingMode
    } = (0, _lockUnlock.unlock)(select(_store.store));
    const {
      getActiveBlockVariation
    } = select(_blocks.store);
    const _firstParentClientId = getBlockRootClientId(firstBlockClientId);
    const parentBlockName = _firstParentClientId && getBlockName(_firstParentClientId);
    return {
      firstParentClientId: _firstParentClientId,
      parentBlockType: _firstParentClientId && (getActiveBlockVariation(parentBlockName, getBlockAttributes(_firstParentClientId)) || (0, _blocks.getBlockType)(parentBlockName)),
      previousBlockClientId: getPreviousBlockClientId(firstBlockClientId),
      selectedBlockClientIds: getSelectedBlockClientIds(),
      openedBlockSettingsMenu: getOpenedBlockSettingsMenu(),
      isContentOnly: getBlockEditingMode(firstBlockClientId) === 'contentOnly'
    };
  }, [firstBlockClientId]);
  const {
    getBlockOrder,
    getSelectedBlockClientIds
  } = (0, _data.useSelect)(_store.store);
  const {
    setOpenedBlockSettingsMenu
  } = (0, _lockUnlock.unlock)((0, _data.useDispatch)(_store.store));
  const shortcuts = (0, _data.useSelect)(select => {
    const {
      getShortcutRepresentation
    } = select(_keyboardShortcuts.store);
    return {
      duplicate: getShortcutRepresentation('core/block-editor/duplicate'),
      remove: getShortcutRepresentation('core/block-editor/remove'),
      insertAfter: getShortcutRepresentation('core/block-editor/insert-after'),
      insertBefore: getShortcutRepresentation('core/block-editor/insert-before')
    };
  }, []);
  const hasSelectedBlocks = selectedBlockClientIds.length > 0;
  async function updateSelectionAfterDuplicate(clientIdsPromise) {
    if (!__experimentalSelectBlock) {
      return;
    }
    const ids = await clientIdsPromise;
    if (ids && ids[0]) {
      __experimentalSelectBlock(ids[0], false);
    }
  }
  function updateSelectionAfterRemove() {
    if (!__experimentalSelectBlock) {
      return;
    }
    let blockToFocus = previousBlockClientId || firstParentClientId;

    // Focus the first block if there's no previous block nor parent block.
    if (!blockToFocus) {
      blockToFocus = getBlockOrder()[0];
    }

    // Only update the selection if the original selection is removed.
    const shouldUpdateSelection = hasSelectedBlocks && getSelectedBlockClientIds().length === 0;
    __experimentalSelectBlock(blockToFocus, shouldUpdateSelection);
  }

  // This can occur when the selected block (the parent)
  // displays child blocks within a List View.
  const parentBlockIsSelected = selectedBlockClientIds?.includes(firstParentClientId);

  // When a currentClientId is in use, treat the menu as a controlled component.
  // This ensures that only one block settings menu is open at a time.
  // This is a temporary solution to work around an issue with `onFocusOutside`
  // where it does not allow a dropdown to be closed if focus was never within
  // the dropdown to begin with. Examples include a user either CMD+Clicking or
  // right clicking into an inactive window.
  // See: https://github.com/WordPress/gutenberg/pull/54083
  const open = !currentClientId ? undefined : openedBlockSettingsMenu === currentClientId || false;
  function onToggle(localOpen) {
    if (localOpen && openedBlockSettingsMenu !== currentClientId) {
      setOpenedBlockSettingsMenu(currentClientId);
    } else if (!localOpen && openedBlockSettingsMenu && openedBlockSettingsMenu === currentClientId) {
      setOpenedBlockSettingsMenu(undefined);
    }
  }
  const shouldShowBlockParentMenuItem = !parentBlockIsSelected && !!firstParentClientId;
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_blockActions.default, {
    clientIds: clientIds,
    __experimentalUpdateSelection: !__experimentalSelectBlock,
    children: ({
      canCopyStyles,
      canDuplicate,
      canInsertBlock,
      canRemove,
      onDuplicate,
      onInsertAfter,
      onInsertBefore,
      onRemove,
      onCopy,
      onPasteStyles
    }) => {
      // It is possible that some plugins register fills for this menu
      // even if Core doesn't render anything in the block settings menu.
      // in which case, we may want to render the menu anyway.
      // That said for now, we can start more conservative.
      const isEmpty = !canRemove && !canDuplicate && !canInsertBlock && isContentOnly;
      if (isEmpty) {
        return null;
      }
      return /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.DropdownMenu, {
        icon: _icons.moreVertical,
        label: (0, _i18n.__)('Options'),
        className: "block-editor-block-settings-menu",
        popoverProps: POPOVER_PROPS,
        open: open,
        onToggle: onToggle,
        noIcons: true,
        ...props,
        children: ({
          onClose
        }) => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
          children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_components.MenuGroup, {
            children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_blockSettingsMenuFirstItem.default.Slot, {
              fillProps: {
                onClose
              }
            }), shouldShowBlockParentMenuItem && /*#__PURE__*/(0, _jsxRuntime.jsx)(_blockParentSelectorMenuItem.default, {
              parentClientId: firstParentClientId,
              parentBlockType: parentBlockType
            }), count === 1 && /*#__PURE__*/(0, _jsxRuntime.jsx)(_blockHtmlConvertButton.default, {
              clientId: firstBlockClientId
            }), !isContentOnly && /*#__PURE__*/(0, _jsxRuntime.jsx)(CopyMenuItem, {
              clientIds: clientIds,
              onCopy: onCopy,
              shortcut: _keycodes.displayShortcut.primary('c')
            }), canDuplicate && /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.MenuItem, {
              onClick: (0, _compose.pipe)(onClose, onDuplicate, updateSelectionAfterDuplicate),
              shortcut: shortcuts.duplicate,
              children: (0, _i18n.__)('Duplicate')
            }), canInsertBlock && !isContentOnly && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
              children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_components.MenuItem, {
                onClick: (0, _compose.pipe)(onClose, onInsertBefore),
                shortcut: shortcuts.insertBefore,
                children: (0, _i18n.__)('Add before')
              }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.MenuItem, {
                onClick: (0, _compose.pipe)(onClose, onInsertAfter),
                shortcut: shortcuts.insertAfter,
                children: (0, _i18n.__)('Add after')
              })]
            }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_blockCommentIconSlot.default.Slot, {
              fillProps: {
                onClose
              }
            })]
          }), canCopyStyles && !isContentOnly && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_components.MenuGroup, {
            children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(CopyMenuItem, {
              clientIds: clientIds,
              onCopy: onCopy,
              label: (0, _i18n.__)('Copy styles')
            }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.MenuItem, {
              onClick: onPasteStyles,
              children: (0, _i18n.__)('Paste styles')
            })]
          }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_blockSettingsMenuControls.default.Slot, {
            fillProps: {
              onClose,
              count,
              firstBlockClientId
            },
            clientIds: clientIds
          }), typeof children === 'function' ? children({
            onClose
          }) : _element.Children.map(child => (0, _element.cloneElement)(child, {
            onClose
          })), canRemove && /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.MenuGroup, {
            children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.MenuItem, {
              onClick: (0, _compose.pipe)(onClose, onRemove, updateSelectionAfterRemove),
              shortcut: shortcuts.remove,
              children: (0, _i18n.__)('Delete')
            })
          })]
        })
      });
    }
  });
}
var _default = exports.default = BlockSettingsDropdown;
//# sourceMappingURL=block-settings-dropdown.js.map