const ROOT_CLASS_NAME = "__prosemirror-dev-tools__";
const COLLAPSED_BUTTON_SELECTOR = '[data-test-id="__prosemirror_devtools_collapsed_button__"]';
const CONTAINER_SELECTOR = '[data-test-id="__prosemirror_devtools_container__"]';
const CLOSE_BUTTON_SELECTOR = '[data-test-id="__prosemirror_devtools_close_button__"]';
const CLICK_OUTSIDE_SAFE_DATA_HOOK = "mock-modal";
const DEV_TOOLS_Z_INDEX = 1e4;
const DEFAULT_DOCK_SIZE = 0.5;
const MIN_DOCK_SIZE = 0.15;
const MAX_DOCK_SIZE = 0.95;
const STOP_PROPAGATION_EVENT_NAMES = ["mousedown", "touchstart"];
const getGlobalState = () => {
  window.__RICOS_PROSEMIRROR_DEV_TOOLS__ = window.__RICOS_PROSEMIRROR_DEV_TOOLS__ ?? {};
  return window.__RICOS_PROSEMIRROR_DEV_TOOLS__;
};
const getRoot = () => document.querySelector(`.${ROOT_CLASS_NAME}`);
const getProseMirrorDevToolsElements = () => {
  const root = getRoot();
  const container = root?.querySelector(CONTAINER_SELECTOR) ?? null;
  const collapsedButton = root?.querySelector(COLLAPSED_BUTTON_SELECTOR) ?? null;
  const closeButton = root?.querySelector(CLOSE_BUTTON_SELECTOR) ?? null;
  const dock = container?.parentElement?.parentElement instanceof HTMLDivElement ? container.parentElement.parentElement : null;
  const dockWrapper = dock?.parentElement instanceof HTMLDivElement ? dock.parentElement : null;
  const floatingButtons = Array.from(
    root?.querySelectorAll("button") ?? []
  ).filter(
    (button) => button !== collapsedButton && button !== closeButton && button.parentElement === container
  );
  const saveSnapshotButton = floatingButtons.find((button) => Boolean(button.textContent?.trim().length)) ?? null;
  const nodePickerButton = floatingButtons.find((button) => button !== saveSnapshotButton) ?? null;
  return {
    root,
    dockWrapper,
    dock,
    container,
    collapsedButton,
    closeButton,
    floatingButtons,
    nodePickerButton,
    saveSnapshotButton
  };
};
const waitForDevToolsElements = (predicate, timeout = 1500) => {
  const existing = getProseMirrorDevToolsElements();
  if (predicate(existing)) {
    return Promise.resolve(existing);
  }
  return new Promise((resolve, reject) => {
    const observer = new MutationObserver(() => {
      const elements = getProseMirrorDevToolsElements();
      if (predicate(elements)) {
        observer.disconnect();
        clearTimeout(timeoutId);
        resolve(elements);
      }
    });
    const timeoutId = window.setTimeout(() => {
      observer.disconnect();
      reject(new Error("Timed out while waiting for ProseMirror devtools"));
    }, timeout);
    observer.observe(document.body, {
      attributes: true,
      childList: true,
      subtree: true
    });
  });
};
const setCollapsedButtonVisibility = (elements, isVisible) => {
  if (elements.collapsedButton) {
    elements.collapsedButton.style.display = isVisible ? "" : "none";
  }
};
const setCloseButtonVisibility = (elements, isVisible) => {
  if (elements.closeButton) {
    elements.closeButton.style.display = isVisible ? "" : "none";
  }
};
const clampDockSize = (size) => Math.min(MAX_DOCK_SIZE, Math.max(MIN_DOCK_SIZE, size));
const getReservedHeight = (size) => clampDockSize(size) * window.innerHeight;
const captureHtmlMarginBottomBeforeOverride = () => {
  const state = getGlobalState();
  if (typeof state.htmlMarginBottomBeforeOverride === "undefined") {
    state.htmlMarginBottomBeforeOverride = document.documentElement.style.marginBottom;
  }
};
const setDevToolsHtmlMarginBottomPixels = (height) => {
  const state = getGlobalState();
  if (typeof height === "number") {
    captureHtmlMarginBottomBeforeOverride();
    document.documentElement.style.marginBottom = `${height}px`;
    return;
  }
  if (typeof state.htmlMarginBottomBeforeOverride !== "undefined") {
    document.documentElement.style.marginBottom = state.htmlMarginBottomBeforeOverride;
    state.htmlMarginBottomBeforeOverride = void 0;
  }
};
const setHtmlMarginBottom = (size) => {
  setDevToolsHtmlMarginBottomPixels(typeof size === "number" ? getReservedHeight(size) : void 0);
};
const setRootVisibility = (elements, isVisible) => {
  if (!elements.root) {
    return;
  }
  elements.root.style.display = isVisible ? "" : "none";
  elements.root.style.pointerEvents = isVisible ? "" : "none";
};
const stopEventPropagation = (event) => {
  event.stopPropagation();
};
const syncStandaloneProseMirrorDevToolsWrapper = (elements) => {
  const state = getGlobalState();
  elements.root?.setAttribute("data-hook", CLICK_OUTSIDE_SAFE_DATA_HOOK);
  if (elements.dockWrapper) {
    elements.dockWrapper.style.zIndex = `${DEV_TOOLS_Z_INDEX}`;
  }
  if (state.guardedRoot === elements.root) {
    return;
  }
  state.eventGuardsCleanup?.();
  state.guardedRoot = elements.root ?? void 0;
  if (!elements.root) {
    state.eventGuardsCleanup = void 0;
    return;
  }
  STOP_PROPAGATION_EVENT_NAMES.forEach((eventName) => {
    elements.root?.addEventListener(eventName, stopEventPropagation);
  });
  state.eventGuardsCleanup = () => {
    STOP_PROPAGATION_EVENT_NAMES.forEach((eventName) => {
      elements.root?.removeEventListener(eventName, stopEventPropagation);
    });
    if (state.guardedRoot === elements.root) {
      state.guardedRoot = void 0;
    }
    state.eventGuardsCleanup = void 0;
  };
};
const setProseMirrorFloatingControlsOffset = (offsetTop) => {
  const elements = getProseMirrorDevToolsElements();
  elements.floatingButtons.forEach((button) => {
    button.style.top = typeof offsetTop === "number" ? `${offsetTop}px` : "";
  });
};
const setProseMirrorFloatingControlsVisibility = (isVisible) => {
  const elements = getProseMirrorDevToolsElements();
  elements.floatingButtons.forEach((button) => {
    button.style.display = isVisible ? "" : "none";
  });
};
const setProseMirrorDevToolsSize = (size, reservedHeight = getReservedHeight(size)) => {
  const nextSize = clampDockSize(size);
  const elements = getProseMirrorDevToolsElements();
  if (elements.dock) {
    const dockHeight = nextSize * window.innerHeight;
    elements.dock.style.top = `${window.innerHeight - dockHeight}px`;
    elements.dock.style.height = `${dockHeight}px`;
  }
  if (elements.root?.style.display !== "none") {
    setDevToolsHtmlMarginBottomPixels(reservedHeight);
  }
};
const mountStandaloneProseMirrorDevTools = async (editorView) => {
  if (typeof window === "undefined") {
    return null;
  }
  const state = getGlobalState();
  const existing = getProseMirrorDevToolsElements();
  if (state.currentEditorView === editorView && existing.root) {
    setCollapsedButtonVisibility(existing, false);
    setCloseButtonVisibility(existing, false);
    setRootVisibility(existing, false);
    setHtmlMarginBottom();
    syncStandaloneProseMirrorDevToolsWrapper(existing);
    return existing;
  }
  if (state.mountPromise && state.currentEditorView === editorView) {
    return state.mountPromise;
  }
  const requestId = (state.mountRequestId ?? 0) + 1;
  state.mountRequestId = requestId;
  state.currentEditorView = editorView;
  state.mountPromise = import(
    /* webpackChunkName: "ricos_prosemirror-dev-tools" */
    "prosemirror-dev-tools"
  ).then(({ applyDevTools }) => {
    if (state.currentEditorView !== editorView || state.mountRequestId !== requestId) {
      return getProseMirrorDevToolsElements();
    }
    state.cleanup?.();
    state.cleanup = applyDevTools(editorView, {});
    return waitForDevToolsElements((elements) => Boolean(elements.root)).then((elements) => {
      if (state.mountRequestId === requestId) {
        state.mountPromise = void 0;
      }
      if (state.currentEditorView !== editorView || state.mountRequestId !== requestId) {
        return getProseMirrorDevToolsElements();
      }
      setCollapsedButtonVisibility(elements, false);
      setCloseButtonVisibility(elements, false);
      setRootVisibility(elements, false);
      setProseMirrorFloatingControlsOffset();
      setHtmlMarginBottom();
      syncStandaloneProseMirrorDevToolsWrapper(elements);
      return elements;
    });
  }).catch((error) => {
    if (state.mountRequestId === requestId) {
      state.mountPromise = void 0;
    }
    console.error("Failed to load prosemirror-dev-tools", error);
    return null;
  });
  return state.mountPromise;
};
const showStandaloneProseMirrorDevTools = async (editorView, preferredSize = DEFAULT_DOCK_SIZE, reservedHeight = getReservedHeight(preferredSize)) => {
  const mountedElements = await mountStandaloneProseMirrorDevTools(editorView);
  if (!mountedElements) {
    return null;
  }
  let elements = getProseMirrorDevToolsElements();
  if (!elements.container) {
    captureHtmlMarginBottomBeforeOverride();
    setCollapsedButtonVisibility(elements, true);
    elements.collapsedButton?.click();
    try {
      elements = await waitForDevToolsElements((nextElements) => Boolean(nextElements.container));
    } catch (error) {
      console.error("Failed to open prosemirror-dev-tools", error);
      return getProseMirrorDevToolsElements();
    }
  }
  setCollapsedButtonVisibility(elements, false);
  setCloseButtonVisibility(elements, false);
  setRootVisibility(elements, true);
  setProseMirrorDevToolsSize(preferredSize, reservedHeight);
  setProseMirrorFloatingControlsOffset();
  setDevToolsHtmlMarginBottomPixels(reservedHeight);
  syncStandaloneProseMirrorDevToolsWrapper(elements);
  return elements;
};
const hideStandaloneProseMirrorDevTools = (preservedReservedHeight) => {
  if (typeof window === "undefined") {
    return null;
  }
  const elements = getProseMirrorDevToolsElements();
  if (!elements.root) {
    return null;
  }
  if (elements.container && typeof preservedReservedHeight !== "number") {
    setCloseButtonVisibility(elements, true);
    elements.closeButton?.click();
  }
  const nextElements = getProseMirrorDevToolsElements();
  setRootVisibility(nextElements, false);
  setDevToolsHtmlMarginBottomPixels(preservedReservedHeight);
  setCollapsedButtonVisibility(nextElements, false);
  setCloseButtonVisibility(nextElements, false);
  setProseMirrorFloatingControlsOffset();
  setProseMirrorFloatingControlsVisibility(true);
  return nextElements;
};
export {
  CLICK_OUTSIDE_SAFE_DATA_HOOK,
  DEV_TOOLS_Z_INDEX,
  getProseMirrorDevToolsElements,
  hideStandaloneProseMirrorDevTools,
  setDevToolsHtmlMarginBottomPixels,
  setProseMirrorDevToolsSize,
  setProseMirrorFloatingControlsOffset,
  setProseMirrorFloatingControlsVisibility,
  showStandaloneProseMirrorDevTools
};
//# sourceMappingURL=prosemirror-dev-tools-controller.js.map
