/* wp:polyfill */
"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.PrivateRichText = void 0;
Object.defineProperty(exports, "RichTextShortcut", {
  enumerable: true,
  get: function () {
    return _shortcut.RichTextShortcut;
  }
});
Object.defineProperty(exports, "RichTextToolbarButton", {
  enumerable: true,
  get: function () {
    return _toolbarButton.RichTextToolbarButton;
  }
});
exports.RichTextWrapper = RichTextWrapper;
Object.defineProperty(exports, "__unstableRichTextInputEvent", {
  enumerable: true,
  get: function () {
    return _inputEvent.__unstableRichTextInputEvent;
  }
});
exports.keyboardShortcutContext = exports.inputEventContext = exports.default = void 0;
var _clsx = _interopRequireDefault(require("clsx"));
var _element = require("@wordpress/element");
var _data = require("@wordpress/data");
var _compose = require("@wordpress/compose");
var _richText = require("@wordpress/rich-text");
var _components = require("@wordpress/components");
var _blocks = require("@wordpress/blocks");
var _deprecated = _interopRequireDefault(require("@wordpress/deprecated"));
var _i18n = require("@wordpress/i18n");
var _autocomplete = require("../autocomplete");
var _blockEdit = require("../block-edit");
var _context = require("../block-edit/context");
var _formatToolbarContainer = _interopRequireDefault(require("./format-toolbar-container"));
var _store = require("../../store");
var _useMarkPersistent = require("./use-mark-persistent");
var _useFormatTypes = require("./use-format-types");
var _eventListeners = require("./event-listeners");
var _formatEdit = _interopRequireDefault(require("./format-edit"));
var _utils = require("./utils");
var _content = require("./content");
var _withDeprecations = require("./with-deprecations");
var _useBindingsAttributes = require("../../hooks/use-bindings-attributes");
var _blockContext = _interopRequireDefault(require("../block-context"));
var _jsxRuntime = require("react/jsx-runtime");
var _shortcut = require("./shortcut");
var _toolbarButton = require("./toolbar-button");
var _inputEvent = require("./input-event");
/**
 * External dependencies
 */

/**
 * WordPress dependencies
 */

/**
 * Internal dependencies
 */

const keyboardShortcutContext = exports.keyboardShortcutContext = (0, _element.createContext)();
const inputEventContext = exports.inputEventContext = (0, _element.createContext)();
const instanceIdKey = Symbol('instanceId');

/**
 * Removes props used for the native version of RichText so that they are not
 * passed to the DOM element and log warnings.
 *
 * @param {Object} props Props to filter.
 *
 * @return {Object} Filtered props.
 */
function removeNativeProps(props) {
  const {
    __unstableMobileNoFocusOnMount,
    deleteEnter,
    placeholderTextColor,
    textAlign,
    selectionColor,
    tagsToEliminate,
    disableEditingMenu,
    fontSize,
    fontFamily,
    fontWeight,
    fontStyle,
    minWidth,
    maxWidth,
    disableSuggestions,
    disableAutocorrection,
    ...restProps
  } = props;
  return restProps;
}
function RichTextWrapper({
  children,
  tagName = 'div',
  value: adjustedValue = '',
  onChange: adjustedOnChange,
  isSelected: originalIsSelected,
  multiline,
  inlineToolbar,
  wrapperClassName,
  autocompleters,
  onReplace,
  placeholder,
  allowedFormats,
  withoutInteractiveFormatting,
  onRemove,
  onMerge,
  onSplit,
  __unstableOnSplitAtEnd: onSplitAtEnd,
  __unstableOnSplitAtDoubleLineEnd: onSplitAtDoubleLineEnd,
  identifier,
  preserveWhiteSpace,
  __unstablePastePlainText: pastePlainText,
  __unstableEmbedURLOnPaste,
  __unstableDisableFormats: disableFormats,
  disableLineBreaks,
  __unstableAllowPrefixTransformations,
  readOnly,
  ...props
}, forwardedRef) {
  props = removeNativeProps(props);
  if (onSplit) {
    (0, _deprecated.default)('wp.blockEditor.RichText onSplit prop', {
      since: '6.4',
      alternative: 'block.json support key: "splitting"'
    });
  }
  const instanceId = (0, _compose.useInstanceId)(RichTextWrapper);
  const anchorRef = (0, _element.useRef)();
  const context = (0, _blockEdit.useBlockEditContext)();
  const {
    clientId,
    isSelected: isBlockSelected,
    name: blockName
  } = context;
  const blockBindings = context[_context.blockBindingsKey];
  const blockContext = (0, _element.useContext)(_blockContext.default);
  const registry = (0, _data.useRegistry)();
  const selector = select => {
    // Avoid subscribing to the block editor store if the block is not
    // selected.
    if (!isBlockSelected) {
      return {
        isSelected: false
      };
    }
    const {
      getSelectionStart,
      getSelectionEnd
    } = select(_store.store);
    const selectionStart = getSelectionStart();
    const selectionEnd = getSelectionEnd();
    let isSelected;
    if (originalIsSelected === undefined) {
      isSelected = selectionStart.clientId === clientId && selectionEnd.clientId === clientId && (identifier ? selectionStart.attributeKey === identifier : selectionStart[instanceIdKey] === instanceId);
    } else if (originalIsSelected) {
      isSelected = selectionStart.clientId === clientId;
    }
    return {
      selectionStart: isSelected ? selectionStart.offset : undefined,
      selectionEnd: isSelected ? selectionEnd.offset : undefined,
      isSelected
    };
  };
  const {
    selectionStart,
    selectionEnd,
    isSelected
  } = (0, _data.useSelect)(selector, [clientId, identifier, instanceId, originalIsSelected, isBlockSelected]);
  const {
    disableBoundBlock,
    bindingsPlaceholder,
    bindingsLabel
  } = (0, _data.useSelect)(select => {
    var _fieldsList$relatedBi;
    if (!blockBindings?.[identifier] || !(0, _useBindingsAttributes.canBindBlock)(blockName)) {
      return {};
    }
    const relatedBinding = blockBindings[identifier];
    const blockBindingsSource = (0, _blocks.getBlockBindingsSource)(relatedBinding.source);
    const blockBindingsContext = {};
    if (blockBindingsSource?.usesContext?.length) {
      for (const key of blockBindingsSource.usesContext) {
        blockBindingsContext[key] = blockContext[key];
      }
    }
    const _disableBoundBlock = !blockBindingsSource?.canUserEditValue?.({
      select,
      context: blockBindingsContext,
      args: relatedBinding.args
    });

    // Don't modify placeholders if value is not empty.
    if (adjustedValue.length > 0) {
      return {
        disableBoundBlock: _disableBoundBlock,
        // Null values will make them fall back to the default behavior.
        bindingsPlaceholder: null,
        bindingsLabel: null
      };
    }
    const {
      getBlockAttributes
    } = select(_store.store);
    const blockAttributes = getBlockAttributes(clientId);
    const fieldsList = blockBindingsSource?.getFieldsList?.({
      select,
      context: blockBindingsContext
    });
    const bindingKey = (_fieldsList$relatedBi = fieldsList?.[relatedBinding?.args?.key]?.label) !== null && _fieldsList$relatedBi !== void 0 ? _fieldsList$relatedBi : blockBindingsSource?.label;
    const _bindingsPlaceholder = _disableBoundBlock ? bindingKey : (0, _i18n.sprintf)(/* translators: %s: connected field label or source label */
    (0, _i18n.__)('Add %s'), bindingKey);
    const _bindingsLabel = _disableBoundBlock ? relatedBinding?.args?.key || blockBindingsSource?.label : (0, _i18n.sprintf)(/* translators: %s: source label or key */
    (0, _i18n.__)('Empty %s; start writing to edit its value'), relatedBinding?.args?.key || blockBindingsSource?.label);
    return {
      disableBoundBlock: _disableBoundBlock,
      bindingsPlaceholder: blockAttributes?.placeholder || _bindingsPlaceholder,
      bindingsLabel: _bindingsLabel
    };
  }, [blockBindings, identifier, blockName, adjustedValue, clientId, blockContext]);
  const shouldDisableEditing = readOnly || disableBoundBlock;
  const {
    getSelectionStart,
    getSelectionEnd,
    getBlockRootClientId
  } = (0, _data.useSelect)(_store.store);
  const {
    selectionChange
  } = (0, _data.useDispatch)(_store.store);
  const adjustedAllowedFormats = (0, _utils.getAllowedFormats)({
    allowedFormats,
    disableFormats
  });
  const hasFormats = !adjustedAllowedFormats || adjustedAllowedFormats.length > 0;
  const onSelectionChange = (0, _element.useCallback)((start, end) => {
    const selection = {};
    const unset = start === undefined && end === undefined;
    const baseSelection = {
      clientId,
      [identifier ? 'attributeKey' : instanceIdKey]: identifier ? identifier : instanceId
    };
    if (typeof start === 'number' || unset) {
      // If we are only setting the start (or the end below), which
      // means a partial selection, and we're not updating a selection
      // with the same client ID, abort. This means the selected block
      // is a parent block.
      if (end === undefined && getBlockRootClientId(clientId) !== getBlockRootClientId(getSelectionEnd().clientId)) {
        return;
      }
      selection.start = {
        ...baseSelection,
        offset: start
      };
    }
    if (typeof end === 'number' || unset) {
      if (start === undefined && getBlockRootClientId(clientId) !== getBlockRootClientId(getSelectionStart().clientId)) {
        return;
      }
      selection.end = {
        ...baseSelection,
        offset: end
      };
    }
    selectionChange(selection);
  }, [clientId, getBlockRootClientId, getSelectionEnd, getSelectionStart, identifier, instanceId, selectionChange]);
  const {
    formatTypes,
    prepareHandlers,
    valueHandlers,
    changeHandlers,
    dependencies
  } = (0, _useFormatTypes.useFormatTypes)({
    clientId,
    identifier,
    withoutInteractiveFormatting,
    allowedFormats: adjustedAllowedFormats
  });
  function addEditorOnlyFormats(value) {
    return valueHandlers.reduce((accumulator, fn) => fn(accumulator, value.text), value.formats);
  }
  function removeEditorOnlyFormats(value) {
    formatTypes.forEach(formatType => {
      // Remove formats created by prepareEditableTree, because they are editor only.
      if (formatType.__experimentalCreatePrepareEditableTree) {
        value = (0, _richText.removeFormat)(value, formatType.name, 0, value.text.length);
      }
    });
    return value.formats;
  }
  function addInvisibleFormats(value) {
    return prepareHandlers.reduce((accumulator, fn) => fn(accumulator, value.text), value.formats);
  }
  const {
    value,
    getValue,
    onChange,
    ref: richTextRef
  } = (0, _richText.__unstableUseRichText)({
    value: adjustedValue,
    onChange(html, {
      __unstableFormats,
      __unstableText
    }) {
      adjustedOnChange(html);
      Object.values(changeHandlers).forEach(changeHandler => {
        changeHandler(__unstableFormats, __unstableText);
      });
    },
    selectionStart,
    selectionEnd,
    onSelectionChange,
    placeholder: bindingsPlaceholder || placeholder,
    __unstableIsSelected: isSelected,
    __unstableDisableFormats: disableFormats,
    preserveWhiteSpace,
    __unstableDependencies: [...dependencies, tagName],
    __unstableAfterParse: addEditorOnlyFormats,
    __unstableBeforeSerialize: removeEditorOnlyFormats,
    __unstableAddInvisibleFormats: addInvisibleFormats
  });
  const autocompleteProps = (0, _autocomplete.useBlockEditorAutocompleteProps)({
    onReplace,
    completers: autocompleters,
    record: value,
    onChange
  });
  (0, _useMarkPersistent.useMarkPersistent)({
    html: adjustedValue,
    value
  });
  const keyboardShortcuts = (0, _element.useRef)(new Set());
  const inputEvents = (0, _element.useRef)(new Set());
  function onFocus() {
    anchorRef.current?.focus();
  }
  const TagName = tagName;
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
    children: [isSelected && /*#__PURE__*/(0, _jsxRuntime.jsx)(keyboardShortcutContext.Provider, {
      value: keyboardShortcuts,
      children: /*#__PURE__*/(0, _jsxRuntime.jsx)(inputEventContext.Provider, {
        value: inputEvents,
        children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_components.Popover.__unstableSlotNameProvider, {
          value: "__unstable-block-tools-after",
          children: [children && children({
            value,
            onChange,
            onFocus
          }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_formatEdit.default, {
            value: value,
            onChange: onChange,
            onFocus: onFocus,
            formatTypes: formatTypes,
            forwardedRef: anchorRef
          })]
        })
      })
    }), isSelected && hasFormats && /*#__PURE__*/(0, _jsxRuntime.jsx)(_formatToolbarContainer.default, {
      inline: inlineToolbar,
      editableContentElement: anchorRef.current
    }), /*#__PURE__*/(0, _jsxRuntime.jsx)(TagName
    // Overridable props.
    , {
      role: "textbox",
      "aria-multiline": !disableLineBreaks,
      "aria-readonly": shouldDisableEditing,
      ...props,
      "aria-label": bindingsLabel || props['aria-label'] || placeholder,
      ...autocompleteProps,
      ref: (0, _compose.useMergeRefs)([
      // Rich text ref must be first because its focus listener
      // must be set up before any other ref calls .focus() on
      // mount.
      richTextRef, forwardedRef, autocompleteProps.ref, props.ref, (0, _eventListeners.useEventListeners)({
        registry,
        getValue,
        onChange,
        __unstableAllowPrefixTransformations,
        formatTypes,
        onReplace,
        selectionChange,
        isSelected,
        disableFormats,
        value,
        tagName,
        onSplit,
        __unstableEmbedURLOnPaste,
        pastePlainText,
        onMerge,
        onRemove,
        removeEditorOnlyFormats,
        disableLineBreaks,
        onSplitAtEnd,
        onSplitAtDoubleLineEnd,
        keyboardShortcuts,
        inputEvents
      }), anchorRef]),
      contentEditable: !shouldDisableEditing,
      suppressContentEditableWarning: true,
      className: (0, _clsx.default)('block-editor-rich-text__editable', props.className, 'rich-text')
      // Setting tabIndex to 0 is unnecessary, the element is already
      // focusable because it's contentEditable. This also fixes a
      // Safari bug where it's not possible to Shift+Click multi
      // select blocks when Shift Clicking into an element with
      // tabIndex because Safari will focus the element. However,
      // Safari will correctly ignore nested contentEditable elements.
      ,
      tabIndex: props.tabIndex === 0 && !shouldDisableEditing ? null : props.tabIndex,
      "data-wp-block-attribute-key": identifier
    })]
  });
}

// This is the private API for the RichText component.
// It allows access to all props, not just the public ones.
const PrivateRichText = exports.PrivateRichText = (0, _withDeprecations.withDeprecations)((0, _element.forwardRef)(RichTextWrapper));
PrivateRichText.Content = _content.Content;
PrivateRichText.isEmpty = value => {
  return !value || value.length === 0;
};

// This is the public API for the RichText component.
// We wrap the PrivateRichText component to hide some props from the public API.
/**
 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/rich-text/README.md
 */
const PublicForwardedRichTextContainer = (0, _element.forwardRef)((props, ref) => {
  const context = (0, _blockEdit.useBlockEditContext)();
  const isPreviewMode = context[_context.isPreviewModeKey];
  if (isPreviewMode) {
    // Remove all non-content props.
    const {
      children,
      tagName: Tag = 'div',
      value,
      onChange,
      isSelected,
      multiline,
      inlineToolbar,
      wrapperClassName,
      autocompleters,
      onReplace,
      placeholder,
      allowedFormats,
      withoutInteractiveFormatting,
      onRemove,
      onMerge,
      onSplit,
      __unstableOnSplitAtEnd,
      __unstableOnSplitAtDoubleLineEnd,
      identifier,
      preserveWhiteSpace,
      __unstablePastePlainText,
      __unstableEmbedURLOnPaste,
      __unstableDisableFormats,
      disableLineBreaks,
      __unstableAllowPrefixTransformations,
      readOnly,
      ...contentProps
    } = removeNativeProps(props);
    return /*#__PURE__*/(0, _jsxRuntime.jsx)(Tag, {
      ...contentProps,
      dangerouslySetInnerHTML: {
        __html: (0, _content.valueToHTMLString)(value, multiline)
      }
    });
  }
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(PrivateRichText, {
    ref: ref,
    ...props,
    readOnly: false
  });
});
PublicForwardedRichTextContainer.Content = _content.Content;
PublicForwardedRichTextContainer.isEmpty = value => {
  return !value || value.length === 0;
};
var _default = exports.default = PublicForwardedRichTextContainer;
//# sourceMappingURL=index.js.map