@kedataindo/docflow-plugins 0.0.87 → 0.0.89

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -47,10 +47,18 @@ __export(index_exports, {
47
47
  LocationChipNode: () => LocationChipNode,
48
48
  PageBreak: () => PageBreak,
49
49
  PeopleChipNode: () => PeopleChipNode,
50
+ SUGGESTION_DELETE: () => SUGGESTION_DELETE,
51
+ SUGGESTION_FORMAT: () => SUGGESTION_FORMAT,
52
+ SUGGESTION_INSERT: () => SUGGESTION_INSERT,
50
53
  SlashMenuExtension: () => SlashMenuExtension,
54
+ SuggestionDeleteMark: () => SuggestionDeleteMark,
55
+ SuggestionFormatMark: () => SuggestionFormatMark,
56
+ SuggestionInsertMark: () => SuggestionInsertMark,
51
57
  TocEntryNode: () => TocEntryNode,
52
58
  TocNode: () => TocNode,
53
59
  TocPageNumNode: () => TocPageNumNode,
60
+ acceptAllSuggestions: () => acceptAllSuggestions,
61
+ acceptSuggestion: () => acceptSuggestion,
54
62
  aiPlugin: () => aiPlugin,
55
63
  aiPluginKey: () => aiPluginKey,
56
64
  alignmentPlugin: () => alignmentPlugin,
@@ -67,6 +75,7 @@ __export(index_exports, {
67
75
  formattingPlugin: () => formattingPlugin,
68
76
  getAIPreview: () => getAIPreview,
69
77
  getCitationEngine: () => getCitationEngine,
78
+ getSuggestions: () => getSuggestions,
70
79
  headingsPlugin: () => headingsPlugin,
71
80
  highlightPlugin: () => highlightPlugin,
72
81
  imagePlugin: () => imagePlugin,
@@ -80,10 +89,15 @@ __export(index_exports, {
80
89
  placeholderPlugin: () => placeholderPlugin,
81
90
  regenerateToc: () => regenerateToc,
82
91
  registerSlashCommands: () => registerSlashCommands,
92
+ rejectAllSuggestions: () => rejectAllSuggestions,
93
+ rejectSuggestion: () => rejectSuggestion,
83
94
  sanitizeCiteprocHtml: () => sanitizeCiteprocHtml,
95
+ setDocumentMode: () => setDocumentMode,
96
+ setSuggestionAuthor: () => setSuggestionAuthor,
84
97
  slashMenuPlugin: () => slashMenuPlugin,
85
98
  slashState: () => slashState,
86
99
  smartElementsPlugin: () => smartElementsPlugin,
100
+ suggestChangesPlugin: () => suggestChangesPlugin,
87
101
  tablePageSplitPlugin: () => tablePageSplitPlugin,
88
102
  tablePlugin: () => tablePlugin,
89
103
  textColorPlugin: () => textColorPlugin,
@@ -911,8 +925,22 @@ var GoogleDocsHighlight = import_extension_highlight.default.extend({
911
925
  return [
912
926
  // Standard <mark> tag (default TipTap behavior)
913
927
  { tag: "mark" },
914
- // Google Docs pastes background-color as inline span style
915
- { tag: "span", style: "background-color" }
928
+ // Google Docs pastes background-color as an inline span style.
929
+ //
930
+ // This MUST be a *style* rule (no `tag`). A tag rule — `{ tag: 'span',
931
+ // style: 'background-color' }` — is treated as `{ tag: 'span' }` by
932
+ // ProseMirror (a rule with `tag` is a tag rule and `style` is ignored),
933
+ // and since mark rules run before node rules and only the first matching
934
+ // tag rule wins, it swallows EVERY <span>: custom nodes such as
935
+ // `span[data-toc-page]` degrade to highlight-marked text on load (issue
936
+ // #23), and it also loses to TextStyle's own bare span rule anyway.
937
+ //
938
+ // A style rule is applied in addition to the matched tag rule (see
939
+ // DOMParser.readStyles), and only fires for elements that actually carry
940
+ // the inline style — so bare spans and custom span-nodes are left alone.
941
+ // `getAttrs` receives the style VALUE here (not the element), so read the
942
+ // colour straight from it.
943
+ { style: "background-color", getAttrs: (value) => ({ color: value }) }
916
944
  ];
917
945
  },
918
946
  renderHTML({ HTMLAttributes }) {
@@ -2869,9 +2897,394 @@ var commentPlugin = {
2869
2897
  commands: {}
2870
2898
  };
2871
2899
 
2872
- // src/smartElements.ts
2900
+ // src/suggestChanges.ts
2873
2901
  var import_core11 = require("@tiptap/core");
2902
+ var import_state3 = require("@tiptap/pm/state");
2903
+ var import_transform2 = require("@tiptap/pm/transform");
2874
2904
  var import_docflow_core19 = require("@kedataindo/docflow-core");
2905
+ var SUGGESTION_INSERT = "suggestionInsert";
2906
+ var SUGGESTION_DELETE = "suggestionDelete";
2907
+ var SUGGESTION_FORMAT = "suggestionFormat";
2908
+ var FORMAT_MARKS = /* @__PURE__ */ new Set(["bold", "italic", "underline", "strike", "highlight"]);
2909
+ var SUGGEST_APPLIED_META = "suggestChanges:applied";
2910
+ var suggestChangesKey = new import_state3.PluginKey("suggestChanges");
2911
+ var suggestionAttributes = () => ({
2912
+ suggestionId: {
2913
+ default: null,
2914
+ parseHTML: (el) => el.getAttribute("data-suggestion-id"),
2915
+ renderHTML: (attrs) => attrs.suggestionId ? { "data-suggestion-id": attrs.suggestionId } : {}
2916
+ },
2917
+ authorId: {
2918
+ default: null,
2919
+ parseHTML: (el) => el.getAttribute("data-suggestion-author"),
2920
+ renderHTML: (attrs) => attrs.authorId ? { "data-suggestion-author": attrs.authorId } : {}
2921
+ },
2922
+ authorName: { default: null },
2923
+ createdAt: { default: null }
2924
+ });
2925
+ var SuggestionInsertMark = import_core11.Mark.create({
2926
+ name: SUGGESTION_INSERT,
2927
+ addAttributes() {
2928
+ return suggestionAttributes();
2929
+ },
2930
+ parseHTML() {
2931
+ return [{ tag: 'span[data-suggestion="insert"]' }];
2932
+ },
2933
+ renderHTML({ HTMLAttributes }) {
2934
+ return [
2935
+ "span",
2936
+ (0, import_core11.mergeAttributes)(HTMLAttributes, {
2937
+ "data-suggestion": "insert",
2938
+ class: "docflow-suggestion docflow-suggestion--insert"
2939
+ }),
2940
+ 0
2941
+ ];
2942
+ }
2943
+ });
2944
+ var SuggestionDeleteMark = import_core11.Mark.create({
2945
+ name: SUGGESTION_DELETE,
2946
+ addAttributes() {
2947
+ return suggestionAttributes();
2948
+ },
2949
+ parseHTML() {
2950
+ return [{ tag: 'span[data-suggestion="delete"]' }];
2951
+ },
2952
+ renderHTML({ HTMLAttributes }) {
2953
+ return [
2954
+ "span",
2955
+ (0, import_core11.mergeAttributes)(HTMLAttributes, {
2956
+ "data-suggestion": "delete",
2957
+ class: "docflow-suggestion docflow-suggestion--delete"
2958
+ }),
2959
+ 0
2960
+ ];
2961
+ }
2962
+ });
2963
+ var SuggestionFormatMark = import_core11.Mark.create({
2964
+ name: SUGGESTION_FORMAT,
2965
+ addAttributes() {
2966
+ return {
2967
+ ...suggestionAttributes(),
2968
+ format: {
2969
+ default: null,
2970
+ parseHTML: (el) => el.getAttribute("data-suggestion-format"),
2971
+ renderHTML: (attrs) => attrs.format ? { "data-suggestion-format": attrs.format } : {}
2972
+ },
2973
+ delta: { default: "add" }
2974
+ };
2975
+ },
2976
+ parseHTML() {
2977
+ return [{ tag: 'span[data-suggestion="format"]' }];
2978
+ },
2979
+ renderHTML({ HTMLAttributes }) {
2980
+ return [
2981
+ "span",
2982
+ (0, import_core11.mergeAttributes)(HTMLAttributes, {
2983
+ "data-suggestion": "format",
2984
+ class: "docflow-suggestion docflow-suggestion--format"
2985
+ }),
2986
+ 0
2987
+ ];
2988
+ }
2989
+ });
2990
+ var suggestionSeq = 0;
2991
+ var newSuggestionId = () => {
2992
+ suggestionSeq += 1;
2993
+ return `sug-${Date.now().toString(36)}-${suggestionSeq.toString(36)}`;
2994
+ };
2995
+ var adjacentRunId = (editorState, pos, markName) => {
2996
+ if (pos <= 0) return null;
2997
+ const before = editorState.doc.resolve(pos).nodeBefore;
2998
+ if (!before || !before.isText) return null;
2999
+ const mark = before.marks.find((m) => m.type.name === markName);
3000
+ return mark?.attrs.suggestionId ?? null;
3001
+ };
3002
+ var markAttrs = (id, author) => ({
3003
+ suggestionId: id,
3004
+ authorId: author.id ?? null,
3005
+ authorName: author.name ?? null,
3006
+ createdAt: Date.now()
3007
+ });
3008
+ var collectRanges = (doc, markName, id) => {
3009
+ const out = [];
3010
+ doc.descendants((node, pos) => {
3011
+ if (!node.isText || node.marks.length === 0) return;
3012
+ for (const mark of node.marks) {
3013
+ if (mark.type.name !== markName) continue;
3014
+ if (id && mark.attrs.suggestionId !== id) continue;
3015
+ out.push({ from: pos, to: pos + node.nodeSize, attrs: mark.attrs });
3016
+ }
3017
+ });
3018
+ return out;
3019
+ };
3020
+ var SuggestChanges = import_core11.Extension.create({
3021
+ name: "suggestChanges",
3022
+ addStorage() {
3023
+ return { suggestions: [] };
3024
+ },
3025
+ addProseMirrorPlugins() {
3026
+ const editor = this.editor;
3027
+ const syncStorage = () => {
3028
+ const storage = editor.storage.suggestChanges;
3029
+ if (storage) storage.suggestions = getSuggestions(editor);
3030
+ };
3031
+ return [
3032
+ new import_state3.Plugin({
3033
+ key: suggestChangesKey,
3034
+ state: {
3035
+ init: () => ({ mode: "editing", author: {} }),
3036
+ apply: (tr, value) => {
3037
+ const meta = tr.getMeta(suggestChangesKey);
3038
+ if (!meta) return value;
3039
+ return {
3040
+ mode: meta.mode ?? value.mode,
3041
+ author: meta.author ?? value.author
3042
+ };
3043
+ }
3044
+ },
3045
+ view: () => {
3046
+ syncStorage();
3047
+ return { update: syncStorage };
3048
+ },
3049
+ appendTransaction: (transactions, _oldState, newState) => {
3050
+ if (transactions.some((tr2) => tr2.getMeta(SUGGEST_APPLIED_META))) return null;
3051
+ const current = suggestChangesKey.getState(newState);
3052
+ if (current?.mode !== "suggesting") return null;
3053
+ const formatMark = newState.schema.marks[SUGGESTION_FORMAT];
3054
+ if (!formatMark) return null;
3055
+ const changes = [];
3056
+ for (const tr2 of transactions) {
3057
+ for (const step of tr2.steps) {
3058
+ if (step instanceof import_transform2.AddMarkStep || step instanceof import_transform2.RemoveMarkStep) {
3059
+ if (!FORMAT_MARKS.has(step.mark.type.name)) continue;
3060
+ changes.push({ from: step.from, to: step.to, name: step.mark.type.name, add: step instanceof import_transform2.AddMarkStep });
3061
+ }
3062
+ }
3063
+ }
3064
+ if (changes.length === 0) return null;
3065
+ const tr = newState.tr;
3066
+ for (const change of changes) {
3067
+ const target = newState.schema.marks[change.name];
3068
+ if (!target) continue;
3069
+ if (change.add) tr.removeMark(change.from, change.to, target);
3070
+ else tr.addMark(change.from, change.to, target.create());
3071
+ tr.addMark(
3072
+ change.from,
3073
+ change.to,
3074
+ formatMark.create({ ...markAttrs(newSuggestionId(), current.author), format: change.name, delta: change.add ? "add" : "remove" })
3075
+ );
3076
+ }
3077
+ tr.setMeta(SUGGEST_APPLIED_META, true);
3078
+ return tr;
3079
+ },
3080
+ props: {
3081
+ handleTextInput: (view, from, to, text) => {
3082
+ const current = suggestChangesKey.getState(view.state);
3083
+ if (current?.mode !== "suggesting" || !text) return false;
3084
+ const insert = view.state.schema.marks[SUGGESTION_INSERT];
3085
+ const del = view.state.schema.marks[SUGGESTION_DELETE];
3086
+ if (!insert || !del) return false;
3087
+ const id = adjacentRunId(view.state, from, SUGGESTION_INSERT) ?? newSuggestionId();
3088
+ const tr = view.state.tr;
3089
+ if (to > from) tr.addMark(from, to, del.create(markAttrs(id, current.author)));
3090
+ const insertAt = to;
3091
+ tr.insertText(text, insertAt, insertAt);
3092
+ tr.addMark(insertAt, insertAt + text.length, insert.create(markAttrs(id, current.author)));
3093
+ view.dispatch(tr);
3094
+ return true;
3095
+ },
3096
+ handleKeyDown: (view, event) => {
3097
+ const current = suggestChangesKey.getState(view.state);
3098
+ if (current?.mode !== "suggesting") return false;
3099
+ if (event.key !== "Backspace" && event.key !== "Delete") return false;
3100
+ const del = view.state.schema.marks[SUGGESTION_DELETE];
3101
+ if (!del) return false;
3102
+ const { selection, doc } = view.state;
3103
+ let from;
3104
+ let to;
3105
+ if (!selection.empty) {
3106
+ from = selection.from;
3107
+ to = selection.to;
3108
+ } else if (event.key === "Backspace") {
3109
+ if (selection.from <= 1) return false;
3110
+ from = selection.from - 1;
3111
+ to = selection.from;
3112
+ } else {
3113
+ if (selection.to >= doc.content.size - 1) return false;
3114
+ from = selection.to;
3115
+ to = selection.to + 1;
3116
+ }
3117
+ const id = adjacentRunId(view.state, from, SUGGESTION_DELETE) ?? newSuggestionId();
3118
+ const tr = view.state.tr.addMark(from, to, del.create(markAttrs(id, current.author)));
3119
+ if (event.key === "Backspace" && selection.empty) {
3120
+ tr.setSelection(import_state3.TextSelection.create(tr.doc, from));
3121
+ }
3122
+ view.dispatch(tr);
3123
+ return true;
3124
+ },
3125
+ handlePaste: (view, _event, slice) => {
3126
+ const current = suggestChangesKey.getState(view.state);
3127
+ if (current?.mode !== "suggesting") return false;
3128
+ const insert = view.state.schema.marks[SUGGESTION_INSERT];
3129
+ const del = view.state.schema.marks[SUGGESTION_DELETE];
3130
+ if (!insert || !del) return false;
3131
+ const { from, to } = view.state.selection;
3132
+ const id = adjacentRunId(view.state, from, SUGGESTION_INSERT) ?? newSuggestionId();
3133
+ const tr = view.state.tr;
3134
+ if (to > from) tr.addMark(from, to, del.create(markAttrs(id, current.author)));
3135
+ const insertAt = to;
3136
+ tr.insert(insertAt, slice.content);
3137
+ tr.addMark(insertAt, insertAt + slice.content.size, insert.create(markAttrs(id, current.author)));
3138
+ view.dispatch(tr);
3139
+ return true;
3140
+ }
3141
+ }
3142
+ })
3143
+ ];
3144
+ },
3145
+ addCommands() {
3146
+ return {
3147
+ setDocumentMode: (mode) => ({ state, dispatch }) => {
3148
+ if (!dispatch) return false;
3149
+ dispatch(state.tr.setMeta(suggestChangesKey, { mode }));
3150
+ return true;
3151
+ },
3152
+ setSuggestionAuthor: (author) => ({ state, dispatch }) => {
3153
+ if (!dispatch) return false;
3154
+ dispatch(state.tr.setMeta(suggestChangesKey, { author }));
3155
+ return true;
3156
+ },
3157
+ acceptSuggestion: (id) => ({ state, dispatch }) => {
3158
+ const tr = buildResolveTr(state, true, id);
3159
+ if (!tr || !dispatch) return false;
3160
+ dispatch(tr);
3161
+ return true;
3162
+ },
3163
+ rejectSuggestion: (id) => ({ state, dispatch }) => {
3164
+ const tr = buildResolveTr(state, false, id);
3165
+ if (!tr || !dispatch) return false;
3166
+ dispatch(tr);
3167
+ return true;
3168
+ },
3169
+ acceptAllSuggestions: () => ({ state, dispatch }) => {
3170
+ const tr = buildResolveTr(state, true);
3171
+ if (!tr || !dispatch) return false;
3172
+ dispatch(tr);
3173
+ return true;
3174
+ },
3175
+ rejectAllSuggestions: () => ({ state, dispatch }) => {
3176
+ const tr = buildResolveTr(state, false);
3177
+ if (!tr || !dispatch) return false;
3178
+ dispatch(tr);
3179
+ return true;
3180
+ }
3181
+ };
3182
+ }
3183
+ });
3184
+ function editorDispatch(editor, meta) {
3185
+ editor.view.dispatch(editor.state.tr.setMeta(suggestChangesKey, meta));
3186
+ }
3187
+ function setDocumentMode(editor, mode) {
3188
+ editorDispatch(editor, { mode });
3189
+ return true;
3190
+ }
3191
+ function setSuggestionAuthor(editor, author) {
3192
+ editorDispatch(editor, { author });
3193
+ return true;
3194
+ }
3195
+ function getSuggestions(editor) {
3196
+ const byId = /* @__PURE__ */ new Map();
3197
+ const scan = (markName, type) => {
3198
+ editor.state.doc.descendants((node, pos) => {
3199
+ if (!node.isText) return;
3200
+ for (const mark of node.marks) {
3201
+ if (mark.type.name !== markName) continue;
3202
+ const id = mark.attrs.suggestionId;
3203
+ const existing = byId.get(id);
3204
+ if (existing) {
3205
+ existing.from = Math.min(existing.from, pos);
3206
+ existing.to = Math.max(existing.to, pos + node.nodeSize);
3207
+ } else {
3208
+ byId.set(id, {
3209
+ id,
3210
+ type,
3211
+ authorId: mark.attrs.authorId ?? null,
3212
+ authorName: mark.attrs.authorName ?? null,
3213
+ from: pos,
3214
+ to: pos + node.nodeSize,
3215
+ ...type === "format" ? {
3216
+ format: mark.attrs.format ?? void 0,
3217
+ delta: mark.attrs.delta ?? void 0
3218
+ } : {}
3219
+ });
3220
+ }
3221
+ }
3222
+ });
3223
+ };
3224
+ scan(SUGGESTION_INSERT, "insert");
3225
+ scan(SUGGESTION_DELETE, "delete");
3226
+ scan(SUGGESTION_FORMAT, "format");
3227
+ return [...byId.values()].sort((a, b) => a.from - b.from);
3228
+ }
3229
+ function buildResolveTr(state, accept, id) {
3230
+ const { schema } = state;
3231
+ const insertMark = schema.marks[SUGGESTION_INSERT];
3232
+ const deleteMark = schema.marks[SUGGESTION_DELETE];
3233
+ const formatMark = schema.marks[SUGGESTION_FORMAT];
3234
+ if (!insertMark || !deleteMark) return null;
3235
+ const insertRanges = collectRanges(state.doc, SUGGESTION_INSERT, id);
3236
+ const deleteRanges = collectRanges(state.doc, SUGGESTION_DELETE, id);
3237
+ const formatRanges = formatMark ? collectRanges(state.doc, SUGGESTION_FORMAT, id) : [];
3238
+ if (insertRanges.length === 0 && deleteRanges.length === 0 && formatRanges.length === 0) return null;
3239
+ const tr = state.tr;
3240
+ for (const range of formatRanges) {
3241
+ if (accept) {
3242
+ const target = schema.marks[range.attrs.format];
3243
+ if (target) {
3244
+ if (range.attrs.delta === "remove") tr.removeMark(range.from, range.to, target);
3245
+ else tr.addMark(range.from, range.to, target.create());
3246
+ }
3247
+ }
3248
+ if (formatMark) tr.removeMark(range.from, range.to, formatMark);
3249
+ }
3250
+ const rangesToUnmark = accept ? insertRanges : deleteRanges;
3251
+ const markToRemove = accept ? insertMark : deleteMark;
3252
+ const rangesToDelete = accept ? deleteRanges : insertRanges;
3253
+ for (const range of rangesToUnmark) {
3254
+ tr.removeMark(range.from, range.to, markToRemove);
3255
+ }
3256
+ for (const range of [...rangesToDelete].sort((a, b) => b.from - a.from)) {
3257
+ tr.delete(range.from, range.to);
3258
+ }
3259
+ tr.setMeta(SUGGEST_APPLIED_META, true);
3260
+ return tr.docChanged ? tr : null;
3261
+ }
3262
+ function resolveSuggestions(editor, accept, id) {
3263
+ const tr = buildResolveTr(editor.state, accept, id);
3264
+ if (!tr) return false;
3265
+ editor.view.dispatch(tr);
3266
+ return true;
3267
+ }
3268
+ var acceptSuggestion = (editor, id) => resolveSuggestions(editor, true, id);
3269
+ var rejectSuggestion = (editor, id) => resolveSuggestions(editor, false, id);
3270
+ var acceptAllSuggestions = (editor) => resolveSuggestions(editor, true);
3271
+ var rejectAllSuggestions = (editor) => resolveSuggestions(editor, false);
3272
+ var suggestChangesPlugin = (0, import_docflow_core19.definePlugin)({
3273
+ id: "suggestChanges",
3274
+ tiptapExtensions: [SuggestionInsertMark, SuggestionDeleteMark, SuggestionFormatMark, SuggestChanges],
3275
+ commands: {
3276
+ setDocumentMode: (editor, ...args) => setDocumentMode(editor, args[0]),
3277
+ setSuggestionAuthor: (editor, ...args) => setSuggestionAuthor(editor, args[0] ?? {}),
3278
+ acceptSuggestion: (editor, ...args) => acceptSuggestion(editor, args[0]),
3279
+ rejectSuggestion: (editor, ...args) => rejectSuggestion(editor, args[0]),
3280
+ acceptAllSuggestions: (editor) => acceptAllSuggestions(editor),
3281
+ rejectAllSuggestions: (editor) => rejectAllSuggestions(editor)
3282
+ }
3283
+ });
3284
+
3285
+ // src/smartElements.ts
3286
+ var import_core12 = require("@tiptap/core");
3287
+ var import_docflow_core20 = require("@kedataindo/docflow-core");
2875
3288
  function todayISO() {
2876
3289
  return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
2877
3290
  }
@@ -2888,7 +3301,7 @@ var DEFAULT_STATUSES = ["To Do", "In Progress", "Review", "Approved"];
2888
3301
  function slugify(s) {
2889
3302
  return s.toLowerCase().replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, "");
2890
3303
  }
2891
- var DateChipNode = import_core11.Node.create({
3304
+ var DateChipNode = import_core12.Node.create({
2892
3305
  name: "dateChip",
2893
3306
  group: "inline",
2894
3307
  inline: true,
@@ -2908,7 +3321,7 @@ var DateChipNode = import_core11.Node.create({
2908
3321
  return [{ tag: 'span[data-node-type="date-chip"]' }];
2909
3322
  },
2910
3323
  renderHTML({ node, HTMLAttributes }) {
2911
- return ["span", (0, import_core11.mergeAttributes)(HTMLAttributes, {
3324
+ return ["span", (0, import_core12.mergeAttributes)(HTMLAttributes, {
2912
3325
  "data-node-type": "date-chip",
2913
3326
  class: "docs-chip docs-chip--date"
2914
3327
  }), formatDate(node.attrs.date)];
@@ -2961,7 +3374,7 @@ var DateChipNode = import_core11.Node.create({
2961
3374
  };
2962
3375
  }
2963
3376
  });
2964
- var PeopleChipNode = import_core11.Node.create({
3377
+ var PeopleChipNode = import_core12.Node.create({
2965
3378
  name: "peopleChip",
2966
3379
  group: "inline",
2967
3380
  inline: true,
@@ -2986,7 +3399,7 @@ var PeopleChipNode = import_core11.Node.create({
2986
3399
  return [{ tag: 'span[data-node-type="people-chip"]' }];
2987
3400
  },
2988
3401
  renderHTML({ node, HTMLAttributes }) {
2989
- return ["span", (0, import_core11.mergeAttributes)(HTMLAttributes, {
3402
+ return ["span", (0, import_core12.mergeAttributes)(HTMLAttributes, {
2990
3403
  "data-node-type": "people-chip",
2991
3404
  class: "docs-chip docs-chip--people"
2992
3405
  }), `@${node.attrs.name || "user"}`];
@@ -3023,7 +3436,7 @@ var PeopleChipNode = import_core11.Node.create({
3023
3436
  };
3024
3437
  }
3025
3438
  });
3026
- var FileChipNode = import_core11.Node.create({
3439
+ var FileChipNode = import_core12.Node.create({
3027
3440
  name: "fileChip",
3028
3441
  group: "inline",
3029
3442
  inline: true,
@@ -3048,7 +3461,7 @@ var FileChipNode = import_core11.Node.create({
3048
3461
  return [{ tag: 'span[data-node-type="file-chip"]' }];
3049
3462
  },
3050
3463
  renderHTML({ node, HTMLAttributes }) {
3051
- return ["span", (0, import_core11.mergeAttributes)(HTMLAttributes, {
3464
+ return ["span", (0, import_core12.mergeAttributes)(HTMLAttributes, {
3052
3465
  "data-node-type": "file-chip",
3053
3466
  class: "docs-chip docs-chip--file"
3054
3467
  }), node.attrs.name || "file"];
@@ -3085,7 +3498,7 @@ var FileChipNode = import_core11.Node.create({
3085
3498
  };
3086
3499
  }
3087
3500
  });
3088
- var DropdownChipNode = import_core11.Node.create({
3501
+ var DropdownChipNode = import_core12.Node.create({
3089
3502
  name: "dropdownChip",
3090
3503
  group: "inline",
3091
3504
  inline: true,
@@ -3116,7 +3529,7 @@ var DropdownChipNode = import_core11.Node.create({
3116
3529
  return [{ tag: 'span[data-node-type="dropdown-chip"]' }];
3117
3530
  },
3118
3531
  renderHTML({ node, HTMLAttributes }) {
3119
- return ["span", (0, import_core11.mergeAttributes)(HTMLAttributes, {
3532
+ return ["span", (0, import_core12.mergeAttributes)(HTMLAttributes, {
3120
3533
  "data-node-type": "dropdown-chip",
3121
3534
  class: "docs-chip docs-chip--dropdown"
3122
3535
  }), node.attrs.selected || ""];
@@ -3168,7 +3581,7 @@ var DropdownChipNode = import_core11.Node.create({
3168
3581
  };
3169
3582
  }
3170
3583
  });
3171
- var LocationChipNode = import_core11.Node.create({
3584
+ var LocationChipNode = import_core12.Node.create({
3172
3585
  name: "locationChip",
3173
3586
  group: "inline",
3174
3587
  inline: true,
@@ -3204,7 +3617,7 @@ var LocationChipNode = import_core11.Node.create({
3204
3617
  return [{ tag: 'span[data-node-type="location-chip"]' }];
3205
3618
  },
3206
3619
  renderHTML({ node, HTMLAttributes }) {
3207
- return ["span", (0, import_core11.mergeAttributes)(HTMLAttributes, {
3620
+ return ["span", (0, import_core12.mergeAttributes)(HTMLAttributes, {
3208
3621
  "data-node-type": "location-chip",
3209
3622
  class: "docs-chip docs-chip--location"
3210
3623
  }), node.attrs.label || ""];
@@ -3241,7 +3654,7 @@ var LocationChipNode = import_core11.Node.create({
3241
3654
  };
3242
3655
  }
3243
3656
  });
3244
- var smartElementsPlugin = (0, import_docflow_core19.definePlugin)({
3657
+ var smartElementsPlugin = (0, import_docflow_core20.definePlugin)({
3245
3658
  id: "smart-elements",
3246
3659
  tiptapExtensions: [
3247
3660
  DateChipNode,
@@ -3300,10 +3713,10 @@ var smartElementsPlugin = (0, import_docflow_core19.definePlugin)({
3300
3713
  });
3301
3714
 
3302
3715
  // src/tablePageSplit.ts
3303
- var import_docflow_core20 = require("@kedataindo/docflow-core");
3304
- var import_core12 = require("@tiptap/core");
3305
- var import_state3 = require("@tiptap/pm/state");
3306
- var PLUGIN_KEY = new import_state3.PluginKey("docflow/table-page-split");
3716
+ var import_docflow_core21 = require("@kedataindo/docflow-core");
3717
+ var import_core13 = require("@tiptap/core");
3718
+ var import_state4 = require("@tiptap/pm/state");
3719
+ var PLUGIN_KEY = new import_state4.PluginKey("docflow/table-page-split");
3307
3720
  var SPLIT_MARK = "head";
3308
3721
  var MAX_SPLIT_DEPTH = 16;
3309
3722
  function readPageContentHeightPx(view, editor) {
@@ -3480,7 +3893,7 @@ function runSplitPass(view, editor) {
3480
3893
  tr.setMeta(PLUGIN_KEY, { splitAtRow: -1 });
3481
3894
  v.dispatch(tr);
3482
3895
  }
3483
- var TablePageSplitExtension = import_core12.Extension.create({
3896
+ var TablePageSplitExtension = import_core13.Extension.create({
3484
3897
  name: "tablePageSplit",
3485
3898
  addProseMirrorPlugins() {
3486
3899
  let viewRef = null;
@@ -3488,7 +3901,7 @@ var TablePageSplitExtension = import_core12.Extension.create({
3488
3901
  const ext = this;
3489
3902
  const editorRef = ext.editor ?? null;
3490
3903
  return [
3491
- new import_state3.Plugin({
3904
+ new import_state4.Plugin({
3492
3905
  key: PLUGIN_KEY,
3493
3906
  view(_editorView) {
3494
3907
  viewRef = _editorView;
@@ -3520,15 +3933,15 @@ var TablePageSplitExtension = import_core12.Extension.create({
3520
3933
  ];
3521
3934
  }
3522
3935
  });
3523
- var tablePageSplitPlugin = (0, import_docflow_core20.definePlugin)({
3936
+ var tablePageSplitPlugin = (0, import_docflow_core21.definePlugin)({
3524
3937
  id: "tablePageSplit",
3525
3938
  tiptapExtensions: [TablePageSplitExtension]
3526
3939
  });
3527
3940
 
3528
3941
  // src/slashMenu.ts
3529
- var import_core13 = require("@tiptap/core");
3530
- var import_state4 = require("@tiptap/pm/state");
3531
- var import_docflow_core21 = require("@kedataindo/docflow-core");
3942
+ var import_core14 = require("@tiptap/core");
3943
+ var import_state5 = require("@tiptap/pm/state");
3944
+ var import_docflow_core22 = require("@kedataindo/docflow-core");
3532
3945
  var slashState = {
3533
3946
  open: false,
3534
3947
  query: "",
@@ -3582,12 +3995,12 @@ function getRegisteredCommands() {
3582
3995
  return true;
3583
3996
  });
3584
3997
  }
3585
- var SlashMenuExtension = import_core13.Extension.create({
3998
+ var SlashMenuExtension = import_core14.Extension.create({
3586
3999
  name: "slashMenu",
3587
4000
  addProseMirrorPlugins() {
3588
4001
  return [
3589
- new import_state4.Plugin({
3590
- key: new import_state4.PluginKey("slashMenu"),
4002
+ new import_state5.Plugin({
4003
+ key: new import_state5.PluginKey("slashMenu"),
3591
4004
  props: {
3592
4005
  handleTextInput(view, from, _to, text) {
3593
4006
  if (text === "/") {
@@ -3673,7 +4086,7 @@ var SlashMenuExtension = import_core13.Extension.create({
3673
4086
  ];
3674
4087
  }
3675
4088
  });
3676
- var slashMenuPlugin = (0, import_docflow_core21.definePlugin)({
4089
+ var slashMenuPlugin = (0, import_docflow_core22.definePlugin)({
3677
4090
  id: "slash-menu",
3678
4091
  tiptapExtensions: [SlashMenuExtension],
3679
4092
  hooks: {
@@ -3706,6 +4119,7 @@ var defaultPlugins = [
3706
4119
  citationPlugin,
3707
4120
  aiPlugin,
3708
4121
  commentPlugin,
4122
+ suggestChangesPlugin,
3709
4123
  smartElementsPlugin
3710
4124
  ];
3711
4125
  // Annotate the CommonJS export names for ESM import in node:
@@ -3727,10 +4141,18 @@ var defaultPlugins = [
3727
4141
  LocationChipNode,
3728
4142
  PageBreak,
3729
4143
  PeopleChipNode,
4144
+ SUGGESTION_DELETE,
4145
+ SUGGESTION_FORMAT,
4146
+ SUGGESTION_INSERT,
3730
4147
  SlashMenuExtension,
4148
+ SuggestionDeleteMark,
4149
+ SuggestionFormatMark,
4150
+ SuggestionInsertMark,
3731
4151
  TocEntryNode,
3732
4152
  TocNode,
3733
4153
  TocPageNumNode,
4154
+ acceptAllSuggestions,
4155
+ acceptSuggestion,
3734
4156
  aiPlugin,
3735
4157
  aiPluginKey,
3736
4158
  alignmentPlugin,
@@ -3747,6 +4169,7 @@ var defaultPlugins = [
3747
4169
  formattingPlugin,
3748
4170
  getAIPreview,
3749
4171
  getCitationEngine,
4172
+ getSuggestions,
3750
4173
  headingsPlugin,
3751
4174
  highlightPlugin,
3752
4175
  imagePlugin,
@@ -3760,10 +4183,15 @@ var defaultPlugins = [
3760
4183
  placeholderPlugin,
3761
4184
  regenerateToc,
3762
4185
  registerSlashCommands,
4186
+ rejectAllSuggestions,
4187
+ rejectSuggestion,
3763
4188
  sanitizeCiteprocHtml,
4189
+ setDocumentMode,
4190
+ setSuggestionAuthor,
3764
4191
  slashMenuPlugin,
3765
4192
  slashState,
3766
4193
  smartElementsPlugin,
4194
+ suggestChangesPlugin,
3767
4195
  tablePageSplitPlugin,
3768
4196
  tablePlugin,
3769
4197
  textColorPlugin,