"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 _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,
    onlyBlock,
    parentBlockType,
    previousBlockClientId,
    selectedBlockClientIds,
    openedBlockSettingsMenu,
    isContentOnly
  } = (0, _data.useSelect)(select => {
    const {
      getBlockCount,
      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,
      onlyBlock: 1 === getBlockCount(_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);
    }
  }
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_blockActions.default, {
    clientIds: clientIds,
    __experimentalUpdateSelection: !__experimentalSelectBlock,
    children: ({
      canCopyStyles,
      canDuplicate,
      canInsertBlock,
      canMove,
      canRemove,
      onDuplicate,
      onInsertAfter,
      onInsertBefore,
      onRemove,
      onCopy,
      onPasteStyles,
      onMoveTo
    }) => /*#__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
            }
          }), !parentBlockIsSelected && !!firstParentClientId && /*#__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')
            })]
          })]
        }), 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,
            canMove,
            onMoveTo,
            onlyBlock,
            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