@aicayzer/inkkit 0.1.6 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -38
- package/dist/chunks/{core-nIObsA9D.js → core-C612uj1Q.js} +357 -107
- package/dist/chunks/{highlight-CeNqcHAb.js → highlight-AI86evan.js} +1 -1
- package/dist/core.d.ts +1 -1
- package/dist/core.js +1 -1
- package/dist/editor.d.ts +10 -1
- package/dist/index.js +1 -1
- package/dist/style.css +7 -1
- package/dist/types.d.ts +5 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,48 +1,32 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Inkkit
|
|
2
2
|
|
|
3
|
-
A Markdown editor for
|
|
3
|
+
A Markdown editor for web pages and for apps that host a web view. People edit formatted text, and your app saves the Markdown as it was written: an unedited document is saved unchanged, and an edit rewrites only the blocks it touches.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
- Mermaid diagram previews, offline
|
|
8
|
-
- Copy as readable text or HTML, or copy the Markdown itself
|
|
9
|
-
- Images and files through your own storage adapter
|
|
10
|
-
- Your app owns the toolbar, menus, files and appearance
|
|
11
|
-
|
|
12
|
-
## How it works
|
|
5
|
+
<details>
|
|
6
|
+
<summary>How Inkkit preserves Markdown</summary>
|
|
13
7
|
|
|
14
8
|
<picture>
|
|
15
|
-
<source media="(prefers-color-scheme: dark)" srcset="
|
|
16
|
-
<img src="
|
|
9
|
+
<source media="(prefers-color-scheme: dark)" srcset="docs/images/how-inkkit-works-dark.svg">
|
|
10
|
+
<img src="docs/images/how-inkkit-works.svg" alt="Inkkit keeps unchanged source and checks edited blocks before your app saves them.">
|
|
17
11
|
</picture>
|
|
18
12
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
For the exact guarantees, see [Preservation](https://github.com/aicayzer/inkkit/blob/main/docs/preservation.md).
|
|
13
|
+
</details>
|
|
22
14
|
|
|
23
|
-
##
|
|
15
|
+
## Get started
|
|
24
16
|
|
|
25
17
|
```sh
|
|
26
18
|
npm install @aicayzer/inkkit
|
|
27
19
|
```
|
|
28
20
|
|
|
29
|
-
An app that does not render diagrams can import from `@aicayzer/inkkit/core` instead. That entry leaves Mermaid out of the app's bundle and keeps diagrams as editable source. See [Builds without diagrams](https://github.com/aicayzer/inkkit/blob/main/docs/api.md#builds-without-diagrams).
|
|
30
|
-
|
|
31
|
-
## Supported engines
|
|
32
|
-
|
|
33
|
-
InkKit supports Safari and `WKWebView` 17.5 or later (iOS 17.5, macOS 14.5), Chrome and Edge 123 or later, and Firefox 125 or later. The host page must declare UTF-8. See [Supported engines](https://github.com/aicayzer/inkkit/blob/main/docs/integration.md#supported-engines) for the APIs behind these versions.
|
|
34
|
-
|
|
35
|
-
## Use
|
|
36
|
-
|
|
37
21
|
```ts
|
|
38
22
|
import { InkKitEditor } from '@aicayzer/inkkit'
|
|
39
23
|
import '@aicayzer/inkkit/style.css'
|
|
40
24
|
|
|
41
25
|
const editor = await InkKitEditor.mount(document.getElementById('editor')!, {
|
|
42
|
-
changed(
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
26
|
+
changed() {},
|
|
27
|
+
error(error) {
|
|
28
|
+
console.error(error.code, error.message)
|
|
29
|
+
},
|
|
46
30
|
})
|
|
47
31
|
|
|
48
32
|
editor.loadDocument({
|
|
@@ -55,17 +39,9 @@ editor.loadDocument({
|
|
|
55
39
|
const { text } = editor.snapshot(1)
|
|
56
40
|
```
|
|
57
41
|
|
|
58
|
-
##
|
|
59
|
-
|
|
60
|
-
- [Memos](https://github.com/aicayzer/memos): a small Mac app for memos, in one floating window
|
|
61
|
-
- [PadPad](https://github.com/aicayzer/padpad): a small Mac app for quick text and files
|
|
62
|
-
|
|
63
|
-
## Learn more
|
|
42
|
+
## Documentation
|
|
64
43
|
|
|
65
|
-
|
|
66
|
-
- [Integration guide](https://github.com/aicayzer/inkkit/blob/main/docs/integration.md)
|
|
67
|
-
- [API reference](https://github.com/aicayzer/inkkit/blob/main/docs/api.md)
|
|
68
|
-
- [All documentation](https://github.com/aicayzer/inkkit/blob/main/docs/README.md)
|
|
44
|
+
[inkkit.cyzr.me](https://inkkit.cyzr.me) covers how Inkkit works, compatibility, integration guides and the API reference.
|
|
69
45
|
|
|
70
46
|
## License
|
|
71
47
|
|
|
@@ -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.6_patch_hash=
|
|
22737
|
+
//#region node_modules/.pnpm/prosemirror-view@1.42.6_patch_hash=808819d35255b79fc131ebc4873ab2fbcd47cd8f5bc05cd11e8caab02ecee548/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;
|
|
@@ -25232,6 +25232,17 @@ editHandlers.keydown = (view, _event) => {
|
|
|
25232
25232
|
view.input.lastKeyCodeTime = Date.now();
|
|
25233
25233
|
if (android && chrome && event.keyCode == 13) return;
|
|
25234
25234
|
if (event.keyCode != 229) view.domObserver.forceFlush();
|
|
25235
|
+
if (event.keyCode != 229 && ![
|
|
25236
|
+
16,
|
|
25237
|
+
17,
|
|
25238
|
+
18,
|
|
25239
|
+
91,
|
|
25240
|
+
92,
|
|
25241
|
+
93
|
|
25242
|
+
].includes(event.keyCode)) {
|
|
25243
|
+
view.domObserver.flush();
|
|
25244
|
+
view.input.lastFocus = 0;
|
|
25245
|
+
}
|
|
25235
25246
|
if (ios && event.keyCode == 13 && !event.ctrlKey && !event.altKey && !event.metaKey) {
|
|
25236
25247
|
let now = Date.now();
|
|
25237
25248
|
view.input.lastIOSEnter = now;
|
|
@@ -31243,6 +31254,18 @@ function mermaidPreview(onError) {
|
|
|
31243
31254
|
}));
|
|
31244
31255
|
}
|
|
31245
31256
|
//#endregion
|
|
31257
|
+
//#region src/literal-text.ts
|
|
31258
|
+
/** Literal lines stay in their textblock, including headings and table cells. */
|
|
31259
|
+
function literalTextNodes(schema, text, marks, isHTML) {
|
|
31260
|
+
const nodes = [];
|
|
31261
|
+
const lines = text.replace(/\r\n?/g, "\n").split("\n");
|
|
31262
|
+
lines.forEach((line, index) => {
|
|
31263
|
+
if (index) nodes.push(schema.nodes.hardbreak.create({ isHTML }, null, index === lines.length - 1 && line === "" ? [] : marks));
|
|
31264
|
+
if (line) nodes.push(schema.text(line, marks));
|
|
31265
|
+
});
|
|
31266
|
+
return nodes;
|
|
31267
|
+
}
|
|
31268
|
+
//#endregion
|
|
31246
31269
|
//#region node_modules/.pnpm/rope-sequence@1.3.4/node_modules/rope-sequence/dist/index.js
|
|
31247
31270
|
var GOOD_LEAF_SIZE = 200;
|
|
31248
31271
|
var RopeSequence = function RopeSequence() {};
|
|
@@ -31697,6 +31720,13 @@ A command function that redoes the last undone change, if any.
|
|
|
31697
31720
|
*/
|
|
31698
31721
|
var redo = buildCommand(true, true);
|
|
31699
31722
|
/**
|
|
31723
|
+
The amount of redoable events available in a given editor state.
|
|
31724
|
+
*/
|
|
31725
|
+
function redoDepth(state) {
|
|
31726
|
+
let hist = historyKey.getState(state);
|
|
31727
|
+
return hist ? hist.undone.eventCount : 0;
|
|
31728
|
+
}
|
|
31729
|
+
/**
|
|
31700
31730
|
Returns true if the given transaction was generated by the history
|
|
31701
31731
|
plugin.
|
|
31702
31732
|
*/
|
|
@@ -34978,7 +35008,7 @@ var associationAttrs = {
|
|
|
34978
35008
|
identifier: { default: "" }
|
|
34979
35009
|
};
|
|
34980
35010
|
/** Whether an element reads as `text`, with whitespace collapsed as shown. */
|
|
34981
|
-
function showsText
|
|
35011
|
+
function showsText(dom, text) {
|
|
34982
35012
|
const shown = (value) => value.replace(/\s+/g, " ").trim();
|
|
34983
35013
|
return shown(dom.textContent ?? "") === shown(text);
|
|
34984
35014
|
}
|
|
@@ -35003,7 +35033,7 @@ var references = [
|
|
|
35003
35033
|
const url = dom.getAttribute("data-inkkit-url") ?? "";
|
|
35004
35034
|
const label = dom.getAttribute("data-inkkit-label") ?? "";
|
|
35005
35035
|
const title = dom.getAttribute("data-inkkit-title");
|
|
35006
|
-
if (!isSafeLinkTarget(url) || !showsText
|
|
35036
|
+
if (!isSafeLinkTarget(url) || !showsText(dom, definitionText(label, url, title))) return false;
|
|
35007
35037
|
return {
|
|
35008
35038
|
label,
|
|
35009
35039
|
identifier: dom.getAttribute("data-inkkit-reference-definition") ?? "",
|
|
@@ -35055,7 +35085,7 @@ var references = [
|
|
|
35055
35085
|
tag: "sup[data-inkkit-footnote-reference]",
|
|
35056
35086
|
getAttrs: (dom) => {
|
|
35057
35087
|
const label = dom.getAttribute("data-inkkit-label") ?? "";
|
|
35058
|
-
return showsText
|
|
35088
|
+
return showsText(dom, label) ? {
|
|
35059
35089
|
label,
|
|
35060
35090
|
identifier: dom.getAttribute("data-inkkit-footnote-reference") ?? ""
|
|
35061
35091
|
} : false;
|
|
@@ -35499,7 +35529,7 @@ var wikiLinkSchema = $node("inkkit_wiki_link", () => ({
|
|
|
35499
35529
|
tag: "span[data-inkkit-wiki]",
|
|
35500
35530
|
getAttrs(dom) {
|
|
35501
35531
|
const parsed = parseLinkedSyntax(dom.getAttribute("data-inkkit-wiki-raw") ?? "", dom.getAttribute("data-inkkit-wiki-table") === "true");
|
|
35502
|
-
return parsed && !parsed.embed && showsWikiTarget(parsed) && showsText
|
|
35532
|
+
return parsed && !parsed.embed && showsWikiTarget(parsed) && showsText(dom, parsed.label) ? {
|
|
35503
35533
|
raw: parsed.raw,
|
|
35504
35534
|
target: parsed.target,
|
|
35505
35535
|
fragment: parsed.fragment,
|
|
@@ -43706,6 +43736,7 @@ function commentNode(inline) {
|
|
|
43706
43736
|
marks: "",
|
|
43707
43737
|
code: true,
|
|
43708
43738
|
defining: true,
|
|
43739
|
+
createGapCursor: !inline,
|
|
43709
43740
|
attrs: {
|
|
43710
43741
|
syntax: { default: "html" },
|
|
43711
43742
|
block: { default: !inline }
|
|
@@ -44118,7 +44149,7 @@ function nodeText(node, missingImages, fileDescriptions) {
|
|
|
44118
44149
|
}
|
|
44119
44150
|
return clipboardText(node.content, missingImages, fileDescriptions);
|
|
44120
44151
|
}
|
|
44121
|
-
function
|
|
44152
|
+
function clipboardDOM(content, schema) {
|
|
44122
44153
|
content = shareableFragment(content);
|
|
44123
44154
|
const container = document.createElement("div");
|
|
44124
44155
|
const serializer = DOMSerializer.fromSchema(schema);
|
|
@@ -44148,14 +44179,30 @@ function clipboardContent(content, schema) {
|
|
|
44148
44179
|
label.textContent = `[${definition.getAttribute("data-inkkit-label")}] `;
|
|
44149
44180
|
definition.prepend(label);
|
|
44150
44181
|
}
|
|
44182
|
+
return container;
|
|
44183
|
+
}
|
|
44184
|
+
function clipboardContent(content, schema) {
|
|
44151
44185
|
return {
|
|
44152
44186
|
text: clipboardText(content),
|
|
44153
|
-
html:
|
|
44187
|
+
html: clipboardDOM(content, schema).innerHTML
|
|
44188
|
+
};
|
|
44189
|
+
}
|
|
44190
|
+
function clipboardSerializer(schema) {
|
|
44191
|
+
const serializer = DOMSerializer.fromSchema(schema);
|
|
44192
|
+
const safe = new DOMSerializer(serializer.nodes, serializer.marks);
|
|
44193
|
+
safe.serializeFragment = (content, options = {}, target) => {
|
|
44194
|
+
const output = target ?? (options.document ?? document).createDocumentFragment();
|
|
44195
|
+
output.append(...clipboardDOM(content, schema).childNodes);
|
|
44196
|
+
return output;
|
|
44154
44197
|
};
|
|
44198
|
+
return safe;
|
|
44155
44199
|
}
|
|
44156
|
-
var visibleClipboard = $prose(() => new Plugin({
|
|
44200
|
+
var visibleClipboard = $prose((ctx) => new Plugin({
|
|
44157
44201
|
key: new PluginKey("visibleClipboard"),
|
|
44158
|
-
props: {
|
|
44202
|
+
props: {
|
|
44203
|
+
clipboardSerializer: clipboardSerializer(ctx.get(schemaCtx)),
|
|
44204
|
+
clipboardTextSerializer: (slice) => clipboardText(slice.content)
|
|
44205
|
+
}
|
|
44159
44206
|
}));
|
|
44160
44207
|
/** Export a frozen document fragment; presentation URLs never enter the clipboard. */
|
|
44161
44208
|
async function portableClipboard(content, schema, markdown, adapter, context, completeDiagrams, files, signal = new AbortController().signal) {
|
|
@@ -44878,50 +44925,63 @@ function blockDropRange(view, x, y) {
|
|
|
44878
44925
|
* callout, where typing would change text the reader can't see or didn't
|
|
44879
44926
|
* choose.
|
|
44880
44927
|
*/
|
|
44881
|
-
function caretAfter(doc, pos) {
|
|
44928
|
+
function caretAfter(doc, pos, folds = /* @__PURE__ */ new Map()) {
|
|
44929
|
+
const hides = (node) => isComment(node) || node.type.name === "inkkit_callout" && (folds.get(node) ?? node.attrs.fold === "-");
|
|
44930
|
+
const concealedDepth = ($pos) => {
|
|
44931
|
+
for (let depth = 1; depth <= $pos.depth; depth++) if (hides($pos.node(depth))) return depth;
|
|
44932
|
+
return -1;
|
|
44933
|
+
};
|
|
44934
|
+
const concealed = ($pos) => concealedDepth($pos) >= 0;
|
|
44882
44935
|
const $pos = doc.resolve(pos);
|
|
44883
44936
|
const before = $pos.nodeBefore;
|
|
44884
44937
|
if (before?.isTextblock && !concealed(doc.resolve(pos - 1))) return TextSelection.create(doc, pos - 1);
|
|
44885
|
-
|
|
44938
|
+
const gap = GapCursor;
|
|
44939
|
+
const forward = before && !showsText(before) ? shownText(doc, pos, 1) : null;
|
|
44940
|
+
if (forward) return forward;
|
|
44941
|
+
if (gap.valid($pos)) return new GapCursor($pos);
|
|
44886
44942
|
const [first, second] = before && !showsText(before) ? [1, -1] : [-1, 1];
|
|
44887
44943
|
return shownText(doc, pos, first) ?? shownText(doc, pos, second) ?? Selection.near($pos);
|
|
44888
|
-
|
|
44889
|
-
|
|
44890
|
-
|
|
44891
|
-
|
|
44892
|
-
|
|
44893
|
-
|
|
44894
|
-
|
|
44895
|
-
|
|
44896
|
-
|
|
44897
|
-
|
|
44898
|
-
}
|
|
44899
|
-
function showsText(node) {
|
|
44900
|
-
if (hides(node)) return false;
|
|
44901
|
-
if (node.isTextblock) return true;
|
|
44902
|
-
let found = false;
|
|
44903
|
-
node.descendants((child) => {
|
|
44904
|
-
if (found || hides(child)) return false;
|
|
44905
|
-
if (child.isTextblock) found = true;
|
|
44906
|
-
return !found;
|
|
44907
|
-
});
|
|
44908
|
-
return found;
|
|
44909
|
-
}
|
|
44910
|
-
function shownText(doc, pos, dir) {
|
|
44911
|
-
let $from = doc.resolve(pos);
|
|
44912
|
-
for (;;) {
|
|
44913
|
-
const found = TextSelection.findFrom($from, dir, true);
|
|
44914
|
-
if (!found) return null;
|
|
44915
|
-
const depth = concealedDepth(found.$head);
|
|
44916
|
-
if (depth < 0) return found;
|
|
44917
|
-
$from = doc.resolve(dir > 0 ? found.$head.after(depth) : found.$head.before(depth));
|
|
44944
|
+
function showsText(node) {
|
|
44945
|
+
if (hides(node)) return false;
|
|
44946
|
+
if (node.isTextblock) return true;
|
|
44947
|
+
let found = false;
|
|
44948
|
+
node.descendants((child) => {
|
|
44949
|
+
if (found || hides(child)) return false;
|
|
44950
|
+
if (child.isTextblock) found = true;
|
|
44951
|
+
return !found;
|
|
44952
|
+
});
|
|
44953
|
+
return found;
|
|
44918
44954
|
}
|
|
44955
|
+
function shownText(doc, pos, dir) {
|
|
44956
|
+
let $from = doc.resolve(pos);
|
|
44957
|
+
for (;;) {
|
|
44958
|
+
const found = TextSelection.findFrom($from, dir, true);
|
|
44959
|
+
if (!found) return null;
|
|
44960
|
+
const depth = concealedDepth(found.$head);
|
|
44961
|
+
if (depth < 0) return found;
|
|
44962
|
+
$from = doc.resolve(dir > 0 ? found.$head.after(depth) : found.$head.before(depth));
|
|
44963
|
+
}
|
|
44964
|
+
}
|
|
44965
|
+
}
|
|
44966
|
+
/** Capture reader folding before dispatch, then map it to the new document. */
|
|
44967
|
+
function calloutFolds(view, tr) {
|
|
44968
|
+
const folds = /* @__PURE__ */ new Map();
|
|
44969
|
+
view.state.doc.descendants((node, pos) => {
|
|
44970
|
+
if (node.type.name !== "inkkit_callout") return;
|
|
44971
|
+
const dom = view.nodeDOM(pos);
|
|
44972
|
+
if (!(dom instanceof HTMLElement)) return;
|
|
44973
|
+
const mapped = tr.mapping.mapResult(pos, 1);
|
|
44974
|
+
if (mapped.deleted) return;
|
|
44975
|
+
const next = tr.doc.nodeAt(mapped.pos);
|
|
44976
|
+
if (next?.type === node.type) folds.set(next, dom.getAttribute("data-inkkit-folded") === "true");
|
|
44977
|
+
});
|
|
44978
|
+
return folds;
|
|
44919
44979
|
}
|
|
44920
44980
|
/**
|
|
44921
44981
|
* Puts the caret just after what the transaction's last step inserted, so
|
|
44922
44982
|
* typing continues after pasted or dropped content instead of replacing it.
|
|
44923
44983
|
*/
|
|
44924
|
-
function caretAfterInsertion(tr) {
|
|
44984
|
+
function caretAfterInsertion(tr, view) {
|
|
44925
44985
|
const map = tr.mapping.maps[tr.mapping.maps.length - 1];
|
|
44926
44986
|
let end;
|
|
44927
44987
|
map?.forEach((_from, _to, _newFrom, newTo) => {
|
|
@@ -44929,7 +44989,7 @@ function caretAfterInsertion(tr) {
|
|
|
44929
44989
|
});
|
|
44930
44990
|
if (end == null) return tr;
|
|
44931
44991
|
const $end = tr.doc.resolve(end);
|
|
44932
|
-
return tr.setSelection($end.parent.inlineContent ? TextSelection.create(tr.doc, end) : caretAfter(tr.doc, end));
|
|
44992
|
+
return tr.setSelection($end.parent.inlineContent ? TextSelection.create(tr.doc, end) : caretAfter(tr.doc, end, view && calloutFolds(view, tr)));
|
|
44933
44993
|
}
|
|
44934
44994
|
//#endregion
|
|
44935
44995
|
//#region src/code-fences.ts
|
|
@@ -45099,13 +45159,16 @@ function lineBreakHTML(value) {
|
|
|
45099
45159
|
"<br/>"
|
|
45100
45160
|
].includes(value.trim());
|
|
45101
45161
|
}
|
|
45102
|
-
function restoreInlineBreaks(node) {
|
|
45103
|
-
|
|
45104
|
-
|
|
45105
|
-
|
|
45106
|
-
|
|
45107
|
-
|
|
45108
|
-
|
|
45162
|
+
function restoreInlineBreaks(node, inline = false) {
|
|
45163
|
+
const restore = node.type === "paragraph" && node.children.length > 1 || node.type === "heading" || node.type === "tableCell" || inline;
|
|
45164
|
+
if ("children" in node) {
|
|
45165
|
+
node.children = node.children.map((child) => restore && child.type === "html" && lineBreakHTML(child.value) ? {
|
|
45166
|
+
type: "break",
|
|
45167
|
+
data: { inkkitHTMLBreak: true },
|
|
45168
|
+
position: child.position
|
|
45169
|
+
} : child);
|
|
45170
|
+
node.children.forEach((child) => restoreInlineBreaks(child, restore));
|
|
45171
|
+
}
|
|
45109
45172
|
}
|
|
45110
45173
|
function containsUnsupported(node, images, inline = false) {
|
|
45111
45174
|
if (!inline && node.type === "html" && lineBreakHTML(node.value)) return false;
|
|
@@ -46010,6 +46073,12 @@ function retainSource(before, after, source, canonical, lineEnding, inTable = fa
|
|
|
46010
46073
|
}, source, canonical, lineEnding, inTable);
|
|
46011
46074
|
const first = before.children[0];
|
|
46012
46075
|
if (spacer(first)) return retained;
|
|
46076
|
+
const gap = source.slice(first.position.end.offset, before.children[1].position.start.offset);
|
|
46077
|
+
if (!/\r?\n[ \t]*\r?\n/.test(gap)) {
|
|
46078
|
+
const from = first.position.start.offset - start;
|
|
46079
|
+
const to = before.children[1].position.start.offset - start;
|
|
46080
|
+
return retained.startsWith(source.slice(start, start + to)) ? retained.slice(0, from) + retained.slice(to) : retained;
|
|
46081
|
+
}
|
|
46013
46082
|
const from = first.position.start.offset - start;
|
|
46014
46083
|
const to = first.position.end.offset - start;
|
|
46015
46084
|
return retained.startsWith(source.slice(start, before.children[1].position.start.offset)) ? retained.slice(0, from) + "<br />" + retained.slice(to) : retained;
|
|
@@ -48145,6 +48214,7 @@ var calloutSchema = $node("inkkit_callout", (ctx) => ({
|
|
|
48145
48214
|
group: "block",
|
|
48146
48215
|
content: "block+",
|
|
48147
48216
|
defining: true,
|
|
48217
|
+
createGapCursor: true,
|
|
48148
48218
|
attrs: {
|
|
48149
48219
|
kind: { default: "NOTE" },
|
|
48150
48220
|
marker: { default: "[!NOTE]" },
|
|
@@ -50190,7 +50260,23 @@ function padShortRows(node) {
|
|
|
50190
50260
|
if ("children" in node) node.children.forEach(padShortRows);
|
|
50191
50261
|
}
|
|
50192
50262
|
var remarkDialectPlugin = $remark("remarkDialect", () => remarkDialect);
|
|
50193
|
-
var
|
|
50263
|
+
var preservingSoftBreaks = $remark("preservingSoftBreaks", () => () => (tree) => {
|
|
50264
|
+
const walk = (parent) => {
|
|
50265
|
+
parent.children = parent.children.flatMap((child) => {
|
|
50266
|
+
if ("children" in child) walk(child);
|
|
50267
|
+
if (child.type !== "text" || !/[\r\n]/.test(child.value)) return [child];
|
|
50268
|
+
return child.value.split(/(\r?\n|\r)/).flatMap((value) => !value ? [] : /^(?:\r?\n|\r)$/.test(value) ? [{
|
|
50269
|
+
type: "break",
|
|
50270
|
+
data: { isInline: true }
|
|
50271
|
+
}] : [{
|
|
50272
|
+
type: "text",
|
|
50273
|
+
value
|
|
50274
|
+
}]);
|
|
50275
|
+
});
|
|
50276
|
+
};
|
|
50277
|
+
walk(tree);
|
|
50278
|
+
});
|
|
50279
|
+
var commonmarkWithLiteralReferences = commonmark.filter((plugin) => !remarkInlineLinkPlugin.includes(plugin) && !remarkLineBreak.includes(plugin) && plugin !== hardbreakClearMarkPlugin && !hardbreakKeymap.some((part) => part === plugin) && plugin !== syncHeadingIdPlugin && plugin !== createCodeBlockInputRule);
|
|
50194
50280
|
var breaksWithoutMarks = $prose((ctx) => new Plugin({
|
|
50195
50281
|
key: new PluginKey("inkkitBreaksWithoutMarks"),
|
|
50196
50282
|
appendTransaction(transactions, oldState, newState) {
|
|
@@ -50200,9 +50286,24 @@ var breaksWithoutMarks = $prose((ctx) => new Plugin({
|
|
|
50200
50286
|
const end = oldState.doc.content.findDiffEnd(newState.doc.content).b;
|
|
50201
50287
|
const type = hardbreakSchema.type(ctx);
|
|
50202
50288
|
const tr = newState.tr;
|
|
50289
|
+
newState.doc.nodesBetween(start, Math.max(start, end), (node, pos) => {
|
|
50290
|
+
if (!node.isTextblock || !node.firstChild) return;
|
|
50291
|
+
let count = 0;
|
|
50292
|
+
for (let index = 0; index < node.childCount; index++) {
|
|
50293
|
+
const child = node.child(index);
|
|
50294
|
+
if (child.type !== type || !child.attrs.isInline || child.attrs.isHTML) break;
|
|
50295
|
+
let previous = pos + 1 + count;
|
|
50296
|
+
for (let transaction = transactions.length - 1; transaction >= 0; transaction--) previous = transactions[transaction].mapping.invert().map(previous, 1);
|
|
50297
|
+
const before = oldState.doc.nodeAt(previous);
|
|
50298
|
+
if (before?.type !== type || !before.attrs.isInline || before.attrs.isHTML || oldState.doc.resolve(previous).parentOffset === 0) break;
|
|
50299
|
+
count += child.nodeSize;
|
|
50300
|
+
}
|
|
50301
|
+
if (count) tr.delete(tr.mapping.map(pos + 1), tr.mapping.map(pos + 1 + count));
|
|
50302
|
+
return false;
|
|
50303
|
+
});
|
|
50203
50304
|
newState.doc.nodesBetween(start, Math.max(start, end), (node, pos) => {
|
|
50204
50305
|
if (node.type !== type) return;
|
|
50205
|
-
for (const mark of node.marks) if (mark.type.spec.code) tr.removeMark(pos, pos + 1, mark.type);
|
|
50306
|
+
for (const mark of node.marks) if (mark.type.spec.code) tr.removeMark(tr.mapping.map(pos), tr.mapping.map(pos + 1), mark.type);
|
|
50206
50307
|
});
|
|
50207
50308
|
return tr.steps.length ? tr : null;
|
|
50208
50309
|
}
|
|
@@ -50464,6 +50565,7 @@ function createDialect(images, wikiLinks = false, files = false) {
|
|
|
50464
50565
|
wikiLinks || files ? linkedSyntax(wikiLinks, files) : [],
|
|
50465
50566
|
createLiteralPreservation(images || files),
|
|
50466
50567
|
commonmarkWithLiteralReferences,
|
|
50568
|
+
preservingSoftBreaks,
|
|
50467
50569
|
$node("doc", () => ({
|
|
50468
50570
|
...docSchema.schema,
|
|
50469
50571
|
attrs: {
|
|
@@ -51419,7 +51521,8 @@ var ImageView = class {
|
|
|
51419
51521
|
return;
|
|
51420
51522
|
}
|
|
51421
51523
|
const presentation = state.presentation;
|
|
51422
|
-
if (presentation.kind === "missing"
|
|
51524
|
+
if (presentation.kind === "missing") this.card(label, this.runtime.labels.fileMissing, true);
|
|
51525
|
+
else if (presentation.kind === "error") this.card(label, presentation.message || this.runtime.labels.fileError, true);
|
|
51423
51526
|
else if (presentation.kind === "image") {
|
|
51424
51527
|
this.renderImage(presentation.url, label, width);
|
|
51425
51528
|
this.card(label);
|
|
@@ -53763,7 +53866,7 @@ function pasteSpreadsheet(ctx, input, at) {
|
|
|
53763
53866
|
}
|
|
53764
53867
|
let grid;
|
|
53765
53868
|
try {
|
|
53766
|
-
grid = input.html?.match(/<table[\s>]/i) ? htmlGrid(view.state.schema, input.html) : input.text.includes(" ") ? textGrid(view.state.schema, input.text) : void 0;
|
|
53869
|
+
grid = input.html?.match(/<table[\s>]/i) ? htmlGrid(view.state.schema, input.html) : !input.html && input.text.includes(" ") && (inTable || looksLikeGrid(input.text)) ? textGrid(view.state.schema, input.text) : void 0;
|
|
53767
53870
|
} catch (error) {
|
|
53768
53871
|
if (inTable || !input.html) throw error;
|
|
53769
53872
|
if (!standaloneTable(input.html)) return false;
|
|
@@ -53781,7 +53884,7 @@ function pasteSpreadsheet(ctx, input, at) {
|
|
|
53781
53884
|
if (cursor < input.html.length) children.push(schema.text(input.html.slice(cursor)));
|
|
53782
53885
|
const content = importableSlice(ctx, new Slice(Fragment.from(schema.nodes.literal_markdown.create(null, children)), 0, 0)).content;
|
|
53783
53886
|
const selection = view.state.selection;
|
|
53784
|
-
dispatchTableOperation(view, at ? caretAfterInsertion(view.state.tr.replaceWith(at.from, at.to, content)) : selection.$from.parent.type.name === "paragraph" && selection.empty && selection.$from.parent.content.size === 0 ? view.state.tr.replaceWith(selection.$from.before(), selection.$from.after(), content) : content.childCount === 1 ? view.state.tr.replaceSelectionWith(content.firstChild) : view.state.tr.replaceSelection(new Slice(content, 0, 0)));
|
|
53887
|
+
dispatchTableOperation(view, at ? caretAfterInsertion(view.state.tr.replaceWith(at.from, at.to, content), view) : selection.$from.parent.type.name === "paragraph" && selection.empty && selection.$from.parent.content.size === 0 ? view.state.tr.replaceWith(selection.$from.before(), selection.$from.after(), content) : content.childCount === 1 ? view.state.tr.replaceSelectionWith(content.firstChild) : view.state.tr.replaceSelection(new Slice(content, 0, 0)));
|
|
53785
53888
|
return true;
|
|
53786
53889
|
}
|
|
53787
53890
|
if (!grid) return false;
|
|
@@ -53796,7 +53899,7 @@ function pasteSpreadsheet(ctx, input, at) {
|
|
|
53796
53899
|
if (node === table) tableStart = pos + 1;
|
|
53797
53900
|
});
|
|
53798
53901
|
if (tableStart < 0) reject();
|
|
53799
|
-
tr.setSelection(caretAfter(tr.doc, tableStart - 1 + table.nodeSize));
|
|
53902
|
+
tr.setSelection(caretAfter(tr.doc, tableStart - 1 + table.nodeSize, calloutFolds(view, tr)));
|
|
53800
53903
|
dispatchTableOperation(view, tr);
|
|
53801
53904
|
return true;
|
|
53802
53905
|
}
|
|
@@ -53841,6 +53944,12 @@ function standaloneTable(html) {
|
|
|
53841
53944
|
function reject() {
|
|
53842
53945
|
throw new InkKitError("preservation", "This spreadsheet cannot be represented safely in a Markdown table. Paste as plain text outside the table to retain its source.");
|
|
53843
53946
|
}
|
|
53947
|
+
function looksLikeGrid(input) {
|
|
53948
|
+
const rows = input.replace(/\r\n?/g, "\n").replace(/\n$/, "").split("\n");
|
|
53949
|
+
if (rows.length < 2) return false;
|
|
53950
|
+
const widths = rows.map((row) => row.split(" ").length);
|
|
53951
|
+
return widths[0] > 1 && widths.every((width) => width === widths[0]) && rows.some((row) => row.split(" ")[0].trim().length > 0);
|
|
53952
|
+
}
|
|
53844
53953
|
function textGrid(schema, input) {
|
|
53845
53954
|
const text = input.replace(/\r\n?/g, "\n").replace(/\n$/, "");
|
|
53846
53955
|
const rows = [[]];
|
|
@@ -54031,7 +54140,10 @@ var PasteController = class {
|
|
|
54031
54140
|
return mapped?.operation === operation ? mapped : operation;
|
|
54032
54141
|
}
|
|
54033
54142
|
cancelPending() {
|
|
54143
|
+
const operation = this.active;
|
|
54144
|
+
if (!operation) return;
|
|
54034
54145
|
this.active = void 0;
|
|
54146
|
+
operation.controller.abort();
|
|
54035
54147
|
this.options.onPendingChanged?.();
|
|
54036
54148
|
}
|
|
54037
54149
|
destroy() {
|
|
@@ -54043,6 +54155,26 @@ var PasteController = class {
|
|
|
54043
54155
|
const current = this.options.context();
|
|
54044
54156
|
if (this.active !== operation || current.documentId !== context.documentId || current.generation !== context.generation) throw new InkKitError("stale-document", "The document changed while images were importing.");
|
|
54045
54157
|
}
|
|
54158
|
+
async importImage(image, context, operation) {
|
|
54159
|
+
this.assertContext(context, operation);
|
|
54160
|
+
const signal = operation.controller.signal;
|
|
54161
|
+
let abort;
|
|
54162
|
+
const cancelled = new Promise((_, reject) => {
|
|
54163
|
+
abort = () => reject(new InkKitError(this.dead ? "destroyed" : "stale-document", "The image import was cancelled."));
|
|
54164
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
54165
|
+
});
|
|
54166
|
+
try {
|
|
54167
|
+
return await Promise.race([new Promise((resolve) => {
|
|
54168
|
+
resolve(this.options.adapter.importImage(image, {
|
|
54169
|
+
...context,
|
|
54170
|
+
signal
|
|
54171
|
+
}));
|
|
54172
|
+
}), cancelled]);
|
|
54173
|
+
} finally {
|
|
54174
|
+
signal.removeEventListener("abort", abort);
|
|
54175
|
+
this.assertContext(context, operation);
|
|
54176
|
+
}
|
|
54177
|
+
}
|
|
54046
54178
|
commit(apply) {
|
|
54047
54179
|
return this.options.commit ? this.options.commit(apply) : apply();
|
|
54048
54180
|
}
|
|
@@ -54057,12 +54189,13 @@ var PasteController = class {
|
|
|
54057
54189
|
const blocks = Fragment.fromArray(topLevel(view.state.schema, slice.content));
|
|
54058
54190
|
const tr = view.state.tr.replaceWith(range.from, range.to, blocks);
|
|
54059
54191
|
const end = tr.mapping.map(range.to);
|
|
54060
|
-
this.dispatch(view, tr.setSelection(caretAfter(tr.doc, end)).scrollIntoView());
|
|
54192
|
+
this.dispatch(view, tr.setSelection(caretAfter(tr.doc, end, calloutFolds(view, tr))).scrollIntoView());
|
|
54061
54193
|
}
|
|
54062
54194
|
/** Imports the input at the selection, or in place of `target`. */
|
|
54063
54195
|
async run(input, files = [], target) {
|
|
54064
54196
|
if (this.dead) throw new InkKitError("destroyed", "The editor was destroyed.");
|
|
54065
54197
|
if (this.pending) throw new InkKitError("operation-pending", "An image paste is still pending.");
|
|
54198
|
+
input = this.options.restoreCopy?.(input) ?? input;
|
|
54066
54199
|
const context = { ...this.options.context() };
|
|
54067
54200
|
const ctx = this.options.ctx();
|
|
54068
54201
|
const view = ctx.get(editorViewCtx);
|
|
@@ -54073,9 +54206,12 @@ var PasteController = class {
|
|
|
54073
54206
|
from: exit,
|
|
54074
54207
|
to: exit
|
|
54075
54208
|
};
|
|
54076
|
-
const operation =
|
|
54077
|
-
|
|
54078
|
-
|
|
54209
|
+
const operation = {
|
|
54210
|
+
...target ?? {
|
|
54211
|
+
from: view.state.selection.from,
|
|
54212
|
+
to: view.state.selection.to
|
|
54213
|
+
},
|
|
54214
|
+
controller: new AbortController()
|
|
54079
54215
|
};
|
|
54080
54216
|
const inCode = () => view.state.doc.resolve(this.anchor(operation).from).parent.type.spec.code;
|
|
54081
54217
|
this.active = operation;
|
|
@@ -54103,8 +54239,12 @@ var PasteController = class {
|
|
|
54103
54239
|
this.dispatch(view, caretAfterInsertion(view.state.tr.insertText(input.text, anchor.from, anchor.to)).scrollIntoView());
|
|
54104
54240
|
return;
|
|
54105
54241
|
}
|
|
54106
|
-
const
|
|
54107
|
-
|
|
54242
|
+
const anchor = this.anchor(operation);
|
|
54243
|
+
const start = view.state.doc.resolve(anchor.from);
|
|
54244
|
+
const end = view.state.doc.resolve(anchor.to);
|
|
54245
|
+
const marks = view.state.storedMarks ?? (anchor.from === anchor.to ? start.marks() : start.marksAcross(end)) ?? [];
|
|
54246
|
+
const nodes = literalTextNodes(schema, input.text, marks, htmlBreakAt(start));
|
|
54247
|
+
slice = new Slice(Fragment.from(schema.nodes.paragraph.create(null, nodes)), 1, 1);
|
|
54108
54248
|
} else if (input.html) {
|
|
54109
54249
|
const container = visibleContent(ctx, input.html);
|
|
54110
54250
|
const imported = /* @__PURE__ */ new Map();
|
|
@@ -54120,14 +54260,14 @@ var PasteController = class {
|
|
|
54120
54260
|
if (!reference) {
|
|
54121
54261
|
const captured = images.find((image) => image.source === source) ?? dataImage(source) ?? positional[index++];
|
|
54122
54262
|
if (!captured || !this.options.adapter) throw new Error("The pasted image is unavailable.");
|
|
54123
|
-
reference = (await this.
|
|
54263
|
+
reference = (await this.importImage(captured, context, operation)).reference;
|
|
54124
54264
|
this.assertContext(context, operation);
|
|
54125
54265
|
imported.set(source, reference);
|
|
54126
54266
|
}
|
|
54127
54267
|
element.setAttribute("src", reference);
|
|
54128
54268
|
element.removeAttribute("srcset");
|
|
54129
54269
|
} catch (error) {
|
|
54130
|
-
if (error instanceof InkKitError) throw error;
|
|
54270
|
+
if (error instanceof InkKitError && error.code !== "image-unavailable") throw error;
|
|
54131
54271
|
element.replaceWith(document.createTextNode(`[${alt}: image unavailable]`));
|
|
54132
54272
|
this.options.onError?.(coded(error, "image-unavailable", error instanceof Error ? error.message : "The pasted image is unavailable."));
|
|
54133
54273
|
}
|
|
@@ -54172,7 +54312,7 @@ var PasteController = class {
|
|
|
54172
54312
|
if (input.text) nodes.push(schema.nodes.paragraph.create(null, schema.text(input.text)));
|
|
54173
54313
|
for (const image of images) try {
|
|
54174
54314
|
if (!this.options.adapter) throw new InkKitError("image-unavailable", "No image adapter is configured.");
|
|
54175
|
-
const imported = await this.
|
|
54315
|
+
const imported = await this.importImage(image, context, operation);
|
|
54176
54316
|
this.assertContext(context, operation);
|
|
54177
54317
|
const imageNode = schema.nodes.image?.create({
|
|
54178
54318
|
src: imported.reference,
|
|
@@ -54219,8 +54359,8 @@ var PasteController = class {
|
|
|
54219
54359
|
});
|
|
54220
54360
|
return;
|
|
54221
54361
|
}
|
|
54222
|
-
if (anchor.from === anchor.to && insertion.parent.type.name === "paragraph" && insertion.parent.content.size === 0 && slice.content.firstChild?.isBlock && slice.content.firstChild.type.spec.isolating) this.dispatch(view, caretAfterInsertion(view.state.tr.replaceRange(insertion.before(), insertion.after(), new Slice(slice.content, 0, 0))).scrollIntoView());
|
|
54223
|
-
else this.dispatch(view, caretAfterInsertion(view.state.tr.replaceRange(anchor.from, anchor.to, source == null ? slice : withEdgeSpaces(slice, source, view.state.doc.resolve(anchor.from), view.state.doc.resolve(anchor.to)))).scrollIntoView());
|
|
54362
|
+
if (anchor.from === anchor.to && insertion.parent.type.name === "paragraph" && insertion.parent.content.size === 0 && slice.content.firstChild?.isBlock && slice.content.firstChild.type.spec.isolating) this.dispatch(view, caretAfterInsertion(view.state.tr.replaceRange(insertion.before(), insertion.after(), new Slice(slice.content, 0, 0)), view).scrollIntoView());
|
|
54363
|
+
else this.dispatch(view, caretAfterInsertion(view.state.tr.replaceRange(anchor.from, anchor.to, source == null ? slice : withEdgeSpaces(slice, source, view.state.doc.resolve(anchor.from), view.state.doc.resolve(anchor.to))), view).scrollIntoView());
|
|
54224
54364
|
} finally {
|
|
54225
54365
|
if (this.active === operation) {
|
|
54226
54366
|
this.active = void 0;
|
|
@@ -55095,14 +55235,7 @@ function replacementSlice(state, from, to, value) {
|
|
|
55095
55235
|
const nodes = [];
|
|
55096
55236
|
if (start.parent.type.spec.code) {
|
|
55097
55237
|
if (value) nodes.push(state.schema.text(value, marks));
|
|
55098
|
-
} else
|
|
55099
|
-
const isHTML = htmlBreakAt(start);
|
|
55100
|
-
const lines = value.split("\n");
|
|
55101
|
-
lines.forEach((line, index) => {
|
|
55102
|
-
if (index) nodes.push(state.schema.nodes.hardbreak.create({ isHTML }, null, index === lines.length - 1 && line === "" ? [] : marks));
|
|
55103
|
-
if (line) nodes.push(state.schema.text(line, marks));
|
|
55104
|
-
});
|
|
55105
|
-
}
|
|
55238
|
+
} else nodes.push(...literalTextNodes(state.schema, value, marks, htmlBreakAt(start)));
|
|
55106
55239
|
return new Slice(Fragment.fromArray(nodes), 0, 0);
|
|
55107
55240
|
}
|
|
55108
55241
|
function replaceFormatted(view, search, replacement, preflight, all = false) {
|
|
@@ -55229,17 +55362,35 @@ function navigateFormattedHeading(view, requested, context) {
|
|
|
55229
55362
|
}
|
|
55230
55363
|
//#endregion
|
|
55231
55364
|
//#region src/tasks.ts
|
|
55365
|
+
function onTaskMarker(event) {
|
|
55366
|
+
const target = event.target;
|
|
55367
|
+
if (!(target instanceof HTMLElement) || !target.matches("li[data-item-type=\"task\"]")) return false;
|
|
55368
|
+
const marker = getComputedStyle(target, "::before");
|
|
55369
|
+
const rect = target.getBoundingClientRect();
|
|
55370
|
+
const left = rect.left + parseFloat(marker.left);
|
|
55371
|
+
const top = rect.top + parseFloat(marker.top);
|
|
55372
|
+
return event.clientX >= left && event.clientX <= left + parseFloat(marker.width) && event.clientY >= top && event.clientY <= top + parseFloat(marker.height);
|
|
55373
|
+
}
|
|
55232
55374
|
var taskListPlugin = $prose(() => new Plugin({
|
|
55233
55375
|
key: new PluginKey("taskToggle"),
|
|
55234
|
-
props: {
|
|
55235
|
-
|
|
55236
|
-
|
|
55237
|
-
|
|
55238
|
-
|
|
55239
|
-
|
|
55240
|
-
|
|
55241
|
-
|
|
55242
|
-
|
|
55376
|
+
props: { handleDOMEvents: {
|
|
55377
|
+
mousedown(view, event) {
|
|
55378
|
+
if (!view.editable || event.button !== 0 || !onTaskMarker(event)) return false;
|
|
55379
|
+
event.preventDefault();
|
|
55380
|
+
return true;
|
|
55381
|
+
},
|
|
55382
|
+
click(view, event) {
|
|
55383
|
+
if (!view.editable || event.button !== 0 || !onTaskMarker(event)) return false;
|
|
55384
|
+
const nodePos = view.posAtDOM(event.target, 0) - 1;
|
|
55385
|
+
const node = view.state.doc.nodeAt(nodePos);
|
|
55386
|
+
if (node?.type.name !== "list_item" || node.attrs.checked == null) return false;
|
|
55387
|
+
event.preventDefault();
|
|
55388
|
+
view.dispatch(view.state.tr.setNodeMarkup(nodePos, void 0, {
|
|
55389
|
+
...node.attrs,
|
|
55390
|
+
checked: !node.attrs.checked
|
|
55391
|
+
}));
|
|
55392
|
+
return true;
|
|
55393
|
+
}
|
|
55243
55394
|
} }
|
|
55244
55395
|
}));
|
|
55245
55396
|
function listItemsInSelection(view) {
|
|
@@ -55929,6 +56080,15 @@ function caretState(state) {
|
|
|
55929
56080
|
quoted: quoted($from, $to)
|
|
55930
56081
|
};
|
|
55931
56082
|
}
|
|
56083
|
+
function terminalSelection(doc) {
|
|
56084
|
+
const $end = doc.resolve(doc.content.size);
|
|
56085
|
+
const gap = GapCursor;
|
|
56086
|
+
if (isImageBlock(doc.lastChild) && gap.valid($end)) return new GapCursor($end);
|
|
56087
|
+
const text = Selection.findFrom($end, -1, true);
|
|
56088
|
+
if (text) return text;
|
|
56089
|
+
if (gap.valid($end)) return new GapCursor($end);
|
|
56090
|
+
throw new InkKitError("preservation", "Document has no safe writing position");
|
|
56091
|
+
}
|
|
55932
56092
|
function quoted($from, $to) {
|
|
55933
56093
|
return $from.blockRange($to, (node) => node.type.name === "blockquote") != null;
|
|
55934
56094
|
}
|
|
@@ -56124,7 +56284,7 @@ var sourceGroupDelay = 500;
|
|
|
56124
56284
|
var sourceStepLimit = 100;
|
|
56125
56285
|
/**
|
|
56126
56286
|
* The editor. Create it with `InkKitEditor.mount`, load a document, and read it back with
|
|
56127
|
-
* `snapshot`. The reference is https://
|
|
56287
|
+
* `snapshot`. The reference is https://inkkit.cyzr.me/reference/editor.
|
|
56128
56288
|
*/
|
|
56129
56289
|
var InkKitEditor = class InkKitEditor {
|
|
56130
56290
|
options;
|
|
@@ -56141,6 +56301,8 @@ var InkKitEditor = class InkKitEditor {
|
|
|
56141
56301
|
typedSteps = [];
|
|
56142
56302
|
undoneSteps = [];
|
|
56143
56303
|
formattedUndone = 0;
|
|
56304
|
+
formattedRedoLimit;
|
|
56305
|
+
historyDirection;
|
|
56144
56306
|
lastSourceInput = 0;
|
|
56145
56307
|
syncingSource = false;
|
|
56146
56308
|
mode = "formatted";
|
|
@@ -56158,6 +56320,52 @@ var InkKitEditor = class InkKitEditor {
|
|
|
56158
56320
|
auxClickHandler;
|
|
56159
56321
|
untrackLinkModifier;
|
|
56160
56322
|
footnoteKeyHandler;
|
|
56323
|
+
localCopies = /* @__PURE__ */ new Map();
|
|
56324
|
+
rememberCopy(output, markdown, content, privateSource = false, actualCopy = false) {
|
|
56325
|
+
let comments = privateSource;
|
|
56326
|
+
content.descendants((node) => {
|
|
56327
|
+
const labelled = (label) => typeof label === "string" && literalCommentSpans(label).length > 0;
|
|
56328
|
+
if (isComment(node) || /^(?:reference|footnote)_/.test(node.type.name) && labelled(node.attrs.label) || node.marks.some((mark) => mark.type.name === "link" && (labelled(mark.attrs.label) || commentProvenance(mark.attrs.referenceContent)))) comments = true;
|
|
56329
|
+
});
|
|
56330
|
+
if (!comments) {
|
|
56331
|
+
if (actualCopy) this.localCopies.clear();
|
|
56332
|
+
return output;
|
|
56333
|
+
}
|
|
56334
|
+
const key = JSON.stringify([
|
|
56335
|
+
output.text,
|
|
56336
|
+
output.html,
|
|
56337
|
+
markdown
|
|
56338
|
+
]);
|
|
56339
|
+
const previous = this.localCopies.get(key);
|
|
56340
|
+
if (previous) {
|
|
56341
|
+
output.html = previous.html;
|
|
56342
|
+
if (actualCopy) this.localCopies.clear();
|
|
56343
|
+
this.localCopies.set(key, previous);
|
|
56344
|
+
return output;
|
|
56345
|
+
}
|
|
56346
|
+
const wrapper = document.createElement("div");
|
|
56347
|
+
const token = Array.from(crypto.getRandomValues(/* @__PURE__ */ new Uint8Array(16)), (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
56348
|
+
wrapper.setAttribute("data-inkkit-local-copy", token);
|
|
56349
|
+
wrapper.innerHTML = output.html;
|
|
56350
|
+
output.html = wrapper.outerHTML;
|
|
56351
|
+
if (actualCopy) this.localCopies.clear();
|
|
56352
|
+
this.localCopies.set(key, {
|
|
56353
|
+
text: output.text,
|
|
56354
|
+
html: output.html,
|
|
56355
|
+
markdown
|
|
56356
|
+
});
|
|
56357
|
+
return output;
|
|
56358
|
+
}
|
|
56359
|
+
retainCopy(html) {
|
|
56360
|
+
for (const [key, copy] of this.localCopies) if (copy.html !== html) this.localCopies.delete(key);
|
|
56361
|
+
}
|
|
56362
|
+
restoreCopy(input) {
|
|
56363
|
+
const copy = [...this.localCopies.values()].find((copy) => copy.text === input.text && copy.html === input.html);
|
|
56364
|
+
return copy && input.markdown == null && !input.plainText && copy.text === input.text && copy.html === input.html ? {
|
|
56365
|
+
...input,
|
|
56366
|
+
markdown: copy.markdown
|
|
56367
|
+
} : input;
|
|
56368
|
+
}
|
|
56161
56369
|
copyHandler;
|
|
56162
56370
|
originalSource = "";
|
|
56163
56371
|
reportingSuppressed = false;
|
|
@@ -56373,7 +56581,9 @@ var InkKitEditor = class InkKitEditor {
|
|
|
56373
56581
|
revision: this.session.mark(),
|
|
56374
56582
|
lastMarkdown: this.lastMarkdown,
|
|
56375
56583
|
literalMatch: this.literalMatch,
|
|
56376
|
-
textScope: this.textScope
|
|
56584
|
+
textScope: this.textScope,
|
|
56585
|
+
formattedRedoLimit: this.formattedRedoLimit,
|
|
56586
|
+
formattedUndone: this.formattedUndone
|
|
56377
56587
|
};
|
|
56378
56588
|
}
|
|
56379
56589
|
finish(call, before, failure) {
|
|
@@ -56395,6 +56605,8 @@ var InkKitEditor = class InkKitEditor {
|
|
|
56395
56605
|
this.lastMarkdown = before.lastMarkdown;
|
|
56396
56606
|
this.literalMatch = before.literalMatch;
|
|
56397
56607
|
this.textScope = before.textScope;
|
|
56608
|
+
this.formattedRedoLimit = before.formattedRedoLimit;
|
|
56609
|
+
this.formattedUndone = before.formattedUndone;
|
|
56398
56610
|
}
|
|
56399
56611
|
/** Reports a refused edit to the facade call that made it, or else to `events.error`. */
|
|
56400
56612
|
refuse(error) {
|
|
@@ -56535,7 +56747,7 @@ var InkKitEditor = class InkKitEditor {
|
|
|
56535
56747
|
table: this.literalSurface ? void 0 : tableContext(state),
|
|
56536
56748
|
commands: {
|
|
56537
56749
|
undo: mutable && (!!this.pendingSource || undo(state)),
|
|
56538
|
-
redo: mutable && (this.undoneSteps.length > 0 || !this.pendingSource && redo(state)),
|
|
56750
|
+
redo: mutable && (this.undoneSteps.length > 0 || !this.pendingSource && this.formattedRedoLimit !== 0 && redo(state)),
|
|
56539
56751
|
insertText: mutable,
|
|
56540
56752
|
paste: mutable,
|
|
56541
56753
|
replace: mutable,
|
|
@@ -56705,7 +56917,9 @@ var InkKitEditor = class InkKitEditor {
|
|
|
56705
56917
|
this.assertAlive();
|
|
56706
56918
|
expectString(text, "text");
|
|
56707
56919
|
this.assertMutation(expectedGeneration);
|
|
56708
|
-
|
|
56920
|
+
const changed = this.applySource(text, true);
|
|
56921
|
+
if (changed) this.localCopies.clear();
|
|
56922
|
+
return changed;
|
|
56709
56923
|
}
|
|
56710
56924
|
applySource(text, isolated, from, to, native = false) {
|
|
56711
56925
|
if (!this.writable) throw new InkKitError("read-only", "The editor is read-only");
|
|
@@ -56724,6 +56938,7 @@ var InkKitEditor = class InkKitEditor {
|
|
|
56724
56938
|
const previous = this.pendingSource;
|
|
56725
56939
|
const continuing = previous && !previous.closed && !closed && now - this.lastSourceInput <= sourceGroupDelay;
|
|
56726
56940
|
if (previous && !continuing) this.rememberTypedStep(previous);
|
|
56941
|
+
this.formattedRedoLimit = 0;
|
|
56727
56942
|
this.lastSourceInput = now;
|
|
56728
56943
|
this.undoneSteps = [];
|
|
56729
56944
|
this.formattedUndone = 0;
|
|
@@ -56851,7 +57066,7 @@ var InkKitEditor = class InkKitEditor {
|
|
|
56851
57066
|
}
|
|
56852
57067
|
}
|
|
56853
57068
|
let tr = view.state.tr.replaceWith(0, view.state.doc.content.size, parsed.content).setDocAttribute(sourceAttribute, provenance).setMeta(sourceReplacement, true);
|
|
56854
|
-
tr.setSelection(
|
|
57069
|
+
tr.setSelection(terminalSelection(tr.doc));
|
|
56855
57070
|
if (isolated) tr = closeHistory(tr);
|
|
56856
57071
|
view.dispatch(tr);
|
|
56857
57072
|
if (isolated) view.dispatch(closeHistory(view.state.tr).setMeta("addToHistory", false));
|
|
@@ -56862,7 +57077,7 @@ var InkKitEditor = class InkKitEditor {
|
|
|
56862
57077
|
this.assertMutation(expectedGeneration);
|
|
56863
57078
|
if (this.literalSurface && this.stepTypedSource("undo")) return true;
|
|
56864
57079
|
const view = this.editor.ctx.get(editorViewCtx);
|
|
56865
|
-
const undone = !this.literalSurface && undoSmartPunctuation(view.state, view.dispatch) || undo
|
|
57080
|
+
const undone = !this.literalSurface && undoSmartPunctuation(view.state, view.dispatch) || this.stepFormattedHistory("undo");
|
|
56866
57081
|
if (undone) {
|
|
56867
57082
|
if (this.literalSurface && this.undoneSteps.length) this.formattedUndone++;
|
|
56868
57083
|
else this.undoneSteps = [];
|
|
@@ -56875,14 +57090,30 @@ var InkKitEditor = class InkKitEditor {
|
|
|
56875
57090
|
const view = this.editor.ctx.get(editorViewCtx);
|
|
56876
57091
|
if (this.literalSurface) {
|
|
56877
57092
|
if (this.formattedUndone > 0) {
|
|
56878
|
-
this.
|
|
56879
|
-
|
|
57093
|
+
if (this.formattedRedoLimit !== 0 && redo(view.state)) {
|
|
57094
|
+
const redone = this.stepFormattedHistory("redo");
|
|
57095
|
+
if (redone) this.formattedUndone--;
|
|
57096
|
+
return redone;
|
|
57097
|
+
}
|
|
56880
57098
|
this.formattedUndone = 0;
|
|
56881
57099
|
}
|
|
56882
57100
|
if (this.stepTypedSource("redo")) return true;
|
|
56883
57101
|
if (this.pendingSource) return false;
|
|
56884
57102
|
}
|
|
56885
|
-
return redo
|
|
57103
|
+
return this.stepFormattedHistory("redo");
|
|
57104
|
+
}
|
|
57105
|
+
stepFormattedHistory(direction) {
|
|
57106
|
+
if (direction === "redo" && this.formattedRedoLimit === 0) return false;
|
|
57107
|
+
const view = this.editor.ctx.get(editorViewCtx);
|
|
57108
|
+
const before = view.state;
|
|
57109
|
+
const previous = this.historyDirection;
|
|
57110
|
+
this.historyDirection = direction;
|
|
57111
|
+
try {
|
|
57112
|
+
(direction === "undo" ? undo : redo)(before, view.dispatch);
|
|
57113
|
+
return view.state !== before;
|
|
57114
|
+
} finally {
|
|
57115
|
+
this.historyDirection = previous;
|
|
57116
|
+
}
|
|
56886
57117
|
}
|
|
56887
57118
|
replaceLiteralSelection(text, isolated = true, retainEndings = false) {
|
|
56888
57119
|
const value = this.plain.value;
|
|
@@ -56985,16 +57216,22 @@ var InkKitEditor = class InkKitEditor {
|
|
|
56985
57216
|
const metadata = referenceMetadata(this.editor.ctx, selectedDoc ?? doc, content);
|
|
56986
57217
|
if (metadata != null) result.html = withReferenceMetadata(result.html, metadata);
|
|
56987
57218
|
this.assertCaptured(captured);
|
|
57219
|
+
this.rememberCopy(result, markdown, content, selectedSource != null && selectedSource.markdown !== selectedSource.shareable);
|
|
56988
57220
|
return {
|
|
56989
57221
|
...version,
|
|
56990
57222
|
...result
|
|
56991
57223
|
};
|
|
56992
57224
|
}
|
|
57225
|
+
/** Cancels the pending image paste without changing the document or editability. */
|
|
57226
|
+
cancelPendingImports(expectedGeneration) {
|
|
57227
|
+
this.assertReady(expectedGeneration);
|
|
57228
|
+
this.pasteController.cancelPending();
|
|
57229
|
+
}
|
|
56993
57230
|
/** Pastes content the host read from the native clipboard. Capture it once; don't read the
|
|
56994
57231
|
* clipboard again while this runs. */
|
|
56995
57232
|
async paste(input, expectedGeneration) {
|
|
56996
57233
|
this.assertAlive();
|
|
56997
|
-
input = clipboardInput(input);
|
|
57234
|
+
input = this.restoreCopy(clipboardInput(input));
|
|
56998
57235
|
this.assertMutation(expectedGeneration);
|
|
56999
57236
|
if (this.literalSurface) {
|
|
57000
57237
|
this.pasteAsPlainText(this.mode === "source" && this.formatType === "md" ? input.markdown ?? input.text : input.text);
|
|
@@ -57027,14 +57264,9 @@ var InkKitEditor = class InkKitEditor {
|
|
|
57027
57264
|
else {
|
|
57028
57265
|
const { schema } = view.state;
|
|
57029
57266
|
const marks = view.state.storedMarks ?? (view.state.selection.empty ? view.state.selection.$from.marks() : view.state.selection.$from.marksAcross(view.state.selection.$to)) ?? [];
|
|
57030
|
-
const children = [];
|
|
57031
57267
|
const isHTML = !inHiddenComment && htmlBreakAt(view.state.selection.$from);
|
|
57032
57268
|
const lines = text.replace(/\r\n?/g, "\n").split("\n");
|
|
57033
|
-
|
|
57034
|
-
const finalBreak = index === lines.length - 1 && line === "";
|
|
57035
|
-
if (index) children.push(schema.nodes.hardbreak.create({ isHTML }, null, finalBreak ? [] : marks));
|
|
57036
|
-
if (line) children.push(schema.text(line, marks));
|
|
57037
|
-
});
|
|
57269
|
+
const children = literalTextNodes(schema, text, marks, isHTML);
|
|
57038
57270
|
if (!children.length) {
|
|
57039
57271
|
view.dispatch(view.state.tr.deleteSelection());
|
|
57040
57272
|
return;
|
|
@@ -57077,12 +57309,14 @@ var InkKitEditor = class InkKitEditor {
|
|
|
57077
57309
|
async destroy() {
|
|
57078
57310
|
if (this.destroyed) return;
|
|
57079
57311
|
this.destroyed = true;
|
|
57312
|
+
this.localCopies.clear();
|
|
57080
57313
|
this.ready = false;
|
|
57081
57314
|
this.session.close();
|
|
57082
57315
|
this.pendingSource = void 0;
|
|
57083
57316
|
this.typedSteps = [];
|
|
57084
57317
|
this.undoneSteps = [];
|
|
57085
57318
|
this.formattedUndone = 0;
|
|
57319
|
+
this.formattedRedoLimit = void 0;
|
|
57086
57320
|
this.cancelExports();
|
|
57087
57321
|
this.mediaPolicy();
|
|
57088
57322
|
this.pasteController.destroy();
|
|
@@ -57122,6 +57356,7 @@ var InkKitEditor = class InkKitEditor {
|
|
|
57122
57356
|
if (portable && this.events.clipboard) this.clipboardSnapshot("selection").then(async (content) => {
|
|
57123
57357
|
if (cut) refuseUnportableCut(content);
|
|
57124
57358
|
await writeClipboard(this.events, content);
|
|
57359
|
+
this.retainCopy(content.html);
|
|
57125
57360
|
if (cut) {
|
|
57126
57361
|
this.assertCut(captured);
|
|
57127
57362
|
this.plain.setSelectionRange(from, to);
|
|
@@ -57131,6 +57366,7 @@ var InkKitEditor = class InkKitEditor {
|
|
|
57131
57366
|
else {
|
|
57132
57367
|
const output = clipboardContent(parsed.content, parsed.type.schema);
|
|
57133
57368
|
if (!event.clipboardData) return;
|
|
57369
|
+
this.rememberCopy(output, selected.markdown, parsed.content, selected.markdown !== selected.shareable, true);
|
|
57134
57370
|
event.clipboardData.setData("text/plain", output.text);
|
|
57135
57371
|
event.clipboardData.setData("text/html", output.html);
|
|
57136
57372
|
if (portable) {
|
|
@@ -57155,6 +57391,7 @@ var InkKitEditor = class InkKitEditor {
|
|
|
57155
57391
|
instance.ownsRootClass = !root.classList.contains("inkkit-root");
|
|
57156
57392
|
root.classList.add("inkkit-root");
|
|
57157
57393
|
instance.pasteController = new PasteController({
|
|
57394
|
+
restoreCopy: (input) => instance.restoreCopy(input),
|
|
57158
57395
|
ctx: () => instance.editor.ctx,
|
|
57159
57396
|
context: () => instance.context(),
|
|
57160
57397
|
adapter: options.images,
|
|
@@ -57258,6 +57495,14 @@ var InkKitEditor = class InkKitEditor {
|
|
|
57258
57495
|
return;
|
|
57259
57496
|
}
|
|
57260
57497
|
}
|
|
57498
|
+
if (instance.formattedRedoLimit !== void 0) {
|
|
57499
|
+
const depth = redoDepth(next);
|
|
57500
|
+
if (depth === 0) instance.formattedRedoLimit = void 0;
|
|
57501
|
+
else if (next !== this.state) {
|
|
57502
|
+
if (instance.historyDirection === "undo") instance.formattedRedoLimit = Math.min(depth, instance.formattedRedoLimit + 1);
|
|
57503
|
+
else if (instance.historyDirection === "redo") instance.formattedRedoLimit = Math.max(0, instance.formattedRedoLimit - 1);
|
|
57504
|
+
}
|
|
57505
|
+
}
|
|
57261
57506
|
this.updateState(next);
|
|
57262
57507
|
},
|
|
57263
57508
|
handleScrollToSelection: () => {
|
|
@@ -57265,7 +57510,7 @@ var InkKitEditor = class InkKitEditor {
|
|
|
57265
57510
|
return true;
|
|
57266
57511
|
}
|
|
57267
57512
|
}));
|
|
57268
|
-
}).use(labelsCtx).use(instance.pasteController.plugin).use(visibleClipboard).use($prose(() => instance.suggestions.plugin())).use(instance.keymapPlugin).use(createDialect(Boolean(options.images || options.files), Boolean(options.wikiLinks), Boolean(options.files))).use(codeControlCtx).use(codeControlsPlugin(() => instance.viewport().rect)).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-
|
|
57513
|
+
}).use(labelsCtx).use(instance.pasteController.plugin).use(visibleClipboard).use($prose(() => instance.suggestions.plugin())).use(instance.keymapPlugin).use(createDialect(Boolean(options.images || options.files), Boolean(options.wikiLinks), Boolean(options.files))).use(codeControlCtx).use(codeControlsPlugin(() => instance.viewport().rect)).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-AI86evan.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, {
|
|
57269
57514
|
capture: () => instance.adapterCapture(),
|
|
57270
57515
|
active: () => instance.ready && !instance.destroyed && !instance.literalSurface,
|
|
57271
57516
|
labels: {
|
|
@@ -57345,6 +57590,7 @@ var InkKitEditor = class InkKitEditor {
|
|
|
57345
57590
|
event.preventDefault();
|
|
57346
57591
|
instance.paste({
|
|
57347
57592
|
text: event.clipboardData.getData("text/plain"),
|
|
57593
|
+
html: event.clipboardData.getData("text/html"),
|
|
57348
57594
|
markdown: event.clipboardData.getData("text/markdown") || void 0
|
|
57349
57595
|
}).catch((error) => instance.report(error));
|
|
57350
57596
|
});
|
|
@@ -57414,11 +57660,13 @@ var InkKitEditor = class InkKitEditor {
|
|
|
57414
57660
|
instance.snapshot();
|
|
57415
57661
|
const content = expanded;
|
|
57416
57662
|
const valid = fragment.firstChild?.isInline ? Fragment.from(view.state.schema.nodes.paragraph.create(null, fragment)) : fragment;
|
|
57417
|
-
selectionMarkdown(instance.editor.ctx, view.state.doc, valid);
|
|
57663
|
+
const markdown = selectionMarkdown(instance.editor.ctx, view.state.doc, valid);
|
|
57418
57664
|
const output = clipboardContent(content, view.state.schema);
|
|
57419
|
-
event.clipboardData.setData("text/plain", output.text);
|
|
57420
57665
|
const metadata = referenceMetadata(instance.editor.ctx, view.state.doc, valid);
|
|
57421
|
-
|
|
57666
|
+
if (metadata != null) output.html = withReferenceMetadata(output.html, metadata);
|
|
57667
|
+
instance.rememberCopy(output, markdown, fragment, false, true);
|
|
57668
|
+
event.clipboardData.setData("text/plain", output.text);
|
|
57669
|
+
event.clipboardData.setData("text/html", output.html);
|
|
57422
57670
|
if (event.type === "cut" && instance.writable) view.dispatch(view.state.tr.deleteSelection().scrollIntoView());
|
|
57423
57671
|
} catch (error) {
|
|
57424
57672
|
instance.report(error);
|
|
@@ -57434,6 +57682,7 @@ var InkKitEditor = class InkKitEditor {
|
|
|
57434
57682
|
instance.clipboardSnapshot("selection").then(async (content) => {
|
|
57435
57683
|
if (cut) refuseUnportableCut(content);
|
|
57436
57684
|
await writeClipboard(events, content);
|
|
57685
|
+
instance.retainCopy(content.html);
|
|
57437
57686
|
if (cut) {
|
|
57438
57687
|
instance.assertCut(captured);
|
|
57439
57688
|
view.dispatch(view.state.tr.deleteRange(from, to).scrollIntoView());
|
|
@@ -57481,6 +57730,7 @@ var InkKitEditor = class InkKitEditor {
|
|
|
57481
57730
|
this.typedSteps = [];
|
|
57482
57731
|
this.undoneSteps = [];
|
|
57483
57732
|
this.formattedUndone = 0;
|
|
57733
|
+
this.formattedRedoLimit = void 0;
|
|
57484
57734
|
this.mode = "formatted";
|
|
57485
57735
|
this.plainComposing = false;
|
|
57486
57736
|
this.beforePlainInput = void 0;
|
|
@@ -57860,6 +58110,7 @@ var InkKitEditor = class InkKitEditor {
|
|
|
57860
58110
|
}])[0]);
|
|
57861
58111
|
}
|
|
57862
58112
|
load(markdown, preservation) {
|
|
58113
|
+
this.localCopies.clear();
|
|
57863
58114
|
this.originalSource = markdown;
|
|
57864
58115
|
const { ctx } = this.editor;
|
|
57865
58116
|
const view = ctx.get(editorViewCtx);
|
|
@@ -57876,9 +58127,7 @@ var InkKitEditor = class InkKitEditor {
|
|
|
57876
58127
|
this.preservation = preservation;
|
|
57877
58128
|
this.carried = void 0;
|
|
57878
58129
|
this.lastMarkdown = markdown;
|
|
57879
|
-
const
|
|
57880
|
-
const $end = doc.resolve(doc.content.size);
|
|
57881
|
-
const end = isImageBlock(doc.lastChild) ? new GapCursor($end) : Selection.findFrom($end, -1, true) ?? Selection.atEnd(doc);
|
|
58130
|
+
const end = terminalSelection(view.state.doc);
|
|
57882
58131
|
view.dispatch(setSearchState(view.state.tr.setSelection(end), new SearchQuery({ search: "" })));
|
|
57883
58132
|
}
|
|
57884
58133
|
/** Selects the next match and returns whether there was one. */
|
|
@@ -58607,6 +58856,7 @@ var InkKitEditor = class InkKitEditor {
|
|
|
58607
58856
|
"printableSnapshot",
|
|
58608
58857
|
"clipboardSnapshot",
|
|
58609
58858
|
"paste",
|
|
58859
|
+
"cancelPendingImports",
|
|
58610
58860
|
"pasteAsPlainText",
|
|
58611
58861
|
"commandState",
|
|
58612
58862
|
"setEditable",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as Decoration, c as PluginKey, d as __toESM, i as $prose, o as DecorationSet, s as Plugin, u as __commonJSMin } from "./core-
|
|
1
|
+
import { a as Decoration, c as PluginKey, d as __toESM, i as $prose, o as DecorationSet, s as Plugin, u as __commonJSMin } from "./core-C612uj1Q.js";
|
|
2
2
|
//#region node_modules/.pnpm/highlight.js@11.11.2/node_modules/highlight.js/es/languages/arduino.js
|
|
3
3
|
/** @type LanguageFn */
|
|
4
4
|
function cPlusPlus(hljs) {
|
package/dist/core.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { InkKitEditor } from './editor.js';
|
|
2
2
|
export type { EditorEvents, EditorOptions, TextInputPreferences, CommandState, EditingMode, CaretState, Mark, Block, FormatCommand, FormatOptions, KeyInput, ImageInsertion, ShortcutName, Keymap, } from './editor.js';
|
|
3
3
|
export { InkKitError } from './types.js';
|
|
4
|
-
export type { DocumentFormat, EditorLabels, Heading, TableCommand, TableOptions, BlockMoveDirection, DocumentContext, DocumentInput, DocumentSnapshot, DocumentVersion, EditorErrorCode, ImageAdapter, WikiLinkReference, WikiLinkAdapter, FileReference, ClientPoint, FileContext, FilePresentation, FileAdapter, CapturedImage, PortableImage, ClipboardInput, ClipboardOutput, ClipboardScope, ClipboardImage, ClipboardDiagram, PrintableDocument, PrintableWarning, TextRange, ReadableTextSnapshot, TextRect, ViewportInsets, ViewportOptions, ViewportSnapshot, } from './types.js';
|
|
4
|
+
export type { DocumentFormat, EditorLabels, Heading, TableCommand, TableOptions, BlockMoveDirection, DocumentContext, DocumentInput, DocumentSnapshot, DocumentVersion, EditorErrorCode, ImageAdapter, ImageImportContext, WikiLinkReference, WikiLinkAdapter, FileReference, ClientPoint, FileContext, FilePresentation, FileAdapter, CapturedImage, PortableImage, ClipboardInput, ClipboardOutput, ClipboardScope, ClipboardImage, ClipboardDiagram, PrintableDocument, PrintableWarning, TextRange, ReadableTextSnapshot, TextRect, ViewportInsets, ViewportOptions, ViewportSnapshot, } from './types.js';
|
|
5
5
|
export type { SlashMenuOptions, SlashCommandName, SlashCommand } from './types.js';
|
package/dist/core.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { r as InkKitError, t as InkKitEditor } from "./chunks/core-
|
|
1
|
+
import { r as InkKitError, t as InkKitEditor } from "./chunks/core-C612uj1Q.js";
|
|
2
2
|
export { InkKitEditor, InkKitError };
|
package/dist/editor.d.ts
CHANGED
|
@@ -143,7 +143,7 @@ export interface EditorEvents {
|
|
|
143
143
|
export declare const editorEvents: readonly ["changed", "commandStateChanged", "openLink", "copy", "error", "clipboard"];
|
|
144
144
|
/**
|
|
145
145
|
* The editor. Create it with `InkKitEditor.mount`, load a document, and read it back with
|
|
146
|
-
* `snapshot`. The reference is https://
|
|
146
|
+
* `snapshot`. The reference is https://inkkit.cyzr.me/reference/editor.
|
|
147
147
|
*/
|
|
148
148
|
export declare class InkKitEditor {
|
|
149
149
|
private readonly options;
|
|
@@ -160,6 +160,8 @@ export declare class InkKitEditor {
|
|
|
160
160
|
private typedSteps;
|
|
161
161
|
private undoneSteps;
|
|
162
162
|
private formattedUndone;
|
|
163
|
+
private formattedRedoLimit?;
|
|
164
|
+
private historyDirection?;
|
|
163
165
|
private lastSourceInput;
|
|
164
166
|
private syncingSource;
|
|
165
167
|
private mode;
|
|
@@ -177,6 +179,10 @@ export declare class InkKitEditor {
|
|
|
177
179
|
private auxClickHandler?;
|
|
178
180
|
private untrackLinkModifier?;
|
|
179
181
|
private footnoteKeyHandler?;
|
|
182
|
+
private readonly localCopies;
|
|
183
|
+
private rememberCopy;
|
|
184
|
+
private retainCopy;
|
|
185
|
+
private restoreCopy;
|
|
180
186
|
private copyHandler?;
|
|
181
187
|
private originalSource;
|
|
182
188
|
private reportingSuppressed;
|
|
@@ -298,6 +304,7 @@ export declare class InkKitEditor {
|
|
|
298
304
|
undo(expectedGeneration?: number): boolean;
|
|
299
305
|
/** Returns whether a history step applied. */
|
|
300
306
|
redo(expectedGeneration?: number): boolean;
|
|
307
|
+
private stepFormattedHistory;
|
|
301
308
|
private replaceLiteralSelection;
|
|
302
309
|
/** The complete current text, which is what a host saves. It throws rather than return partial
|
|
303
310
|
* text. */
|
|
@@ -314,6 +321,8 @@ export declare class InkKitEditor {
|
|
|
314
321
|
/** Prepares the document or the selection for the native clipboard. Rejects with `stale-document`
|
|
315
322
|
* if the document changes first. */
|
|
316
323
|
clipboardSnapshot(scope?: ClipboardScope, expectedGeneration?: number): Promise<ClipboardOutput>;
|
|
324
|
+
/** Cancels the pending image paste without changing the document or editability. */
|
|
325
|
+
cancelPendingImports(expectedGeneration?: number): void;
|
|
317
326
|
/** Pastes content the host read from the native clipboard. Capture it once; don't read the
|
|
318
327
|
* clipboard again while this runs. */
|
|
319
328
|
paste(input: ClipboardInput, expectedGeneration?: number): Promise<void>;
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as registerMermaid, r as InkKitError, t as InkKitEditor } from "./chunks/core-
|
|
1
|
+
import { n as registerMermaid, r as InkKitError, t as InkKitEditor } from "./chunks/core-C612uj1Q.js";
|
|
2
2
|
//#region src/index.ts
|
|
3
3
|
registerMermaid(async () => (await import("mermaid")).default);
|
|
4
4
|
//#endregion
|
package/dist/style.css
CHANGED
|
@@ -154,9 +154,11 @@
|
|
|
154
154
|
transform: translate(-50%, -50%);
|
|
155
155
|
border-radius: 4px;
|
|
156
156
|
box-shadow: 0 0 0 1px var(--_inkkit-rule);
|
|
157
|
-
cursor: grab;
|
|
158
157
|
touch-action: none;
|
|
159
158
|
}
|
|
159
|
+
.inkkit-root .inkkit-table-controls .inkkit-table-grip:not(:disabled) {
|
|
160
|
+
cursor: grab;
|
|
161
|
+
}
|
|
160
162
|
.inkkit-root .inkkit-table-grip[data-inkkit-axis='column'] {
|
|
161
163
|
width: 24px;
|
|
162
164
|
height: 14px;
|
|
@@ -252,6 +254,10 @@
|
|
|
252
254
|
outline-offset: 2px;
|
|
253
255
|
border-radius: 6px;
|
|
254
256
|
}
|
|
257
|
+
/* A gap or node selection draws its own indicator, not a native text caret. */
|
|
258
|
+
.inkkit-root .ProseMirror.ProseMirror-hideselection {
|
|
259
|
+
caret-color: transparent;
|
|
260
|
+
}
|
|
255
261
|
.inkkit-root .ProseMirror-gapcursor {
|
|
256
262
|
display: none;
|
|
257
263
|
pointer-events: none;
|
package/dist/types.d.ts
CHANGED
|
@@ -51,6 +51,10 @@ export interface PortableImage {
|
|
|
51
51
|
mimeType: string;
|
|
52
52
|
filename?: string;
|
|
53
53
|
}
|
|
54
|
+
/** The document and cancellation signal for one image import. */
|
|
55
|
+
export interface ImageImportContext extends DocumentContext {
|
|
56
|
+
signal: AbortSignal;
|
|
57
|
+
}
|
|
54
58
|
/** Stores, shows and exports the images a host owns. References stay opaque to the editor. */
|
|
55
59
|
export interface ImageAdapter {
|
|
56
60
|
/** The display URL for `reference`, or `undefined` when the image is unavailable. */
|
|
@@ -58,7 +62,7 @@ export interface ImageAdapter {
|
|
|
58
62
|
url: string;
|
|
59
63
|
} | undefined;
|
|
60
64
|
/** Stores the bytes and returns the reference to write into the Markdown. */
|
|
61
|
-
importImage(input: CapturedImage, context:
|
|
65
|
+
importImage(input: CapturedImage, context: ImageImportContext): Promise<{
|
|
62
66
|
reference: string;
|
|
63
67
|
}>;
|
|
64
68
|
/** The stored bytes and type of `reference`, for portable clipboard and print output. */
|