"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
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 __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  // If the importer is in node compatibility mode or this is not an ESM
  // file that has been converted to a CommonJS file using a Babel-
  // compatible transform (i.e. "__esModule" has not been set), then set
  // "default" to the CommonJS "module.exports" for node compatibility.
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var table_view_exports = {};
__export(table_view_exports, {
  TableView: () => TableView
});
module.exports = __toCommonJS(table_view_exports);
var import_drag_handle_icons = require("./../../../_shared/drag-handle-icons.js");
var import_state = require("./../../../tiptap/pm/state.js");
var import_general_scss = __toESM(require("./../../../editor-common/statics/styles/general-scss.js"));
var import_data_hooks = require("../../data-hooks.js");
var import_defaults = require("../../defaults.js");
var import_queries = require("../commands/queries.js");
var import_svgs = require("../decorations/svgs.js");
var import_tableHandles_scss = __toESM(require("../decorations/tableHandles-scss.js"));
var import_find_table = require("../utilities/find-table.js");
var import_is_selection_type = require("../utilities/is-selection-type.js");
var import_resize_hit_zone_overlay = require("./resize-hit-zone-overlay.js");
var import_resize_utils = require("./resize-utils.js");
var import_table_scss = __toESM(require("./table-scss.js"));
class TableView {
  constructor(node, editor, getPos, { columnResizeHandleWidth, rowResizeHandleHeight }, isMobile = false) {
    this.handlesVisible = false;
    this.resizeObserver = null;
    this.selectionUpdateHandler = null;
    this.editor = editor;
    this.node = node;
    this.getPos = getPos;
    this.isMobile = isMobile;
    this.dom = document.createElement("div");
    this.dom.className = import_table_scss.default.tableContainer;
    this.dom.dataset.tableContainer = "true";
    if (typeof node.attrs.id === "string") {
      this.dom.dataset.tableContainerId = node.attrs.id;
    }
    this.viewport = document.createElement("div");
    this.viewport.className = import_table_scss.default.tableViewport;
    this.dom.appendChild(this.viewport);
    this.table = document.createElement("table");
    this.table.dataset.hook = import_data_hooks.ROOT;
    this.viewport.appendChild(this.table);
    this.updateTableSpacing(node);
    this.updateTablePadding(node);
    this.updateBorderEdgePadding(node);
    this.updateAriaDescription(node);
    this.colgroup = document.createElement("colgroup");
    this.table.appendChild(this.colgroup);
    (0, import_resize_utils.updateColumns)({
      node,
      colgroup: this.colgroup,
      table: this.table,
      cellMinWidth: this.getMinColumnWidth(node),
      commands: this.editor.commands,
      shouldUpdateState: false
    });
    this.contentDOM = document.createElement("tbody");
    this.table.appendChild(this.contentDOM);
    this.addColBar = this.createAddColBar();
    this.dom.appendChild(this.addColBar);
    this.addRowBar = this.createAddRowBar();
    this.dom.appendChild(this.addRowBar);
    this.tableSelectorBar = this.createTableSelectorBar();
    this.dom.appendChild(this.tableSelectorBar);
    if (!this.isMobile) {
      this.columnHandle = this.createColumnHandle();
      this.rowHandle = this.createRowHandle();
      this.viewport.appendChild(this.columnHandle);
      this.viewport.appendChild(this.rowHandle);
    } else {
      this.columnHandle = null;
      this.rowHandle = null;
    }
    this.resizeHitZoneOverlay = new import_resize_hit_zone_overlay.ResizeHitZoneOverlay({
      editor: this.editor,
      node: this.node,
      getPos: this.getPos,
      columnHitZoneWidth: columnResizeHandleWidth,
      rowHitZoneHeight: rowResizeHandleHeight,
      viewport: this.viewport,
      table: this.table,
      colgroup: this.colgroup,
      contentDOM: this.contentDOM,
      onResizeTick: () => this.updateHandlesDuringResize()
    });
    this.hideHandles();
    this.resizeHitZoneOverlay.scheduleUpdate();
    this.viewport.addEventListener("scroll", () => {
      if (this.handlesVisible) {
        requestAnimationFrame(() => this.updateSelectionHandles());
      }
    });
    this.selectionUpdateHandler = () => {
      const { state } = this.editor;
      const table = (0, import_find_table.findTable)(state.selection);
      const isEditorFocused = this.editor.view.hasFocus();
      const hasRicosCellSelection = (0, import_is_selection_type.isRicosCellSelection)(state.selection);
      const isThisTableFocused = table && this.editor.view.nodeDOM(table.pos) === this.dom && (isEditorFocused || hasRicosCellSelection);
      if (isThisTableFocused && !this.handlesVisible) {
        this.showHandles();
        requestAnimationFrame(() => {
          this.updateSelectionHandles();
          this.updateAddBarPositions();
        });
      } else if (!isThisTableFocused && this.handlesVisible) {
        this.hideHandles();
      } else if (this.handlesVisible) {
        requestAnimationFrame(() => this.updateSelectionHandles());
      }
    };
    this.editor.on("selectionUpdate", this.selectionUpdateHandler);
    this.resizeObserver = new ResizeObserver(() => {
      if (this.handlesVisible) {
        requestAnimationFrame(() => this.updateAddBarPositions());
      }
      this.resizeHitZoneOverlay.scheduleUpdate();
    });
    this.resizeObserver.observe(this.table);
  }
  updateAddBarPositions() {
    const containerStyles = getComputedStyle(this.dom);
    const gap = this.getCssNumber(containerStyles, "--table-handle-gap", 12);
    const selectionHandleSpace = this.getCssNumber(
      containerStyles,
      "--table-selection-handle-space",
      10
    );
    const viewportLeft = this.viewport.offsetLeft;
    const viewportTop = this.viewport.offsetTop;
    const viewportWidth = this.viewport.offsetWidth;
    const viewportHeight = this.viewport.offsetHeight;
    const tableTop = viewportTop + this.table.offsetTop;
    const tableHeight = this.table.offsetHeight;
    const addRowTop = viewportTop + viewportHeight + gap;
    this.addRowBar.style.top = `${addRowTop}px`;
    this.addRowBar.style.left = `${viewportLeft + selectionHandleSpace}px`;
    this.addRowBar.style.width = `${viewportWidth - selectionHandleSpace}px`;
    this.addColBar.style.height = `${tableHeight}px`;
    this.addColBar.style.top = `${tableTop}px`;
    const addRowButtonHeight = this.getCssNumber(containerStyles, "--table-add-button-size", 18);
    const selectorTop = addRowTop + addRowButtonHeight + gap;
    const addRowBarWidth = viewportWidth - selectionHandleSpace;
    const addRowBarCenterX = viewportLeft + selectionHandleSpace + addRowBarWidth / 2;
    this.tableSelectorBar.style.top = `${selectorTop}px`;
    this.tableSelectorBar.style.left = `${addRowBarCenterX}px`;
    this.tableSelectorBar.style.transform = "translateX(-50%)";
  }
  updateHandlesDuringResize() {
    if (!this.handlesVisible) {
      return;
    }
    this.updateSelectionHandles();
    this.updateAddBarPositions();
  }
  getCssNumber(styles2, propertyName, fallbackValue) {
    const value = styles2.getPropertyValue(propertyName).trim();
    const parsed = Number.parseFloat(value);
    return Number.isFinite(parsed) ? parsed : fallbackValue;
  }
  createAddColBar() {
    const bar = document.createElement("div");
    bar.className = import_table_scss.default.addColBar;
    const button = document.createElement("div");
    button.className = import_tableHandles_scss.default.addColButton;
    button.dataset.hook = "addCol";
    button.innerHTML = import_svgs.addSvg;
    button.addEventListener("mousedown", (e) => {
      e.stopPropagation();
      e.preventDefault();
      this.editor.chain().addColumnAtIndex(this.getTableWidth()).run();
    });
    bar.appendChild(button);
    return bar;
  }
  createAddRowBar() {
    const bar = document.createElement("div");
    bar.className = import_table_scss.default.addRowBar;
    const button = document.createElement("div");
    button.className = import_tableHandles_scss.default.addRowButton;
    button.dataset.hook = "addRow";
    button.innerHTML = import_svgs.addSvg;
    button.addEventListener("mousedown", (e) => {
      e.stopPropagation();
      e.preventDefault();
      this.editor.chain().addRowAtIndex(this.getTableHeight()).run();
    });
    bar.appendChild(button);
    return bar;
  }
  createTableSelectorBar() {
    const bar = document.createElement("div");
    bar.className = import_table_scss.default.tableSelectorBar;
    bar.setAttribute("contenteditable", "false");
    const selector = document.createElement("div");
    selector.className = import_tableHandles_scss.default.tableSelector;
    selector.dataset.hook = "table-selector";
    selector.dataset.tableHandle = "true";
    selector.setAttribute("data-drag-handle", "");
    selector.innerHTML = (0, import_drag_handle_icons.getMoveIcon)();
    selector.draggable = true;
    selector.addEventListener("click", (e) => {
      e.stopPropagation();
      this.editor.commands.selectWholeTable();
    });
    selector.addEventListener("dragstart", (event) => {
      const dragHandle = event.target?.closest("[data-drag-handle]");
      if (!dragHandle) {
        return;
      }
      const selection = import_state.NodeSelection.create(this.editor.view.state.doc, this.getPos());
      const transaction = this.editor.view.state.tr.setSelection(selection);
      this.editor.view.dispatch(transaction);
      const domBox = this.table.getBoundingClientRect();
      const handleBox = dragHandle.getBoundingClientRect();
      const x = Math.min(Math.max(0, handleBox.x - domBox.x + event.offsetX), domBox.width - 1);
      const y = Math.min(Math.max(0, handleBox.y - domBox.y + event.offsetY), domBox.height - 1);
      this.table.classList.add(import_general_scss.default.dragImageView);
      event.dataTransfer?.setDragImage(this.table, x, y);
      setTimeout(() => {
        this.table.classList.remove(import_general_scss.default.dragImageView);
      }, 0);
    });
    bar.appendChild(selector);
    return bar;
  }
  createColumnHandle() {
    const handle = document.createElement("div");
    handle.className = import_tableHandles_scss.default.columnHandle;
    handle.dataset.hook = "column-handle";
    handle.dataset.tableTopHandle = "true";
    handle.innerHTML = (0, import_drag_handle_icons.getHorizontalHandleIcon)();
    handle.style.display = "none";
    handle.addEventListener("mousedown", (e) => {
      e.preventDefault();
      if (handle.dataset.selected === "true" || handle.dataset.dragging === "true") {
        return;
      }
      e.stopPropagation();
      const state = this.editor.state;
      const table = (0, import_find_table.findTable)(state.selection);
      if (!table) {
        return;
      }
      try {
        const rect = (0, import_queries.selectedRect)(state);
        this.editor.commands.selectColumns(rect.left, rect.right - 1, table.start);
      } catch {
      }
    });
    return handle;
  }
  createRowHandle() {
    const handle = document.createElement("div");
    handle.className = import_tableHandles_scss.default.rowHandle;
    handle.dataset.hook = "row-handle";
    handle.innerHTML = (0, import_drag_handle_icons.getVerticalHandleIcon)();
    handle.style.display = "none";
    handle.addEventListener("mousedown", (e) => {
      e.preventDefault();
      if (handle.dataset.selected === "true" || handle.dataset.dragging === "true") {
        return;
      }
      e.stopPropagation();
      const state = this.editor.state;
      const table = (0, import_find_table.findTable)(state.selection);
      if (!table) {
        return;
      }
      try {
        const rect = (0, import_queries.selectedRect)(state);
        this.editor.commands.selectRows(rect.top, rect.bottom - 1, table.start);
      } catch {
      }
    });
    return handle;
  }
  getTableWidth() {
    const firstRow = this.node.firstChild;
    if (!firstRow) {
      return 0;
    }
    let width = 0;
    firstRow.forEach((cell) => {
      width += cell.attrs.colspan || 1;
    });
    return width;
  }
  getTableHeight() {
    return this.node.childCount;
  }
  hideHandles() {
    if (!this.handlesVisible) {
      return;
    }
    this.handlesVisible = false;
    this.dom.classList.remove(import_table_scss.default.tableContainerFocused);
    if (this.columnHandle) {
      this.columnHandle.style.display = "none";
      this.columnHandle.classList.remove(import_tableHandles_scss.default.selected);
    }
    if (this.rowHandle) {
      this.rowHandle.style.display = "none";
      this.rowHandle.classList.remove(import_tableHandles_scss.default.selected);
    }
  }
  showHandles() {
    if (this.handlesVisible) {
      return;
    }
    this.handlesVisible = true;
    this.dom.classList.add(import_table_scss.default.tableContainerFocused);
    if (this.columnHandle) {
      this.columnHandle.style.display = "flex";
    }
    if (this.rowHandle) {
      this.rowHandle.style.display = "flex";
    }
  }
  updateSelectionHandles() {
    if (!this.handlesVisible || !this.columnHandle || !this.rowHandle) {
      return;
    }
    const state = this.editor.state;
    const selection = state.selection;
    const isCellSelection = (0, import_is_selection_type.isRicosCellSelection)(selection);
    let rect;
    let isFullColumnSelected = false;
    let isFullRowSelected = false;
    let isEntireTableSelected = false;
    try {
      if (isCellSelection) {
        rect = selection.getRect();
        isFullColumnSelected = selection.isColSelection();
        isFullRowSelected = selection.isRowSelection();
        isEntireTableSelected = selection.isTableSelection();
      } else {
        rect = (0, import_queries.selectedRect)(state);
      }
    } catch {
      return;
    }
    if (!isCellSelection) {
      isFullColumnSelected = false;
      isFullRowSelected = false;
      isEntireTableSelected = false;
    }
    if (isEntireTableSelected) {
      this.columnHandle.style.display = "none";
      this.rowHandle.style.display = "none";
      return;
    }
    this.columnHandle.style.display = "flex";
    this.rowHandle.style.display = "flex";
    this.columnHandle.classList.toggle(import_tableHandles_scss.default.selected, isFullColumnSelected);
    this.rowHandle.classList.toggle(import_tableHandles_scss.default.selected, isFullRowSelected);
    this.columnHandle.dataset.selected = isFullColumnSelected ? "true" : "false";
    this.rowHandle.dataset.selected = isFullRowSelected ? "true" : "false";
    this.updateColumnHandlePosition(rect);
    this.updateRowHandlePosition(rect);
  }
  updateColumnHandlePosition(rect) {
    const firstRow = this.table.querySelector("tr");
    if (!firstRow) {
      return;
    }
    const cells = firstRow.querySelectorAll("td, th");
    const cellSpacing = this.node.attrs.tableData?.cellSpacing ?? 0;
    let leftPx = 0;
    let widthPx = 0;
    let cellIndex = 0;
    cells.forEach((cell) => {
      const colspan = parseInt(cell.getAttribute("colspan") || "1", 10);
      const cellWidth = cell.offsetWidth;
      const cellLeft = cell.offsetLeft;
      for (let c = 0; c < colspan; c++) {
        if (cellIndex >= rect.left && cellIndex < rect.right) {
          if (cellIndex === rect.left) {
            leftPx = cellLeft + c * cellWidth / colspan;
          }
          widthPx += cellWidth / colspan;
        }
        cellIndex++;
      }
    });
    const centerPx = leftPx + widthPx / 2 + (rect.left > 0 ? cellSpacing / 2 : 0);
    const tableLeftInViewport = this.table.offsetLeft;
    if (this.columnHandle) {
      this.columnHandle.style.left = `${tableLeftInViewport + centerPx}px`;
      this.columnHandle.style.top = `${this.table.offsetTop}px`;
    }
  }
  updateRowHandlePosition(rect) {
    const rows = this.table.querySelectorAll("tbody tr");
    if (!rows.length) {
      return;
    }
    const cellSpacing = this.node.attrs.tableData?.cellSpacing ?? 0;
    let topOffset = 0;
    for (let i = 0; i < rect.top && i < rows.length; i++) {
      topOffset += rows[i].offsetHeight;
    }
    let selectedHeight = 0;
    for (let i = rect.top; i < rect.bottom && i < rows.length; i++) {
      selectedHeight += rows[i].offsetHeight;
    }
    const centerPx = topOffset + selectedHeight / 2 + (rect.top > 0 ? cellSpacing / 2 : 0);
    const tableTopInViewport = this.table.offsetTop;
    const tableLeftInViewport = this.table.offsetLeft;
    if (this.rowHandle) {
      this.rowHandle.style.left = `${tableLeftInViewport}px`;
      this.rowHandle.style.top = `${tableTopInViewport + centerPx}px`;
    }
  }
  update(node, _decorations) {
    if (node.type !== this.node.type) {
      return false;
    }
    this.node = node;
    if (typeof node.attrs.id === "string") {
      this.dom.dataset.tableContainerId = node.attrs.id;
    } else {
      delete this.dom.dataset.tableContainerId;
    }
    this.updateTableSpacing(node);
    this.updateTablePadding(node);
    this.updateBorderEdgePadding(node);
    this.updateAriaDescription(node);
    (0, import_resize_utils.updateColumns)({
      node,
      colgroup: this.colgroup,
      table: this.table,
      cellMinWidth: this.getMinColumnWidth(node),
      commands: this.editor.commands,
      shouldUpdateState: false
    });
    if (this.handlesVisible) {
      requestAnimationFrame(() => {
        this.updateSelectionHandles();
        this.updateAddBarPositions();
      });
    }
    this.resizeHitZoneOverlay.setNode(node);
    this.resizeHitZoneOverlay.scheduleUpdate();
    return true;
  }
  updateAriaDescription(node) {
    const text = node.attrs.tableData?.altText;
    if (text) {
      this.table.setAttribute("aria-label", text);
    } else {
      this.table.removeAttribute("aria-label");
    }
  }
  updateTableSpacing(node) {
    const cellSpacing = node.attrs.tableData?.cellSpacing ?? 0;
    this.dom.style.setProperty("--ricos-internal-table-gap", `${cellSpacing}px`);
    this.table.style.borderCollapse = "separate";
    this.table.style.borderSpacing = "0";
  }
  updateTablePadding(node) {
    const cellPadding = (0, import_defaults.normalizePadding)(node.attrs.tableData?.cellPadding, [
      ...import_defaults.TABLE_DEFAULTS.cellPadding
    ]);
    if (cellPadding && cellPadding.length > 0) {
      this.dom.style.setProperty("--ricos-internal-table-cell-padding-top", `${cellPadding[0]}px`);
      this.dom.style.setProperty(
        "--ricos-internal-table-cell-padding-right",
        `${cellPadding[1] ?? cellPadding[0]}px`
      );
      this.dom.style.setProperty(
        "--ricos-internal-table-cell-padding-bottom",
        `${cellPadding[2] ?? cellPadding[0]}px`
      );
      this.dom.style.setProperty(
        "--ricos-internal-table-cell-padding-left",
        `${cellPadding[3] ?? cellPadding[1] ?? cellPadding[0]}px`
      );
    }
  }
  updateBorderEdgePadding(node) {
    let maxTop = 0;
    let maxBottom = 0;
    let maxLeft = 0;
    let maxRight = 0;
    const rowCount = node.content.childCount;
    if (rowCount === 0) {
      this.dom.style.setProperty("--table-border-top", "0px");
      this.dom.style.setProperty("--table-border-bottom", "0px");
      this.dom.style.setProperty("--table-border-left", "0px");
      this.dom.style.setProperty("--table-border-right", "0px");
      return;
    }
    const DEFAULT_BORDER_WIDTH = 1;
    const firstRow = node.content.child(0);
    firstRow.content.forEach((cell) => {
      const topWidth = cell.attrs.borderWidths?.top ?? DEFAULT_BORDER_WIDTH;
      maxTop = Math.max(maxTop, topWidth);
    });
    const lastRow = node.content.child(rowCount - 1);
    lastRow.content.forEach((cell) => {
      const bottomWidth = cell.attrs.borderWidths?.bottom ?? DEFAULT_BORDER_WIDTH;
      maxBottom = Math.max(maxBottom, bottomWidth);
    });
    node.content.forEach((row) => {
      const cellCount = row.content.childCount;
      if (cellCount === 0) {
        return;
      }
      const firstCell = row.content.child(0);
      const leftWidth = firstCell.attrs.borderWidths?.left ?? DEFAULT_BORDER_WIDTH;
      maxLeft = Math.max(maxLeft, leftWidth);
      const lastCell = row.content.child(cellCount - 1);
      const rightWidth = lastCell.attrs.borderWidths?.right ?? DEFAULT_BORDER_WIDTH;
      maxRight = Math.max(maxRight, rightWidth);
    });
    this.dom.style.setProperty("--table-border-top", `${Math.ceil(maxTop / 2)}px`);
    this.dom.style.setProperty("--table-border-bottom", `${Math.ceil(maxBottom / 2)}px`);
    this.dom.style.setProperty("--table-border-left", `${Math.ceil(maxLeft / 2)}px`);
    this.dom.style.setProperty("--table-border-right", `${Math.ceil(maxRight / 2)}px`);
  }
  getMinColumnWidth(node) {
    return (0, import_defaults.getMinColumnWidthForPadding)(node.attrs.tableData?.cellPadding);
  }
  ignoreMutation(mutation) {
    if (mutation.type === "attributes") {
      if (mutation.target === this.dom) {
        return true;
      }
      return mutation.target === this.table || this.colgroup.contains(mutation.target) || this.columnHandle && mutation.target === this.columnHandle || this.rowHandle && mutation.target === this.rowHandle || this.addColBar.contains(mutation.target) || this.addRowBar.contains(mutation.target) || this.tableSelectorBar.contains(mutation.target) || mutation.target === this.resizeHitZoneOverlay.dom || this.resizeHitZoneOverlay.dom.contains(mutation.target);
    }
    if (mutation.type === "childList") {
      return mutation.target === this.dom || mutation.target === this.viewport || mutation.target === this.addColBar || mutation.target === this.addRowBar || mutation.target === this.tableSelectorBar || mutation.target === this.resizeHitZoneOverlay.dom || this.resizeHitZoneOverlay.dom.contains(mutation.target);
    }
    return false;
  }
  destroy() {
    if (this.resizeObserver) {
      this.resizeObserver.disconnect();
      this.resizeObserver = null;
    }
    if (this.selectionUpdateHandler) {
      this.editor.off("selectionUpdate", this.selectionUpdateHandler);
      this.selectionUpdateHandler = null;
    }
    this.resizeHitZoneOverlay.destroy();
  }
}
//# sourceMappingURL=table-view.js.map
