// packages/block-library/src/table-of-contents/hooks.js
import fastDeepEqual from "fast-deep-equal/es6";
import { useRegistry } from "@wordpress/data";
import { __unstableStripHTML as stripHTML } from "@wordpress/dom";
import { useEffect } from "@wordpress/element";
import { addQueryArgs, removeQueryArgs } from "@wordpress/url";
import { store as blockEditorStore } from "@wordpress/block-editor";
function getLatestHeadings(select, clientId) {
  const {
    getBlockAttributes,
    getBlockName,
    getBlocksByName,
    getClientIdsOfDescendants
  } = select(blockEditorStore);
  const permalink = select("core/editor").getPermalink() ?? null;
  const isPaginated = getBlocksByName("core/nextpage").length !== 0;
  const { onlyIncludeCurrentPage, maxLevel } = getBlockAttributes(clientId) ?? {};
  const [postContentClientId = ""] = getBlocksByName("core/post-content");
  const allBlockClientIds = getClientIdsOfDescendants(postContentClientId);
  let tocPage = 1;
  if (isPaginated && onlyIncludeCurrentPage) {
    const tocIndex = allBlockClientIds.indexOf(clientId);
    for (const [
      blockIndex,
      blockClientId
    ] of allBlockClientIds.entries()) {
      if (blockIndex >= tocIndex) {
        break;
      }
      if (getBlockName(blockClientId) === "core/nextpage") {
        tocPage++;
      }
    }
  }
  const latestHeadings = [];
  let headingPage = 1;
  let headingPageLink = null;
  if (typeof permalink === "string") {
    headingPageLink = isPaginated ? addQueryArgs(permalink, { page: headingPage }) : permalink;
  }
  for (const blockClientId of allBlockClientIds) {
    const blockName = getBlockName(blockClientId);
    if (blockName === "core/nextpage") {
      headingPage++;
      if (onlyIncludeCurrentPage && headingPage > tocPage) {
        break;
      }
      if (typeof permalink === "string") {
        headingPageLink = addQueryArgs(
          removeQueryArgs(permalink, ["page"]),
          { page: headingPage }
        );
      }
    } else if (!onlyIncludeCurrentPage || headingPage === tocPage) {
      if (blockName === "core/heading") {
        const headingAttributes = getBlockAttributes(blockClientId);
        if (maxLevel && headingAttributes.level > maxLevel) {
          continue;
        }
        const canBeLinked = typeof headingPageLink === "string" && typeof headingAttributes.anchor === "string" && headingAttributes.anchor !== "";
        latestHeadings.push({
          // Convert line breaks to spaces, and get rid of HTML tags in the headings.
          content: stripHTML(
            headingAttributes.content.replace(
              /(<br *\/?>)+/g,
              " "
            )
          ),
          level: headingAttributes.level,
          link: canBeLinked ? `${headingPageLink}#${headingAttributes.anchor}` : null
        });
      }
    }
  }
  return latestHeadings;
}
function observeCallback(select, dispatch, clientId) {
  const { getBlockAttributes } = select(blockEditorStore);
  const { updateBlockAttributes, __unstableMarkNextChangeAsNotPersistent } = dispatch(blockEditorStore);
  const attributes = getBlockAttributes(clientId);
  if (attributes === null) {
    return;
  }
  const headings = getLatestHeadings(select, clientId);
  if (!fastDeepEqual(headings, attributes.headings)) {
    window.queueMicrotask(() => {
      __unstableMarkNextChangeAsNotPersistent();
      updateBlockAttributes(clientId, { headings });
    });
  }
}
function useObserveHeadings(clientId) {
  const registry = useRegistry();
  useEffect(() => {
    return registry.subscribe(
      () => observeCallback(registry.select, registry.dispatch, clientId)
    );
  }, [registry, clientId]);
}
export {
  useObserveHeadings
};
//# sourceMappingURL=hooks.js.map
