@aicayzer/inkkit 0.1.0 → 0.1.2
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/chunks/{core-vtCr4MBS.js → core-Dyg5rJLT.js} +989 -118
- package/dist/chunks/{highlight-Daj2fv_u.js → highlight-DQC71L-N.js} +1 -1
- package/dist/core.d.ts +1 -1
- package/dist/core.js +1 -1
- package/dist/editor.d.ts +22 -7
- package/dist/index.js +1 -1
- package/dist/style.css +19 -5
- package/dist/types.d.ts +2 -0
- package/package.json +1 -1
|
@@ -22734,7 +22734,7 @@ var SerializerState = class extends Stack {
|
|
|
22734
22734
|
#closeMark;
|
|
22735
22735
|
};
|
|
22736
22736
|
//#endregion
|
|
22737
|
-
//#region node_modules/.pnpm/prosemirror-view@1.42.
|
|
22737
|
+
//#region node_modules/.pnpm/prosemirror-view@1.42.6_patch_hash=a3414754d6cb6cd32517617a4affee5f7895ca0b3b976186951d43106adf18b3/node_modules/prosemirror-view/dist/index.js
|
|
22738
22738
|
var domIndex = function(node) {
|
|
22739
22739
|
for (var index = 0;; index++) {
|
|
22740
22740
|
node = node.previousSibling;
|
|
@@ -25155,6 +25155,7 @@ var InputState = class {
|
|
|
25155
25155
|
this.lastIOSEnter = 0;
|
|
25156
25156
|
this.lastIOSEnterFallbackTimeout = -1;
|
|
25157
25157
|
this.lastFocus = 0;
|
|
25158
|
+
this.focusTimeout = -1;
|
|
25158
25159
|
this.lastTouch = 0;
|
|
25159
25160
|
this.lastChromeDelete = 0;
|
|
25160
25161
|
this.composing = false;
|
|
@@ -25185,6 +25186,7 @@ function setSelectionOrigin(view, origin) {
|
|
|
25185
25186
|
view.input.lastSelectionTime = Date.now();
|
|
25186
25187
|
}
|
|
25187
25188
|
function destroyInput(view) {
|
|
25189
|
+
clearTimeout(view.input.focusTimeout);
|
|
25188
25190
|
if (view.input.mouseDown) view.input.mouseDown.done();
|
|
25189
25191
|
view.domObserver.stop();
|
|
25190
25192
|
for (let type in view.input.eventHandlers) view.dom.removeEventListener(type, view.input.eventHandlers[type]);
|
|
@@ -25213,6 +25215,17 @@ function dispatchEvent$1(view, event) {
|
|
|
25213
25215
|
}
|
|
25214
25216
|
editHandlers.keydown = (view, _event) => {
|
|
25215
25217
|
let event = _event;
|
|
25218
|
+
if (![
|
|
25219
|
+
16,
|
|
25220
|
+
17,
|
|
25221
|
+
18,
|
|
25222
|
+
91,
|
|
25223
|
+
92,
|
|
25224
|
+
93
|
|
25225
|
+
].includes(event.keyCode)) {
|
|
25226
|
+
clearTimeout(view.input.focusTimeout);
|
|
25227
|
+
view.input.focusTimeout = -1;
|
|
25228
|
+
}
|
|
25216
25229
|
view.input.shiftKey = event.keyCode == 16 || event.shiftKey;
|
|
25217
25230
|
if (inOrNearComposition(view)) return;
|
|
25218
25231
|
view.input.lastKeyCode = event.keyCode;
|
|
@@ -25755,12 +25768,15 @@ handlers.focus = (view) => {
|
|
|
25755
25768
|
view.dom.classList.add("ProseMirror-focused");
|
|
25756
25769
|
view.domObserver.start();
|
|
25757
25770
|
view.focused = true;
|
|
25758
|
-
setTimeout(() => {
|
|
25771
|
+
view.input.focusTimeout = setTimeout(() => {
|
|
25772
|
+
view.input.focusTimeout = -1;
|
|
25759
25773
|
if (view.docView && view.hasFocus() && !view.domObserver.currentSelection.eq(view.domSelectionRange())) selectionToDOM(view);
|
|
25760
25774
|
}, 20);
|
|
25761
25775
|
}
|
|
25762
25776
|
};
|
|
25763
25777
|
handlers.blur = (view, _event) => {
|
|
25778
|
+
clearTimeout(view.input.focusTimeout);
|
|
25779
|
+
view.input.focusTimeout = -1;
|
|
25764
25780
|
let event = _event;
|
|
25765
25781
|
if (view.focused) {
|
|
25766
25782
|
view.domObserver.stop();
|
|
@@ -31127,6 +31143,11 @@ function mermaidPreview(onError) {
|
|
|
31127
31143
|
}));
|
|
31128
31144
|
}
|
|
31129
31145
|
//#endregion
|
|
31146
|
+
//#region src/hard-break.ts
|
|
31147
|
+
function htmlBreakAt(position) {
|
|
31148
|
+
return position.parent.type.name === "heading" && position.parent.attrs.form !== "setext" || position.depth > 1 && /^table_(cell|header)$/.test(position.node(-1).type.name);
|
|
31149
|
+
}
|
|
31150
|
+
//#endregion
|
|
31130
31151
|
//#region node_modules/.pnpm/rope-sequence@1.3.4/node_modules/rope-sequence/dist/index.js
|
|
31131
31152
|
var GOOD_LEAF_SIZE = 200;
|
|
31132
31153
|
var RopeSequence = function RopeSequence() {};
|
|
@@ -39485,6 +39506,194 @@ var cursor = [
|
|
|
39485
39506
|
})
|
|
39486
39507
|
].flat();
|
|
39487
39508
|
//#endregion
|
|
39509
|
+
//#region src/smart-punctuation.ts
|
|
39510
|
+
/**
|
|
39511
|
+
* Smart punctuation: the quote or dash being typed becomes a curly quote or a dash.
|
|
39512
|
+
*
|
|
39513
|
+
* - `"` and `'` open after the start of a block, a line break, whitespace, an opening bracket, a
|
|
39514
|
+
* dash or another opening quote, and close everywhere else. A `'` between letters is an
|
|
39515
|
+
* apostrophe, which is the closing form.
|
|
39516
|
+
* - `--` gives an en dash and `---` an em dash: the third hyphen turns the en dash that the second
|
|
39517
|
+
* one made into an em dash. Only a hyphen that text input has just inserted counts as the first
|
|
39518
|
+
* of the two, so a hyphen already in the note, or typed before the caret moved, stays one.
|
|
39519
|
+
* - A quote that a dead key made arrives as a composition. When the composition commits exactly
|
|
39520
|
+
* that quote at the caret, it follows the same rules.
|
|
39521
|
+
*
|
|
39522
|
+
* These are input rules, so only the character being typed changes, Backspace and Undo straight
|
|
39523
|
+
* after restore what was typed, and nothing in a note is rewritten. The editor answers
|
|
39524
|
+
* `smartPunctuationCtx` with the current option, so turning it on or off needs no new editor.
|
|
39525
|
+
*/
|
|
39526
|
+
var smartPunctuationCtx = $ctx(() => false, "inkkitSmartPunctuation");
|
|
39527
|
+
/** Set on the transaction of each rule that this file makes. */
|
|
39528
|
+
var smartRule = "inkkitSmartPunctuation";
|
|
39529
|
+
var enDash = "–";
|
|
39530
|
+
var emDash = "—";
|
|
39531
|
+
/** What may come before a quote for it to open. */
|
|
39532
|
+
var opensAfter = /[\s([{<\u2013\u2014\u2018\u201C]/u;
|
|
39533
|
+
/**
|
|
39534
|
+
* Markdown that a person is typing out in a line of text, not words: a code span, a link
|
|
39535
|
+
* destination, a web address, a wiki link or footnote label, an HTML tag or comment and a
|
|
39536
|
+
* reference definition. Smart punctuation leaves a line alone while one is open, because the
|
|
39537
|
+
* curly character would change what the Markdown means.
|
|
39538
|
+
*/
|
|
39539
|
+
var typingSyntax = [
|
|
39540
|
+
(before) => (before.match(/`+/g)?.length ?? 0) % 2 === 1,
|
|
39541
|
+
(before) => /\]\([^)]*$/.test(before),
|
|
39542
|
+
(before) => /\[\[[^\]]*$/.test(before),
|
|
39543
|
+
(before) => /\[\^[^\]]*$/.test(before),
|
|
39544
|
+
(before) => /(?:^|[^\w])(?:[a-z][a-z0-9+.-]*:\/\/|www\.|mailto:)\S*$/i.test(before),
|
|
39545
|
+
(before) => /(?:^|[^\w])<[A-Za-z!/?][^>]*$/.test(before),
|
|
39546
|
+
(before) => /^\s*\[[^\]]+\]:/.test(before)
|
|
39547
|
+
];
|
|
39548
|
+
/**
|
|
39549
|
+
* The text of the block before `pos`, with each code span and each non-text node as one
|
|
39550
|
+
* placeholder, so that a backtick or `<` inside code is not syntax being typed.
|
|
39551
|
+
*/
|
|
39552
|
+
function textBefore(state, pos) {
|
|
39553
|
+
const $pos = state.doc.resolve(pos);
|
|
39554
|
+
let text = "";
|
|
39555
|
+
$pos.parent.forEach((child, offset) => {
|
|
39556
|
+
if (offset >= $pos.parentOffset) return;
|
|
39557
|
+
text += child.isText && !child.marks.some((mark) => mark.type.spec.code) ? child.text.slice(0, $pos.parentOffset - offset) : "";
|
|
39558
|
+
});
|
|
39559
|
+
return text;
|
|
39560
|
+
}
|
|
39561
|
+
var input = new PluginKey("inkkitSmartPunctuationInput");
|
|
39562
|
+
/** The text a transaction inserted, when it is one step that inserts text at `at` and nothing else. */
|
|
39563
|
+
function insertedAt(tr, at) {
|
|
39564
|
+
const [step] = tr.steps;
|
|
39565
|
+
if (tr.steps.length !== 1 || !(step instanceof ReplaceStep)) return void 0;
|
|
39566
|
+
if (step.from !== at || step.slice.openStart || step.slice.openEnd) return void 0;
|
|
39567
|
+
return step.slice.content.textBetween(0, step.slice.content.size);
|
|
39568
|
+
}
|
|
39569
|
+
var inputTracking = $prose(() => new Plugin({
|
|
39570
|
+
key: input,
|
|
39571
|
+
state: {
|
|
39572
|
+
init: () => ({
|
|
39573
|
+
pending: null,
|
|
39574
|
+
hyphen: null,
|
|
39575
|
+
composition: null,
|
|
39576
|
+
composedQuote: null
|
|
39577
|
+
}),
|
|
39578
|
+
apply(tr, value) {
|
|
39579
|
+
const { pending, composition } = value;
|
|
39580
|
+
value.pending = value.hyphen = value.composedQuote = null;
|
|
39581
|
+
if (tr.getMeta(hyphenReceived)) value.hyphen = tr.selection.from;
|
|
39582
|
+
if (!tr.docChanged) return value;
|
|
39583
|
+
if (pending !== null && insertedAt(tr, pending) === "-") value.hyphen = pending + 1;
|
|
39584
|
+
if (composition) {
|
|
39585
|
+
value.composition = null;
|
|
39586
|
+
const text = insertedAt(tr, composition.pos);
|
|
39587
|
+
if (tr.getMeta("composition") !== void 0 && (text === "\"" || text === "'") && tr.doc.content.size === composition.size + 1) value.composedQuote = composition.pos + 1;
|
|
39588
|
+
}
|
|
39589
|
+
return value;
|
|
39590
|
+
}
|
|
39591
|
+
},
|
|
39592
|
+
props: {
|
|
39593
|
+
handleTextInput(view, from, _to, text) {
|
|
39594
|
+
input.getState(view.state).pending = text === "-" ? from : null;
|
|
39595
|
+
return false;
|
|
39596
|
+
},
|
|
39597
|
+
handleDOMEvents: { compositionstart(view) {
|
|
39598
|
+
const { from, empty } = view.state.selection;
|
|
39599
|
+
const tracked = input.getState(view.state);
|
|
39600
|
+
tracked.composedQuote = null;
|
|
39601
|
+
tracked.composition = empty ? {
|
|
39602
|
+
pos: from,
|
|
39603
|
+
size: view.state.doc.content.size
|
|
39604
|
+
} : null;
|
|
39605
|
+
return false;
|
|
39606
|
+
} }
|
|
39607
|
+
}
|
|
39608
|
+
}));
|
|
39609
|
+
/** Set on a transaction that inserted text ending in a hyphen, whatever else came with it. */
|
|
39610
|
+
var hyphenReceived = "inkkitHyphenReceived";
|
|
39611
|
+
/** Marks a transaction that inserted text ending in a hyphen that no rule changed. */
|
|
39612
|
+
function insertedHyphen(tr) {
|
|
39613
|
+
return tr.setMeta(hyphenReceived, true);
|
|
39614
|
+
}
|
|
39615
|
+
/**
|
|
39616
|
+
* The state that input rules see for text that arrived in one piece, which holds only what the
|
|
39617
|
+
* rules need: it follows the document, with the tracking plugin when the editor has one. When
|
|
39618
|
+
* `rest` ends in a hyphen, the last character follows a hyphen that came in the same piece.
|
|
39619
|
+
*/
|
|
39620
|
+
function chunkState(state, config, rest) {
|
|
39621
|
+
const tracker = input.get(state);
|
|
39622
|
+
const prepared = EditorState.create({
|
|
39623
|
+
...config,
|
|
39624
|
+
plugins: tracker ? [tracker] : []
|
|
39625
|
+
});
|
|
39626
|
+
return tracker && rest.endsWith("-") ? prepared.apply(insertedHyphen(prepared.tr)) : prepared;
|
|
39627
|
+
}
|
|
39628
|
+
/**
|
|
39629
|
+
* Whether a rule may change what `match` found at `pos`: the option is on, the last character of
|
|
39630
|
+
* the match is the one being typed, which is not in the document yet, and the text is ordinary,
|
|
39631
|
+
* with no Markdown being typed. The input rules plugin also runs every rule when a composition
|
|
39632
|
+
* ends, over text that is all in the document; that is not typing, and is left alone.
|
|
39633
|
+
*/
|
|
39634
|
+
function applies(on, state, match, pos) {
|
|
39635
|
+
if (!on()) return false;
|
|
39636
|
+
const typed = pos + match[0].length - 1 === state.selection.from;
|
|
39637
|
+
const composed = !typed && match[0].length === 1 && input.getState(state)?.composedQuote === state.selection.from && pos === state.selection.from - 1;
|
|
39638
|
+
if (!typed && !composed) return false;
|
|
39639
|
+
const $pos = state.doc.resolve(pos);
|
|
39640
|
+
if ($pos.parent.type.spec.code || !$pos.parent.inlineContent) return false;
|
|
39641
|
+
if ((state.storedMarks ?? $pos.marks()).some((mark) => mark.type.spec.code)) return false;
|
|
39642
|
+
const before = textBefore(state, pos);
|
|
39643
|
+
return !typingSyntax.some((open) => open(before));
|
|
39644
|
+
}
|
|
39645
|
+
function opensHere(state, pos) {
|
|
39646
|
+
const node = state.doc.resolve(pos).nodeBefore;
|
|
39647
|
+
if (!node) return true;
|
|
39648
|
+
if (node.isText) {
|
|
39649
|
+
const text = node.text ?? "";
|
|
39650
|
+
return opensAfter.test(String.fromCodePoint(text.codePointAt(text.length - 1)));
|
|
39651
|
+
}
|
|
39652
|
+
return node.type.name === "hardbreak";
|
|
39653
|
+
}
|
|
39654
|
+
/** The input rule that ran at the last change, when nothing has happened since. */
|
|
39655
|
+
function lastRule(state) {
|
|
39656
|
+
for (const plugin of state.plugins) if (plugin.spec.isInputRules) {
|
|
39657
|
+
const stored = plugin.getState(state);
|
|
39658
|
+
if (stored) return stored;
|
|
39659
|
+
}
|
|
39660
|
+
}
|
|
39661
|
+
var quotes$1 = {
|
|
39662
|
+
"\"": ["“", "”"],
|
|
39663
|
+
"'": ["‘", "’"]
|
|
39664
|
+
};
|
|
39665
|
+
var smartPunctuation = [
|
|
39666
|
+
smartPunctuationCtx,
|
|
39667
|
+
inputTracking,
|
|
39668
|
+
$inputRule((ctx) => new InputRule(/["']$/, (state, match, start, end) => {
|
|
39669
|
+
if (!applies(ctx.get(smartPunctuationCtx.key), state, match, start)) return null;
|
|
39670
|
+
const [opening, closing] = quotes$1[match[0]];
|
|
39671
|
+
return state.tr.insertText(opensHere(state, start) ? opening : closing, start, end).setMeta(smartRule, "quote");
|
|
39672
|
+
}, { inCodeMark: false })),
|
|
39673
|
+
$inputRule((ctx) => new InputRule(/--$/, (state, match, start, end) => {
|
|
39674
|
+
if (!applies(ctx.get(smartPunctuationCtx.key), state, match, start)) return null;
|
|
39675
|
+
if (input.getState(state)?.hyphen !== state.selection.from) return null;
|
|
39676
|
+
const before = textBefore(state, start);
|
|
39677
|
+
if (!before.trim() || before.endsWith("-") || /^\s*\|/.test(before)) return null;
|
|
39678
|
+
return state.tr.insertText(enDash, start, end).setMeta(smartRule, "en");
|
|
39679
|
+
}, { inCodeMark: false })),
|
|
39680
|
+
$inputRule((ctx) => new InputRule(/\u2013-$/, (state, match, start, end) => {
|
|
39681
|
+
if (!applies(ctx.get(smartPunctuationCtx.key), state, match, start)) return null;
|
|
39682
|
+
if (lastRule(state)?.transform.getMeta(smartRule) !== "en") return null;
|
|
39683
|
+
return state.tr.insertText(emDash, start, end).setMeta(smartRule, "em");
|
|
39684
|
+
}, { inCodeMark: false }))
|
|
39685
|
+
].flat();
|
|
39686
|
+
/**
|
|
39687
|
+
* Undo straight after a smart quote or dash puts back the character that was typed, as Backspace
|
|
39688
|
+
* does for any input rule. The replacement joins the typing's history step, so the next Undo
|
|
39689
|
+
* removes the typing and not the curly character. Returns whether it applied.
|
|
39690
|
+
*/
|
|
39691
|
+
var undoSmartPunctuation = (state, dispatch) => {
|
|
39692
|
+
const rule = lastRule(state);
|
|
39693
|
+
if (!rule?.transform.getMeta(smartRule)) return false;
|
|
39694
|
+
return undoInputRule(state, dispatch && ((tr) => dispatch(tr.setMeta("appendedTransaction", rule.transform))));
|
|
39695
|
+
};
|
|
39696
|
+
//#endregion
|
|
39488
39697
|
//#region src/text-input.ts
|
|
39489
39698
|
var isInputRules = (plugin) => plugin.spec.isInputRules === true;
|
|
39490
39699
|
/**
|
|
@@ -39514,12 +39723,12 @@ function insertTextChunk(view, from, to, text, deflt) {
|
|
|
39514
39723
|
return true;
|
|
39515
39724
|
}
|
|
39516
39725
|
const rules = state.plugins.filter(isInputRules);
|
|
39517
|
-
const prepared =
|
|
39726
|
+
const prepared = chunkState(state, {
|
|
39518
39727
|
schema: state.schema,
|
|
39519
39728
|
doc: tr.doc,
|
|
39520
39729
|
selection: TextSelection.create(tr.doc, at),
|
|
39521
39730
|
storedMarks: state.storedMarks ?? (from === to ? $from.marks() : $from.marksAcross($to))
|
|
39522
|
-
});
|
|
39731
|
+
}, rest);
|
|
39523
39732
|
let ruled;
|
|
39524
39733
|
const preparedView = Object.create(view, {
|
|
39525
39734
|
state: { value: prepared },
|
|
@@ -39528,7 +39737,8 @@ function insertTextChunk(view, from, to, text, deflt) {
|
|
|
39528
39737
|
} }
|
|
39529
39738
|
});
|
|
39530
39739
|
if (!rules.some((rule) => rule.props.handleTextInput?.call(rule, preparedView, at, at, last, () => prepared.tr.insertText(last, at)))) {
|
|
39531
|
-
|
|
39740
|
+
const plain = deflt().scrollIntoView();
|
|
39741
|
+
view.dispatch(last === "-" ? insertedHyphen(plain) : plain);
|
|
39532
39742
|
return true;
|
|
39533
39743
|
}
|
|
39534
39744
|
if (ruled) {
|
|
@@ -44225,7 +44435,7 @@ function lineBreakHTML(value) {
|
|
|
44225
44435
|
].includes(value.trim());
|
|
44226
44436
|
}
|
|
44227
44437
|
function restoreInlineBreaks(node) {
|
|
44228
|
-
if (
|
|
44438
|
+
if (node.type === "paragraph" && node.children.length > 1 || node.type === "heading" || node.type === "tableCell") node.children = node.children.map((child) => child.type === "html" && lineBreakHTML(child.value) ? {
|
|
44229
44439
|
type: "break",
|
|
44230
44440
|
data: { inkkitHTMLBreak: true },
|
|
44231
44441
|
position: child.position
|
|
@@ -44483,6 +44693,39 @@ function relabel(text, offsets, marker) {
|
|
|
44483
44693
|
}
|
|
44484
44694
|
return text;
|
|
44485
44695
|
}
|
|
44696
|
+
var parentKey = (node) => `${node.type}:${node.position.start.offset}`;
|
|
44697
|
+
function reorderedWithin(node, reorder) {
|
|
44698
|
+
if (!reorder) return false;
|
|
44699
|
+
const start = node.position?.start.offset;
|
|
44700
|
+
const end = node.position?.end.offset;
|
|
44701
|
+
if (start == null || end == null) return false;
|
|
44702
|
+
for (const key of reorder.keys()) {
|
|
44703
|
+
const at = Number(key.slice(key.lastIndexOf(":") + 1));
|
|
44704
|
+
if (at >= start && at < end) return true;
|
|
44705
|
+
}
|
|
44706
|
+
return false;
|
|
44707
|
+
}
|
|
44708
|
+
/**
|
|
44709
|
+
* An item of an ordered list moved from `original`'s place to `place`'s, which
|
|
44710
|
+
* takes the number written there, so the numbers keep their order. Lines after
|
|
44711
|
+
* the first that are indented to the item's content move with it when the
|
|
44712
|
+
* number's width changes.
|
|
44713
|
+
*/
|
|
44714
|
+
function renumberItem(text, source, original, place) {
|
|
44715
|
+
const own = /^\d{1,9}/.exec(text)?.[0];
|
|
44716
|
+
const number = /^\d{1,9}/.exec(source.slice(place.position.start.offset))?.[0];
|
|
44717
|
+
if (!own || !number || own === number) return text;
|
|
44718
|
+
const start = original.position.start.offset;
|
|
44719
|
+
const content = original.children?.[0]?.position?.start.offset;
|
|
44720
|
+
const lines = text.split(/(?<=\n)/);
|
|
44721
|
+
const prefix = source.slice(source.lastIndexOf("\n", start - 1) + 1, start);
|
|
44722
|
+
const indent = content == null ? -1 : content - start;
|
|
44723
|
+
const first = lines[0];
|
|
44724
|
+
if (indent < 0 || first.slice(0, indent).includes("\n")) return text;
|
|
44725
|
+
const from = prefix + " ".repeat(indent);
|
|
44726
|
+
const to = prefix + " ".repeat(indent + number.length - own.length);
|
|
44727
|
+
return [number + first.slice(own.length), ...lines.slice(1).map((line) => line.startsWith(from) ? to + line.slice(from.length) : line)].join("");
|
|
44728
|
+
}
|
|
44486
44729
|
function authoredMarker(list, source) {
|
|
44487
44730
|
const at = list.children?.[0]?.position?.start.offset;
|
|
44488
44731
|
return at == null ? void 0 : markerAt(source, at)?.marker;
|
|
@@ -44724,11 +44967,18 @@ function runOffsets(nodes, text, from, to) {
|
|
|
44724
44967
|
let decoded = "";
|
|
44725
44968
|
const offsets = [from];
|
|
44726
44969
|
const links = [];
|
|
44970
|
+
const breaks = /* @__PURE__ */ new Set();
|
|
44727
44971
|
let at = from;
|
|
44972
|
+
let afterBreak = false;
|
|
44728
44973
|
for (const node of nodes) {
|
|
44729
44974
|
const start = node.position?.start.offset;
|
|
44730
44975
|
const end = node.position?.end.offset;
|
|
44731
|
-
if (start
|
|
44976
|
+
if (start == null || end == null) return void 0;
|
|
44977
|
+
if (afterBreak && start >= at && /^[ \t>]*$/.test(text.slice(at, start))) {
|
|
44978
|
+
at = start;
|
|
44979
|
+
offsets[offsets.length - 1] = start;
|
|
44980
|
+
}
|
|
44981
|
+
if (start !== at) return void 0;
|
|
44732
44982
|
const raw = text.slice(start, end);
|
|
44733
44983
|
if (node.type === "link") {
|
|
44734
44984
|
const label = inlineText(node);
|
|
@@ -44742,13 +44992,19 @@ function runOffsets(nodes, text, from, to) {
|
|
|
44742
44992
|
if (!read || read.decoded !== lf(node.value ?? "")) return void 0;
|
|
44743
44993
|
decoded += read.decoded;
|
|
44744
44994
|
offsets.push(...read.offsets.slice(1).map((offset) => start + offset));
|
|
44995
|
+
} else if (node.type === "break") {
|
|
44996
|
+
breaks.add(decoded.length);
|
|
44997
|
+
decoded += "\n";
|
|
44998
|
+
offsets.push(end);
|
|
44745
44999
|
} else return void 0;
|
|
45000
|
+
afterBreak = node.type === "break";
|
|
44746
45001
|
at = end;
|
|
44747
45002
|
}
|
|
44748
45003
|
return at === to ? {
|
|
44749
45004
|
decoded,
|
|
44750
45005
|
offsets,
|
|
44751
|
-
links
|
|
45006
|
+
links,
|
|
45007
|
+
breaks
|
|
44752
45008
|
} : void 0;
|
|
44753
45009
|
}
|
|
44754
45010
|
function retainRun(before, after, source, canonical, [from, to], [newFrom, newTo]) {
|
|
@@ -44758,9 +45014,9 @@ function retainRun(before, after, source, canonical, [from, to], [newFrom, newTo
|
|
|
44758
45014
|
const a = old.decoded;
|
|
44759
45015
|
const b = now.decoded;
|
|
44760
45016
|
let prefix = 0;
|
|
44761
|
-
while (prefix < a.length && prefix < b.length && a[prefix] === b[prefix]) prefix++;
|
|
45017
|
+
while (prefix < a.length && prefix < b.length && a[prefix] === b[prefix] && old.breaks.has(prefix) === now.breaks.has(prefix)) prefix++;
|
|
44762
45018
|
let suffix = 0;
|
|
44763
|
-
while (suffix < a.length - prefix && suffix < b.length - prefix && a[a.length - 1 - suffix] === b[b.length - 1 - suffix]) suffix++;
|
|
45019
|
+
while (suffix < a.length - prefix && suffix < b.length - prefix && a[a.length - 1 - suffix] === b[b.length - 1 - suffix] && old.breaks.has(a.length - 1 - suffix) === now.breaks.has(b.length - 1 - suffix)) suffix++;
|
|
44764
45020
|
for (let widened = true; widened;) {
|
|
44765
45021
|
widened = false;
|
|
44766
45022
|
for (const [links, length] of [[old.links, a.length], [now.links, b.length]]) for (const [start, end] of links) if (start <= length - suffix && end >= prefix) {
|
|
@@ -44774,7 +45030,7 @@ function retainRun(before, after, source, canonical, [from, to], [newFrom, newTo
|
|
|
44774
45030
|
}
|
|
44775
45031
|
}
|
|
44776
45032
|
}
|
|
44777
|
-
return source.slice(from, old.offsets[prefix]) + canonical.slice(now.offsets[prefix], now.offsets[b.length - suffix]) + source.slice(old.offsets[a.length - suffix], to);
|
|
45033
|
+
return source.slice(from, old.offsets[prefix]) + canonical.slice(now.offsets[prefix], now.offsets[b.length - suffix]) + (now.breaks.has(b.length - suffix - 1) ? retainBoundaryText(source.slice(old.offsets[a.length - suffix], to), canonical.slice(now.offsets[b.length - suffix], newTo), true) : source.slice(old.offsets[a.length - suffix], to));
|
|
44778
45034
|
}
|
|
44779
45035
|
function retainText(raw, before, after, inTable = false, written, beside = [false, false]) {
|
|
44780
45036
|
before = lf(before);
|
|
@@ -44796,14 +45052,38 @@ function retainText(raw, before, after, inTable = false, written, beside = [fals
|
|
|
44796
45052
|
}).join("");
|
|
44797
45053
|
return raw.slice(0, offsets[prefix]) + inserted + raw.slice(offsets[before.length - suffix]);
|
|
44798
45054
|
}
|
|
44799
|
-
function
|
|
45055
|
+
function retainBoundaryText(raw, canonical, afterBreak = false) {
|
|
45056
|
+
if (afterBreak) {
|
|
45057
|
+
const opening = /^(?:\d+)?(?:\\.)+/.exec(canonical)?.[0];
|
|
45058
|
+
const written = opening ? decodedOffsets(opening) : void 0;
|
|
45059
|
+
const original = written ? decodedOffsets(raw, true) : void 0;
|
|
45060
|
+
if (written && original?.decoded.startsWith(written.decoded)) raw = opening + raw.slice(original.offsets[written.decoded.length]);
|
|
45061
|
+
}
|
|
44800
45062
|
const token = "(?:[ \\t]|&#(?:[xX]0*(?:20|9)|0*(?:32|9));|	)";
|
|
44801
45063
|
const decoded = (value) => (value.match(new RegExp(token, "g")) ?? []).map((value) => value === " " || /(?:9;|Tab;)$/.test(value) ? " " : " ").join("");
|
|
44802
45064
|
const encode = (value) => value.replace(/[ \t]/g, (value) => value === " " ? "	" : " ");
|
|
44803
|
-
|
|
45065
|
+
if (raw.includes("\n")) {
|
|
45066
|
+
const lines = raw.split(/(\r?\n)/);
|
|
45067
|
+
const written = canonical.split(/\r?\n/);
|
|
45068
|
+
if (lines.length === written.length * 2 - 1) return lines.map((line, index) => {
|
|
45069
|
+
if (index % 2) return line;
|
|
45070
|
+
const canonicalLine = written[index / 2];
|
|
45071
|
+
const gutter = (value) => /^(?:[ \t]*>)*/.exec(value)?.[0] ?? "";
|
|
45072
|
+
const prefix = gutter(line);
|
|
45073
|
+
const canonicalPrefix = gutter(canonicalLine);
|
|
45074
|
+
if (prefix.replace(/[ \t]/g, "") !== canonicalPrefix.replace(/[ \t]/g, "")) return line;
|
|
45075
|
+
const canonicalBody = canonicalLine.slice(canonicalPrefix.length);
|
|
45076
|
+
return prefix + retainBoundaryText(line.slice(prefix.length), canonicalBody);
|
|
45077
|
+
}).join("");
|
|
45078
|
+
}
|
|
44804
45079
|
const rawStart = new RegExp(`^${token}+`).exec(raw)?.[0];
|
|
44805
45080
|
const encodedStart = new RegExp(`^${token}+`).exec(canonical)?.[0];
|
|
44806
|
-
if (
|
|
45081
|
+
if (rawStart && encodedStart?.includes("&")) {
|
|
45082
|
+
const content = decoded(encodedStart.slice(encodedStart.indexOf("&")));
|
|
45083
|
+
const parts = rawStart.match(new RegExp(token, "g"));
|
|
45084
|
+
const from = parts.length - content.length;
|
|
45085
|
+
if (from >= 0 && decoded(parts.slice(from).join("")) === content) raw = parts.map((part, index) => index < from ? part : encode(part)).join("") + raw.slice(rawStart.length);
|
|
45086
|
+
}
|
|
44807
45087
|
const end = /[ \t]+$/.exec(raw)?.[0];
|
|
44808
45088
|
const rawEnd = new RegExp(`${token}+$`).exec(raw)?.[0];
|
|
44809
45089
|
const encodedEnd = new RegExp(`${token}+$`).exec(canonical)?.[0];
|
|
@@ -44966,7 +45246,7 @@ function markLiterals(raw, transformed, blocks = []) {
|
|
|
44966
45246
|
};
|
|
44967
45247
|
raw.children.forEach(mark);
|
|
44968
45248
|
}
|
|
44969
|
-
function retainSource(before, after, source, canonical, lineEnding, inTable = false, width, beside = [false, false], joined = []) {
|
|
45249
|
+
function retainSource(before, after, source, canonical, lineEnding, inTable = false, width, beside = [false, false], joined = [], reorder, afterBreak = false) {
|
|
44970
45250
|
if (literals$1.has(after)) return withEnding(retainLiteral(source.slice(before.position.start.offset, before.position.end.offset), literalForms.get(before), lf(canonical.slice(after.position.start.offset, after.position.end.offset))), lineEnding);
|
|
44971
45251
|
if (before.type === "list" && after.type === "list" && before.ordered && after.ordered && !numbered.has(before) && before.position?.start.offset != null) {
|
|
44972
45252
|
const own = {
|
|
@@ -44974,7 +45254,7 @@ function retainSource(before, after, source, canonical, lineEnding, inTable = fa
|
|
|
44974
45254
|
start: after.start
|
|
44975
45255
|
};
|
|
44976
45256
|
numbered.add(own);
|
|
44977
|
-
const text = retainSource(own, after, source, canonical, lineEnding, inTable, width, beside, joined);
|
|
45257
|
+
const text = retainSource(own, after, source, canonical, lineEnding, inTable, width, beside, joined, reorder);
|
|
44978
45258
|
const at = before.position.start.offset;
|
|
44979
45259
|
const prefix = source.slice(source.lastIndexOf("\n", at - 1) + 1, at).replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
44980
45260
|
let count = 0, previous = 0, number = 0;
|
|
@@ -44992,7 +45272,7 @@ function retainSource(before, after, source, canonical, lineEnding, inTable = fa
|
|
|
44992
45272
|
const text = retainSource({
|
|
44993
45273
|
...before,
|
|
44994
45274
|
checked: after.checked
|
|
44995
|
-
}, after, source, canonical, lineEnding, inTable, width, beside, joined);
|
|
45275
|
+
}, after, source, canonical, lineEnding, inTable, width, beside, joined, reorder);
|
|
44996
45276
|
const box = /^((?:[-*+]|\d{1,9}[.)])[ \t]+\[)[ xX](\])/.exec(text);
|
|
44997
45277
|
if (box) return box[1] + (after.checked ? "x" : " ") + text.slice(box[1].length + 1);
|
|
44998
45278
|
}
|
|
@@ -45057,8 +45337,8 @@ function retainSource(before, after, source, canonical, lineEnding, inTable = fa
|
|
|
45057
45337
|
const to = first.position.end.offset - start;
|
|
45058
45338
|
return retained.startsWith(source.slice(start, before.children[1].position.start.offset)) ? retained.slice(0, from) + "<br />" + retained.slice(to) : retained;
|
|
45059
45339
|
}
|
|
45060
|
-
if (before.type === "text" && after.type === "text") return
|
|
45061
|
-
if (signature(before) === signature(after) && ownShape(before) === ownShape(after) && !holdsLiteral(after)) return raw;
|
|
45340
|
+
if (before.type === "text" && after.type === "text") return retainBoundaryText(withEnding(retainText(raw, before.value, after.value, inTable, canonical.slice(newStart, newEnd), beside), lineEnding), canonical.slice(newStart, newEnd), afterBreak);
|
|
45341
|
+
if (signature(before) === signature(after) && ownShape(before) === ownShape(after) && !holdsLiteral(after) && !reorderedWithin(before, reorder)) return raw;
|
|
45062
45342
|
const marker = sameList(before, after) ? authoredMarker(before, source) : void 0;
|
|
45063
45343
|
const located = (nodes) => nodes.every((node) => node.position?.start.offset != null);
|
|
45064
45344
|
if (before.type === after.type && ownShape(before) === ownShape(after) && before.children && after.children && before.children.length === after.children.length && located(before.children) && located(after.children)) {
|
|
@@ -45066,15 +45346,17 @@ function retainSource(before, after, source, canonical, lineEnding, inTable = fa
|
|
|
45066
45346
|
let previous;
|
|
45067
45347
|
const same = (candidate, incoming) => signature(candidate) === signature(incoming) && ownShape(candidate) === ownShape(incoming);
|
|
45068
45348
|
const reorderable = before.type === "table" || before.type === "tableRow";
|
|
45349
|
+
const moves = reorder?.get(parentKey(before));
|
|
45069
45350
|
const retained = new Set(reorderable ? before.children.flatMap((child, index) => same(child, after.children[index]) ? [index] : []) : []);
|
|
45070
45351
|
before.children.forEach((child, index) => {
|
|
45071
45352
|
const incoming = after.children[index];
|
|
45072
|
-
const
|
|
45353
|
+
const carried = moves?.get(index);
|
|
45354
|
+
const movedIndex = !reorderable ? carried !== void 0 && before.children[carried] !== void 0 && same(before.children[carried], incoming) ? carried : -1 : same(child, incoming) ? index : before.children.findIndex((candidate, candidateIndex) => !retained.has(candidateIndex) && same(candidate, incoming));
|
|
45073
45355
|
const original = movedIndex < 0 ? child : before.children[movedIndex];
|
|
45074
45356
|
if (movedIndex >= 0) retained.add(movedIndex);
|
|
45075
45357
|
const childStart = child.position?.start.offset, childEnd = child.position?.end.offset;
|
|
45076
45358
|
if (childStart == null || childEnd == null) throw new PreservationError("A source token has no location");
|
|
45077
|
-
let retainedSource = rewrittenAddress(before.type, before.children, movedIndex < 0 ? index : movedIndex, after.children, index, source, canonical) ? canonical.slice(incoming.position.start.offset, incoming.position.end.offset) : incoming.type === "list" && !sameList(original, incoming) ? withEnding(canonicalSlice(void 0, [incoming], canonical, incoming.position.start.offset, incoming.position.end.offset, previous, authoredNeighbour(before.children[index + 1], after.children[index + 1], source)), lineEnding) : retainSource(original, incoming, source, canonical, lineEnding, inTable || before.type === "tableCell", before.type === "table" ? before.children[0]?.children?.length : void 0, [after.children[index - 1]?.type === "link", after.children[index + 1]?.type === "link"]);
|
|
45359
|
+
let retainedSource = rewrittenAddress(before.type, before.children, movedIndex < 0 ? index : movedIndex, after.children, index, source, canonical) ? canonical.slice(incoming.position.start.offset, incoming.position.end.offset) : incoming.type === "list" && !sameList(original, incoming) ? withEnding(canonicalSlice(void 0, [incoming], canonical, incoming.position.start.offset, incoming.position.end.offset, previous, authoredNeighbour(before.children[index + 1], after.children[index + 1], source)), lineEnding) : retainSource(original, incoming, source, canonical, lineEnding, inTable || before.type === "tableCell", before.type === "table" ? before.children[0]?.children?.length : void 0, [after.children[index - 1]?.type === "link", after.children[index + 1]?.type === "link"], [], reorder, after.children[index - 1]?.type === "break");
|
|
45078
45360
|
if (before.type === "tableRow" && movedIndex >= 0 && movedIndex !== index) {
|
|
45079
45361
|
const originalFrom = original.children?.[0]?.position?.start.offset;
|
|
45080
45362
|
const originalTo = original.children?.at(-1)?.position?.end.offset;
|
|
@@ -45082,6 +45364,7 @@ function retainSource(before, after, source, canonical, lineEnding, inTable = fa
|
|
|
45082
45364
|
const to = child.children?.at(-1)?.position?.end.offset;
|
|
45083
45365
|
retainedSource = originalFrom != null && originalTo != null && from != null && to != null ? source.slice(childStart, from) + source.slice(originalFrom, originalTo) + source.slice(to, childEnd) : withEnding(canonical.slice(incoming.position.start.offset, incoming.position.end.offset), lineEnding);
|
|
45084
45366
|
}
|
|
45367
|
+
if (!reorderable && before.ordered && movedIndex >= 0 && movedIndex !== index) retainedSource = renumberItem(retainedSource, source, original, child);
|
|
45085
45368
|
if (marker) retainedSource = relabel(retainedSource, [0], marker);
|
|
45086
45369
|
previous = incoming.type !== "list" ? void 0 : authoredNeighbour(original, incoming, source) ?? {
|
|
45087
45370
|
ordered: incoming.ordered,
|
|
@@ -45098,11 +45381,11 @@ function retainSource(before, after, source, canonical, lineEnding, inTable = fa
|
|
|
45098
45381
|
while (suffix < before.children.length - prefix && suffix < after.children.length - prefix && signature(before.children[before.children.length - 1 - suffix]) === signature(after.children[after.children.length - 1 - suffix])) suffix++;
|
|
45099
45382
|
if (prefix && rewrittenAddress(before.type, before.children, prefix - 1, after.children, prefix - 1, source, canonical)) prefix--;
|
|
45100
45383
|
if (suffix && rewrittenAddress(before.type, before.children, before.children.length - suffix, after.children, after.children.length - suffix, source, canonical)) suffix--;
|
|
45101
|
-
const
|
|
45102
|
-
const first =
|
|
45103
|
-
const last =
|
|
45104
|
-
const newFirst =
|
|
45105
|
-
const newLast =
|
|
45384
|
+
const wrapped = (before.type === "tableCell" || formatting.has(before.type)) && before.children.length > 0 && after.children.length > 0;
|
|
45385
|
+
const first = wrapped ? before.children[0].position?.start.offset : start;
|
|
45386
|
+
const last = wrapped ? before.children.at(-1).position?.end.offset : end;
|
|
45387
|
+
const newFirst = wrapped ? after.children[0].position?.start.offset : newStart;
|
|
45388
|
+
const newLast = wrapped ? after.children.at(-1).position?.end.offset : newEnd;
|
|
45106
45389
|
const ending = (node) => {
|
|
45107
45390
|
const last = node.children?.at(-1);
|
|
45108
45391
|
return last && (node.type === "list" || node.type === "listItem" && last.type === "list") ? ending(last) : node;
|
|
@@ -45117,7 +45400,7 @@ function retainSource(before, after, source, canonical, lineEnding, inTable = fa
|
|
|
45117
45400
|
const changes = after.children.slice(prefix, after.children.length - suffix);
|
|
45118
45401
|
const previous = authoredNeighbour(before.children[prefix - 1], after.children[prefix - 1], source);
|
|
45119
45402
|
const next = authoredNeighbour(before.children[before.children.length - suffix], after.children[after.children.length - suffix], source);
|
|
45120
|
-
return source.slice(start, first) +
|
|
45403
|
+
return source.slice(start, first) + retainBoundaryText(source.slice(first, from) + withEnding((inlineParents.has(before.type) ? retainRun(changed, changes, source, canonical, [from, to], [newFrom, newTo]) : retainParts(marker, [...changed, ...joined], changes, source, canonical, newFrom, newTo, lineEnding, previous, next)) ?? canonicalSlice(marker, changes, canonical, newFrom, newTo, previous, next), lineEnding) + (inlineParents.has(before.type) ? retainBoundaryText(source.slice(to, last), canonical.slice(newTo, newLast), after.children[after.children.length - suffix - 1]?.type === "break") : source.slice(to, last)), canonical.slice(newFirst, newLast)) + source.slice(last, end);
|
|
45121
45404
|
}
|
|
45122
45405
|
}
|
|
45123
45406
|
const lastAfter = after.children?.at(-1)?.position?.end.offset;
|
|
@@ -45213,7 +45496,13 @@ function semanticSignature(doc) {
|
|
|
45213
45496
|
const content = value.content;
|
|
45214
45497
|
if (!content) return value;
|
|
45215
45498
|
const tokens = [];
|
|
45216
|
-
for (const child of content) {
|
|
45499
|
+
for (const [index, child] of content.entries()) {
|
|
45500
|
+
const attrs = child.attrs;
|
|
45501
|
+
const next = content[index + 1];
|
|
45502
|
+
if (child.type === "hardbreak" && attrs?.isInline === false && next?.type === "comment_inline" && next.attrs?.syntax === "html") child.attrs = {
|
|
45503
|
+
...attrs,
|
|
45504
|
+
isHTML: true
|
|
45505
|
+
};
|
|
45217
45506
|
if (child.type !== "text") {
|
|
45218
45507
|
tokens.push(clean(child));
|
|
45219
45508
|
continue;
|
|
@@ -45425,6 +45714,11 @@ function similarity(left, right) {
|
|
|
45425
45714
|
while (suffix < limit - prefix && left[left.length - 1 - suffix] === right[right.length - 1 - suffix]) suffix++;
|
|
45426
45715
|
return prefix + suffix;
|
|
45427
45716
|
}
|
|
45717
|
+
var nothingCarried = {
|
|
45718
|
+
moved: /* @__PURE__ */ new Map(),
|
|
45719
|
+
children: false,
|
|
45720
|
+
within: /* @__PURE__ */ new Set()
|
|
45721
|
+
};
|
|
45428
45722
|
/** Retains the loaded source of blocks the edit leaves alone. */
|
|
45429
45723
|
var Preservation = class Preservation {
|
|
45430
45724
|
ctx;
|
|
@@ -45440,6 +45734,8 @@ var Preservation = class Preservation {
|
|
|
45440
45734
|
itemEdits = /* @__PURE__ */ new WeakMap();
|
|
45441
45735
|
regionEdits = /* @__PURE__ */ new WeakMap();
|
|
45442
45736
|
definitionNodes = /* @__PURE__ */ new Map();
|
|
45737
|
+
moves;
|
|
45738
|
+
origins;
|
|
45443
45739
|
nestedLiterals = /* @__PURE__ */ new Set();
|
|
45444
45740
|
literalsRead = /* @__PURE__ */ new WeakSet();
|
|
45445
45741
|
definitionSources;
|
|
@@ -45505,12 +45801,12 @@ var Preservation = class Preservation {
|
|
|
45505
45801
|
throw new PreservationError("Cannot read Markdown for preservation", { cause });
|
|
45506
45802
|
}
|
|
45507
45803
|
}
|
|
45508
|
-
retainBlock(block, after, canonical, joined = []) {
|
|
45804
|
+
retainBlock(block, after, canonical, joined = [], reorder) {
|
|
45509
45805
|
const offset = this.source.startsWith("") ? 1 : 0;
|
|
45510
45806
|
const start = block.ast.position?.start.offset;
|
|
45511
45807
|
if (start == null) throw new PreservationError("A source block has no location");
|
|
45512
45808
|
this.readNestedLiterals(block);
|
|
45513
|
-
return this.source.slice(block.start, start + offset) + retainSource(block.ast, after, this.source.slice(offset), canonical, this.lineEnding, false, void 0, void 0, joined);
|
|
45809
|
+
return this.source.slice(block.start, start + offset) + retainSource(block.ast, after, this.source.slice(offset), canonical, this.lineEnding, false, void 0, void 0, joined, reorder);
|
|
45514
45810
|
}
|
|
45515
45811
|
readNestedLiterals(block) {
|
|
45516
45812
|
if (!this.nestedLiterals.size || this.literalsRead.has(block)) return;
|
|
@@ -45551,7 +45847,8 @@ var Preservation = class Preservation {
|
|
|
45551
45847
|
for (let index = 0; index <= doc.childCount; index++) {
|
|
45552
45848
|
const node = index < doc.childCount ? doc.child(index) : void 0;
|
|
45553
45849
|
const before = node && this.baseline.child(index);
|
|
45554
|
-
if (
|
|
45850
|
+
if (node && node !== before && this.moves?.has(node)) return void 0;
|
|
45851
|
+
if (!node || node === before || node.eq(before) && !this.carries(node)) {
|
|
45555
45852
|
if (run.length > 1 && !this.pairedInPlace(doc, run)) return void 0;
|
|
45556
45853
|
run = [];
|
|
45557
45854
|
continue;
|
|
@@ -45697,19 +45994,24 @@ var Preservation = class Preservation {
|
|
|
45697
45994
|
if (other !== index && candidate.type === node.type && candidate.childCount === node.childCount && candidate.textContent === node.textContent) return void 0;
|
|
45698
45995
|
}
|
|
45699
45996
|
const marker = authoredMarker(list, source);
|
|
45997
|
+
const reorder = this.moves ? this.carriedChildren(node, index) : void 0;
|
|
45998
|
+
const carried = reorder?.get(parentKey(list));
|
|
45700
45999
|
let output = "";
|
|
45701
46000
|
let previous = block.start;
|
|
45702
46001
|
for (let at = 0; at < node.childCount; at++) {
|
|
45703
46002
|
const item = node.child(at);
|
|
45704
46003
|
const original = before.child(at);
|
|
45705
|
-
if (item === original || item.eq(original)) continue;
|
|
46004
|
+
if (item === original || item.eq(original) && !this.carries(item)) continue;
|
|
46005
|
+
const moved = carried?.get(at);
|
|
46006
|
+
const from = moved !== void 0 && list.children[moved] ? moved : void 0;
|
|
45706
46007
|
let retained = this.itemEdits.get(item);
|
|
45707
|
-
if (retained?.index !== index || retained.item !== at) {
|
|
45708
|
-
const text = this.localItem(node, item, before.child(at), list.children[at], source, marker);
|
|
46008
|
+
if (retained?.index !== index || retained.item !== at || retained.from !== from) {
|
|
46009
|
+
const text = from === void 0 ? this.localItem(node, item, before.child(at), list.children[at], source, marker, reorder) : this.movedItem(node, item, list, list.children[from], list.children[at], source, marker);
|
|
45709
46010
|
if (text === void 0) return void 0;
|
|
45710
46011
|
retained = {
|
|
45711
46012
|
index,
|
|
45712
46013
|
item: at,
|
|
46014
|
+
from,
|
|
45713
46015
|
text
|
|
45714
46016
|
};
|
|
45715
46017
|
this.itemEdits.set(item, retained);
|
|
@@ -45720,18 +46022,17 @@ var Preservation = class Preservation {
|
|
|
45720
46022
|
}
|
|
45721
46023
|
return output + this.source.slice(previous, block.end);
|
|
45722
46024
|
}
|
|
45723
|
-
|
|
45724
|
-
const start =
|
|
45725
|
-
const end =
|
|
45726
|
-
if (!
|
|
45727
|
-
|
|
45728
|
-
|
|
45729
|
-
if (!local || local.node.children.length !== 1 || !after) return void 0;
|
|
45730
|
-
let text = retainSource(ast, {
|
|
45731
|
-
...after,
|
|
45732
|
-
spread: ast.spread
|
|
45733
|
-
}, source, local.canonical, this.lineEnding);
|
|
46025
|
+
movedItem(node, item, list, original, place, source, marker) {
|
|
46026
|
+
const start = original.position.start.offset;
|
|
46027
|
+
const end = original.position.end.offset;
|
|
46028
|
+
if (!Preservation.plainInline(item) || !this.inContext(source.slice(start, end))) return void 0;
|
|
46029
|
+
let text = source.slice(start, end);
|
|
46030
|
+
if (list.ordered) text = renumberItem(text, source, original, place);
|
|
45734
46031
|
if (marker) text = relabel(text, [0], marker);
|
|
46032
|
+
return this.readsAsItem(node, item, text, place, source);
|
|
46033
|
+
}
|
|
46034
|
+
readsAsItem(list, item, text, ast, source) {
|
|
46035
|
+
const start = ast.position.start.offset;
|
|
45735
46036
|
const content = ast.children?.[0]?.position?.start.offset;
|
|
45736
46037
|
if (content == null || !text.startsWith(source.slice(start, content))) return void 0;
|
|
45737
46038
|
if (/^(?:[-*+]|\d{1,9}[.)])[ \t]*(?:\r?\n|$)/.test(text)) return void 0;
|
|
@@ -45744,6 +46045,20 @@ var Preservation = class Preservation {
|
|
|
45744
46045
|
const { label: _l, spread: _s, ...expected } = item.attrs;
|
|
45745
46046
|
return reread.type === item.type && JSON.stringify(attrs) === JSON.stringify(expected) && reread.content.eq(item.content) ? text : void 0;
|
|
45746
46047
|
}
|
|
46048
|
+
localItem(list, item, before, ast, source, marker, reorder) {
|
|
46049
|
+
const start = ast.position.start.offset;
|
|
46050
|
+
const end = ast.position.end.offset;
|
|
46051
|
+
if (!item.sameMarkup(before) || !sameBlocks(item, before) || !Preservation.plainInline(item) || !Preservation.plainInline(before) || !this.inContext(source.slice(start, end))) return void 0;
|
|
46052
|
+
const local = this.canonicalTree(form(write(this.ctx, list.type.schema.topNodeType.create(null, [list.type.create(list.attrs, [item])]))));
|
|
46053
|
+
const after = local?.node.children?.[0];
|
|
46054
|
+
if (!local || local.node.children.length !== 1 || !after) return void 0;
|
|
46055
|
+
let text = retainSource(ast, {
|
|
46056
|
+
...after,
|
|
46057
|
+
spread: ast.spread
|
|
46058
|
+
}, source, local.canonical, this.lineEnding, false, void 0, void 0, [], reorder);
|
|
46059
|
+
if (marker) text = relabel(text, [0], marker);
|
|
46060
|
+
return this.readsAsItem(list, item, text, ast, source);
|
|
46061
|
+
}
|
|
45747
46062
|
separateLists(doc, pieces, kept, positions, current) {
|
|
45748
46063
|
const kind = (index) => {
|
|
45749
46064
|
const name = doc.maybeChild(index)?.type.name;
|
|
@@ -45763,7 +46078,7 @@ var Preservation = class Preservation {
|
|
|
45763
46078
|
return true;
|
|
45764
46079
|
};
|
|
45765
46080
|
const cost = (index) => {
|
|
45766
|
-
if (kept[index] === "canonical") return 1;
|
|
46081
|
+
if (kept[index] === "canonical" || kept[index] === "moved") return 1;
|
|
45767
46082
|
if (kept[index] === "edited") return 10;
|
|
45768
46083
|
const own = marker(index);
|
|
45769
46084
|
const sides = [-1, 1].map((step) => inPlace(index, step));
|
|
@@ -45826,7 +46141,18 @@ var Preservation = class Preservation {
|
|
|
45826
46141
|
const reread = read(relabelled);
|
|
45827
46142
|
return reread.length === 1 && signature(reread[0]) === signature(list) && markerAt(relabelled, list.children[0].position.start.offset)?.marker === marker ? relabelled : void 0;
|
|
45828
46143
|
}
|
|
45829
|
-
|
|
46144
|
+
/** `moved` holds the nodes block moves carried. A moved node that is still a
|
|
46145
|
+
* node of the loaded document keeps that node's source where it reads the
|
|
46146
|
+
* same; every other edit is saved without it. */
|
|
46147
|
+
serialize(doc, moved) {
|
|
46148
|
+
this.moves = moved;
|
|
46149
|
+
try {
|
|
46150
|
+
return this.serializeWith(doc);
|
|
46151
|
+
} finally {
|
|
46152
|
+
this.moves = void 0;
|
|
46153
|
+
}
|
|
46154
|
+
}
|
|
46155
|
+
serializeWith(doc) {
|
|
45830
46156
|
if (this.unchanged(doc)) return this.source;
|
|
45831
46157
|
let local;
|
|
45832
46158
|
try {
|
|
@@ -45848,10 +46174,20 @@ var Preservation = class Preservation {
|
|
|
45848
46174
|
for (let index = 0; index < doc.childCount; index++) {
|
|
45849
46175
|
const node = doc.child(index);
|
|
45850
46176
|
const before = this.baseline.child(index);
|
|
45851
|
-
if (node !== before && !node.eq(before)) return false;
|
|
46177
|
+
if (node !== before && (!node.eq(before) || this.carries(node))) return false;
|
|
45852
46178
|
}
|
|
45853
46179
|
return true;
|
|
45854
46180
|
}
|
|
46181
|
+
carries(node) {
|
|
46182
|
+
const moves = this.moves;
|
|
46183
|
+
if (!moves) return false;
|
|
46184
|
+
let found = moves.has(node);
|
|
46185
|
+
node.descendants((child) => {
|
|
46186
|
+
found ||= moves.has(child);
|
|
46187
|
+
return !found && !child.isTextblock;
|
|
46188
|
+
});
|
|
46189
|
+
return found;
|
|
46190
|
+
}
|
|
45855
46191
|
checked(doc, text) {
|
|
45856
46192
|
if (!crossCheck.enabled) return text;
|
|
45857
46193
|
crossCheck.compared++;
|
|
@@ -45884,7 +46220,7 @@ var Preservation = class Preservation {
|
|
|
45884
46220
|
const previous = positions[index - 1];
|
|
45885
46221
|
return previous != null && position === previous + 1 && block ? this.source.slice(this.blocks[previous].end, block.start) : this.lineEnding.repeat(2);
|
|
45886
46222
|
}
|
|
45887
|
-
build(doc, positions, current, from, to, canonical, tree) {
|
|
46223
|
+
build(doc, positions, current, carried, from, to, canonical, tree) {
|
|
45888
46224
|
const transformed = (index) => tree.transformed.children[index - from];
|
|
45889
46225
|
if (tree) {
|
|
45890
46226
|
const failed = [];
|
|
@@ -45912,12 +46248,13 @@ var Preservation = class Preservation {
|
|
|
45912
46248
|
for (let index = from; index < to; index++) {
|
|
45913
46249
|
const text = current[index];
|
|
45914
46250
|
const position = positions[index];
|
|
45915
|
-
const
|
|
46251
|
+
const moved = carried.moved.get(index);
|
|
46252
|
+
const block = position == null ? moved === void 0 ? void 0 : this.blocks[moved] : this.blocks[position];
|
|
45916
46253
|
gaps.push(this.gap(index, positions));
|
|
45917
|
-
const kind = block && block.form === text ? "unchanged" : block && tree ? "edited" : "canonical";
|
|
46254
|
+
const kind = block && block.form === text && !carried.within.has(index) ? position == null ? "moved" : "unchanged" : block && tree && position != null ? "edited" : "canonical";
|
|
45918
46255
|
kept.push(kind);
|
|
45919
46256
|
const node = tree ? positionalNode(tree.raw, transformed(index)) : void 0;
|
|
45920
|
-
pieces.push(kind === "unchanged" ? this.source.slice(block.start, block.end) : kind === "edited" ? this.retainBlock(block, node, canonical, this.around(positions, index).filter((other) => !paired.has(other) && other.ast.type === block.ast.type).flatMap((other) => other.ast.children ?? [])) : (node && this.retainPart(positions, index, node, canonical, taken)) ?? restoreCodeEndings(this.ctx, doc.type.create(null, [doc.child(index)]), withEnding(text, this.lineEnding)));
|
|
46257
|
+
pieces.push(kind === "unchanged" || kind === "moved" ? this.source.slice(block.start, block.end) : kind === "edited" ? this.retainBlock(block, node, canonical, this.around(positions, index).filter((other) => !paired.has(other) && other.ast.type === block.ast.type).flatMap((other) => other.ast.children ?? []), carried.children ? this.carriedChildren(doc.child(index), position) : void 0) : (node && this.retainPart(positions, index, node, canonical, taken)) ?? restoreCodeEndings(this.ctx, doc.type.create(null, [doc.child(index)]), withEnding(text, this.lineEnding)));
|
|
45921
46258
|
}
|
|
45922
46259
|
return {
|
|
45923
46260
|
gaps,
|
|
@@ -45961,10 +46298,10 @@ var Preservation = class Preservation {
|
|
|
45961
46298
|
extra
|
|
45962
46299
|
};
|
|
45963
46300
|
}
|
|
45964
|
-
runs(positions, current) {
|
|
46301
|
+
runs(positions, current, within = nothingCarried.within) {
|
|
45965
46302
|
const unchanged = (index) => {
|
|
45966
46303
|
const position = positions[index];
|
|
45967
|
-
return position != null && this.blocks[position].form === current[index];
|
|
46304
|
+
return position != null && this.blocks[position].form === current[index] && !within.has(index);
|
|
45968
46305
|
};
|
|
45969
46306
|
const consecutive = (index) => index === 0 ? positions[0] === 0 : positions[index] != null && positions[index - 1] != null && positions[index] === positions[index - 1] + 1;
|
|
45970
46307
|
const runs = [];
|
|
@@ -45994,7 +46331,7 @@ var Preservation = class Preservation {
|
|
|
45994
46331
|
return true;
|
|
45995
46332
|
});
|
|
45996
46333
|
}
|
|
45997
|
-
runPieces(doc, positions, current, run) {
|
|
46334
|
+
runPieces(doc, positions, current, carried, run) {
|
|
45998
46335
|
const from = run.previous === void 0 ? 0 : run.previous + 1;
|
|
45999
46336
|
const to = run.next ?? doc.childCount;
|
|
46000
46337
|
if (from === to) return {
|
|
@@ -46005,26 +46342,27 @@ var Preservation = class Preservation {
|
|
|
46005
46342
|
const nodes = [];
|
|
46006
46343
|
for (let index = from; index < to; index++) nodes.push(doc.child(index));
|
|
46007
46344
|
const { canonical, tree } = from === 0 && to === doc.childCount ? this.canonicalDocument(doc) : this.canonicalBlocks(doc, nodes);
|
|
46008
|
-
return this.build(doc, positions, current, from, to, canonical, tree);
|
|
46345
|
+
return this.build(doc, positions, current, carried, from, to, canonical, tree);
|
|
46009
46346
|
}
|
|
46010
46347
|
regions(doc) {
|
|
46011
46348
|
if (!doc.childCount || this.baseline.childCount !== this.blocks.length || !doc.sameMarkup(this.baseline) || this.definitionSources === void 0) return void 0;
|
|
46012
46349
|
const current = [];
|
|
46013
46350
|
doc.forEach((node) => current.push(this.formOf(node)));
|
|
46014
46351
|
let positions;
|
|
46352
|
+
let carried;
|
|
46015
46353
|
try {
|
|
46016
|
-
positions =
|
|
46354
|
+
({positions, carried} = this.pairing(doc, current));
|
|
46017
46355
|
} catch {
|
|
46018
46356
|
return;
|
|
46019
46357
|
}
|
|
46020
|
-
const runs = this.runs(positions, current);
|
|
46358
|
+
const runs = this.runs(positions, current, carried.within);
|
|
46021
46359
|
if (runs.some((run) => run.previous === void 0 && run.next === void 0) || !this.readAlone(doc, positions, runs)) return void 0;
|
|
46022
46360
|
let output = "";
|
|
46023
46361
|
let at = 0;
|
|
46024
46362
|
for (const run of runs) {
|
|
46025
46363
|
const from = run.previous === void 0 ? 0 : this.blocks[positions[run.previous]].end;
|
|
46026
46364
|
const to = run.next === void 0 ? this.source.length : this.blocks[positions[run.next]].start;
|
|
46027
|
-
const text = this.region(doc, positions, current, run);
|
|
46365
|
+
const text = this.region(doc, positions, current, carried, run);
|
|
46028
46366
|
if (text === void 0) return void 0;
|
|
46029
46367
|
output += this.source.slice(at, from) + text;
|
|
46030
46368
|
at = to;
|
|
@@ -46035,7 +46373,7 @@ var Preservation = class Preservation {
|
|
|
46035
46373
|
if (frontmatter !== sourceFrontmatter(bom(this.source)) || doc.firstChild?.type.name === "hr" && frontmatter?.startsWith("---")) return void 0;
|
|
46036
46374
|
return output;
|
|
46037
46375
|
}
|
|
46038
|
-
region(doc, positions, current, run) {
|
|
46376
|
+
region(doc, positions, current, carried, run) {
|
|
46039
46377
|
const from = run.previous === void 0 ? 0 : run.previous + 1;
|
|
46040
46378
|
const to = run.next ?? doc.childCount;
|
|
46041
46379
|
const nodes = [];
|
|
@@ -46046,7 +46384,7 @@ var Preservation = class Preservation {
|
|
|
46046
46384
|
const identity = [
|
|
46047
46385
|
original(run.previous),
|
|
46048
46386
|
original(run.next),
|
|
46049
|
-
...
|
|
46387
|
+
...Array.from({ length: to - from }, (_, at) => positions[from + at] ?? `m${carried.moved.get(from + at) ?? ""}`)
|
|
46050
46388
|
].join();
|
|
46051
46389
|
const cached = this.regionEdits.get(key);
|
|
46052
46390
|
if (cached && cached.identity === identity && cached.nodes.length === nodes.length + neighbours.length && [...nodes, ...neighbours].every((node, index) => cached.nodes[index] === node)) return cached.text;
|
|
@@ -46055,10 +46393,10 @@ var Preservation = class Preservation {
|
|
|
46055
46393
|
return name === "bullet_list" || name === "ordered_list" ? name : void 0;
|
|
46056
46394
|
};
|
|
46057
46395
|
for (let index = Math.max(1, from); index <= Math.min(to, doc.childCount - 1); index++) if (list(index) && list(index) === list(index - 1)) return void 0;
|
|
46058
|
-
const { gaps, pieces } = this.runPieces(doc, positions, current, run);
|
|
46396
|
+
const { gaps, pieces } = this.runPieces(doc, positions, current, carried, run);
|
|
46059
46397
|
let text = pieces.map((piece, index) => gaps[index] + piece).join("");
|
|
46060
46398
|
if (run.next !== void 0) text += this.gap(run.next, positions);
|
|
46061
|
-
else text +=
|
|
46399
|
+
else text += this.endsAsAuthored(positions, carried) ? this.source.slice(this.blocks.at(-1).end) : finalCodeEnding(doc) ?? this.lineEnding;
|
|
46062
46400
|
const slice = (index) => {
|
|
46063
46401
|
if (index === void 0) return "";
|
|
46064
46402
|
const block = this.blocks[positions[index]];
|
|
@@ -46118,26 +46456,21 @@ var Preservation = class Preservation {
|
|
|
46118
46456
|
if (canonical === "") return this.source.startsWith("") ? "" : "";
|
|
46119
46457
|
const current = [];
|
|
46120
46458
|
doc.forEach((node) => current.push(this.formOf(node)));
|
|
46121
|
-
const
|
|
46122
|
-
const
|
|
46123
|
-
|
|
46124
|
-
|
|
46125
|
-
|
|
46126
|
-
|
|
46127
|
-
|
|
46128
|
-
|
|
46129
|
-
|
|
46130
|
-
|
|
46131
|
-
kept[from + index] = written.kept[index];
|
|
46132
|
-
});
|
|
46459
|
+
const pairing = this.pairing(doc, current);
|
|
46460
|
+
const carries = pairing.carried.moved.size > 0 || pairing.carried.children;
|
|
46461
|
+
if (carries) {
|
|
46462
|
+
let output;
|
|
46463
|
+
try {
|
|
46464
|
+
output = this.writeDocument(doc, current, pairing);
|
|
46465
|
+
} catch {
|
|
46466
|
+
output = void 0;
|
|
46467
|
+
}
|
|
46468
|
+
if (output !== void 0 && this.reopens(doc, output, canonical)) return output;
|
|
46133
46469
|
}
|
|
46134
|
-
const
|
|
46135
|
-
|
|
46136
|
-
|
|
46137
|
-
|
|
46138
|
-
else if (output) output += finalCodeEnding(doc) ?? this.lineEnding;
|
|
46139
|
-
const bom = output.startsWith("") ? 1 : 0;
|
|
46140
|
-
if (doc.firstChild?.type.name === "hr" && sourceFrontmatter(output.slice(bom))?.startsWith("---")) output = output.slice(0, bom) + "***" + output.slice(bom + 3);
|
|
46470
|
+
const output = this.writeDocument(doc, current, carries ? {
|
|
46471
|
+
positions: correspondence(this.blockForms, current),
|
|
46472
|
+
carried: nothingCarried
|
|
46473
|
+
} : pairing);
|
|
46141
46474
|
if (this.reopens(doc, output, canonical)) return output;
|
|
46142
46475
|
throw new PreservationError("The edited Markdown cannot be reopened without changing its content");
|
|
46143
46476
|
} catch (cause) {
|
|
@@ -46145,6 +46478,157 @@ var Preservation = class Preservation {
|
|
|
46145
46478
|
throw new PreservationError("Cannot preserve the edited Markdown", { cause });
|
|
46146
46479
|
}
|
|
46147
46480
|
}
|
|
46481
|
+
writeDocument(doc, current, { positions, carried }) {
|
|
46482
|
+
const gaps = current.map((_, index) => this.gap(index, positions));
|
|
46483
|
+
const pieces = positions.map((position) => position == null ? "" : this.source.slice(this.blocks[position].start, this.blocks[position].end));
|
|
46484
|
+
const kept = current.map(() => "unchanged");
|
|
46485
|
+
const runs = this.runs(positions, current, carried.within);
|
|
46486
|
+
for (const run of this.readAlone(doc, positions, runs) ? runs : [{}]) {
|
|
46487
|
+
const from = run.previous === void 0 ? 0 : run.previous + 1;
|
|
46488
|
+
const written = this.runPieces(doc, positions, current, carried, run);
|
|
46489
|
+
written.pieces.forEach((piece, index) => {
|
|
46490
|
+
pieces[from + index] = piece;
|
|
46491
|
+
kept[from + index] = written.kept[index];
|
|
46492
|
+
});
|
|
46493
|
+
}
|
|
46494
|
+
positions.at(-1);
|
|
46495
|
+
this.separateLists(doc, pieces, kept, positions, current);
|
|
46496
|
+
let output = pieces.map((piece, index) => gaps[index] + piece).join("");
|
|
46497
|
+
if (this.endsAsAuthored(positions, carried)) output += this.source.slice(this.blocks.at(-1).end);
|
|
46498
|
+
else if (output) output += finalCodeEnding(doc) ?? this.lineEnding;
|
|
46499
|
+
const bom = output.startsWith("") ? 1 : 0;
|
|
46500
|
+
if (doc.firstChild?.type.name === "hr" && sourceFrontmatter(output.slice(bom))?.startsWith("---")) output = output.slice(0, bom) + "***" + output.slice(bom + 3);
|
|
46501
|
+
return output;
|
|
46502
|
+
}
|
|
46503
|
+
originIndex() {
|
|
46504
|
+
if (this.origins) return this.origins;
|
|
46505
|
+
const origins = /* @__PURE__ */ new WeakMap();
|
|
46506
|
+
const visit = (node, path) => node.forEach((child, _, index) => {
|
|
46507
|
+
const at = [...path, index];
|
|
46508
|
+
origins.set(child, at);
|
|
46509
|
+
if (!child.isTextblock && !child.isLeaf && child.type.name !== "table") visit(child, at);
|
|
46510
|
+
});
|
|
46511
|
+
visit(this.baseline, []);
|
|
46512
|
+
return this.origins = origins;
|
|
46513
|
+
}
|
|
46514
|
+
pairing(doc, current) {
|
|
46515
|
+
const moves = this.moves;
|
|
46516
|
+
if (!moves || this.baseline.childCount !== this.blocks.length) return {
|
|
46517
|
+
positions: correspondence(this.blockForms, current),
|
|
46518
|
+
carried: nothingCarried
|
|
46519
|
+
};
|
|
46520
|
+
const origins = this.originIndex();
|
|
46521
|
+
const pinned = /* @__PURE__ */ new Map();
|
|
46522
|
+
doc.forEach((node, _, index) => {
|
|
46523
|
+
if (moves.has(node)) {
|
|
46524
|
+
const origin = origins.get(node);
|
|
46525
|
+
if (origin?.length === 1) pinned.set(index, origin[0]);
|
|
46526
|
+
}
|
|
46527
|
+
});
|
|
46528
|
+
if (!pinned.size) {
|
|
46529
|
+
const positions = correspondence(this.blockForms, current);
|
|
46530
|
+
return {
|
|
46531
|
+
positions,
|
|
46532
|
+
carried: {
|
|
46533
|
+
moved: pinned,
|
|
46534
|
+
children: true,
|
|
46535
|
+
within: this.within(doc, positions, current)
|
|
46536
|
+
}
|
|
46537
|
+
};
|
|
46538
|
+
}
|
|
46539
|
+
const taken = new Set(pinned.values());
|
|
46540
|
+
const before = this.blocks.flatMap((_, index) => taken.has(index) ? [] : [index]);
|
|
46541
|
+
const after = current.flatMap((_, index) => pinned.has(index) ? [] : [index]);
|
|
46542
|
+
const present = /* @__PURE__ */ new Map();
|
|
46543
|
+
for (const index of after) {
|
|
46544
|
+
const origin = origins.get(doc.child(index));
|
|
46545
|
+
if (origin?.length === 1) present.set(index, origin[0]);
|
|
46546
|
+
}
|
|
46547
|
+
const kept = new Set(present.values());
|
|
46548
|
+
const matched = correspondence(before.map((index) => kept.has(index) ? `${this.blockForms[index]}\u0000${index}` : this.blockForms[index]), after.map((index) => present.has(index) ? `${current[index]}\u0000${present.get(index)}` : current[index]));
|
|
46549
|
+
const positions = new Array(current.length);
|
|
46550
|
+
after.forEach((index, at) => {
|
|
46551
|
+
const match = matched[at];
|
|
46552
|
+
if (match !== void 0) positions[index] = before[match];
|
|
46553
|
+
});
|
|
46554
|
+
const next = new Array(current.length);
|
|
46555
|
+
let following = this.blocks.length;
|
|
46556
|
+
for (let index = current.length - 1; index >= 0; index--) {
|
|
46557
|
+
next[index] = following;
|
|
46558
|
+
if (positions[index] !== void 0) following = positions[index];
|
|
46559
|
+
}
|
|
46560
|
+
const own = (index) => {
|
|
46561
|
+
const origin = origins.get(doc.child(index));
|
|
46562
|
+
return origin?.length === 1 ? origin[0] : void 0;
|
|
46563
|
+
};
|
|
46564
|
+
const above = new Array(current.length);
|
|
46565
|
+
let upper = this.blocks.length;
|
|
46566
|
+
for (let index = current.length - 1; index >= 0; index--) {
|
|
46567
|
+
above[index] = upper;
|
|
46568
|
+
upper = own(index) ?? upper;
|
|
46569
|
+
}
|
|
46570
|
+
const moved = /* @__PURE__ */ new Map();
|
|
46571
|
+
let last = -1;
|
|
46572
|
+
let lower = -1;
|
|
46573
|
+
for (let index = 0; index < current.length; index++) {
|
|
46574
|
+
const origin = pinned.get(index);
|
|
46575
|
+
const inOrder = origin > lower && origin < above[index];
|
|
46576
|
+
lower = own(index) ?? lower;
|
|
46577
|
+
if (origin === void 0) {
|
|
46578
|
+
if (positions[index] !== void 0) last = positions[index];
|
|
46579
|
+
} else if (origin > last && origin < next[index] && inOrder) {
|
|
46580
|
+
positions[index] = origin;
|
|
46581
|
+
last = origin;
|
|
46582
|
+
} else moved.set(index, origin);
|
|
46583
|
+
}
|
|
46584
|
+
return {
|
|
46585
|
+
positions,
|
|
46586
|
+
carried: {
|
|
46587
|
+
moved,
|
|
46588
|
+
children: true,
|
|
46589
|
+
within: this.within(doc, positions, current)
|
|
46590
|
+
}
|
|
46591
|
+
};
|
|
46592
|
+
}
|
|
46593
|
+
endsAsAuthored(positions, carried) {
|
|
46594
|
+
const end = this.blocks.length - 1;
|
|
46595
|
+
if (end < 0) return false;
|
|
46596
|
+
if (positions.at(-1) === end) return true;
|
|
46597
|
+
return carried.moved.has(positions.length - 1) && [...carried.moved.values()].includes(end);
|
|
46598
|
+
}
|
|
46599
|
+
within(doc, positions, current) {
|
|
46600
|
+
const within = /* @__PURE__ */ new Set();
|
|
46601
|
+
positions.forEach((position, index) => {
|
|
46602
|
+
const node = doc.child(index);
|
|
46603
|
+
if (position !== void 0 && this.blocks[position].form === current[index] && node !== this.baseline.child(position) && this.carries(node)) within.add(index);
|
|
46604
|
+
});
|
|
46605
|
+
return within;
|
|
46606
|
+
}
|
|
46607
|
+
carriedChildren(node, original) {
|
|
46608
|
+
const moves = this.moves;
|
|
46609
|
+
if (!moves || this.baseline.childCount !== this.blocks.length) return;
|
|
46610
|
+
const origins = this.originIndex();
|
|
46611
|
+
let reorder;
|
|
46612
|
+
const walk = (current, path, ast) => {
|
|
46613
|
+
if (!ast?.children || ast.position?.start.offset == null) return;
|
|
46614
|
+
current.forEach((child, _, index) => {
|
|
46615
|
+
let from = index;
|
|
46616
|
+
const origin = moves.has(child) ? origins.get(child) : void 0;
|
|
46617
|
+
if (origin?.length === path.length + 1 && origin.every((step, at) => at === path.length || step === path[at])) {
|
|
46618
|
+
from = origin.at(-1);
|
|
46619
|
+
if (from !== index) {
|
|
46620
|
+
reorder ??= /* @__PURE__ */ new Map();
|
|
46621
|
+
const key = parentKey(ast);
|
|
46622
|
+
if (!reorder.has(key)) reorder.set(key, /* @__PURE__ */ new Map());
|
|
46623
|
+
reorder.get(key).set(index, from);
|
|
46624
|
+
}
|
|
46625
|
+
}
|
|
46626
|
+
if (!child.isTextblock && !child.isLeaf && child.type.name !== "table") walk(child, [...path, from], ast.children[from]);
|
|
46627
|
+
});
|
|
46628
|
+
};
|
|
46629
|
+
walk(node, [original], this.blocks[original].ast);
|
|
46630
|
+
return reorder;
|
|
46631
|
+
}
|
|
46148
46632
|
};
|
|
46149
46633
|
//#endregion
|
|
46150
46634
|
//#region src/autolink.ts
|
|
@@ -46194,14 +46678,8 @@ function read(ctx, sources, texts) {
|
|
|
46194
46678
|
function literals(ctx, texts) {
|
|
46195
46679
|
const possible = texts.map((text) => /www\.|https?:\/\/|@/i.test(text));
|
|
46196
46680
|
const candidates = texts.filter((_, index) => possible[index]);
|
|
46197
|
-
const
|
|
46198
|
-
|
|
46199
|
-
const changed = candidates.flatMap((text, index) => escaped[index] === text ? [] : [index]);
|
|
46200
|
-
const written = read(ctx, changed.map((index) => escaped[index]), changed.map((index) => candidates[index]));
|
|
46201
|
-
changed.forEach((index, at) => {
|
|
46202
|
-
if (JSON.stringify(written[at]) !== JSON.stringify(raw[index])) raw[index] = void 0;
|
|
46203
|
-
});
|
|
46204
|
-
return texts.map((_, index) => possible[index] ? raw.shift() : []);
|
|
46681
|
+
const found = read(ctx, candidates.map((text) => text.replace(/[\\`[\]<>]/g, "\\$&")), candidates);
|
|
46682
|
+
return texts.map((_, index) => possible[index] ? found.shift() : []);
|
|
46205
46683
|
}
|
|
46206
46684
|
function angleHref(text) {
|
|
46207
46685
|
if (/^[a-zA-Z][a-zA-Z0-9+.-]{1,31}:[^\s<>\u0000-\u001f]*$/.test(text)) return text;
|
|
@@ -46233,7 +46711,7 @@ function wantedLinks(ctx, chars, from, to) {
|
|
|
46233
46711
|
}
|
|
46234
46712
|
const free = (index) => {
|
|
46235
46713
|
const char = chars[index];
|
|
46236
|
-
return char !== void 0 && (released.has(index) || char.form !== "angle" && !(char.link && !char.form));
|
|
46714
|
+
return char !== void 0 && !char.marks.some((mark) => mark.type.spec.code) && (released.has(index) || char.form !== "angle" && !(char.link && !char.form));
|
|
46237
46715
|
};
|
|
46238
46716
|
const spans = [];
|
|
46239
46717
|
for (let index = 0; index < chars.length;) {
|
|
@@ -46403,9 +46881,96 @@ var autolinkLiterals = $prose((ctx) => new Plugin({
|
|
|
46403
46881
|
}
|
|
46404
46882
|
}));
|
|
46405
46883
|
//#endregion
|
|
46884
|
+
//#region src/inline-code.ts
|
|
46885
|
+
var held = new PluginKey("storedInlineCode");
|
|
46886
|
+
function finish(state, pending, code) {
|
|
46887
|
+
const { selection } = state;
|
|
46888
|
+
if (state.storedMarks || !selection.empty || selection.from !== pending.to) return null;
|
|
46889
|
+
const tr = state.tr;
|
|
46890
|
+
if (pending.from < pending.to) tr.addMark(pending.from, pending.to, code.create());
|
|
46891
|
+
return tr.setStoredMarks(pending.marks);
|
|
46892
|
+
}
|
|
46893
|
+
var storedInlineCode = $prose((ctx) => {
|
|
46894
|
+
const type = () => inlineCodeSchema.type(ctx);
|
|
46895
|
+
let composing;
|
|
46896
|
+
return new Plugin({
|
|
46897
|
+
key: held,
|
|
46898
|
+
state: {
|
|
46899
|
+
init: () => null,
|
|
46900
|
+
apply(tr, value, old) {
|
|
46901
|
+
const id = tr.getMeta("composition");
|
|
46902
|
+
if (id === void 0) return tr.docChanged || tr.selectionSet || tr.storedMarksSet ? null : value;
|
|
46903
|
+
const marks = old.storedMarks;
|
|
46904
|
+
const start = value?.id === id ? value : marks && type().isInSet(marks) ? {
|
|
46905
|
+
marks,
|
|
46906
|
+
id,
|
|
46907
|
+
from: old.selection.from,
|
|
46908
|
+
to: 0
|
|
46909
|
+
} : null;
|
|
46910
|
+
if (!start) return null;
|
|
46911
|
+
let to = value?.id === id ? tr.mapping.map(start.to, 1) : start.from;
|
|
46912
|
+
tr.mapping.maps.forEach((map, index) => map.forEach((_from, _to, _start, end) => {
|
|
46913
|
+
to = Math.max(to, tr.mapping.slice(index + 1).map(end, 1));
|
|
46914
|
+
}));
|
|
46915
|
+
return {
|
|
46916
|
+
...start,
|
|
46917
|
+
to
|
|
46918
|
+
};
|
|
46919
|
+
}
|
|
46920
|
+
},
|
|
46921
|
+
view: (view) => {
|
|
46922
|
+
composing = view;
|
|
46923
|
+
return { destroy() {
|
|
46924
|
+
composing = void 0;
|
|
46925
|
+
} };
|
|
46926
|
+
},
|
|
46927
|
+
props: { handleDOMEvents: { compositionend(view) {
|
|
46928
|
+
Promise.resolve().then(() => void 0).then(() => {
|
|
46929
|
+
if (view.isDestroyed || view.composing) return;
|
|
46930
|
+
const pending = held.getState(view.state);
|
|
46931
|
+
const tr = pending && finish(view.state, pending, type());
|
|
46932
|
+
if (tr) view.dispatch(tr.setMeta("appendedTransaction", tr));
|
|
46933
|
+
});
|
|
46934
|
+
return false;
|
|
46935
|
+
} } },
|
|
46936
|
+
appendTransaction(transactions, oldState, newState) {
|
|
46937
|
+
const code = type();
|
|
46938
|
+
const stored = oldState.storedMarks;
|
|
46939
|
+
if (!stored || !code.isInSet(stored) || composing?.composing || transactions.some((tr) => tr.getMeta("composition"))) return null;
|
|
46940
|
+
const { $from } = newState.selection;
|
|
46941
|
+
if ($from.start() !== oldState.selection.$from.start()) return newState.storedMarks && code.isInSet(newState.storedMarks) ? newState.tr.setStoredMarks(code.removeFromSet(newState.storedMarks)) : null;
|
|
46942
|
+
const before = $from.nodeBefore;
|
|
46943
|
+
if (newState.storedMarks || !transactions.some((tr) => tr.docChanged) || !newState.selection.empty || !before?.isText || !code.isInSet(before.marks)) return null;
|
|
46944
|
+
return newState.tr.setStoredMarks(stored);
|
|
46945
|
+
}
|
|
46946
|
+
});
|
|
46947
|
+
});
|
|
46948
|
+
//#endregion
|
|
46406
46949
|
//#region src/source.ts
|
|
46407
46950
|
var sourceAttribute = "inkkitSource";
|
|
46951
|
+
var completedLines = /* @__PURE__ */ new WeakMap();
|
|
46952
|
+
function completedSource(node) {
|
|
46953
|
+
const cached = completedLines.get(node);
|
|
46954
|
+
if (cached) return cached;
|
|
46955
|
+
let result = node;
|
|
46956
|
+
if (node.type.name === "paragraph" || node.type.name === "heading" && node.attrs.form === "setext") {
|
|
46957
|
+
let end = node.content.size;
|
|
46958
|
+
for (let index = node.childCount - 1; index >= 0; index--) {
|
|
46959
|
+
const child = node.child(index);
|
|
46960
|
+
if (child.type.name !== "hardbreak" || child.attrs.isInline || child.attrs.isHTML) break;
|
|
46961
|
+
end -= child.nodeSize;
|
|
46962
|
+
}
|
|
46963
|
+
if (end !== node.content.size) result = node.copy(node.content.cut(0, end));
|
|
46964
|
+
} else if (!node.isLeaf && !node.isTextblock) {
|
|
46965
|
+
const children = [];
|
|
46966
|
+
node.forEach((child) => children.push(completedSource(child)));
|
|
46967
|
+
if (children.some((child, index) => child !== node.child(index))) result = node.copy(Fragment.fromArray(children));
|
|
46968
|
+
}
|
|
46969
|
+
completedLines.set(node, result);
|
|
46970
|
+
return result;
|
|
46971
|
+
}
|
|
46408
46972
|
function cleanSourceDoc(doc) {
|
|
46973
|
+
doc = completedSource(doc);
|
|
46409
46974
|
return doc.attrs["inkkitSource"] == null ? doc : doc.type.create({
|
|
46410
46975
|
...doc.attrs,
|
|
46411
46976
|
[sourceAttribute]: null
|
|
@@ -48548,6 +49113,7 @@ function writesBare(node, index, ancestors) {
|
|
|
48548
49113
|
const follows = (parent, text) => {
|
|
48549
49114
|
if (text.type !== "text") return false;
|
|
48550
49115
|
const run = /^\S*/.exec(text.value)[0];
|
|
49116
|
+
if (!node.url.startsWith("mailto:") && blocks$2.has(parent.type) && parent.children.at(-1) === text && /^[ \t]+$/.test(text.value.slice(run.length))) return false;
|
|
48551
49117
|
return trailing.test(run) && (run.length < text.value.length || blocks$2.has(parent.type) && parent.children.at(-1) === text);
|
|
48552
49118
|
};
|
|
48553
49119
|
const side = (step) => {
|
|
@@ -48707,6 +49273,10 @@ function remarkDialect() {
|
|
|
48707
49273
|
]
|
|
48708
49274
|
}],
|
|
48709
49275
|
handlers: {
|
|
49276
|
+
break(node, parent, state, info) {
|
|
49277
|
+
const next = parent?.children[parent.children.indexOf(node) + 1];
|
|
49278
|
+
return next?.type === "inkkitCommentInline" && next.syntax === "html" ? "<br />" : handle.break(node, parent, state, info);
|
|
49279
|
+
},
|
|
48710
49280
|
text(node, parent, state, info) {
|
|
48711
49281
|
const value = handle.text(node, parent, state, info);
|
|
48712
49282
|
if (!state.stack.includes("tableCell") || parent?.type !== "paragraph" && parent?.type !== "tableCell") return value;
|
|
@@ -48738,12 +49308,11 @@ function padShortRows(node) {
|
|
|
48738
49308
|
if ("children" in node) node.children.forEach(padShortRows);
|
|
48739
49309
|
}
|
|
48740
49310
|
var remarkDialectPlugin = $remark("remarkDialect", () => remarkDialect);
|
|
48741
|
-
var commonmarkWithLiteralReferences = commonmark.filter((plugin) => !remarkInlineLinkPlugin.includes(plugin) && plugin !== hardbreakClearMarkPlugin && plugin !== syncHeadingIdPlugin && plugin !== createCodeBlockInputRule);
|
|
49311
|
+
var commonmarkWithLiteralReferences = commonmark.filter((plugin) => !remarkInlineLinkPlugin.includes(plugin) && plugin !== hardbreakClearMarkPlugin && !hardbreakKeymap.some((part) => part === plugin) && plugin !== syncHeadingIdPlugin && plugin !== createCodeBlockInputRule);
|
|
48742
49312
|
var breaksWithoutMarks = $prose((ctx) => new Plugin({
|
|
48743
49313
|
key: new PluginKey("inkkitBreaksWithoutMarks"),
|
|
48744
49314
|
appendTransaction(transactions, oldState, newState) {
|
|
48745
49315
|
if (!transactions.some((tr) => tr.docChanged)) return null;
|
|
48746
|
-
const inserted = transactions.some((tr) => tr.getMeta("hardbreak"));
|
|
48747
49316
|
const start = oldState.doc.content.findDiffStart(newState.doc.content);
|
|
48748
49317
|
if (start == null) return null;
|
|
48749
49318
|
const end = oldState.doc.content.findDiffEnd(newState.doc.content).b;
|
|
@@ -48751,7 +49320,7 @@ var breaksWithoutMarks = $prose((ctx) => new Plugin({
|
|
|
48751
49320
|
const tr = newState.tr;
|
|
48752
49321
|
newState.doc.nodesBetween(start, Math.max(start, end), (node, pos) => {
|
|
48753
49322
|
if (node.type !== type) return;
|
|
48754
|
-
for (const mark of node.marks) if (
|
|
49323
|
+
for (const mark of node.marks) if (mark.type.spec.code) tr.removeMark(pos, pos + 1, mark.type);
|
|
48755
49324
|
});
|
|
48756
49325
|
return tr.steps.length ? tr : null;
|
|
48757
49326
|
}
|
|
@@ -48785,6 +49354,36 @@ var preserveSpacerParagraphs = paragraphSchema.extendSchema((base) => (ctx) => {
|
|
|
48785
49354
|
}
|
|
48786
49355
|
};
|
|
48787
49356
|
});
|
|
49357
|
+
var headingsWithBreaks = headingSchema.extendSchema((base) => (ctx) => {
|
|
49358
|
+
const schema = base(ctx);
|
|
49359
|
+
return {
|
|
49360
|
+
...schema,
|
|
49361
|
+
attrs: {
|
|
49362
|
+
...schema.attrs,
|
|
49363
|
+
form: { default: "atx" }
|
|
49364
|
+
},
|
|
49365
|
+
parseMarkdown: {
|
|
49366
|
+
...schema.parseMarkdown,
|
|
49367
|
+
runner(state, node, type) {
|
|
49368
|
+
const position = node.position;
|
|
49369
|
+
state.openNode(type, {
|
|
49370
|
+
level: node.depth,
|
|
49371
|
+
form: position && position.end.line > position.start.line ? "setext" : "atx"
|
|
49372
|
+
});
|
|
49373
|
+
state.next(node.children);
|
|
49374
|
+
state.closeNode();
|
|
49375
|
+
}
|
|
49376
|
+
},
|
|
49377
|
+
toMarkdown: {
|
|
49378
|
+
...schema.toMarkdown,
|
|
49379
|
+
runner(state, node) {
|
|
49380
|
+
state.openNode("heading", void 0, { depth: node.attrs.level });
|
|
49381
|
+
state.next(node.content);
|
|
49382
|
+
state.closeNode();
|
|
49383
|
+
}
|
|
49384
|
+
}
|
|
49385
|
+
};
|
|
49386
|
+
});
|
|
48788
49387
|
var visibleSoftbreaks = hardbreakSchema.extendSchema((base) => (ctx) => {
|
|
48789
49388
|
const schema = base(ctx);
|
|
48790
49389
|
return {
|
|
@@ -48881,10 +49480,14 @@ function cellToMarkdown(base) {
|
|
|
48881
49480
|
}
|
|
48882
49481
|
};
|
|
48883
49482
|
}
|
|
48884
|
-
var
|
|
49483
|
+
var breakKeymap = $prose(() => keymap$3({ "Shift-Enter": (state, dispatch, view) => {
|
|
48885
49484
|
const { $from } = state.selection;
|
|
48886
|
-
if (
|
|
48887
|
-
|
|
49485
|
+
if (!(state.selection instanceof TextSelection) || $from.parent.type.spec.code) return false;
|
|
49486
|
+
const isHTML = htmlBreakAt($from);
|
|
49487
|
+
if (dispatch) {
|
|
49488
|
+
dispatch(closeHistory(state.tr).replaceSelectionWith(state.schema.nodes.hardbreak.create({ isHTML }), false).scrollIntoView());
|
|
49489
|
+
if (view) dispatch(closeHistory(view.state.tr).setMeta("addToHistory", false));
|
|
49490
|
+
}
|
|
48888
49491
|
return true;
|
|
48889
49492
|
} }));
|
|
48890
49493
|
var listItems = extendListItemSchemaForTask.extendSchema((previous) => (ctx) => {
|
|
@@ -48970,7 +49573,7 @@ var tables = [
|
|
|
48970
49573
|
].flat();
|
|
48971
49574
|
function createDialect(images, wikiLinks = false, files = false) {
|
|
48972
49575
|
return [
|
|
48973
|
-
|
|
49576
|
+
breakKeymap,
|
|
48974
49577
|
remarkCodeFences,
|
|
48975
49578
|
remarkReferencesPlugin,
|
|
48976
49579
|
remarkLinkFormsPlugin,
|
|
@@ -48998,9 +49601,11 @@ function createDialect(images, wikiLinks = false, files = false) {
|
|
|
48998
49601
|
joinKeepingSourceKeymap,
|
|
48999
49602
|
preserveSpacerParagraphs,
|
|
49000
49603
|
visibleSoftbreaks,
|
|
49604
|
+
headingsWithBreaks,
|
|
49001
49605
|
normalizedImages,
|
|
49002
49606
|
imageBlocks,
|
|
49003
49607
|
autolinkLiterals,
|
|
49608
|
+
storedInlineCode,
|
|
49004
49609
|
breaksWithoutMarks,
|
|
49005
49610
|
listItems,
|
|
49006
49611
|
strikethroughAttr,
|
|
@@ -49009,6 +49614,7 @@ function createDialect(images, wikiLinks = false, files = false) {
|
|
|
49009
49614
|
strikethroughKeymap,
|
|
49010
49615
|
toggleStrikethroughCommand,
|
|
49011
49616
|
wrapInTaskListInputRule,
|
|
49617
|
+
smartPunctuation,
|
|
49012
49618
|
remarkDialectPlugin,
|
|
49013
49619
|
tables,
|
|
49014
49620
|
literalBlock,
|
|
@@ -49289,7 +49895,7 @@ function selectionContent(doc, content) {
|
|
|
49289
49895
|
return content.append(Fragment.fromArray(extra));
|
|
49290
49896
|
}
|
|
49291
49897
|
function selectionMarkdown(ctx, doc, content) {
|
|
49292
|
-
return serialize(ctx, doc.type.create(null, selectionContent(doc, content)));
|
|
49898
|
+
return serialize(ctx, cleanSourceDoc(doc.type.create(null, selectionContent(doc, content))));
|
|
49293
49899
|
}
|
|
49294
49900
|
function referenceMetadata(ctx, doc, content) {
|
|
49295
49901
|
doc = doc.copy(shareableFragment(doc.content));
|
|
@@ -49883,9 +50489,116 @@ function tableAvailability(ctx) {
|
|
|
49883
50489
|
available.sortRows = [...body].sort((a, b) => compareCells(a.key, b.key, "text", "ascending") || a.index - b.index).some((row, index) => row !== body[index]);
|
|
49884
50490
|
return available;
|
|
49885
50491
|
}
|
|
50492
|
+
/** Trims the whitespace at both ends of a cell's inline content. */
|
|
50493
|
+
function trimCell(nodes) {
|
|
50494
|
+
const trimmed = [...nodes];
|
|
50495
|
+
for (const [edge, trim] of [[0, (text) => text.trimStart()], [-1, (text) => text.trimEnd()]]) for (;;) {
|
|
50496
|
+
const node = trimmed.at(edge);
|
|
50497
|
+
if (!node?.text) break;
|
|
50498
|
+
const text = trim(node.text);
|
|
50499
|
+
if (text) {
|
|
50500
|
+
trimmed.splice(edge < 0 ? trimmed.length - 1 : 0, 1, node.type.schema.text(text, node.marks));
|
|
50501
|
+
break;
|
|
50502
|
+
}
|
|
50503
|
+
trimmed.splice(edge < 0 ? trimmed.length - 1 : 0, 1);
|
|
50504
|
+
}
|
|
50505
|
+
return trimmed;
|
|
50506
|
+
}
|
|
50507
|
+
/**
|
|
50508
|
+
* The cells of a paragraph that is one table row typed as Markdown, such as `| Name | Date |`: it
|
|
50509
|
+
* starts and ends with a pipe and holds at least two cells. A pipe written `\|` or inside inline
|
|
50510
|
+
* code belongs to its cell. Returns nothing for any other paragraph, including one with a line
|
|
50511
|
+
* break or an inline node, which a cell could not hold the same way.
|
|
50512
|
+
*/
|
|
50513
|
+
function typedRowCells(paragraph) {
|
|
50514
|
+
const rows = [[]];
|
|
50515
|
+
for (let index = 0; index < paragraph.childCount; index++) {
|
|
50516
|
+
const child = paragraph.child(index);
|
|
50517
|
+
if (!child.isText || /[\r\n]/.test(child.text)) return void 0;
|
|
50518
|
+
if (child.marks.some((mark) => mark.type.spec.code)) {
|
|
50519
|
+
rows.at(-1).push(child);
|
|
50520
|
+
continue;
|
|
50521
|
+
}
|
|
50522
|
+
let piece = "", slashes = 0;
|
|
50523
|
+
const flush = () => {
|
|
50524
|
+
if (piece) rows.at(-1).push(child.type.schema.text(piece, child.marks));
|
|
50525
|
+
piece = "";
|
|
50526
|
+
};
|
|
50527
|
+
for (const character of child.text) if (character !== "|") {
|
|
50528
|
+
slashes = character === "\\" ? slashes + 1 : 0;
|
|
50529
|
+
piece += character;
|
|
50530
|
+
} else if (slashes % 2) {
|
|
50531
|
+
piece = piece.slice(0, -1) + character;
|
|
50532
|
+
slashes = 0;
|
|
50533
|
+
} else {
|
|
50534
|
+
flush();
|
|
50535
|
+
rows.push([]);
|
|
50536
|
+
slashes = 0;
|
|
50537
|
+
}
|
|
50538
|
+
flush();
|
|
50539
|
+
}
|
|
50540
|
+
const blank = (cell) => cell.every((node) => node.isText && !node.text.trim());
|
|
50541
|
+
if (rows.length < 4 || !blank(rows[0]) || !blank(rows.at(-1))) return void 0;
|
|
50542
|
+
const cells = rows.slice(1, -1);
|
|
50543
|
+
return cells.length <= 100 ? cells.map(trimCell) : void 0;
|
|
50544
|
+
}
|
|
50545
|
+
/**
|
|
50546
|
+
* Turns the paragraph holding the caret at its end into a table when it is a typed table row: the
|
|
50547
|
+
* typed cells are the header, one empty row follows, and the caret is in its first cell. It builds
|
|
50548
|
+
* the table `table('insert')` does and replaces the paragraph in one undo step of its own, so Undo
|
|
50549
|
+
* restores the typed line with the caret at its end.
|
|
50550
|
+
*/
|
|
50551
|
+
function typedRowToTable(ctx) {
|
|
50552
|
+
return (state, dispatch) => {
|
|
50553
|
+
const view = ctx.get(editorViewCtx);
|
|
50554
|
+
const { $cursor } = state.selection;
|
|
50555
|
+
if (!$cursor || !view.editable || view.composing || $cursor.parent.type.name !== "paragraph" || $cursor.parentOffset !== $cursor.parent.content.size || $cursor.depth < 1) return false;
|
|
50556
|
+
const cells = typedRowCells($cursor.parent);
|
|
50557
|
+
if (!cells) return false;
|
|
50558
|
+
const template = createTable(ctx, 2, cells.length);
|
|
50559
|
+
const [head, ...rest] = [template.child(0), template.child(1)];
|
|
50560
|
+
const paragraph = state.schema.nodes.paragraph;
|
|
50561
|
+
let table;
|
|
50562
|
+
try {
|
|
50563
|
+
table = template.copy(Fragment.from([head.copy(Fragment.fromArray(cells.map((cell, column) => {
|
|
50564
|
+
return head.child(column).copy(Fragment.from(paragraph.create(null, cell)));
|
|
50565
|
+
}))), ...rest]));
|
|
50566
|
+
table.check();
|
|
50567
|
+
} catch {
|
|
50568
|
+
return false;
|
|
50569
|
+
}
|
|
50570
|
+
const index = $cursor.index(-1), parent = $cursor.node(-1);
|
|
50571
|
+
const replaces = parent.canReplaceWith(index, index + 1, table.type);
|
|
50572
|
+
if (!replaces && (parent.attrs.checked != null || !parent.canReplaceWith(index + 1, index + 1, table.type))) return false;
|
|
50573
|
+
if (dispatch) {
|
|
50574
|
+
const tr = state.tr;
|
|
50575
|
+
if (replaces) tr.replaceWith($cursor.before(), $cursor.after(), table);
|
|
50576
|
+
else {
|
|
50577
|
+
tr.delete($cursor.start(), $cursor.end());
|
|
50578
|
+
tr.insert($cursor.start() + 1, table);
|
|
50579
|
+
}
|
|
50580
|
+
const body = (replaces ? $cursor.before() : $cursor.start() + 1) + 1 + table.child(0).nodeSize;
|
|
50581
|
+
tr.setSelection(Selection.findFrom(tr.doc.resolve(body), 1, true));
|
|
50582
|
+
dispatchTableOperation(view, tr);
|
|
50583
|
+
}
|
|
50584
|
+
return true;
|
|
50585
|
+
};
|
|
50586
|
+
}
|
|
49886
50587
|
var tablePlugins = [
|
|
49887
50588
|
moveRowCommand,
|
|
49888
50589
|
moveColCommand,
|
|
50590
|
+
$shortcut((ctx) => ({
|
|
50591
|
+
Enter: {
|
|
50592
|
+
key: "Enter",
|
|
50593
|
+
onRun: () => typedRowToTable(ctx),
|
|
50594
|
+
priority: 60
|
|
50595
|
+
},
|
|
50596
|
+
Tab: {
|
|
50597
|
+
key: "Tab",
|
|
50598
|
+
onRun: () => typedRowToTable(ctx),
|
|
50599
|
+
priority: 60
|
|
50600
|
+
}
|
|
50601
|
+
})),
|
|
49889
50602
|
$prose(() => keymap$3({
|
|
49890
50603
|
Tab: goToNextCell(1),
|
|
49891
50604
|
"Shift-Tab": goToNextCell(-1)
|
|
@@ -50954,6 +51667,101 @@ function literalVisibleRanges(plain, viewport) {
|
|
|
50954
51667
|
}) ?? [];
|
|
50955
51668
|
}
|
|
50956
51669
|
//#endregion
|
|
51670
|
+
//#region src/block-move.ts
|
|
51671
|
+
var containers = /* @__PURE__ */ new Set([
|
|
51672
|
+
"doc",
|
|
51673
|
+
"blockquote",
|
|
51674
|
+
"inkkit_callout",
|
|
51675
|
+
"bullet_list",
|
|
51676
|
+
"ordered_list",
|
|
51677
|
+
"footnote_definition"
|
|
51678
|
+
]);
|
|
51679
|
+
var tableParts = /* @__PURE__ */ new Set([
|
|
51680
|
+
"table",
|
|
51681
|
+
"table_row",
|
|
51682
|
+
"table_header_row",
|
|
51683
|
+
"table_cell",
|
|
51684
|
+
"table_header"
|
|
51685
|
+
]);
|
|
51686
|
+
/** On a move's transaction, the blocks it carried, so their source can go
|
|
51687
|
+
* with them. */
|
|
51688
|
+
var carriedBlocks = new PluginKey("carriedBlocks");
|
|
51689
|
+
var frontMatter = (node) => node.type.name === "literal_markdown" && /^(?:---|\+\+\+)[ \t]*\r?\n/.test(node.textContent);
|
|
51690
|
+
/**
|
|
51691
|
+
* The move a selection makes, or `'boundary'` when its blocks are already
|
|
51692
|
+
* first or last in their container, or `undefined` when it has no blocks to
|
|
51693
|
+
* move, such as in a table, where the table's own row moves apply.
|
|
51694
|
+
*/
|
|
51695
|
+
function plan(state, direction) {
|
|
51696
|
+
const { $from, $to } = state.selection;
|
|
51697
|
+
for (const $pos of [$from, $to]) for (let depth = $pos.depth; depth > 0; depth--) if (tableParts.has($pos.node(depth).type.name)) return void 0;
|
|
51698
|
+
const range = $from.blockRange($to, (node) => containers.has(node.type.name));
|
|
51699
|
+
if (!range) return void 0;
|
|
51700
|
+
const container = range.parent;
|
|
51701
|
+
const first = range.depth === 0 && frontMatter(container.child(0)) ? 1 : 0;
|
|
51702
|
+
if (range.startIndex < first) return void 0;
|
|
51703
|
+
const hidden = (index) => !commentsVisible(state) && container.child(index).type.name === "comment_block";
|
|
51704
|
+
const up = direction === "up";
|
|
51705
|
+
let index = up ? range.startIndex - 1 : range.endIndex;
|
|
51706
|
+
const step = up ? -1 : 1;
|
|
51707
|
+
const inside = (index) => up ? index >= first : index < container.childCount;
|
|
51708
|
+
while (inside(index) && hidden(index)) index += step;
|
|
51709
|
+
if (!inside(index)) return "boundary";
|
|
51710
|
+
const past = up ? [index, range.startIndex] : [range.endIndex, index + 1];
|
|
51711
|
+
return {
|
|
51712
|
+
depth: range.depth,
|
|
51713
|
+
start: range.startIndex,
|
|
51714
|
+
end: range.endIndex,
|
|
51715
|
+
past
|
|
51716
|
+
};
|
|
51717
|
+
}
|
|
51718
|
+
/** Whether `moveBlock` would move the blocks at the selection. */
|
|
51719
|
+
function canMoveBlock(state, direction) {
|
|
51720
|
+
return typeof plan(state, direction) === "object";
|
|
51721
|
+
}
|
|
51722
|
+
/**
|
|
51723
|
+
* `'move'` when `moveBlock` would move the blocks at the selection,
|
|
51724
|
+
* `'boundary'` when they are already first or last in their container, and
|
|
51725
|
+
* undefined when there are none to move, as in a table.
|
|
51726
|
+
*/
|
|
51727
|
+
function blockMove(state, direction) {
|
|
51728
|
+
const move = plan(state, direction);
|
|
51729
|
+
return typeof move === "object" ? "move" : move;
|
|
51730
|
+
}
|
|
51731
|
+
/**
|
|
51732
|
+
* Moves the blocks at the selection past their neighbour in `direction`, as
|
|
51733
|
+
* one step that keeps the moved and the passed nodes as they are, so their
|
|
51734
|
+
* authored source travels with them. Returns undefined when nothing moves.
|
|
51735
|
+
*/
|
|
51736
|
+
function moveBlockTransaction(state, direction) {
|
|
51737
|
+
const move = plan(state, direction);
|
|
51738
|
+
if (typeof move !== "object") return void 0;
|
|
51739
|
+
const { depth, start, end, past } = move;
|
|
51740
|
+
const $at = state.selection.$from;
|
|
51741
|
+
const container = $at.node(depth);
|
|
51742
|
+
const offset = (index) => $at.posAtIndex(index, depth);
|
|
51743
|
+
const children = (from, to) => {
|
|
51744
|
+
const nodes = [];
|
|
51745
|
+
for (let index = from; index < to; index++) nodes.push(container.child(index));
|
|
51746
|
+
return nodes;
|
|
51747
|
+
};
|
|
51748
|
+
const moved = children(start, end);
|
|
51749
|
+
const passed = children(past[0], past[1]);
|
|
51750
|
+
const up = direction === "up";
|
|
51751
|
+
const from = offset(up ? past[0] : start);
|
|
51752
|
+
const to = offset(up ? end : past[1]);
|
|
51753
|
+
const reordered = up ? [...moved, ...passed] : [...passed, ...moved];
|
|
51754
|
+
const tr = state.tr.replaceWith(from, to, Fragment.fromArray(reordered)).setMeta(carriedBlocks, reordered);
|
|
51755
|
+
const shift = up ? -passed.reduce((size, node) => size + node.nodeSize, 0) : passed.reduce((size, node) => size + node.nodeSize, 0);
|
|
51756
|
+
tr.setSelection(shifted(state.selection, tr.doc, shift));
|
|
51757
|
+
return tr.scrollIntoView();
|
|
51758
|
+
}
|
|
51759
|
+
function shifted(selection, doc, shift) {
|
|
51760
|
+
if (selection instanceof NodeSelection) return NodeSelection.create(doc, selection.from + shift);
|
|
51761
|
+
if (selection instanceof TextSelection) return TextSelection.create(doc, selection.anchor + shift, selection.head + shift);
|
|
51762
|
+
return Selection.near(doc.resolve(selection.head + shift));
|
|
51763
|
+
}
|
|
51764
|
+
//#endregion
|
|
50957
51765
|
//#region src/scroll.ts
|
|
50958
51766
|
/** Rounds a distance away from zero, to a whole number of pixels. */
|
|
50959
51767
|
var scrollOutward = (distance) => distance > 0 ? Math.ceil(distance) : Math.floor(distance);
|
|
@@ -53090,9 +53898,10 @@ function replacementSlice(state, from, to, value) {
|
|
|
53090
53898
|
if (start.parent.type.spec.code) {
|
|
53091
53899
|
if (value) nodes.push(state.schema.text(value, marks));
|
|
53092
53900
|
} else {
|
|
53901
|
+
const isHTML = htmlBreakAt(start);
|
|
53093
53902
|
const lines = value.split("\n");
|
|
53094
53903
|
lines.forEach((line, index) => {
|
|
53095
|
-
if (index) nodes.push(state.schema.nodes.hardbreak.create({ isHTML
|
|
53904
|
+
if (index) nodes.push(state.schema.nodes.hardbreak.create({ isHTML }, null, index === lines.length - 1 && line === "" ? [] : marks));
|
|
53096
53905
|
if (line) nodes.push(state.schema.text(line, marks));
|
|
53097
53906
|
});
|
|
53098
53907
|
}
|
|
@@ -53138,8 +53947,8 @@ function replaceFormattedRange(view, from, to, replacement, preflight) {
|
|
|
53138
53947
|
const start = view.state.doc.resolve(from);
|
|
53139
53948
|
const end = view.state.doc.resolve(to);
|
|
53140
53949
|
let textOnly = start.parent === end.parent && start.parent.inlineContent;
|
|
53141
|
-
|
|
53142
|
-
if (!node.isText
|
|
53950
|
+
if (textOnly) start.parent.nodesBetween(start.parentOffset, end.parentOffset, (node) => {
|
|
53951
|
+
if (!node.isText) textOnly = false;
|
|
53143
53952
|
});
|
|
53144
53953
|
if (!textOnly) throw new InkKitError("invalid-range", "Replacement requires literal text within one block");
|
|
53145
53954
|
const value = replacement.replace(/\r\n?/g, "\n");
|
|
@@ -53688,6 +54497,8 @@ var shortcutNames = [
|
|
|
53688
54497
|
...formatShortcuts,
|
|
53689
54498
|
"undo",
|
|
53690
54499
|
"redo",
|
|
54500
|
+
"moveBlockUp",
|
|
54501
|
+
"moveBlockDown",
|
|
53691
54502
|
...tableCommands.map(tableShortcut)
|
|
53692
54503
|
];
|
|
53693
54504
|
/** Checks a keymap and drops omitted entries, so a `null` binding keeps its default. */
|
|
@@ -53716,11 +54527,13 @@ function textInputPreferences(value, name) {
|
|
|
53716
54527
|
const record = expectRecord(value, name, [
|
|
53717
54528
|
"spellcheck",
|
|
53718
54529
|
"autocorrect",
|
|
53719
|
-
"autocapitalize"
|
|
54530
|
+
"autocapitalize",
|
|
54531
|
+
"smartPunctuation"
|
|
53720
54532
|
]);
|
|
53721
54533
|
return {
|
|
53722
54534
|
spellcheck: optionalBoolean(record.spellcheck, `${name}.spellcheck`),
|
|
53723
54535
|
autocorrect: optionalBoolean(record.autocorrect, `${name}.autocorrect`),
|
|
54536
|
+
smartPunctuation: optionalBoolean(record.smartPunctuation, `${name}.smartPunctuation`),
|
|
53724
54537
|
autocapitalize: isOmitted(record.autocapitalize) ? void 0 : expectOneOf(record.autocapitalize, autocapitalizeValues, `${name}.autocapitalize`)
|
|
53725
54538
|
};
|
|
53726
54539
|
}
|
|
@@ -54134,6 +54947,7 @@ var InkKitEditor = class InkKitEditor {
|
|
|
54134
54947
|
ready = false;
|
|
54135
54948
|
destroyed = false;
|
|
54136
54949
|
preservation;
|
|
54950
|
+
carried;
|
|
54137
54951
|
pasteController;
|
|
54138
54952
|
plain;
|
|
54139
54953
|
root;
|
|
@@ -54164,7 +54978,7 @@ var InkKitEditor = class InkKitEditor {
|
|
|
54164
54978
|
changePlugin = $prose(() => new Plugin({
|
|
54165
54979
|
key: new PluginKey("documentChanges"),
|
|
54166
54980
|
view: () => ({ update: (view, previous) => {
|
|
54167
|
-
if (this.loading || view.state.doc
|
|
54981
|
+
if (this.loading || this.sameDocument(view.state.doc, previous.doc)) return;
|
|
54168
54982
|
if (this.syncingSource) {
|
|
54169
54983
|
this.mediaPolicy();
|
|
54170
54984
|
return;
|
|
@@ -54426,7 +55240,7 @@ var InkKitEditor = class InkKitEditor {
|
|
|
54426
55240
|
}
|
|
54427
55241
|
this.publishCommandState();
|
|
54428
55242
|
}
|
|
54429
|
-
/** Replaces the input
|
|
55243
|
+
/** Replaces the input preferences. A field left out takes its default. Throws `composition`
|
|
54430
55244
|
* during text composition. */
|
|
54431
55245
|
setTextInputPreferences(preferences) {
|
|
54432
55246
|
this.assertAlive();
|
|
@@ -54526,7 +55340,9 @@ var InkKitEditor = class InkKitEditor {
|
|
|
54526
55340
|
insertFootnote: formatted,
|
|
54527
55341
|
editReferenceDefinition: formatted && referenceDefinitions(state.doc).size > 0,
|
|
54528
55342
|
format,
|
|
54529
|
-
table: tables
|
|
55343
|
+
table: tables,
|
|
55344
|
+
moveBlockUp: formatted && canMoveBlock(state, "up"),
|
|
55345
|
+
moveBlockDown: formatted && canMoveBlock(state, "down")
|
|
54530
55346
|
}
|
|
54531
55347
|
};
|
|
54532
55348
|
}
|
|
@@ -54548,6 +55364,17 @@ var InkKitEditor = class InkKitEditor {
|
|
|
54548
55364
|
range = new NodeRange(state.doc.resolve($from.before(depth)), state.doc.resolve($from.after(depth)), depth - 1);
|
|
54549
55365
|
return !!findWrapping(range, type);
|
|
54550
55366
|
}
|
|
55367
|
+
historyInputPlugin = $prose(() => new Plugin({
|
|
55368
|
+
key: new PluginKey("inkkitHistoryInput"),
|
|
55369
|
+
props: { handleDOMEvents: { beforeinput: (_view, event) => {
|
|
55370
|
+
if (!this.writable) return false;
|
|
55371
|
+
const name = event.inputType === "historyUndo" ? "undo" : event.inputType === "historyRedo" ? "redo" : void 0;
|
|
55372
|
+
if (!name) return false;
|
|
55373
|
+
event.preventDefault();
|
|
55374
|
+
if (this.ready && this.commandState().commands[name]) this.forPerson(() => this[name](), true);
|
|
55375
|
+
return true;
|
|
55376
|
+
} } }
|
|
55377
|
+
}));
|
|
54551
55378
|
policyPlugin = $prose(() => new Plugin({
|
|
54552
55379
|
key: new PluginKey("inkkitInputPolicy"),
|
|
54553
55380
|
filterTransaction: (tr) => this.loading || this.writable || this.syncingSource || !tr.docChanged && !tr.storedMarksSet,
|
|
@@ -54602,7 +55429,7 @@ var InkKitEditor = class InkKitEditor {
|
|
|
54602
55429
|
this.sourcePreservations.set(provenance, preservation);
|
|
54603
55430
|
}
|
|
54604
55431
|
}
|
|
54605
|
-
text = preservation.serialize(cleanSourceDoc(doc));
|
|
55432
|
+
text = preservation.serialize(cleanSourceDoc(doc), this.carried);
|
|
54606
55433
|
} catch (error) {
|
|
54607
55434
|
throw coded(error, "preservation");
|
|
54608
55435
|
}
|
|
@@ -54818,7 +55645,7 @@ var InkKitEditor = class InkKitEditor {
|
|
|
54818
55645
|
this.assertMutation(expectedGeneration);
|
|
54819
55646
|
if (this.literalSurface && this.stepTypedSource("undo")) return true;
|
|
54820
55647
|
const view = this.editor.ctx.get(editorViewCtx);
|
|
54821
|
-
const undone = undo(view.state, view.dispatch);
|
|
55648
|
+
const undone = !this.literalSurface && undoSmartPunctuation(view.state, view.dispatch) || undo(view.state, view.dispatch);
|
|
54822
55649
|
if (undone) {
|
|
54823
55650
|
if (this.literalSurface && this.undoneSteps.length) this.formattedUndone++;
|
|
54824
55651
|
else this.undoneSteps = [];
|
|
@@ -54984,10 +55811,11 @@ var InkKitEditor = class InkKitEditor {
|
|
|
54984
55811
|
const { schema } = view.state;
|
|
54985
55812
|
const marks = view.state.storedMarks ?? (view.state.selection.empty ? view.state.selection.$from.marks() : view.state.selection.$from.marksAcross(view.state.selection.$to)) ?? [];
|
|
54986
55813
|
const children = [];
|
|
55814
|
+
const isHTML = !inHiddenComment && htmlBreakAt(view.state.selection.$from);
|
|
54987
55815
|
const lines = text.replace(/\r\n?/g, "\n").split("\n");
|
|
54988
55816
|
lines.forEach((line, index) => {
|
|
54989
55817
|
const finalBreak = index === lines.length - 1 && line === "";
|
|
54990
|
-
if (index) children.push(schema.nodes.hardbreak.create({ isHTML
|
|
55818
|
+
if (index) children.push(schema.nodes.hardbreak.create({ isHTML }, null, finalBreak ? [] : marks));
|
|
54991
55819
|
if (line) children.push(schema.text(line, marks));
|
|
54992
55820
|
});
|
|
54993
55821
|
if (!children.length) {
|
|
@@ -54997,8 +55825,9 @@ var InkKitEditor = class InkKitEditor {
|
|
|
54997
55825
|
const paragraph = schema.nodes.paragraph.create(null, children);
|
|
54998
55826
|
const transaction = inHiddenComment ? insertAfterHiddenComment(view.state, Fragment.from(paragraph)) : view.state.tr.replaceSelection(new Slice(Fragment.from(paragraph), 1, 1)).scrollIntoView();
|
|
54999
55827
|
if (!transaction) return;
|
|
55000
|
-
|
|
55001
|
-
view.dispatch(transaction);
|
|
55828
|
+
const isolated = lines.length > 1;
|
|
55829
|
+
view.dispatch(isolated ? closeHistory(transaction) : transaction);
|
|
55830
|
+
if (isolated) view.dispatch(closeHistory(view.state.tr).setMeta("addToHistory", false));
|
|
55002
55831
|
}
|
|
55003
55832
|
}
|
|
55004
55833
|
}
|
|
@@ -55011,6 +55840,21 @@ var InkKitEditor = class InkKitEditor {
|
|
|
55011
55840
|
if (this.literalSurface) return false;
|
|
55012
55841
|
return tableCommand(this.editor.ctx, command, options);
|
|
55013
55842
|
}
|
|
55843
|
+
/** Moves the blocks at the selection one place up or down in their list, quote, callout, footnote
|
|
55844
|
+
* or note, as one undo step. Returns whether they moved: false in source and TXT modes, in a
|
|
55845
|
+
* table, and when they are already first or last. */
|
|
55846
|
+
moveBlock(direction, expectedGeneration) {
|
|
55847
|
+
this.assertAlive();
|
|
55848
|
+
expectOneOf(direction, ["up", "down"], "direction");
|
|
55849
|
+
this.assertMutation(expectedGeneration);
|
|
55850
|
+
if (this.literalSurface) return false;
|
|
55851
|
+
const view = this.editor.ctx.get(editorViewCtx);
|
|
55852
|
+
const tr = moveBlockTransaction(view.state, direction);
|
|
55853
|
+
if (!tr) return false;
|
|
55854
|
+
view.dispatch(closeHistory(tr));
|
|
55855
|
+
view.dispatch(closeHistory(view.state.tr).setMeta("addToHistory", false));
|
|
55856
|
+
return true;
|
|
55857
|
+
}
|
|
55014
55858
|
/** Cancels pending work and releases the editor. It never rejects. Afterwards every other member
|
|
55015
55859
|
* throws `destroyed`. */
|
|
55016
55860
|
async destroy() {
|
|
@@ -55106,6 +55950,7 @@ var InkKitEditor = class InkKitEditor {
|
|
|
55106
55950
|
instance.editor = await Editor.make().config((ctx) => {
|
|
55107
55951
|
ctx.set(rootCtx, root);
|
|
55108
55952
|
ctx.set(authoredSourcesCtx.key, (doc, positions) => instance.authoredSources(doc, positions));
|
|
55953
|
+
ctx.set(smartPunctuationCtx.key, () => instance.inputPreferences.smartPunctuation === true);
|
|
55109
55954
|
ctx.update(labelsCtx.key, () => ({
|
|
55110
55955
|
...defaultLabels,
|
|
55111
55956
|
...options.labels
|
|
@@ -55143,6 +55988,7 @@ var InkKitEditor = class InkKitEditor {
|
|
|
55143
55988
|
...options,
|
|
55144
55989
|
dispatchTransaction: function(tr) {
|
|
55145
55990
|
if (instance.call?.refusal && tr.docChanged) return;
|
|
55991
|
+
for (const node of tr.getMeta(carriedBlocks) ?? []) (instance.carried ??= /* @__PURE__ */ new WeakSet()).add(node);
|
|
55146
55992
|
const applied = this.state.applyTransaction(tr);
|
|
55147
55993
|
let next = applied.state;
|
|
55148
55994
|
if (!instance.loading) {
|
|
@@ -55171,7 +56017,7 @@ var InkKitEditor = class InkKitEditor {
|
|
|
55171
56017
|
return true;
|
|
55172
56018
|
}
|
|
55173
56019
|
}));
|
|
55174
|
-
}).use(labelsCtx).use(instance.pasteController.plugin).use(visibleClipboard).use(instance.keymapPlugin).use(createDialect(Boolean(options.images || options.files), Boolean(options.wikiLinks), Boolean(options.files))).use(tablePlugins).use(tableBlock).use(instance.changePlugin).use(history).use(clipboard).use(cursor).use(taskListPlugin).use(quoteBackspace).use(calloutEnter).use(literalEnter).use(literalReread).use(listItemBackspace).use(listItemShiftTab).use(nestedItemEnter).use(rejoinLists).use(movedListItems).use(textInputPolicy).use(events.copy ? codeCopyPlugin((text) => events.copy?.(text)) : []).use(placeholderPlugin).use(options.rendering?.codeHighlighting === false ? [] : (await import("./highlight-
|
|
56020
|
+
}).use(labelsCtx).use(instance.pasteController.plugin).use(visibleClipboard).use(instance.keymapPlugin).use(createDialect(Boolean(options.images || options.files), Boolean(options.wikiLinks), Boolean(options.files))).use(tablePlugins).use(tableBlock).use(instance.changePlugin).use(instance.historyInputPlugin).use(history).use(clipboard).use(cursor).use(taskListPlugin).use(quoteBackspace).use(calloutEnter).use(literalEnter).use(literalReread).use(listItemBackspace).use(listItemShiftTab).use(nestedItemEnter).use(rejoinLists).use(movedListItems).use(textInputPolicy).use(events.copy ? codeCopyPlugin((text) => events.copy?.(text)) : []).use(placeholderPlugin).use(options.rendering?.codeHighlighting === false ? [] : (await import("./highlight-DQC71L-N.js")).highlightPlugin).use(options.rendering?.diagramPreview === false || !diagramsAvailable() ? [] : mermaidPreview((error) => instance.report(error))).use(selectionPlugin).use($prose(() => search())).use(instance.policyPlugin).use(options.wikiLinks ? wikiLinkView(options.wikiLinks, {
|
|
55175
56021
|
capture: () => instance.adapterCapture(),
|
|
55176
56022
|
active: () => instance.ready && !instance.destroyed && !instance.literalSurface,
|
|
55177
56023
|
labels: {
|
|
@@ -55586,12 +56432,24 @@ var InkKitEditor = class InkKitEditor {
|
|
|
55586
56432
|
if (reveal) this.revealTextRange(range);
|
|
55587
56433
|
this.publishCommandState();
|
|
55588
56434
|
}
|
|
56435
|
+
/** Whether two documents are the same note. A move of blocks that read alike, such as a setext
|
|
56436
|
+
* heading and the same heading written with `#`, gives an equal document with other source. */
|
|
56437
|
+
sameDocument(after, before) {
|
|
56438
|
+
if (after === before) return true;
|
|
56439
|
+
if (!after.eq(before)) return false;
|
|
56440
|
+
if (!this.carried || !this.preservation) return true;
|
|
56441
|
+
try {
|
|
56442
|
+
return this.currentText(after) === this.currentText(before);
|
|
56443
|
+
} catch {
|
|
56444
|
+
return false;
|
|
56445
|
+
}
|
|
56446
|
+
}
|
|
55589
56447
|
/** Throws when a document reached by an edit, after every appended normalisation, cannot be
|
|
55590
56448
|
* saved as preserved Markdown. Dispatch and the replacement commands share this check.
|
|
55591
56449
|
* `written` is false for history steps and source replacement, which restore or supply a
|
|
55592
56450
|
* document that may hold comment text the formatted editor would refuse to accept typed. */
|
|
55593
56451
|
assertPreserved(before, after, written = true) {
|
|
55594
|
-
if (this.literalSurface ||
|
|
56452
|
+
if (this.literalSurface || this.sameDocument(after, before)) return;
|
|
55595
56453
|
if (written) assertCommentsEndWhereWritten(before, after);
|
|
55596
56454
|
if (this.preservation) this.currentText(after);
|
|
55597
56455
|
}
|
|
@@ -55768,6 +56626,7 @@ var InkKitEditor = class InkKitEditor {
|
|
|
55768
56626
|
this.loading = false;
|
|
55769
56627
|
}
|
|
55770
56628
|
this.preservation = preservation;
|
|
56629
|
+
this.carried = void 0;
|
|
55771
56630
|
this.lastMarkdown = markdown;
|
|
55772
56631
|
const { doc } = view.state;
|
|
55773
56632
|
const $end = doc.resolve(doc.content.size);
|
|
@@ -55959,14 +56818,17 @@ var InkKitEditor = class InkKitEditor {
|
|
|
55959
56818
|
this.releaseFocus();
|
|
55960
56819
|
}
|
|
55961
56820
|
/** Replaces every binding. Keys are in ProseMirror's notation. A key given to two shortcuts goes
|
|
55962
|
-
* to the later one, in the order history, formatting, tables, so it lands the same
|
|
55963
|
-
* time.
|
|
56821
|
+
* to the later one, in the order history, formatting, block moves, tables, so it lands the same
|
|
56822
|
+
* way every time. A table binding passes a key it shares with a block move to the move outside
|
|
56823
|
+
* a table. */
|
|
55964
56824
|
setKeymap(keymap) {
|
|
55965
56825
|
this.assertAlive();
|
|
55966
56826
|
keymap = keymapBindings(keymap, "keymap");
|
|
55967
56827
|
this.configuredKeys = {
|
|
55968
56828
|
undo: ["Mod-z"],
|
|
55969
56829
|
redo: ["Mod-y", "Shift-Mod-z"],
|
|
56830
|
+
moveBlockUp: ["Alt-ArrowUp"],
|
|
56831
|
+
moveBlockDown: ["Alt-ArrowDown"],
|
|
55970
56832
|
tableExit: ["Mod-Enter", "Enter"],
|
|
55971
56833
|
...keymap
|
|
55972
56834
|
};
|
|
@@ -55986,11 +56848,19 @@ var InkKitEditor = class InkKitEditor {
|
|
|
55986
56848
|
this.forPerson(() => this.format(name), false);
|
|
55987
56849
|
return true;
|
|
55988
56850
|
};
|
|
55989
|
-
|
|
55990
|
-
|
|
56851
|
+
const moves = {};
|
|
56852
|
+
for (const [name, direction] of [["moveBlockUp", "up"], ["moveBlockDown", "down"]]) for (const key of this.configuredKeys[name] ?? []) moves[key] = bindings[key] = (state) => {
|
|
56853
|
+
if (!this.ready || !this.writable || this.literalSurface) return false;
|
|
56854
|
+
const move = blockMove(state, direction);
|
|
56855
|
+
if (!move) return false;
|
|
56856
|
+
if (move === "move" && !this.composing && !this.pasteController.pending) this.forPerson(() => this.moveBlock(direction), false);
|
|
56857
|
+
return true;
|
|
56858
|
+
};
|
|
56859
|
+
for (const command of tableCommands) for (const key of this.configuredKeys[tableShortcut(command)] ?? []) bindings[key] = (state, dispatch, view) => {
|
|
56860
|
+
if (!this.ready || !this.commandState().commands.table[command]) return moves[key]?.(state, dispatch, view) ?? false;
|
|
55991
56861
|
return this.forPerson(() => this.table(command), true);
|
|
55992
56862
|
};
|
|
55993
|
-
this.readOnlyKeys = keydownHandler(Object.fromEntries(Object.keys(bindings).map((key) => [key, () => {
|
|
56863
|
+
this.readOnlyKeys = keydownHandler(Object.fromEntries(Object.keys(bindings).filter((key) => !moves[key]).map((key) => [key, () => {
|
|
55994
56864
|
throw new InkKitError("read-only", "The editor is read-only");
|
|
55995
56865
|
}])));
|
|
55996
56866
|
this.keys = keydownHandler(bindings);
|
|
@@ -56448,6 +57318,7 @@ var InkKitEditor = class InkKitEditor {
|
|
|
56448
57318
|
"replaceAll",
|
|
56449
57319
|
"format",
|
|
56450
57320
|
"table",
|
|
57321
|
+
"moveBlock",
|
|
56451
57322
|
"insertText",
|
|
56452
57323
|
"keyDown",
|
|
56453
57324
|
"insertPaths",
|