"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);

// packages/block-editor/src/components/typewriter/index.js
var typewriter_exports = {};
__export(typewriter_exports, {
  default: () => typewriter_default,
  useTypewriter: () => useTypewriter
});
module.exports = __toCommonJS(typewriter_exports);
var import_compose = require("@wordpress/compose");
var import_dom = require("@wordpress/dom");
var import_data = require("@wordpress/data");
var import_keycodes = require("@wordpress/keycodes");
var import_store = require("../../store");
var import_jsx_runtime = require("react/jsx-runtime");
var isIE = window.navigator.userAgent.indexOf("Trident") !== -1;
var arrowKeyCodes = /* @__PURE__ */ new Set([import_keycodes.UP, import_keycodes.DOWN, import_keycodes.LEFT, import_keycodes.RIGHT]);
var initialTriggerPercentage = 0.75;
function useTypewriter() {
  const hasSelectedBlock = (0, import_data.useSelect)(
    (select) => select(import_store.store).hasSelectedBlock(),
    []
  );
  return (0, import_compose.useRefEffect)(
    (node) => {
      if (!hasSelectedBlock) {
        return;
      }
      const { ownerDocument } = node;
      const { defaultView } = ownerDocument;
      let scrollResizeRafId;
      let onKeyDownRafId;
      let caretRect;
      function onScrollResize() {
        if (scrollResizeRafId) {
          return;
        }
        scrollResizeRafId = defaultView.requestAnimationFrame(() => {
          computeCaretRectangle();
          scrollResizeRafId = null;
        });
      }
      function onKeyDown(event) {
        if (onKeyDownRafId) {
          defaultView.cancelAnimationFrame(onKeyDownRafId);
        }
        onKeyDownRafId = defaultView.requestAnimationFrame(() => {
          maintainCaretPosition(event);
          onKeyDownRafId = null;
        });
      }
      function maintainCaretPosition({ keyCode }) {
        if (!isSelectionEligibleForScroll()) {
          return;
        }
        const currentCaretRect = (0, import_dom.computeCaretRect)(defaultView);
        if (!currentCaretRect) {
          return;
        }
        if (!caretRect) {
          caretRect = currentCaretRect;
          return;
        }
        if (arrowKeyCodes.has(keyCode)) {
          caretRect = currentCaretRect;
          return;
        }
        const diff = currentCaretRect.top - caretRect.top;
        if (diff === 0) {
          return;
        }
        const scrollContainer = (0, import_dom.getScrollContainer)(node);
        if (!scrollContainer) {
          return;
        }
        const windowScroll = scrollContainer === ownerDocument.body || scrollContainer === ownerDocument.documentElement;
        const scrollY = windowScroll ? defaultView.scrollY : scrollContainer.scrollTop;
        const scrollContainerY = windowScroll ? 0 : scrollContainer.getBoundingClientRect().top;
        const relativeScrollPosition = windowScroll ? caretRect.top / defaultView.innerHeight : (caretRect.top - scrollContainerY) / (defaultView.innerHeight - scrollContainerY);
        if (scrollY === 0 && relativeScrollPosition < initialTriggerPercentage && isLastEditableNode()) {
          caretRect = currentCaretRect;
          return;
        }
        const scrollContainerHeight = windowScroll ? defaultView.innerHeight : scrollContainer.clientHeight;
        if (
          // The caret is under the lower fold.
          caretRect.top + caretRect.height > scrollContainerY + scrollContainerHeight || // The caret is above the upper fold.
          caretRect.top < scrollContainerY
        ) {
          caretRect = currentCaretRect;
          return;
        }
        if (windowScroll) {
          defaultView.scrollBy(0, diff);
        } else {
          scrollContainer.scrollTop += diff;
        }
      }
      function addSelectionChangeListener() {
        ownerDocument.addEventListener(
          "selectionchange",
          computeCaretRectOnSelectionChange
        );
      }
      function computeCaretRectOnSelectionChange() {
        ownerDocument.removeEventListener(
          "selectionchange",
          computeCaretRectOnSelectionChange
        );
        computeCaretRectangle();
      }
      function computeCaretRectangle() {
        if (isSelectionEligibleForScroll()) {
          caretRect = (0, import_dom.computeCaretRect)(defaultView);
        }
      }
      function isSelectionEligibleForScroll() {
        return node.contains(ownerDocument.activeElement) && ownerDocument.activeElement.isContentEditable;
      }
      function isLastEditableNode() {
        const editableNodes = node.querySelectorAll(
          '[contenteditable="true"]'
        );
        const lastEditableNode = editableNodes[editableNodes.length - 1];
        return lastEditableNode === ownerDocument.activeElement;
      }
      defaultView.addEventListener("scroll", onScrollResize, true);
      defaultView.addEventListener("resize", onScrollResize, true);
      node.addEventListener("keydown", onKeyDown);
      node.addEventListener("keyup", maintainCaretPosition);
      node.addEventListener("mousedown", addSelectionChangeListener);
      node.addEventListener("touchstart", addSelectionChangeListener);
      return () => {
        defaultView.removeEventListener(
          "scroll",
          onScrollResize,
          true
        );
        defaultView.removeEventListener(
          "resize",
          onScrollResize,
          true
        );
        node.removeEventListener("keydown", onKeyDown);
        node.removeEventListener("keyup", maintainCaretPosition);
        node.removeEventListener(
          "mousedown",
          addSelectionChangeListener
        );
        node.removeEventListener(
          "touchstart",
          addSelectionChangeListener
        );
        ownerDocument.removeEventListener(
          "selectionchange",
          computeCaretRectOnSelectionChange
        );
        defaultView.cancelAnimationFrame(scrollResizeRafId);
        defaultView.cancelAnimationFrame(onKeyDownRafId);
      };
    },
    [hasSelectedBlock]
  );
}
function Typewriter({ children }) {
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { ref: useTypewriter(), className: "block-editor__typewriter", children });
}
var TypewriterOrIEBypass = isIE ? (props) => props.children : Typewriter;
var typewriter_default = TypewriterOrIEBypass;
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  useTypewriter
});
//# sourceMappingURL=index.js.map
