@stll/folio-core 0.53.0 → 0.54.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.
- package/dist/ai-edits/apply.js +390 -166
- package/dist/ai-edits/batch-claims.d.ts +21 -6
- package/dist/ai-edits/batch-claims.js +47 -16
- package/dist/ai-edits/headless.d.ts +20 -0
- package/dist/ai-edits/headless.js +140 -11
- package/dist/ai-edits/pending-suggestions.js +1 -1
- package/dist/ai-edits/read.d.ts +5 -3
- package/dist/ai-edits/read.js +97 -47
- package/dist/ai-edits/revisionStretches.d.ts +17 -0
- package/dist/ai-edits/revisionStretches.js +80 -0
- package/dist/ai-edits/snapshot.js +3 -2
- package/dist/ai-edits/table-cell-mutations.d.ts +3 -1
- package/dist/ai-edits/table-cell-mutations.js +2 -1
- package/dist/ai-edits/table-row-column-mutations.d.ts +6 -1
- package/dist/ai-edits/table-row-column-mutations.js +27 -10
- package/dist/compare/content-alignment.d.ts +5 -1
- package/dist/compare/content-alignment.js +39 -32
- package/dist/compare/inline-provenance.js +1 -1
- package/dist/controller/layoutPipeline.js +3 -2
- package/dist/docx/archiveInflation.d.ts +127 -0
- package/dist/docx/archiveInflation.js +181 -0
- package/dist/docx/metadataPrivacy.js +24 -1
- package/dist/docx/noteReferenceMark.d.ts +15 -0
- package/dist/docx/noteReferenceMark.js +48 -0
- package/dist/docx/paragraphParser.js +5 -3
- package/dist/docx/paragraphPropertySource.d.ts +1 -1
- package/dist/docx/paragraphPropertySource.js +3 -1
- package/dist/docx/parser.js +2 -2
- package/dist/docx/rezip.js +4 -2
- package/dist/docx/selectiveXmlPatch.d.ts +3 -1
- package/dist/docx/selectiveXmlPatch.js +81 -3
- package/dist/docx/server/boundedArchive.d.ts +8 -13
- package/dist/docx/server/boundedArchive.js +70 -59
- package/dist/docx/server/extractDocxText.d.ts +8 -2
- package/dist/docx/server/extractDocxText.js +2 -2
- package/dist/docx/server/validateDocxConformance.d.ts +1 -1
- package/dist/docx/server/validateDocxConformance.js +1 -0
- package/dist/docx/unzip.d.ts +19 -2
- package/dist/docx/unzip.js +135 -24
- package/dist/fonts/embeddedFonts.js +1 -1
- package/dist/i18n/messages/catalogs.gen.d.ts +34 -34
- package/dist/i18n/messages/catalogs.gen.js +34 -34
- package/dist/i18n/messages/messages.gen.d.ts +2 -2
- package/dist/internal/wholeStoryRevisionResolution.js +95 -25
- package/dist/layout-engine/measure/measureParagraph.js +2 -2
- package/dist/layout-engine/measure/paragraphMeasureShared.d.ts +12 -1
- package/dist/layout-engine/measure/paragraphMeasureShared.js +14 -1
- package/dist/markdown/escape.d.ts +2 -2
- package/dist/markdown/escape.js +4 -5
- package/dist/markdown/renderBlock.js +91 -25
- package/dist/markdown/renderRuns.d.ts +10 -1
- package/dist/markdown/renderRuns.js +320 -59
- package/dist/prosemirror/clearRunColor.d.ts +6 -0
- package/dist/prosemirror/clearRunColor.js +46 -0
- package/dist/prosemirror/commands/comments.js +56 -21
- package/dist/prosemirror/commands/formatPainter.js +1 -1
- package/dist/prosemirror/commands/hyperlink.js +2 -1
- package/dist/prosemirror/commands/propertyChangeScope.d.ts +3 -2
- package/dist/prosemirror/commands/propertyChangeScope.js +24 -3
- package/dist/prosemirror/commands/resolveAllTableChanges.js +46 -41
- package/dist/prosemirror/commands/resolveParagraphProperties.js +20 -6
- package/dist/prosemirror/commands/tableCellMergeResolution.d.ts +8 -1
- package/dist/prosemirror/commands/tableCellMergeResolution.js +23 -7
- package/dist/prosemirror/containerFinalParagraph.d.ts +11 -5
- package/dist/prosemirror/containerFinalParagraph.js +7 -6
- package/dist/prosemirror/conversion/fromProseDoc.d.ts +2 -13
- package/dist/prosemirror/conversion/fromProseDoc.js +12 -590
- package/dist/prosemirror/conversion/toProseDoc.d.ts +4 -11
- package/dist/prosemirror/conversion/toProseDoc.js +31 -150
- package/dist/prosemirror/documentSchema.d.ts +8 -0
- package/dist/prosemirror/documentSchema.js +18 -0
- package/dist/prosemirror/extensions/StarterKit.js +2 -0
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +104 -63
- package/dist/prosemirror/extensions/features/BaseKeymapExtension.js +1 -1
- package/dist/prosemirror/extensions/features/EmptyParagraphFormatExtension.js +24 -3
- package/dist/prosemirror/extensions/features/JoinedRunStyleExtension.d.ts +20 -0
- package/dist/prosemirror/extensions/features/JoinedRunStyleExtension.js +43 -0
- package/dist/prosemirror/extensions/features/ListExtension.js +10 -9
- package/dist/prosemirror/extensions/features/pastedHeadingStyles.js +1 -1
- package/dist/prosemirror/extensions/features/pastedHtmlLists.js +2 -4
- package/dist/prosemirror/extensions/marks/FootnoteRefExtension.js +14 -8
- package/dist/prosemirror/extensions/marks/HyperlinkExtension.js +8 -4
- package/dist/prosemirror/extensions/marks/StrikeExtension.js +2 -2
- package/dist/prosemirror/extensions/marks/SubscriptExtension.js +2 -2
- package/dist/prosemirror/extensions/marks/SuperscriptExtension.js +2 -2
- package/dist/prosemirror/extensions/marks/TextColorExtension.js +4 -3
- package/dist/prosemirror/extensions/marks/markUtils.d.ts +8 -6
- package/dist/prosemirror/extensions/marks/markUtils.js +17 -8
- package/dist/prosemirror/extensions/marks/noteReferenceDeletion.d.ts +3 -1
- package/dist/prosemirror/extensions/marks/noteReferenceDeletion.js +12 -1
- package/dist/prosemirror/extensions/nodes/CommentReferenceExtension.js +2 -2
- package/dist/prosemirror/extensions/nodes/HardBreakExtension.js +5 -3
- package/dist/prosemirror/extensions/nodes/TableExtension.js +104 -210
- package/dist/prosemirror/extensions/types.d.ts +7 -0
- package/dist/prosemirror/hyperlinkRemoval.d.ts +9 -0
- package/dist/prosemirror/hyperlinkRemoval.js +129 -0
- package/dist/prosemirror/index.d.ts +2 -1
- package/dist/prosemirror/index.js +2 -1
- package/dist/prosemirror/listNumbering.d.ts +3 -21
- package/dist/prosemirror/listNumbering.js +10 -25
- package/dist/prosemirror/listRendering.d.ts +27 -0
- package/dist/prosemirror/listRendering.js +27 -0
- package/dist/prosemirror/markupViewNotes.d.ts +8 -0
- package/dist/prosemirror/markupViewNotes.js +49 -0
- package/dist/prosemirror/markupViewProjection.d.ts +3 -1
- package/dist/prosemirror/markupViewProjection.js +7 -2
- package/dist/prosemirror/noteReferenceReview.d.ts +77 -0
- package/dist/prosemirror/noteReferenceReview.js +332 -0
- package/dist/prosemirror/paragraphIndentation.js +5 -2
- package/dist/prosemirror/paragraphMarkJoin.d.ts +6 -4
- package/dist/prosemirror/paragraphMarkJoin.js +21 -19
- package/dist/prosemirror/paragraphPropertyCarry.d.ts +64 -0
- package/dist/prosemirror/paragraphPropertyCarry.js +158 -0
- package/dist/prosemirror/plugins/documentStyleState.d.ts +26 -0
- package/dist/prosemirror/plugins/documentStyleState.js +32 -0
- package/dist/prosemirror/plugins/documentStyles.d.ts +2 -21
- package/dist/prosemirror/plugins/documentStyles.js +66 -29
- package/dist/prosemirror/plugins/index.d.ts +2 -1
- package/dist/prosemirror/plugins/index.js +2 -1
- package/dist/prosemirror/plugins/paragraphStyleResolution.d.ts +15 -0
- package/dist/prosemirror/plugins/paragraphStyleResolution.js +230 -0
- package/dist/prosemirror/plugins/suggestionMode.d.ts +12 -2
- package/dist/prosemirror/plugins/suggestionMode.js +391 -28
- package/dist/prosemirror/rebaseParagraphRunFormatting.d.ts +22 -2
- package/dist/prosemirror/rebaseParagraphRunFormatting.js +39 -13
- package/dist/prosemirror/rebaseParagraphRuns.d.ts +36 -0
- package/dist/prosemirror/rebaseParagraphRuns.js +99 -0
- package/dist/prosemirror/runFormattingFromMarks.d.ts +18 -0
- package/dist/prosemirror/runFormattingFromMarks.js +567 -0
- package/dist/prosemirror/runFormattingReconciliation.js +10 -9
- package/dist/prosemirror/schema/nodes.d.ts +2 -0
- package/dist/prosemirror/styles/paragraphStyleCascade.d.ts +59 -0
- package/dist/prosemirror/styles/paragraphStyleCascade.js +145 -0
- package/dist/prosemirror/styles/resolvedStyleAttrs.d.ts +21 -2
- package/dist/prosemirror/styles/resolvedStyleAttrs.js +38 -1
- package/dist/prosemirror/styles/tableStyleRegions.d.ts +31 -0
- package/dist/prosemirror/styles/tableStyleRegions.js +55 -0
- package/dist/prosemirror/tableCellPaste.d.ts +74 -0
- package/dist/prosemirror/tableCellPaste.js +525 -0
- package/dist/prosemirror/tableGridMutation.d.ts +53 -14
- package/dist/prosemirror/tableGridMutation.js +166 -18
- package/dist/prosemirror/tableRunIn.d.ts +51 -0
- package/dist/prosemirror/tableRunIn.js +165 -0
- package/dist/prosemirror/textInput.js +11 -2
- package/dist/prosemirror/trackedRevisionPath.d.ts +17 -0
- package/dist/prosemirror/trackedRevisionPath.js +32 -0
- package/dist/server.d.ts +2 -2
- package/package.json +5 -5
|
@@ -2,6 +2,26 @@ import { createExtension } from "../create.js";
|
|
|
2
2
|
import { textFormattingToMarks } from "../marks/markUtils.js";
|
|
3
3
|
import { Plugin, PluginKey } from "prosemirror-state";
|
|
4
4
|
//#region src/prosemirror/extensions/features/EmptyParagraphFormatExtension.ts
|
|
5
|
+
/**
|
|
6
|
+
* EmptyParagraphFormat — re-establishes stored marks for an empty styled
|
|
7
|
+
* paragraph so typed text inherits the style's run formatting (bold, color,
|
|
8
|
+
* size, font).
|
|
9
|
+
*
|
|
10
|
+
* Why this exists:
|
|
11
|
+
* An empty paragraph carries its run defaults in the `defaultTextFormatting`
|
|
12
|
+
* attr (set at load by `toProseDoc`, and when a style is applied via
|
|
13
|
+
* `applyStyle`). The visible painter only derives font/size from that attr,
|
|
14
|
+
* so an empty heading renders a correctly sized caret — but typed text only
|
|
15
|
+
* becomes bold/colored if it carries real marks. Those marks live in
|
|
16
|
+
* `storedMarks`, which ProseMirror clears on the next selection change
|
|
17
|
+
* (e.g. when the style picker dropdown returns focus to the editor).
|
|
18
|
+
*
|
|
19
|
+
* This plugin watches for the caret sitting in an empty paragraph with no
|
|
20
|
+
* stored marks and re-derives them from `defaultTextFormatting`, but only
|
|
21
|
+
* when the defaults carry formatting the painter can't reproduce on its own
|
|
22
|
+
* (bold/italic/color/…). Plain body paragraphs (font + size only) are left
|
|
23
|
+
* untouched so ordinary typed text stays mark-free and serializes cleanly.
|
|
24
|
+
*/
|
|
5
25
|
const emptyParagraphFormatKey = new PluginKey("emptyParagraphFormat");
|
|
6
26
|
/**
|
|
7
27
|
* Run-formatting properties the painter does NOT reproduce from
|
|
@@ -15,7 +35,7 @@ const FONT_ONLY_DEFAULTS = /* @__PURE__ */ new Set(["fontFamily", "fontSize"]);
|
|
|
15
35
|
function hasNonFontDefaults(dtf) {
|
|
16
36
|
return Object.entries(dtf).some(([property, value]) => value !== void 0 && !FONT_ONLY_DEFAULTS.has(property));
|
|
17
37
|
}
|
|
18
|
-
function createEmptyParagraphFormatPlugin(
|
|
38
|
+
function createEmptyParagraphFormatPlugin() {
|
|
19
39
|
return new Plugin({
|
|
20
40
|
key: emptyParagraphFormatKey,
|
|
21
41
|
appendTransaction(transactions, _oldState, newState) {
|
|
@@ -27,6 +47,7 @@ function createEmptyParagraphFormatPlugin(schema) {
|
|
|
27
47
|
if (para.type.name !== "paragraph" || para.content.size !== 0) return null;
|
|
28
48
|
const dtf = para.attrs["defaultTextFormatting"];
|
|
29
49
|
if (!dtf || !hasNonFontDefaults(dtf)) return null;
|
|
50
|
+
const { schema } = newState;
|
|
30
51
|
const marks = textFormattingToMarks(dtf, schema);
|
|
31
52
|
if (dtf.styleId) marks.push(schema.mark("characterStyle", { styleId: dtf.styleId }));
|
|
32
53
|
if (marks.length === 0) return null;
|
|
@@ -38,8 +59,8 @@ function createEmptyParagraphFormatPlugin(schema) {
|
|
|
38
59
|
}
|
|
39
60
|
const EmptyParagraphFormatExtension = createExtension({
|
|
40
61
|
name: "emptyParagraphFormat",
|
|
41
|
-
onSchemaReady(
|
|
42
|
-
return { plugins: [createEmptyParagraphFormatPlugin(
|
|
62
|
+
onSchemaReady() {
|
|
63
|
+
return { plugins: [createEmptyParagraphFormatPlugin()] };
|
|
43
64
|
}
|
|
44
65
|
});
|
|
45
66
|
//#endregion
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Extension } from "../types.js";
|
|
2
|
+
//#region src/prosemirror/extensions/features/JoinedRunStyleExtension.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Runs that a join moves into another paragraph take that paragraph's style.
|
|
5
|
+
*
|
|
6
|
+
* Deleting across a paragraph break (Backspace or Delete at the break, a
|
|
7
|
+
* deletion or typing over a selection that spans paragraphs) runs the later
|
|
8
|
+
* paragraph's remaining text on into the earlier one. A run's direct
|
|
9
|
+
* formatting is its own and stays; what the later paragraph's style lent it
|
|
10
|
+
* does not travel, and it reads in the style of the paragraph it now belongs
|
|
11
|
+
* to. The document styles plugin re-reads those runs after an ordinary edit.
|
|
12
|
+
*
|
|
13
|
+
* A transaction that re-reads the runs it moves itself (resolving a tracked
|
|
14
|
+
* change, an operation that merges paragraphs) says so with
|
|
15
|
+
* {@link JOINED_RUNS_RESTYLED_META}, and is left as it is.
|
|
16
|
+
*/
|
|
17
|
+
declare const JOINED_RUNS_RESTYLED_META = "joinedRunsRestyled";
|
|
18
|
+
declare const JoinedRunStyleExtension: (options?: Partial<{}> | undefined) => Extension;
|
|
19
|
+
//#endregion
|
|
20
|
+
export { JOINED_RUNS_RESTYLED_META, JoinedRunStyleExtension };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { createExtension } from "../create.js";
|
|
2
|
+
import { Plugin, PluginKey } from "prosemirror-state";
|
|
3
|
+
//#region src/prosemirror/extensions/features/JoinedRunStyleExtension.ts
|
|
4
|
+
/**
|
|
5
|
+
* Runs that a join moves into another paragraph take that paragraph's style.
|
|
6
|
+
*
|
|
7
|
+
* Deleting across a paragraph break (Backspace or Delete at the break, a
|
|
8
|
+
* deletion or typing over a selection that spans paragraphs) runs the later
|
|
9
|
+
* paragraph's remaining text on into the earlier one. A run's direct
|
|
10
|
+
* formatting is its own and stays; what the later paragraph's style lent it
|
|
11
|
+
* does not travel, and it reads in the style of the paragraph it now belongs
|
|
12
|
+
* to. The document styles plugin re-reads those runs after an ordinary edit.
|
|
13
|
+
*
|
|
14
|
+
* A transaction that re-reads the runs it moves itself (resolving a tracked
|
|
15
|
+
* change, an operation that merges paragraphs) says so with
|
|
16
|
+
* {@link JOINED_RUNS_RESTYLED_META}, and is left as it is.
|
|
17
|
+
*/
|
|
18
|
+
const JOINED_RUNS_RESTYLED_META = "joinedRunsRestyled";
|
|
19
|
+
const pastedTableEndKey = new PluginKey("pastedTableEnd");
|
|
20
|
+
/**
|
|
21
|
+
* A table pasted over a story's last paragraph leaves that paragraph, emptied,
|
|
22
|
+
* after it: a story ends with a paragraph, and the paste replaced the words,
|
|
23
|
+
* not the break that ends the story. ProseMirror's paste replaces the whole
|
|
24
|
+
* paragraph, so the empty one is put back.
|
|
25
|
+
*/
|
|
26
|
+
const createPastedTableEndPlugin = () => new Plugin({
|
|
27
|
+
key: pastedTableEndKey,
|
|
28
|
+
appendTransaction(transactions, oldState, newState) {
|
|
29
|
+
if (!transactions.some((transaction) => transaction.docChanged && transaction.getMeta("uiEvent") === "paste")) return null;
|
|
30
|
+
if (newState.doc.lastChild?.type.spec["tableRole"] !== "table" || oldState.doc.lastChild?.type.name !== "paragraph") return null;
|
|
31
|
+
const paragraph = newState.schema.nodes["paragraph"]?.createAndFill();
|
|
32
|
+
return paragraph ? newState.tr.insert(newState.doc.content.size, paragraph) : null;
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
const JoinedRunStyleExtension = createExtension({
|
|
36
|
+
name: "joinedRunStyle",
|
|
37
|
+
defaultOptions: {},
|
|
38
|
+
onSchemaReady() {
|
|
39
|
+
return { plugins: [createPastedTableEndPlugin()] };
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
//#endregion
|
|
43
|
+
export { JOINED_RUNS_RESTYLED_META, JoinedRunStyleExtension };
|
|
@@ -7,7 +7,7 @@ import { resolveListState } from "../../listState.js";
|
|
|
7
7
|
import { removedNumberingAttr } from "../../numberingAttr.js";
|
|
8
8
|
import { getDocumentNumbering } from "../../plugins/documentNumbering.js";
|
|
9
9
|
import { SUGGESTION_META, makeRevisionInfo, suggestRangeDeletion } from "../../plugins/suggestionMode.js";
|
|
10
|
-
import { listLevelAttrPatch } from "../../styles/resolvedStyleAttrs.js";
|
|
10
|
+
import { listLevelAttrPatch, listLevelIndentRemovalPatch } from "../../styles/resolvedStyleAttrs.js";
|
|
11
11
|
import { createExtension } from "../create.js";
|
|
12
12
|
import { goToNextCell, goToPrevCell } from "../nodes/TableExtension.js";
|
|
13
13
|
import { Priority } from "../types.js";
|
|
@@ -27,9 +27,10 @@ function chainCommands(...commands) {
|
|
|
27
27
|
return false;
|
|
28
28
|
};
|
|
29
29
|
}
|
|
30
|
-
function clearListAttrs(attrs) {
|
|
30
|
+
function clearListAttrs(attrs, numbering) {
|
|
31
31
|
return {
|
|
32
32
|
...attrs,
|
|
33
|
+
...listLevelIndentRemovalPatch(attrs, numbering),
|
|
33
34
|
numPr: removedNumberingAttr(attrs.numPrFromStyle),
|
|
34
35
|
...CLEARED_LIST_RENDERING_ATTRS
|
|
35
36
|
};
|
|
@@ -69,7 +70,7 @@ const numberParagraphs = ({ state, tr, from, to, requests }) => {
|
|
|
69
70
|
updates: paragraphsBetween(tr.doc, from, to).map(({ pos, node }) => ({
|
|
70
71
|
pos,
|
|
71
72
|
node,
|
|
72
|
-
next: listItemAttrs(node
|
|
73
|
+
next: listItemAttrs(expectParagraphAttrs(node), {
|
|
73
74
|
numId: target.numId,
|
|
74
75
|
ilvl: paragraphNumberingLevel(expectParagraphAttrs(node).numPr) ?? target.ilvl
|
|
75
76
|
}, target.numbering)
|
|
@@ -92,7 +93,7 @@ function toggleList(intent) {
|
|
|
92
93
|
updates: paragraphsBetween(state.doc, $from.pos, $to.pos).filter(({ node }) => isItemOfKind(node)).map(({ pos, node }) => ({
|
|
93
94
|
pos,
|
|
94
95
|
node,
|
|
95
|
-
next: clearListAttrs(expectParagraphAttrs(node))
|
|
96
|
+
next: clearListAttrs(expectParagraphAttrs(node), getDocumentNumbering(state))
|
|
96
97
|
}))
|
|
97
98
|
});
|
|
98
99
|
else numberParagraphs({
|
|
@@ -141,7 +142,7 @@ const decreaseListLevel = (state, dispatch) => {
|
|
|
141
142
|
if (!dispatch) return true;
|
|
142
143
|
const paragraphPos = $from.before($from.depth);
|
|
143
144
|
if (currentLevel <= 0) dispatch(state.tr.setNodeMarkup(paragraphPos, void 0, {
|
|
144
|
-
...clearListAttrs(attrs),
|
|
145
|
+
...clearListAttrs(attrs, getDocumentNumbering(state)),
|
|
145
146
|
indentLeft: null,
|
|
146
147
|
indentFirstLine: null,
|
|
147
148
|
hangingIndent: null
|
|
@@ -157,7 +158,7 @@ const removeList = (state, dispatch) => {
|
|
|
157
158
|
state.doc.nodesBetween($from.pos, $to.pos, (node, pos) => {
|
|
158
159
|
if (node.type.name === "paragraph" && hasActiveListNumbering(expectParagraphAttrs(node)) && !seen.has(pos)) {
|
|
159
160
|
seen.add(pos);
|
|
160
|
-
tr = tr.setNodeMarkup(pos, void 0, clearListAttrs(expectParagraphAttrs(node)));
|
|
161
|
+
tr = tr.setNodeMarkup(pos, void 0, clearListAttrs(expectParagraphAttrs(node), getDocumentNumbering(state)));
|
|
161
162
|
}
|
|
162
163
|
});
|
|
163
164
|
dispatch(tr.scrollIntoView());
|
|
@@ -197,7 +198,7 @@ function exitListOnEmptyEnter() {
|
|
|
197
198
|
updates: [{
|
|
198
199
|
pos: $from.before(),
|
|
199
200
|
node: paragraph,
|
|
200
|
-
next: clearListAttrs(attrs)
|
|
201
|
+
next: clearListAttrs(attrs, getDocumentNumbering(state))
|
|
201
202
|
}]
|
|
202
203
|
});
|
|
203
204
|
dispatch(tr);
|
|
@@ -250,7 +251,7 @@ function backspaceExitList() {
|
|
|
250
251
|
updates: [{
|
|
251
252
|
pos: $from.before(),
|
|
252
253
|
node: paragraph,
|
|
253
|
-
next: clearListAttrs(attrs)
|
|
254
|
+
next: clearListAttrs(attrs, getDocumentNumbering(state))
|
|
254
255
|
}]
|
|
255
256
|
});
|
|
256
257
|
dispatch(tr);
|
|
@@ -300,7 +301,7 @@ function decreaseListIndent() {
|
|
|
300
301
|
for (const { pos, attrs } of positions) {
|
|
301
302
|
const currentLevel = attrs.numPr.ilvl ?? 0;
|
|
302
303
|
if (currentLevel <= 0) tr = tr.setNodeMarkup(pos, void 0, {
|
|
303
|
-
...clearListAttrs(attrs),
|
|
304
|
+
...clearListAttrs(attrs, getDocumentNumbering(state)),
|
|
304
305
|
indentLeft: null,
|
|
305
306
|
indentFirstLine: null,
|
|
306
307
|
hangingIndent: null
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { readOutlineLevelAttr } from "../../outlineLevelAttr.js";
|
|
2
|
-
import { getDocumentBuiltInStyles, getDocumentStyleResolver } from "../../plugins/
|
|
2
|
+
import { getDocumentBuiltInStyles, getDocumentStyleResolver } from "../../plugins/documentStyleState.js";
|
|
3
3
|
import { headingLevelOf } from "@stll/docx-core/model";
|
|
4
4
|
import { Fragment, Slice } from "prosemirror-model";
|
|
5
5
|
//#region src/prosemirror/extensions/features/pastedHeadingStyles.ts
|
|
@@ -103,10 +103,8 @@ const numberPastedHtmlLists = (slice, view) => {
|
|
|
103
103
|
groups.set(hint.group, group);
|
|
104
104
|
}
|
|
105
105
|
if (!numbering) panic("Pasted list group has no numbering definition");
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
_pastedHtmlList: void 0
|
|
109
|
-
}, {
|
|
106
|
+
const { _pastedHtmlList: _consumed, ...unhinted } = attrs;
|
|
107
|
+
result = node.type.create(listItemAttrs(unhinted, {
|
|
110
108
|
numId: group.numId,
|
|
111
109
|
ilvl: hint.level
|
|
112
110
|
}, numbering), node.content, node.marks);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { expectFootnoteRefMarkAttrs } from "../../attrs/index.js";
|
|
2
|
-
import { suggestionModeKey } from "../../plugins/suggestionMode.js";
|
|
2
|
+
import { suggestRangeDeletion, suggestionModeKey } from "../../plugins/suggestionMode.js";
|
|
3
3
|
import { createMarkExtension } from "../create.js";
|
|
4
|
-
import { expandNoteReferenceDeletionRange } from "./noteReferenceDeletion.js";
|
|
4
|
+
import { expandNoteReferenceDeletionRange, noteReferenceRanges } from "./noteReferenceDeletion.js";
|
|
5
5
|
import { panic } from "better-result";
|
|
6
6
|
//#region src/prosemirror/extensions/marks/FootnoteRefExtension.ts
|
|
7
7
|
/**
|
|
@@ -59,8 +59,7 @@ const FootnoteRefExtension = createMarkExtension({
|
|
|
59
59
|
];
|
|
60
60
|
}
|
|
61
61
|
},
|
|
62
|
-
onSchemaReady(
|
|
63
|
-
const { schema } = ctx;
|
|
62
|
+
onSchemaReady() {
|
|
64
63
|
const deleteWholeNoteReference = (direction) => (state, dispatch) => {
|
|
65
64
|
if (suggestionModeKey.getState(state)?.active) return false;
|
|
66
65
|
const { from, to, empty } = state.selection;
|
|
@@ -72,6 +71,7 @@ const FootnoteRefExtension = createMarkExtension({
|
|
|
72
71
|
function makeInsertNote(noteType) {
|
|
73
72
|
return (id) => (state, dispatch) => {
|
|
74
73
|
if (!dispatch) return true;
|
|
74
|
+
const { schema } = state;
|
|
75
75
|
const footnoteRefType = schema.marks["footnoteRef"];
|
|
76
76
|
if (!footnoteRefType) panic("Missing mark type: footnoteRef");
|
|
77
77
|
const mark = footnoteRefType.create({
|
|
@@ -84,12 +84,18 @@ const FootnoteRefExtension = createMarkExtension({
|
|
|
84
84
|
return true;
|
|
85
85
|
};
|
|
86
86
|
}
|
|
87
|
+
/**
|
|
88
|
+
* Delete the note references the selection touches (the one beside a
|
|
89
|
+
* caret), each whole: tracked as a deletion of the reference run when
|
|
90
|
+
* suggesting, removed outright otherwise.
|
|
91
|
+
*/
|
|
87
92
|
const deleteNoteRef = (state, dispatch) => {
|
|
88
|
-
const {
|
|
93
|
+
const { from, to, empty } = state.selection;
|
|
94
|
+
const references = noteReferenceRanges(state.doc, empty ? Math.max(0, from - 1) : from, empty ? Math.min(state.doc.content.size, to + 1) : to);
|
|
95
|
+
if (references.length === 0) return false;
|
|
89
96
|
if (!dispatch) return true;
|
|
90
|
-
|
|
91
|
-
const
|
|
92
|
-
tr = tr.removeMark($from.pos, $to.pos, markType);
|
|
97
|
+
const tr = state.tr;
|
|
98
|
+
for (const reference of references.toReversed()) if (!suggestRangeDeletion(state, tr, reference.from, reference.to)) tr.delete(reference.from, reference.to);
|
|
93
99
|
dispatch(tr.scrollIntoView());
|
|
94
100
|
return true;
|
|
95
101
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { anchorTargetAttrs, normalizeUserUrl, sanitizeExternalUrl } from "../../../utils/urlSecurity.js";
|
|
2
2
|
import { expectHyperlinkMarkAttrs } from "../../attrs/index.js";
|
|
3
|
+
import { removeHyperlinkInRange } from "../../hyperlinkRemoval.js";
|
|
3
4
|
import { createMarkExtension } from "../create.js";
|
|
4
5
|
import { isMarkActive } from "./markUtils.js";
|
|
5
6
|
import { panic } from "better-result";
|
|
@@ -118,9 +119,10 @@ const HyperlinkExtension = createMarkExtension({
|
|
|
118
119
|
}
|
|
119
120
|
},
|
|
120
121
|
onSchemaReady(ctx) {
|
|
121
|
-
|
|
122
|
-
|
|
122
|
+
if (!ctx.schema.marks["hyperlink"]) panic("Missing mark type: hyperlink");
|
|
123
|
+
const documentHyperlinkType = (state) => state.schema.marks["hyperlink"] ?? panic("Missing mark type: hyperlink");
|
|
123
124
|
const setHyperlink = (href, tooltip) => (state, dispatch) => {
|
|
125
|
+
const hlType = documentHyperlinkType(state);
|
|
124
126
|
const { from, to, empty } = state.selection;
|
|
125
127
|
if (empty) return false;
|
|
126
128
|
if (dispatch) {
|
|
@@ -136,6 +138,7 @@ const HyperlinkExtension = createMarkExtension({
|
|
|
136
138
|
return true;
|
|
137
139
|
};
|
|
138
140
|
const removeHyperlink = (state, dispatch) => {
|
|
141
|
+
const hlType = documentHyperlinkType(state);
|
|
139
142
|
const { from, to, empty } = state.selection;
|
|
140
143
|
if (empty) {
|
|
141
144
|
const $pos = state.selection.$from;
|
|
@@ -154,13 +157,14 @@ const HyperlinkExtension = createMarkExtension({
|
|
|
154
157
|
}
|
|
155
158
|
}
|
|
156
159
|
});
|
|
157
|
-
if (dispatch) dispatch(state.tr
|
|
160
|
+
if (dispatch) dispatch(removeHyperlinkInRange(state, state.tr, start, end).scrollIntoView());
|
|
158
161
|
return true;
|
|
159
162
|
}
|
|
160
|
-
if (dispatch) dispatch(state.tr
|
|
163
|
+
if (dispatch) dispatch(removeHyperlinkInRange(state, state.tr, from, to).scrollIntoView());
|
|
161
164
|
return true;
|
|
162
165
|
};
|
|
163
166
|
const insertHyperlink = (text, href, tooltip) => (state, dispatch) => {
|
|
167
|
+
const hlType = documentHyperlinkType(state);
|
|
164
168
|
if (dispatch) {
|
|
165
169
|
const mark = hlType.create({
|
|
166
170
|
href: normalizeHyperlinkInput(href),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createMarkExtension } from "../create.js";
|
|
2
|
+
import { toggleDocumentMark } from "./markUtils.js";
|
|
2
3
|
import { panic } from "better-result";
|
|
3
|
-
import { toggleMark } from "prosemirror-commands";
|
|
4
4
|
//#region src/prosemirror/extensions/marks/StrikeExtension.ts
|
|
5
5
|
/**
|
|
6
6
|
* Strikethrough Mark Extension
|
|
@@ -26,7 +26,7 @@ const StrikeExtension = createMarkExtension({
|
|
|
26
26
|
onSchemaReady(ctx) {
|
|
27
27
|
const strikeType = ctx.schema.marks["strike"];
|
|
28
28
|
if (!strikeType) panic("Missing mark type: strike");
|
|
29
|
-
return { commands: { toggleStrike: () =>
|
|
29
|
+
return { commands: { toggleStrike: () => toggleDocumentMark(strikeType) } };
|
|
30
30
|
}
|
|
31
31
|
});
|
|
32
32
|
//#endregion
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createMarkExtension } from "../create.js";
|
|
2
|
+
import { toggleDocumentMark } from "./markUtils.js";
|
|
2
3
|
import { panic } from "better-result";
|
|
3
|
-
import { toggleMark } from "prosemirror-commands";
|
|
4
4
|
//#region src/prosemirror/extensions/marks/SubscriptExtension.ts
|
|
5
5
|
/**
|
|
6
6
|
* Subscript Mark Extension
|
|
@@ -18,7 +18,7 @@ const SubscriptExtension = createMarkExtension({
|
|
|
18
18
|
onSchemaReady(ctx) {
|
|
19
19
|
const subscriptType = ctx.schema.marks["subscript"];
|
|
20
20
|
if (!subscriptType) panic("Missing mark type: subscript");
|
|
21
|
-
return { commands: { toggleSubscript: () =>
|
|
21
|
+
return { commands: { toggleSubscript: () => toggleDocumentMark(subscriptType) } };
|
|
22
22
|
}
|
|
23
23
|
});
|
|
24
24
|
//#endregion
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createMarkExtension } from "../create.js";
|
|
2
|
+
import { toggleDocumentMark } from "./markUtils.js";
|
|
2
3
|
import { panic } from "better-result";
|
|
3
|
-
import { toggleMark } from "prosemirror-commands";
|
|
4
4
|
//#region src/prosemirror/extensions/marks/SuperscriptExtension.ts
|
|
5
5
|
/**
|
|
6
6
|
* Superscript Mark Extension
|
|
@@ -18,7 +18,7 @@ const SuperscriptExtension = createMarkExtension({
|
|
|
18
18
|
onSchemaReady(ctx) {
|
|
19
19
|
const superscriptType = ctx.schema.marks["superscript"];
|
|
20
20
|
if (!superscriptType) panic("Missing mark type: superscript");
|
|
21
|
-
return { commands: { toggleSuperscript: () =>
|
|
21
|
+
return { commands: { toggleSuperscript: () => toggleDocumentMark(superscriptType) } };
|
|
22
22
|
}
|
|
23
23
|
});
|
|
24
24
|
//#endregion
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { textToStyle } from "../../../utils/formatToStyle.js";
|
|
2
2
|
import { expectTextColorMarkAttrs } from "../../attrs/index.js";
|
|
3
|
+
import { clearRunColor } from "../../clearRunColor.js";
|
|
3
4
|
import { createMarkExtension } from "../create.js";
|
|
4
|
-
import {
|
|
5
|
+
import { setMark } from "./markUtils.js";
|
|
5
6
|
import { panic } from "better-result";
|
|
6
7
|
//#region src/prosemirror/extensions/marks/TextColorExtension.ts
|
|
7
8
|
/**
|
|
@@ -39,10 +40,10 @@ const TextColorExtension = createMarkExtension({
|
|
|
39
40
|
if (!textColorType) panic("Missing mark type: textColor");
|
|
40
41
|
return { commands: {
|
|
41
42
|
setTextColor: (attrs) => {
|
|
42
|
-
if (!attrs.rgb && !attrs.themeColor) return
|
|
43
|
+
if (!attrs.rgb && !attrs.themeColor) return clearRunColor();
|
|
43
44
|
return setMark(textColorType, attrs);
|
|
44
45
|
},
|
|
45
|
-
clearTextColor: () =>
|
|
46
|
+
clearTextColor: () => clearRunColor()
|
|
46
47
|
} };
|
|
47
48
|
}
|
|
48
49
|
});
|
|
@@ -4,24 +4,26 @@ import { Command, EditorState } from "prosemirror-state";
|
|
|
4
4
|
//#region src/prosemirror/extensions/marks/markUtils.d.ts
|
|
5
5
|
type MarkAttrs = Record<string, unknown>;
|
|
6
6
|
declare function marksToTextFormatting(marks: readonly Mark[]): document_d_exports.TextFormatting;
|
|
7
|
-
declare function setMark(
|
|
7
|
+
declare function setMark(type: MarkType, attrs: MarkAttrs): Command;
|
|
8
8
|
type PairedToggleProperty = "bold" | "italic";
|
|
9
|
+
/** `toggleMark` for the document's own counterpart of `type`. */
|
|
10
|
+
declare const toggleDocumentMark: (type: MarkType) => Command;
|
|
9
11
|
/** UI toggle whose direct-formatting contract explicitly targets both script families. */
|
|
10
|
-
declare const toggleMarkForAllScripts: (
|
|
12
|
+
declare const toggleMarkForAllScripts: (type: MarkType, property: PairedToggleProperty) => Command;
|
|
11
13
|
/** UI size command whose direct-formatting contract explicitly targets both script families. */
|
|
12
14
|
declare const setFontSizeForAllScripts: (markType: MarkType, size: number) => Command;
|
|
13
15
|
/** Clears both ordinary and complex-script direct size through the UI command boundary. */
|
|
14
16
|
declare const clearFontSizeForAllScripts: (markType: MarkType) => Command;
|
|
15
17
|
declare function toggleUnderlineMark(markType: MarkType): Command;
|
|
16
|
-
declare function removeMark(
|
|
18
|
+
declare function removeMark(type: MarkType): Command;
|
|
17
19
|
/**
|
|
18
20
|
* Check if a mark is active in the current selection
|
|
19
21
|
*/
|
|
20
|
-
declare function isMarkActive(state: EditorState,
|
|
22
|
+
declare function isMarkActive(state: EditorState, type: MarkType, attrs?: Record<string, unknown>): boolean;
|
|
21
23
|
/**
|
|
22
24
|
* Get the current value of a mark attribute
|
|
23
25
|
*/
|
|
24
|
-
declare function getMarkAttr(state: EditorState,
|
|
26
|
+
declare function getMarkAttr(state: EditorState, type: MarkType, attr: string): unknown;
|
|
25
27
|
type AuthoredRunFormattingCarrier = "preserve" | "reconstruct";
|
|
26
28
|
/** Builds a mark by type name; a conversion passes one that shares equal marks. */
|
|
27
29
|
type MarkFactory = (type: string, attrs?: Attrs | null) => Mark;
|
|
@@ -56,4 +58,4 @@ declare function createSetMarkCommand(markType: MarkType, attrs?: Record<string,
|
|
|
56
58
|
*/
|
|
57
59
|
declare function createRemoveMarkCommand(markType: MarkType): Command;
|
|
58
60
|
//#endregion
|
|
59
|
-
export { AuthoredRunFormattingCarrier, MarkFactory, clearFontSizeForAllScripts, clearFormatting, createRemoveMarkCommand, createSetMarkCommand, getMarkAttr, isMarkActive, marksToTextFormatting, removeMark, setFontSizeForAllScripts, setMark, textFormattingToMarks, toggleMarkForAllScripts, toggleUnderlineMark };
|
|
61
|
+
export { AuthoredRunFormattingCarrier, MarkFactory, clearFontSizeForAllScripts, clearFormatting, createRemoveMarkCommand, createSetMarkCommand, getMarkAttr, isMarkActive, marksToTextFormatting, removeMark, setFontSizeForAllScripts, setMark, textFormattingToMarks, toggleDocumentMark, toggleMarkForAllScripts, toggleUnderlineMark };
|
|
@@ -3,6 +3,7 @@ import { mergeFontFamily } from "../../../utils/fontFamilyMerge.js";
|
|
|
3
3
|
import { normalizeHorizontalScalePercent } from "../../../utils/horizontalScale.js";
|
|
4
4
|
import { expectCharacterSpacingMarkAttrs, expectCharacterStyleMarkAttrs, expectEmphasisMarkAttrs, expectFontFamilyMarkAttrs, expectRunFormattingOverrideMarkAttrs, expectRunShadingMarkAttrs, expectStrikeMarkAttrs, expectTextEffectMarkAttrs } from "../../attrs/index.js";
|
|
5
5
|
import { runShadingAttrsToShading, shadingToRunShadingAttrs } from "../../conversion/runShadingMark.js";
|
|
6
|
+
import { documentMarkType } from "../../documentSchema.js";
|
|
6
7
|
import { selectRunFormattingCarrierRepresentations } from "../../runFormattingInlineCarriers.js";
|
|
7
8
|
import { RUN_FORMATTING_MARK_NAMES } from "../../runFormattingMarkNames.js";
|
|
8
9
|
import { hasRunFormattingOverrideAttrs } from "../../runFormattingProvenance.js";
|
|
@@ -178,8 +179,9 @@ function createMarkWithMergedAttrs(markType, currentMark, nextAttrs) {
|
|
|
178
179
|
if (!markRequiresAttrMerge(markType)) return markType.create(nextAttrs);
|
|
179
180
|
return markType.create(mergeMarkAttrs(markType, currentMark, nextAttrs));
|
|
180
181
|
}
|
|
181
|
-
function setMark(
|
|
182
|
+
function setMark(type, attrs) {
|
|
182
183
|
return (state, dispatch) => {
|
|
184
|
+
const markType = documentMarkType(state, type);
|
|
183
185
|
const { from, to, empty } = state.selection;
|
|
184
186
|
if (empty) {
|
|
185
187
|
if (dispatch) {
|
|
@@ -201,7 +203,8 @@ function setMark(markType, attrs) {
|
|
|
201
203
|
if (!node.isText) return;
|
|
202
204
|
const start = Math.max(from, pos);
|
|
203
205
|
const end = Math.min(to, pos + node.nodeSize);
|
|
204
|
-
const
|
|
206
|
+
const currentMark = markType.isInSet(node.marks);
|
|
207
|
+
const mark = createMarkWithMergedAttrs(markType, currentMark, attrs);
|
|
205
208
|
tr = tr.addMark(start, end, mark);
|
|
206
209
|
});
|
|
207
210
|
dispatch(tr.scrollIntoView());
|
|
@@ -283,8 +286,11 @@ const updateRunFormattingOverride = (state, tr, update) => {
|
|
|
283
286
|
const withRunFormattingOverride = (command, update) => (state, dispatch) => command(state, dispatch ? (tr) => {
|
|
284
287
|
dispatch(updateRunFormattingOverride(state, tr, update));
|
|
285
288
|
} : void 0);
|
|
289
|
+
/** `toggleMark` for the document's own counterpart of `type`. */
|
|
290
|
+
const toggleDocumentMark = (type) => (state, dispatch, view) => toggleMark(documentMarkType(state, type))(state, dispatch, view);
|
|
286
291
|
/** UI toggle whose direct-formatting contract explicitly targets both script families. */
|
|
287
|
-
const toggleMarkForAllScripts = (
|
|
292
|
+
const toggleMarkForAllScripts = (type, property) => (state, dispatch) => {
|
|
293
|
+
const markType = documentMarkType(state, type);
|
|
288
294
|
const enabled = !isMarkActive(state, markType);
|
|
289
295
|
return withRunFormattingOverride(toggleMark(markType), (attrs) => updatePairedToggleAttrs(attrs, property, enabled))(state, dispatch);
|
|
290
296
|
};
|
|
@@ -311,10 +317,11 @@ function selectionHasVisibleUnderline(state, markType) {
|
|
|
311
317
|
return hasVisibleUnderline;
|
|
312
318
|
}
|
|
313
319
|
function toggleUnderlineMark(markType) {
|
|
314
|
-
return (state, dispatch) => setMark(markType, { style: selectionHasVisibleUnderline(state, markType) ? "none" : "single" })(state, dispatch);
|
|
320
|
+
return (state, dispatch) => setMark(markType, { style: selectionHasVisibleUnderline(state, documentMarkType(state, markType)) ? "none" : "single" })(state, dispatch);
|
|
315
321
|
}
|
|
316
|
-
function removeMark(
|
|
322
|
+
function removeMark(type) {
|
|
317
323
|
return (state, dispatch) => {
|
|
324
|
+
const markType = documentMarkType(state, type);
|
|
318
325
|
const { from, to, empty } = state.selection;
|
|
319
326
|
if (empty) {
|
|
320
327
|
if (dispatch) dispatchStoredMarks(state, dispatch, (state.storedMarks ?? state.selection.$from.marks()).filter((m) => m.type !== markType));
|
|
@@ -327,7 +334,8 @@ function removeMark(markType) {
|
|
|
327
334
|
/**
|
|
328
335
|
* Check if a mark is active in the current selection
|
|
329
336
|
*/
|
|
330
|
-
function isMarkActive(state,
|
|
337
|
+
function isMarkActive(state, type, attrs) {
|
|
338
|
+
const markType = documentMarkType(state, type);
|
|
331
339
|
const { from, to, empty } = state.selection;
|
|
332
340
|
if (empty) return (state.storedMarks ?? state.selection.$from.marks()).some((mark) => {
|
|
333
341
|
if (mark.type !== markType) return false;
|
|
@@ -356,7 +364,8 @@ function isMarkActive(state, markType, attrs) {
|
|
|
356
364
|
/**
|
|
357
365
|
* Get the current value of a mark attribute
|
|
358
366
|
*/
|
|
359
|
-
function getMarkAttr(state,
|
|
367
|
+
function getMarkAttr(state, type, attr) {
|
|
368
|
+
const markType = documentMarkType(state, type);
|
|
360
369
|
const { empty, $from, from, to } = state.selection;
|
|
361
370
|
if (empty) {
|
|
362
371
|
const marks = state.storedMarks ?? $from.marks();
|
|
@@ -524,4 +533,4 @@ function createRemoveMarkCommand(markType) {
|
|
|
524
533
|
return removeMark(markType);
|
|
525
534
|
}
|
|
526
535
|
//#endregion
|
|
527
|
-
export { clearFontSizeForAllScripts, clearFormatting, createRemoveMarkCommand, createSetMarkCommand, getMarkAttr, isMarkActive, marksToTextFormatting, removeMark, setFontSizeForAllScripts, setMark, textFormattingToMarks, toggleMarkForAllScripts, toggleUnderlineMark };
|
|
536
|
+
export { clearFontSizeForAllScripts, clearFormatting, createRemoveMarkCommand, createSetMarkCommand, getMarkAttr, isMarkActive, marksToTextFormatting, removeMark, setFontSizeForAllScripts, setMark, textFormattingToMarks, toggleDocumentMark, toggleMarkForAllScripts, toggleUnderlineMark };
|
|
@@ -6,5 +6,7 @@ type DeletionRange = {
|
|
|
6
6
|
};
|
|
7
7
|
/** Keep the text carrying one OOXML note reference together during deletion. */
|
|
8
8
|
declare const expandNoteReferenceDeletionRange: (doc: Node, from: number, to: number) => DeletionRange | null;
|
|
9
|
+
/** Each whole note reference [`from`, `to`) of `doc` touches, in document order. */
|
|
10
|
+
declare const noteReferenceRanges: (doc: Node, from: number, to: number) => DeletionRange[];
|
|
9
11
|
//#endregion
|
|
10
|
-
export { expandNoteReferenceDeletionRange };
|
|
12
|
+
export { expandNoteReferenceDeletionRange, noteReferenceRanges };
|
|
@@ -31,5 +31,16 @@ const expandNoteReferenceDeletionRange = (doc, from, to) => {
|
|
|
31
31
|
to: expandedTo
|
|
32
32
|
} : null;
|
|
33
33
|
};
|
|
34
|
+
/** Each whole note reference [`from`, `to`) of `doc` touches, in document order. */
|
|
35
|
+
const noteReferenceRanges = (doc, from, to) => {
|
|
36
|
+
const ranges = [];
|
|
37
|
+
doc.nodesBetween(from, to, (node, pos) => {
|
|
38
|
+
if (!node.isText || !node.marks.some((mark) => mark.type.name === "footnoteRef")) return;
|
|
39
|
+
const whole = expandNoteReferenceDeletionRange(doc, pos, pos + node.nodeSize);
|
|
40
|
+
const last = ranges.at(-1);
|
|
41
|
+
if (whole && (!last || whole.from >= last.to)) ranges.push(whole);
|
|
42
|
+
});
|
|
43
|
+
return ranges;
|
|
44
|
+
};
|
|
34
45
|
//#endregion
|
|
35
|
-
export { expandNoteReferenceDeletionRange };
|
|
46
|
+
export { expandNoteReferenceDeletionRange, noteReferenceRanges };
|
|
@@ -80,9 +80,9 @@ const CommentReferenceExtension = createNodeExtension({
|
|
|
80
80
|
}];
|
|
81
81
|
}
|
|
82
82
|
}),
|
|
83
|
-
onSchemaReady: (
|
|
83
|
+
onSchemaReady: () => ({ plugins: [new Plugin({ appendTransaction(transactions, _oldState, newState) {
|
|
84
84
|
if (!transactions.some(({ docChanged }) => docChanged)) return null;
|
|
85
|
-
const referenceType = schema.nodes[COMMENT_REFERENCE_NODE_NAME];
|
|
85
|
+
const referenceType = newState.schema.nodes[COMMENT_REFERENCE_NODE_NAME];
|
|
86
86
|
if (!referenceType) return null;
|
|
87
87
|
const repairs = planCommentReferenceRepairs(surveyCommentReferences(newState.doc));
|
|
88
88
|
if (repairs.length === 0) return null;
|
|
@@ -41,10 +41,12 @@ const HardBreakExtension = createNodeExtension({
|
|
|
41
41
|
}
|
|
42
42
|
},
|
|
43
43
|
onSchemaReady(ctx) {
|
|
44
|
-
|
|
45
|
-
if (!hardBreakType) panic("Missing node type: hardBreak");
|
|
44
|
+
if (!ctx.schema.nodes["hardBreak"]) panic("Missing node type: hardBreak");
|
|
46
45
|
return { keyboardShortcuts: { "Shift-Enter": (state, dispatch) => {
|
|
47
|
-
if (dispatch)
|
|
46
|
+
if (dispatch) {
|
|
47
|
+
const hardBreakType = state.schema.nodes["hardBreak"] ?? panic("Missing node type: hardBreak");
|
|
48
|
+
dispatch(state.tr.replaceSelectionWith(hardBreakType.create()).scrollIntoView());
|
|
49
|
+
}
|
|
48
50
|
return true;
|
|
49
51
|
} } };
|
|
50
52
|
}
|