class ContentChange {
  constructor(oldSlice, newSlice) {
    this.oldSlice = new SliceTraits(oldSlice);
    this.newSlice = new SliceTraits(newSlice);
  }
  isInsertion() {
    return this.oldSlice.isEmpty() && !this.newSlice.isEmpty();
  }
  isDeletion() {
    return !this.oldSlice.isEmpty() && this.newSlice.isEmpty();
  }
  isReplacement() {
    return !this.isInsertion() && !this.isDeletion();
  }
  isTextChange() {
    return this.isDeletion() && this.oldSlice.hasTextOnly() || this.isInsertion() && this.newSlice.hasTextOnly() || this.isReplacement() && this.oldSlice.hasTextOnly() && this.newSlice.hasTextOnly();
  }
  isMarkChange() {
    return this.isReplacement() && (this.oldSlice.hasMarks() || this.newSlice.hasMarks());
  }
  getMarkDiffs() {
    const oldMarks = this.oldSlice.getMarks();
    const newMarks = this.newSlice.getMarks();
    const diffs = [];
    oldMarks.forEach((mark) => {
      if (!newMarks.has(mark)) {
        diffs.push({ change: "delete", type: mark.type.name });
      }
    });
    newMarks.forEach((mark) => {
      if (!oldMarks.has(mark)) {
        diffs.push({ change: "insert", type: mark.type.name, data: mark.attrs });
      }
    });
    return diffs;
  }
  getNodeDiffs() {
    const oldNodes = this.oldSlice.getNodes();
    const newNodes = this.newSlice.getNodes();
    const diffs = [];
    oldNodes.forEach((node) => {
      if (!newNodes.has(node)) {
        diffs.push({ change: "delete", type: node.type.name, data: node.attrs });
      }
    });
    newNodes.forEach((node) => {
      if (!oldNodes.has(node)) {
        diffs.push({ change: "insert", type: node.type.name, data: node.attrs });
      }
    });
    return diffs;
  }
  getDiff() {
    if (this.isTextChange()) {
      return [
        {
          change: this.isReplacement() ? "replace" : this.isInsertion() ? "insert" : "delete",
          type: "text"
        }
      ];
    }
    if (this.isMarkChange()) {
      return this.getMarkDiffs();
    }
    return this.getNodeDiffs();
  }
  toJSON() {
    return {
      old: this.oldSlice.toJSON(),
      new: this.newSlice.toJSON()
    };
  }
}
class SliceTraits {
  constructor(slice) {
    this.slice = slice;
    this.slice = slice;
  }
  isEmpty() {
    return !this.slice || this.slice.size === 0;
  }
  getMarks() {
    return new Set(this.slice?.content.firstChild?.marks || []);
  }
  getNodes() {
    const nodes = [];
    this.slice?.content.descendants((node) => {
      if (!node.isText) {
        nodes.push(node);
      }
      return true;
    });
    return new Set(nodes);
  }
  toJSON() {
    return this.slice?.toJSON() || {};
  }
  hasTextOnly() {
    return !!this.slice && this.slice.content.childCount === 1 && !!this.slice.content.firstChild?.isText && this.slice.content.firstChild?.marks.length === 0;
  }
  hasMarks() {
    return !!this.slice && this.slice.content.childCount === 1 && !!this.slice.content.firstChild?.isText && this.slice.content.firstChild?.marks.length > 0;
  }
}
export {
  ContentChange
};
//# sourceMappingURL=content-change.js.map
