@magic-marker/prosemirror-suggest-changes 0.3.3-wrap-unwrap.29 → 0.4.0

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.
Files changed (88) hide show
  1. package/dist/__tests__/playwrightHelpers.d.ts +2 -2
  2. package/dist/__tests__/playwrightPage.d.ts +2 -50
  3. package/dist/commands.js +43 -178
  4. package/dist/ensureSelectionPlugin.js +3 -3
  5. package/dist/features/joinOnDelete/index.d.ts +19 -4
  6. package/dist/features/joinOnDelete/index.js +53 -166
  7. package/dist/generateId.js +4 -31
  8. package/dist/index.d.ts +2 -5
  9. package/dist/index.js +2 -4
  10. package/dist/replaceStep.d.ts +1 -1
  11. package/dist/schema.d.ts +1 -2
  12. package/dist/schema.js +1 -37
  13. package/dist/testing/testBuilders.d.ts +2 -1
  14. package/dist/utils.d.ts +0 -1
  15. package/dist/utils.js +2 -6
  16. package/dist/withSuggestChanges.d.ts +14 -11
  17. package/dist/withSuggestChanges.js +94 -64
  18. package/package.json +1 -1
  19. package/src/features/joinOnDelete/README.md +8 -0
  20. package/dist/features/joinOnDelete/__tests__/joinOnDeleteInLists.playwright.test.d.ts +0 -1
  21. package/dist/features/joinOnDelete/__tests__/joinOnDeleteInListsTipTapStyle.playwright.test.d.ts +0 -1
  22. package/dist/features/joinOnDelete/__tests__/listWithJoinsAndStructureMarks.playwright.test.d.ts +0 -1
  23. package/dist/features/joinOnDelete/normalizeJoinNodesMetadata.d.ts +0 -6
  24. package/dist/features/joinOnDelete/normalizeJoinNodesMetadata.js +0 -24
  25. package/dist/features/joinOnDelete/types.d.ts +0 -34
  26. package/dist/features/joinOnDelete/types.js +0 -20
  27. package/dist/features/transactionShaping/detectSpecialTransactionShape.d.ts +0 -3
  28. package/dist/features/transactionShaping/detectSpecialTransactionShape.js +0 -4
  29. package/dist/features/transactionShaping/index.d.ts +0 -3
  30. package/dist/features/transactionShaping/index.js +0 -11
  31. package/dist/features/transactionShaping/tipTapParagraphIntoListJoin/detectTipTapParagraphIntoListJoin.d.ts +0 -3
  32. package/dist/features/transactionShaping/tipTapParagraphIntoListJoin/detectTipTapParagraphIntoListJoin.js +0 -48
  33. package/dist/features/transactionShaping/tipTapParagraphIntoListJoin/detectTipTapParagraphIntoListJoin.test.d.ts +0 -1
  34. package/dist/features/transactionShaping/tipTapParagraphIntoListJoin/detectTipTapParagraphIntoListJoin.test.js +0 -188
  35. package/dist/features/transactionShaping/tipTapParagraphIntoListJoin/handleTipTapParagraphIntoListJoin.d.ts +0 -3
  36. package/dist/features/transactionShaping/tipTapParagraphIntoListJoin/handleTipTapParagraphIntoListJoin.js +0 -64
  37. package/dist/features/transactionShaping/tipTapParagraphIntoListJoin/index.d.ts +0 -2
  38. package/dist/features/transactionShaping/tipTapParagraphIntoListJoin/index.js +0 -2
  39. package/dist/features/transactionShaping/types.d.ts +0 -20
  40. package/dist/features/transactionShaping/types.js +0 -1
  41. package/dist/features/wrapUnwrap/__tests__/blockquoteStructure.playwright.test.d.ts +0 -1
  42. package/dist/features/wrapUnwrap/__tests__/buildMaterializedPaths.test.d.ts +0 -1
  43. package/dist/features/wrapUnwrap/__tests__/listStructure.playwright.test.d.ts +0 -1
  44. package/dist/features/wrapUnwrap/__tests__/listStructureTextEdits.playwright.test.d.ts +0 -1
  45. package/dist/features/wrapUnwrap/__tests__/splitDetection.test.d.ts +0 -1
  46. package/dist/features/wrapUnwrap/addIdAttr.d.ts +0 -2
  47. package/dist/features/wrapUnwrap/addIdAttr.js +0 -60
  48. package/dist/features/wrapUnwrap/apply/applyStructureSuggestions.d.ts +0 -10
  49. package/dist/features/wrapUnwrap/apply/applyStructureSuggestions.js +0 -41
  50. package/dist/features/wrapUnwrap/apply/index.d.ts +0 -5
  51. package/dist/features/wrapUnwrap/apply/index.js +0 -21
  52. package/dist/features/wrapUnwrap/areEquivalentStructureMarks.d.ts +0 -2
  53. package/dist/features/wrapUnwrap/areEquivalentStructureMarks.js +0 -17
  54. package/dist/features/wrapUnwrap/buildMaterializedPaths.d.ts +0 -3
  55. package/dist/features/wrapUnwrap/buildMaterializedPaths.js +0 -82
  56. package/dist/features/wrapUnwrap/constants.d.ts +0 -3
  57. package/dist/features/wrapUnwrap/constants.js +0 -3
  58. package/dist/features/wrapUnwrap/generateUniqueNodeId.d.ts +0 -1
  59. package/dist/features/wrapUnwrap/generateUniqueNodeId.js +0 -6
  60. package/dist/features/wrapUnwrap/getNodeId.d.ts +0 -2
  61. package/dist/features/wrapUnwrap/getNodeId.js +0 -5
  62. package/dist/features/wrapUnwrap/revert/deleteNodeUpwards.d.ts +0 -3
  63. package/dist/features/wrapUnwrap/revert/deleteNodeUpwards.js +0 -37
  64. package/dist/features/wrapUnwrap/revert/index.d.ts +0 -5
  65. package/dist/features/wrapUnwrap/revert/index.js +0 -19
  66. package/dist/features/wrapUnwrap/revert/revertAddOp.d.ts +0 -4
  67. package/dist/features/wrapUnwrap/revert/revertAddOp.js +0 -4
  68. package/dist/features/wrapUnwrap/revert/revertMoveOp.d.ts +0 -16
  69. package/dist/features/wrapUnwrap/revert/revertMoveOp.js +0 -122
  70. package/dist/features/wrapUnwrap/revert/revertStructureSuggestions.d.ts +0 -10
  71. package/dist/features/wrapUnwrap/revert/revertStructureSuggestions.js +0 -236
  72. package/dist/features/wrapUnwrap/sameParentChain.d.ts +0 -2
  73. package/dist/features/wrapUnwrap/sameParentChain.js +0 -4
  74. package/dist/features/wrapUnwrap/structureChangesPlugin.d.ts +0 -17
  75. package/dist/features/wrapUnwrap/structureChangesPlugin.js +0 -299
  76. package/dist/features/wrapUnwrap/types.d.ts +0 -54
  77. package/dist/features/wrapUnwrap/types.js +0 -23
  78. package/dist/features/wrapUnwrap/uniqueNodeIdsPlugin.d.ts +0 -17
  79. package/dist/features/wrapUnwrap/uniqueNodeIdsPlugin.js +0 -106
  80. package/dist/listInputRules.d.ts +0 -2
  81. package/dist/listInputRules.js +0 -14
  82. package/dist/rebaseStep.d.ts +0 -9
  83. package/dist/rebaseStep.js +0 -11
  84. package/dist/testing/e2eTestSchema.d.ts +0 -2
  85. package/dist/transformToSuggestionTransaction.d.ts +0 -22
  86. package/dist/transformToSuggestionTransaction.js +0 -101
  87. package/dist/wrappingInputRule.d.ts +0 -4
  88. package/dist/wrappingInputRule.js +0 -28
@@ -1,106 +0,0 @@
1
- import { Plugin, PluginKey } from "prosemirror-state";
2
- import { getNodeId } from "./getNodeId.js";
3
- import { Transform } from "prosemirror-transform";
4
- // unique ids plugin
5
- // https://discuss.prosemirror.net/t/how-to-avoid-copying-attributes-to-new-paragraph/4568/2
6
- // (also checks and fix duplicates that inevitably appear)
7
- export const uniqueNodeIdsPluginKey = new PluginKey("@handlewithcare/prosemirror-suggest-changes-unique-node-ids");
8
- export const UNIQUE_NODE_IDS_PLUGIN_META = "unique-node-ids-plugin";
9
- const TRACE_ENABLED = false;
10
- function trace(...args) {
11
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
12
- if (!TRACE_ENABLED) return;
13
- console.log("[uniqueNodeIdsPlugin]", ...args);
14
- }
15
- export function uniqueNodeIdsPlugin({ attributeName, generateID }) {
16
- return new Plugin({
17
- key: uniqueNodeIdsPluginKey,
18
- appendTransaction (transactions, oldState, newState) {
19
- trace("appendTransaction");
20
- const pluginState = uniqueNodeIdsPluginKey.getState(newState);
21
- // do nothing if doc hasn't changed (but make sure it runs initially)
22
- const docChanged = transactions.some((transaction)=>transaction.docChanged);
23
- if (!docChanged && pluginState?.completedInitialRun) {
24
- trace("doc not changed, skipping", [
25
- ...transactions
26
- ]);
27
- return;
28
- }
29
- trace("appendTransaction", [
30
- ...transactions
31
- ]);
32
- const tr = newState.tr;
33
- const transform = ensureUniqueNodeIds(transactions, oldState.doc, newState.doc, {
34
- attributeName,
35
- generateID
36
- });
37
- transform.steps.forEach((step)=>{
38
- tr.step(step);
39
- });
40
- trace("tr steps", tr.steps);
41
- if (!tr.steps.length) return;
42
- tr.setMeta(uniqueNodeIdsPluginKey, UNIQUE_NODE_IDS_PLUGIN_META);
43
- return tr;
44
- },
45
- state: {
46
- init () {
47
- return {
48
- completedInitialRun: false
49
- };
50
- },
51
- apply (tr, value) {
52
- const meta = tr.getMeta(uniqueNodeIdsPluginKey);
53
- if (meta === UNIQUE_NODE_IDS_PLUGIN_META && !value.completedInitialRun) {
54
- return {
55
- completedInitialRun: true
56
- };
57
- }
58
- return value;
59
- }
60
- }
61
- });
62
- }
63
- export function ensureUniqueNodeIds(_transactions, _oldDoc, newDoc, options) {
64
- const tr = new Transform(newDoc);
65
- const nodeIds = new Set();
66
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
67
- if (TRACE_ENABLED) console.groupCollapsed("ensureUniqueNodeIds");
68
- tr.doc.descendants((node, pos)=>{
69
- if (node.isText) return false;
70
- const nodeId = getNodeId(node);
71
- // nodeId is set and is not duplicated
72
- if (nodeId != null && !nodeIds.has(nodeId)) {
73
- nodeIds.add(nodeId);
74
- return true;
75
- }
76
- // nodeId is set and it is duplicated
77
- if (nodeId != null && nodeIds.has(nodeId)) {
78
- const id = options.generateID();
79
- nodeIds.add(id);
80
- tr.setNodeMarkup(pos, node.type, {
81
- ...node.attrs,
82
- [options.attributeName]: id
83
- }, node.marks);
84
- trace("fixed duplicate id", id, "for node", node.type.name, "at pos", pos, {
85
- was: nodeId,
86
- is: id
87
- });
88
- return true;
89
- }
90
- // node id is not set
91
- if (nodeId == null) {
92
- const id = options.generateID();
93
- nodeIds.add(id);
94
- tr.setNodeMarkup(pos, node.type, {
95
- ...node.attrs,
96
- [options.attributeName]: id
97
- }, node.marks);
98
- trace("set unique id", id, "for node", node.type.name, "at pos", pos);
99
- return true;
100
- }
101
- return true;
102
- });
103
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
104
- if (TRACE_ENABLED) console.groupEnd();
105
- return tr;
106
- }
@@ -1,2 +0,0 @@
1
- import { type NodeType } from "prosemirror-model";
2
- export declare function listInputRules(bulletListNodeType: NodeType, orderedListNodeType: NodeType): import("prosemirror-inputrules").InputRule[];
@@ -1,14 +0,0 @@
1
- import { wrappingInputRule } from "./wrappingInputRule.js";
2
- import { ZWSP } from "./constants.js";
3
- export function listInputRules(bulletListNodeType, orderedListNodeType) {
4
- const bulletListInputRule = wrappingInputRule(// ^ string start, [${ZWSP}\\s]* zero or more ZWSP or whitespace, ([-+*]) one of -+* , \\s one whitespace, $ end of string
5
- // "u" flag treats \u as unicode code points instead of literal "u"
6
- new RegExp(`^[${ZWSP}\\s]*([-+*])\\s$`, "u"), bulletListNodeType);
7
- // ^ string start, [${ZWSP}\\s]* zero or more ZWSP or whitespace, ([0-9]+\\.) digit followed by dot, \\s one whitespace, $ end of string
8
- // "u" flag treats \u as unicode code points instead of literal "u"
9
- const orderedListInputRule = wrappingInputRule(new RegExp(`^[${ZWSP}\\s]*([0-9]+\\.)\\s$`, "u"), orderedListNodeType);
10
- return [
11
- bulletListInputRule,
12
- orderedListInputRule
13
- ];
14
- }
@@ -1,9 +0,0 @@
1
- import { type Step } from "prosemirror-transform";
2
- /**
3
- * Rebase a step onto a new lineage of steps
4
- *
5
- * @param step The step to rebase
6
- * @param back The old steps to undo, in the order they were originally applied
7
- * @param forth The new steps to map through
8
- */
9
- export declare function rebaseStep(step: Step, back: Step[], forth: Step[]): Step | null;
@@ -1,11 +0,0 @@
1
- /**
2
- * Rebase a step onto a new lineage of steps
3
- *
4
- * @param step The step to rebase
5
- * @param back The old steps to undo, in the order they were originally applied
6
- * @param forth The new steps to map through
7
- */ export function rebaseStep(step, back, forth) {
8
- const reset = back.slice().reverse().reduce((acc, step)=>acc?.map(step.getMap().invert()) ?? null, step);
9
- const rebased = forth.reduce((acc, step)=>acc?.map(step.getMap()) ?? null, reset);
10
- return rebased;
11
- }
@@ -1,2 +0,0 @@
1
- import { Schema } from "prosemirror-model";
2
- export declare function createSchema(deletionMarksVisibility?: "hidden" | "visible"): Schema<"blockquote" | "text" | "doc" | "paragraph" | "horizontal_rule" | "heading" | "code_block" | "image" | "hard_break" | "orderedList" | "bulletList" | "listItem" | "hardBreak", "insertion" | "deletion" | "modification" | "structure" | "code" | "em" | "link" | "strong">;
@@ -1,22 +0,0 @@
1
- import { type Node, type Schema } from "prosemirror-model";
2
- import { type EditorState, type Transaction } from "prosemirror-state";
3
- import { type SuggestionId } from "./generateId.js";
4
- interface PreserveTransactionDataOptions {
5
- selection?: "mapFromOriginalTransaction" | "currentDocument" | false;
6
- preserveScroll?: boolean;
7
- preserveStoredMarks?: boolean;
8
- preserveMeta?: boolean;
9
- }
10
- export declare function preserveTransactionData(transaction: Transaction, originalTransaction: Transaction, options?: PreserveTransactionDataOptions): void;
11
- /**
12
- * Given a standard transaction from ProseMirror, produce
13
- * a new transaction that tracks the changes from the original,
14
- * rather than applying them.
15
- *
16
- * For each type of step, we implement custom behavior to prevent
17
- * deletions from being removed from the document, instead adding
18
- * deletion marks, and ensuring that all insertions have insertion
19
- * marks.
20
- */
21
- export declare function transformToSuggestionTransaction(originalTransaction: Transaction, state: EditorState, generateId?: (schema: Schema, doc?: Node) => SuggestionId): Transaction;
22
- export {};
@@ -1,101 +0,0 @@
1
- import { AddMarkStep, AddNodeMarkStep, AttrStep, Mapping, RemoveMarkStep, RemoveNodeMarkStep, ReplaceAroundStep, ReplaceStep } from "prosemirror-transform";
2
- import { trackAddMarkStep } from "./addMarkStep.js";
3
- import { trackAddNodeMarkStep } from "./addNodeMarkStep.js";
4
- import { trackAttrStep } from "./attrStep.js";
5
- import { generateNextNumberId } from "./generateId.js";
6
- import { suggestRemoveMarkStep } from "./removeMarkStep.js";
7
- import { suggestRemoveNodeMarkStep } from "./removeNodeMarkStep.js";
8
- import { suggestReplaceAroundStep } from "./replaceAroundStep.js";
9
- import { suggestReplaceStep } from "./replaceStep.js";
10
- import { getSuggestionMarks } from "./utils.js";
11
- function getStepHandler(step) {
12
- if (step instanceof ReplaceStep) {
13
- return suggestReplaceStep;
14
- }
15
- if (step instanceof ReplaceAroundStep) {
16
- return suggestReplaceAroundStep;
17
- }
18
- if (step instanceof AddMarkStep) {
19
- return trackAddMarkStep;
20
- }
21
- if (step instanceof RemoveMarkStep) {
22
- return suggestRemoveMarkStep;
23
- }
24
- if (step instanceof AddNodeMarkStep) {
25
- return trackAddNodeMarkStep;
26
- }
27
- if (step instanceof RemoveNodeMarkStep) {
28
- return suggestRemoveNodeMarkStep;
29
- }
30
- if (step instanceof AttrStep) {
31
- return trackAttrStep;
32
- }
33
- // Default handler — simply rebase the step onto the
34
- // tracked transaction and apply it.
35
- return (trackedTransaction, _state, _doc, step, prevSteps)=>{
36
- const reset = prevSteps.slice().reverse().reduce((acc, step)=>acc?.map(step.getMap().invert()) ?? null, step);
37
- const rebased = trackedTransaction.steps.reduce((acc, step)=>acc?.map(step.getMap()) ?? null, reset);
38
- if (rebased) {
39
- trackedTransaction.step(rebased);
40
- }
41
- return false;
42
- };
43
- }
44
- export function preserveTransactionData(transaction, originalTransaction, options = {}) {
45
- const { selection = "mapFromOriginalTransaction", preserveScroll = true, preserveStoredMarks = true, preserveMeta = true } = options;
46
- if (selection && originalTransaction.selectionSet && !transaction.selectionSet) {
47
- if (selection === "currentDocument") {
48
- transaction.setSelection(originalTransaction.selection.map(transaction.doc, new Mapping()));
49
- } else {
50
- const originalBaseDoc = originalTransaction.docs[0];
51
- const base = originalBaseDoc ? originalTransaction.selection.map(originalBaseDoc, originalTransaction.mapping.invert()) : originalTransaction.selection;
52
- transaction.setSelection(base.map(transaction.doc, transaction.mapping));
53
- }
54
- }
55
- if (preserveScroll && originalTransaction.scrolledIntoView) {
56
- transaction.scrollIntoView();
57
- }
58
- if (preserveStoredMarks && originalTransaction.storedMarksSet) {
59
- transaction.setStoredMarks(originalTransaction.storedMarks);
60
- }
61
- if (preserveMeta) {
62
- // @ts-expect-error Preserve original transaction meta exactly as-is
63
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
64
- transaction.meta = originalTransaction.meta;
65
- }
66
- }
67
- /**
68
- * Given a standard transaction from ProseMirror, produce
69
- * a new transaction that tracks the changes from the original,
70
- * rather than applying them.
71
- *
72
- * For each type of step, we implement custom behavior to prevent
73
- * deletions from being removed from the document, instead adding
74
- * deletion marks, and ensuring that all insertions have insertion
75
- * marks.
76
- */ export function transformToSuggestionTransaction(originalTransaction, state, generateId) {
77
- getSuggestionMarks(state.schema);
78
- let suggestionId = generateId ? generateId(state.schema, originalTransaction.docs[0]) : generateNextNumberId(state.schema, originalTransaction.docs[0]);
79
- // Create a new transaction from scratch. The original transaction
80
- // is going to be dropped in favor of this one.
81
- const trackedTransaction = state.tr;
82
- for(let i = 0; i < originalTransaction.steps.length; i++){
83
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
84
- const step = originalTransaction.steps[i];
85
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
86
- const doc = originalTransaction.docs[i];
87
- const stepTracker = getStepHandler(step);
88
- if (stepTracker(trackedTransaction, state, doc, step, originalTransaction.steps.slice(0, i), suggestionId) && i < originalTransaction.steps.length - 1) {
89
- // If the suggestionId was used by one of the step handlers,
90
- // increment it so that it's not reused.
91
- if (generateId) {
92
- suggestionId = generateId(state.schema, trackedTransaction.doc);
93
- } else if (typeof suggestionId === "number") {
94
- suggestionId = suggestionId + 1;
95
- }
96
- }
97
- continue;
98
- }
99
- preserveTransactionData(trackedTransaction, originalTransaction);
100
- return trackedTransaction;
101
- }
@@ -1,4 +0,0 @@
1
- import { InputRule } from "prosemirror-inputrules";
2
- import { type Node } from "prosemirror-model";
3
- import { type Attrs, type NodeType } from "prosemirror-model";
4
- export declare function wrappingInputRule(regexp: RegExp, nodeType: NodeType, getAttrs?: Attrs | null | ((matches: RegExpMatchArray) => Attrs | null), joinPredicate?: (match: RegExpMatchArray, node: Node) => boolean): InputRule;
@@ -1,28 +0,0 @@
1
- import { InputRule } from "prosemirror-inputrules";
2
- import { canJoin, findWrapping } from "prosemirror-transform";
3
- import { getSuggestionMarks } from "./utils.js";
4
- import { ZWSP } from "./constants.js";
5
- /// return a boolean to indicate whether a join should happen.
6
- export function wrappingInputRule(regexp, nodeType, getAttrs = null, joinPredicate) {
7
- return new InputRule(regexp, (state, match, start, end)=>{
8
- const attrs = getAttrs instanceof Function ? getAttrs(match) : getAttrs;
9
- const tr = state.tr;
10
- // check and try to preserve zwsp
11
- const { insertion } = getSuggestionMarks(state.doc.type.schema);
12
- let $start = tr.doc.resolve(start);
13
- if (insertion.isInSet($start.nodeAfter?.marks ?? []) && match[0].startsWith(ZWSP)) {
14
- // preserve a single ZWSP at the start
15
- tr.delete(start + 1, end);
16
- } else {
17
- tr.delete(start, end);
18
- }
19
- // the rest of the rule unchanged
20
- $start = tr.doc.resolve(start);
21
- const range = $start.blockRange(), wrapping = range && findWrapping(range, nodeType, attrs);
22
- if (!wrapping) return null;
23
- tr.wrap(range, wrapping);
24
- const before = tr.doc.resolve(start - 1).nodeBefore;
25
- if (before && before.type == nodeType && canJoin(tr.doc, start - 1) && (!joinPredicate || joinPredicate(match, before))) tr.join(start - 1);
26
- return tr;
27
- });
28
- }