@gjermundgaraba/pixel-paper 0.1.1 → 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 +11 -1
- package/THIRD_PARTY_NOTICES.md +25 -0
- package/dist/board/board.d.ts +12 -12
- package/dist/confirm-dialog/confirm-dialog.d.ts +8 -8
- package/dist/dialog/dialog.d.ts +8 -8
- package/dist/index.d.ts +44 -43
- package/dist/index.js +2 -1
- package/dist/inline-input/inline-input.d.ts +6 -6
- package/dist/key-help/key-help.d.ts +8 -8
- package/dist/markdown-editor/element.d.ts +4 -0
- package/dist/markdown-editor/element.js +120 -0
- package/dist/markdown-editor/engine.js +88 -0
- package/dist/markdown-editor/index.d.ts +5 -0
- package/dist/markdown-editor/index.js +6 -0
- package/dist/markdown-editor/link-policy.js +18 -0
- package/dist/markdown-editor/live/live.js +507 -0
- package/dist/markdown-editor/live/theme.js +132 -0
- package/dist/markdown-editor/markdown-editor.d.ts +11 -0
- package/dist/markdown-editor/markdown-editor.js +22 -0
- package/dist/markdown-editor/reconcile.js +24 -0
- package/dist/menu/menu.d.ts +10 -10
- package/dist/rail/rail.d.ts +16 -16
- package/dist/sortable/sortable.d.ts +12 -12
- package/package.json +16 -2
- package/src/pixel-paper.css +46 -0
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { brandViewResult as __foldkitBrandViewResult } from 'foldkit/brand'
|
|
2
|
+
import { __exportAll } from "../_virtual/_rolldown/runtime.js";
|
|
3
|
+
import { view } from "./markdown-editor.js";
|
|
4
|
+
// src/markdown-editor/index.ts
|
|
5
|
+
var markdown_editor_exports = /* @__PURE__ */ __exportAll({ view: () => __foldkitBrandViewResult((view), "@gjermundgaraba/pixel-paper/markdown-editor/index.js#view") });
|
|
6
|
+
export { markdown_editor_exports, view };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { brandViewResult as __foldkitBrandViewResult } from 'foldkit/brand'
|
|
2
|
+
// src/markdown-editor/link-policy.ts
|
|
3
|
+
const LINK_PROTOCOLS = /* @__PURE__ */ new Set([
|
|
4
|
+
"http:",
|
|
5
|
+
"https:",
|
|
6
|
+
"mailto:"
|
|
7
|
+
]);
|
|
8
|
+
const IMAGE_PROTOCOLS = /* @__PURE__ */ new Set(["http:", "https:"]);
|
|
9
|
+
const allowedUrl = (protocols, url, base) => {
|
|
10
|
+
const parsed = URL.parse(url, base);
|
|
11
|
+
return __foldkitBrandViewResult((parsed !== null && protocols.has(parsed.protocol) ? parsed.href : void 0), "@gjermundgaraba/pixel-paper/markdown-editor/link-policy.js#allowedUrl");
|
|
12
|
+
};
|
|
13
|
+
/** A link's target as an absolute URL, when it is one a click may open. The browser's own
|
|
14
|
+
* URL parser decides, so a tab, a newline or mixed case cannot hide a scheme from it. */
|
|
15
|
+
const safeHref = (url, base) => __foldkitBrandViewResult((allowedUrl(LINK_PROTOCOLS, url, base)), "@gjermundgaraba/pixel-paper/markdown-editor/link-policy.js#safeHref");
|
|
16
|
+
/** An image's source as an absolute URL, when the page may fetch it on render. */
|
|
17
|
+
const safeImageSource = (url, base) => __foldkitBrandViewResult((allowedUrl(IMAGE_PROTOCOLS, url, base)), "@gjermundgaraba/pixel-paper/markdown-editor/link-policy.js#safeImageSource");
|
|
18
|
+
export { safeHref, safeImageSource };
|
|
@@ -0,0 +1,507 @@
|
|
|
1
|
+
import { brandViewResult as __foldkitBrandViewResult } from 'foldkit/brand'
|
|
2
|
+
import { safeHref, safeImageSource } from "../link-policy.js";
|
|
3
|
+
import { liveMarkdownTheme } from "./theme.js";
|
|
4
|
+
import { syntaxTree } from "@codemirror/language";
|
|
5
|
+
import { Prec, RangeSetBuilder, StateEffect, StateField } from "@codemirror/state";
|
|
6
|
+
import { Decoration, EditorView, ViewPlugin, WidgetType, keymap } from "@codemirror/view";
|
|
7
|
+
// src/markdown-editor/live/live.ts
|
|
8
|
+
const UNKNOWN_HEIGHT = -1;
|
|
9
|
+
const TABLE_ROW_HEIGHT = 32;
|
|
10
|
+
const IMAGE_ESTIMATED_HEIGHT = 240;
|
|
11
|
+
const TABLE_HINT = "Click to edit the table";
|
|
12
|
+
var DrawnWidget = class extends WidgetType {
|
|
13
|
+
drawing;
|
|
14
|
+
constructor(drawing) {
|
|
15
|
+
super();
|
|
16
|
+
this.drawing = drawing;
|
|
17
|
+
}
|
|
18
|
+
eq(other) {
|
|
19
|
+
return __foldkitBrandViewResult((other.drawing.key === this.drawing.key), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#eq");
|
|
20
|
+
}
|
|
21
|
+
toDOM(view) {
|
|
22
|
+
return __foldkitBrandViewResult((this.drawing.draw(view)), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#toDOM");
|
|
23
|
+
}
|
|
24
|
+
get estimatedHeight() {
|
|
25
|
+
return __foldkitBrandViewResult((this.drawing.estimatedHeight), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#estimatedHeight");
|
|
26
|
+
}
|
|
27
|
+
ignoreEvent() {
|
|
28
|
+
return __foldkitBrandViewResult((this.drawing.takesOwnEvents), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#ignoreEvent");
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
const spanOf = (className, text) => {
|
|
32
|
+
const span = document.createElement("span");
|
|
33
|
+
span.className = className;
|
|
34
|
+
span.textContent = text;
|
|
35
|
+
return __foldkitBrandViewResult((span), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#spanOf");
|
|
36
|
+
};
|
|
37
|
+
const typographyWidget = (text, isDivider) => __foldkitBrandViewResult((new DrawnWidget({
|
|
38
|
+
key: `typography:${isDivider}:${text}`,
|
|
39
|
+
draw: () => __foldkitBrandViewResult((spanOf(isDivider ? "lmd-labeled-rule" : "", text)), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#draw"),
|
|
40
|
+
estimatedHeight: UNKNOWN_HEIGHT,
|
|
41
|
+
takesOwnEvents: false
|
|
42
|
+
})), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#typographyWidget");
|
|
43
|
+
const checkboxWidget = (isChecked) => __foldkitBrandViewResult((new DrawnWidget({
|
|
44
|
+
key: `checkbox:${isChecked}`,
|
|
45
|
+
draw: () => {
|
|
46
|
+
const box = document.createElement("input");
|
|
47
|
+
box.type = "checkbox";
|
|
48
|
+
box.checked = isChecked;
|
|
49
|
+
box.className = "lmd-check";
|
|
50
|
+
return __foldkitBrandViewResult((box), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#draw~2");
|
|
51
|
+
},
|
|
52
|
+
estimatedHeight: UNKNOWN_HEIGHT,
|
|
53
|
+
takesOwnEvents: false
|
|
54
|
+
})), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#checkboxWidget");
|
|
55
|
+
const listMarkWidget = (text) => __foldkitBrandViewResult((new DrawnWidget({
|
|
56
|
+
key: `list-mark:${text}`,
|
|
57
|
+
draw: () => __foldkitBrandViewResult((spanOf("lmd-bullet", text)), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#draw~3"),
|
|
58
|
+
estimatedHeight: UNKNOWN_HEIGHT,
|
|
59
|
+
takesOwnEvents: true
|
|
60
|
+
})), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#listMarkWidget");
|
|
61
|
+
const imageWidget = (source, alt) => __foldkitBrandViewResult((new DrawnWidget({
|
|
62
|
+
key: `image:${source}\n${alt}`,
|
|
63
|
+
draw: () => {
|
|
64
|
+
const box = spanOf("lmd-img-box", "");
|
|
65
|
+
const safeSource = safeImageSource(source, document.baseURI);
|
|
66
|
+
if (safeSource === void 0) {
|
|
67
|
+
box.append(spanOf("lmd-img-note", alt === "" ? "Image not shown" : alt));
|
|
68
|
+
return __foldkitBrandViewResult((box), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#draw~4");
|
|
69
|
+
}
|
|
70
|
+
const image = document.createElement("img");
|
|
71
|
+
image.className = "lmd-img";
|
|
72
|
+
image.alt = alt;
|
|
73
|
+
image.addEventListener("error", () => {
|
|
74
|
+
image.replaceWith(spanOf("lmd-img-note", alt === "" ? "Image not found" : `Image not found: ${alt}`));
|
|
75
|
+
}, { once: true });
|
|
76
|
+
image.src = safeSource;
|
|
77
|
+
box.append(image);
|
|
78
|
+
return __foldkitBrandViewResult((box), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#draw~4");
|
|
79
|
+
},
|
|
80
|
+
estimatedHeight: IMAGE_ESTIMATED_HEIGHT,
|
|
81
|
+
takesOwnEvents: false
|
|
82
|
+
})), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#imageWidget");
|
|
83
|
+
const isList = (node) => __foldkitBrandViewResult((node?.name === "BulletList" || node?.name === "OrderedList"), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#isList");
|
|
84
|
+
const listDepth = (item) => {
|
|
85
|
+
let depth = 0;
|
|
86
|
+
for (let node = item.parent; node !== null; node = node.parent) if (isList(node)) depth += 1;
|
|
87
|
+
return __foldkitBrandViewResult((depth), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#listDepth");
|
|
88
|
+
};
|
|
89
|
+
const firstMarkOf = (state, item) => {
|
|
90
|
+
const mark = item.parent?.firstChild?.getChild("ListMark");
|
|
91
|
+
return __foldkitBrandViewResult((mark === void 0 || mark === null ? void 0 : state.sliceDoc(mark.from, mark.to)), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#firstMarkOf");
|
|
92
|
+
};
|
|
93
|
+
const itemNumber = (state, item) => {
|
|
94
|
+
const start = Number(/^\d+/u.exec(firstMarkOf(state, item) ?? "")?.[0] ?? 1);
|
|
95
|
+
let index = 0;
|
|
96
|
+
for (let node = item.prevSibling; node !== null; node = node.prevSibling) if (node.name === "ListItem") index += 1;
|
|
97
|
+
return __foldkitBrandViewResult((start + index), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#itemNumber");
|
|
98
|
+
};
|
|
99
|
+
const listDelimiter = (state, item) => __foldkitBrandViewResult((/[.)]$/u.exec(firstMarkOf(state, item) ?? "")?.[0] ?? "."), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#listDelimiter");
|
|
100
|
+
const outlineNumber = (state, item) => {
|
|
101
|
+
const parts = [];
|
|
102
|
+
for (let node = item; node !== null; node = node.parent) if (node.name === "ListItem" && node.parent?.name === "OrderedList") parts.unshift(itemNumber(state, node));
|
|
103
|
+
return __foldkitBrandViewResult((`${parts.join(".")}${listDelimiter(state, item)}`), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#outlineNumber");
|
|
104
|
+
};
|
|
105
|
+
const listMarker = (state, item) => {
|
|
106
|
+
const list = item.parent;
|
|
107
|
+
if (list?.name === "BulletList") return __foldkitBrandViewResult((Array.from({ length: listDepth(item) }, () => __foldkitBrandViewResult(("•"), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#anonymous~2")).join(" ")), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#listMarker");
|
|
108
|
+
return __foldkitBrandViewResult((list?.name === "OrderedList" ? outlineNumber(state, item) : ""), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#listMarker");
|
|
109
|
+
};
|
|
110
|
+
const hide = Decoration.replace({});
|
|
111
|
+
const mark = (className) => __foldkitBrandViewResult((Decoration.mark({ class: className })), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#mark");
|
|
112
|
+
const line = (className) => __foldkitBrandViewResult((Decoration.line({ class: className })), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#line");
|
|
113
|
+
const INLINE = /* @__PURE__ */ new Map([
|
|
114
|
+
["Emphasis", "lmd-em"],
|
|
115
|
+
["StrongEmphasis", "lmd-strong"],
|
|
116
|
+
["Strikethrough", "lmd-strike"],
|
|
117
|
+
["InlineCode", "lmd-code"],
|
|
118
|
+
["Link", "lmd-link"]
|
|
119
|
+
]);
|
|
120
|
+
const HIDDEN_MARKS = /* @__PURE__ */ new Set([
|
|
121
|
+
"EmphasisMark",
|
|
122
|
+
"StrikethroughMark",
|
|
123
|
+
"LinkMark",
|
|
124
|
+
"URL"
|
|
125
|
+
]);
|
|
126
|
+
const LABELED_RULE = /^ {0,3}---[ \t]+(?<title>\S(?:[^\n]*?\S)?)[ \t]+---[ \t]*$/gmu;
|
|
127
|
+
const ATX_HEADING = /^ATXHeading(?<level>\d)$/u;
|
|
128
|
+
const STANDALONE_DASHES = /(?<![\S\\])--(?!\S)/gu;
|
|
129
|
+
const NOT_PLAIN_TEXT = /Code|Link|URL|Image|HTML|HorizontalRule|Table|Escape/u;
|
|
130
|
+
const isLinkLike = (node) => __foldkitBrandViewResult((node?.name === "Link" || node?.name === "Image"), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#isLinkLike");
|
|
131
|
+
const normalizedLabel = (label) => __foldkitBrandViewResult((label.trim().replaceAll(/\s+/gu, " ").toLowerCase()), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#normalizedLabel");
|
|
132
|
+
const linkDefinitions = (state) => {
|
|
133
|
+
const labels = /* @__PURE__ */ new Set();
|
|
134
|
+
for (let node = syntaxTree(state).topNode.firstChild; node !== null; node = node.nextSibling) {
|
|
135
|
+
const label = node.name === "LinkReference" ? node.getChild("LinkLabel") : null;
|
|
136
|
+
if (label !== null) labels.add(normalizedLabel(state.sliceDoc(label.from + 1, label.to - 1)));
|
|
137
|
+
}
|
|
138
|
+
return __foldkitBrandViewResult((labels), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#linkDefinitions");
|
|
139
|
+
};
|
|
140
|
+
const bracketedText = (state, node) => {
|
|
141
|
+
const label = node.getChild("LinkLabel");
|
|
142
|
+
const text = label === null ? "" : state.sliceDoc(label.from + 1, label.to - 1);
|
|
143
|
+
const [opening, closing] = node.getChildren("LinkMark");
|
|
144
|
+
return __foldkitBrandViewResult((normalizedLabel(text) === "" && opening !== void 0 && closing !== void 0 ? state.sliceDoc(opening.to, closing.from) : text), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#bracketedText");
|
|
145
|
+
};
|
|
146
|
+
const isPlainBrackets = (state, node, definitions = linkDefinitions(state)) => __foldkitBrandViewResult((isLinkLike(node) && node.getChild("URL") === null && !definitions.has(normalizedLabel(bracketedText(state, node)))), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#isPlainBrackets");
|
|
147
|
+
const build = (view) => {
|
|
148
|
+
const { state } = view;
|
|
149
|
+
const { ranges } = state.selection;
|
|
150
|
+
const isFocused = view.hasFocus;
|
|
151
|
+
const touched = (from, to) => __foldkitBrandViewResult((isFocused && ranges.some((range) => __foldkitBrandViewResult((range.from <= to && range.to >= from), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#anonymous~3"))), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#touched");
|
|
152
|
+
const activeLine = (position) => {
|
|
153
|
+
const { from, to } = state.doc.lineAt(position);
|
|
154
|
+
return __foldkitBrandViewResult((touched(from, to)), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#activeLine");
|
|
155
|
+
};
|
|
156
|
+
const placed = [];
|
|
157
|
+
const add = (from, to, decoration) => {
|
|
158
|
+
placed.push({
|
|
159
|
+
from,
|
|
160
|
+
to,
|
|
161
|
+
decoration,
|
|
162
|
+
isReplace: decoration === hide
|
|
163
|
+
});
|
|
164
|
+
};
|
|
165
|
+
const replace = (from, to, widget) => {
|
|
166
|
+
placed.push({
|
|
167
|
+
from,
|
|
168
|
+
to,
|
|
169
|
+
decoration: Decoration.replace({ widget }),
|
|
170
|
+
isReplace: true
|
|
171
|
+
});
|
|
172
|
+
};
|
|
173
|
+
const addLine = (position, decoration) => {
|
|
174
|
+
placed.push({
|
|
175
|
+
from: position,
|
|
176
|
+
to: position,
|
|
177
|
+
decoration,
|
|
178
|
+
isReplace: false
|
|
179
|
+
});
|
|
180
|
+
};
|
|
181
|
+
const addLines = (from, to, className) => {
|
|
182
|
+
for (let position = from; position <= to;) {
|
|
183
|
+
const { from: start, to: end } = state.doc.lineAt(position);
|
|
184
|
+
addLine(start, line(className));
|
|
185
|
+
position = end + 1;
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
const hideWithFollowingSpace = (from, to) => {
|
|
189
|
+
add(from, Math.min(to + 1, state.doc.lineAt(from).to), hide);
|
|
190
|
+
};
|
|
191
|
+
const labeledRanges = [];
|
|
192
|
+
const definitions = linkDefinitions(state);
|
|
193
|
+
for (const { from, to } of view.visibleRanges) {
|
|
194
|
+
const text = state.sliceDoc(from, to);
|
|
195
|
+
syntaxTree(state).iterate({
|
|
196
|
+
from,
|
|
197
|
+
to,
|
|
198
|
+
enter: (node) => {
|
|
199
|
+
if (labeledRanges.some(([start, end]) => __foldkitBrandViewResult((node.from >= start && node.to <= end), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#anonymous~4"))) return __foldkitBrandViewResult((false), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#enter");
|
|
200
|
+
const { name } = node;
|
|
201
|
+
const { parent } = node.node;
|
|
202
|
+
if (name === "Paragraph" && parent?.name === "Document") {
|
|
203
|
+
const paragraph = state.sliceDoc(node.from, node.to);
|
|
204
|
+
for (const match of paragraph.matchAll(LABELED_RULE)) {
|
|
205
|
+
const start = node.from + match.index;
|
|
206
|
+
const end = start + match[0].length;
|
|
207
|
+
const title = match.groups?.["title"];
|
|
208
|
+
if (title !== void 0 && !activeLine(start)) {
|
|
209
|
+
labeledRanges.push([start, end]);
|
|
210
|
+
replace(start, end, typographyWidget(title, true));
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
const level = ATX_HEADING.exec(name)?.groups?.["level"];
|
|
215
|
+
if (level !== void 0) {
|
|
216
|
+
addLine(state.doc.lineAt(node.from).from, line(`lmd-h lmd-h${level}`));
|
|
217
|
+
return __foldkitBrandViewResult((true), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#enter");
|
|
218
|
+
}
|
|
219
|
+
if (name === "HeaderMark" && parent?.name.startsWith("ATXHeading") === true) {
|
|
220
|
+
if (!activeLine(node.from)) hideWithFollowingSpace(node.from, node.to);
|
|
221
|
+
return __foldkitBrandViewResult((true), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#enter");
|
|
222
|
+
}
|
|
223
|
+
if (isLinkLike(node.node) && isPlainBrackets(state, node.node, definitions)) return __foldkitBrandViewResult((true), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#enter");
|
|
224
|
+
if (name === "LinkMark" && parent !== null && isPlainBrackets(state, parent, definitions)) return __foldkitBrandViewResult((true), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#enter");
|
|
225
|
+
if (name === "Escape") {
|
|
226
|
+
if (!touched(node.from, node.to)) add(node.from, node.from + 1, hide);
|
|
227
|
+
return __foldkitBrandViewResult((true), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#enter");
|
|
228
|
+
}
|
|
229
|
+
if (name === "Image") {
|
|
230
|
+
const url = node.node.getChild("URL");
|
|
231
|
+
if (url !== null && !touched(node.from, node.to)) {
|
|
232
|
+
const alt = state.sliceDoc(node.from + 2, Math.max(node.from + 2, url.from - 2));
|
|
233
|
+
replace(node.from, node.to, imageWidget(state.sliceDoc(url.from, url.to), alt));
|
|
234
|
+
}
|
|
235
|
+
return __foldkitBrandViewResult((true), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#enter");
|
|
236
|
+
}
|
|
237
|
+
const inlineClass = INLINE.get(name);
|
|
238
|
+
if (inlineClass !== void 0) {
|
|
239
|
+
add(node.from, node.to, mark(inlineClass));
|
|
240
|
+
return __foldkitBrandViewResult((true), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#enter");
|
|
241
|
+
}
|
|
242
|
+
if (name === "URL" && !isLinkLike(parent)) {
|
|
243
|
+
add(node.from, node.to, mark("lmd-link"));
|
|
244
|
+
return __foldkitBrandViewResult((true), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#enter");
|
|
245
|
+
}
|
|
246
|
+
if (parent !== null && (HIDDEN_MARKS.has(name) || name === "CodeMark" && parent.name === "InlineCode")) {
|
|
247
|
+
if (!touched(parent.from, parent.to)) add(node.from, node.to, hide);
|
|
248
|
+
return __foldkitBrandViewResult((true), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#enter");
|
|
249
|
+
}
|
|
250
|
+
if (name === "FencedCode" || name === "CodeBlock") {
|
|
251
|
+
addLines(node.from, node.to, "lmd-codeblock");
|
|
252
|
+
return __foldkitBrandViewResult((false), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#enter");
|
|
253
|
+
}
|
|
254
|
+
if (name === "Blockquote") {
|
|
255
|
+
addLines(node.from, node.to, "lmd-quote");
|
|
256
|
+
return __foldkitBrandViewResult((true), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#enter");
|
|
257
|
+
}
|
|
258
|
+
if (name === "QuoteMark") {
|
|
259
|
+
if (!activeLine(node.from)) hideWithFollowingSpace(node.from, node.to);
|
|
260
|
+
return __foldkitBrandViewResult((true), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#enter");
|
|
261
|
+
}
|
|
262
|
+
if (name === "HorizontalRule") {
|
|
263
|
+
if (!activeLine(node.from)) {
|
|
264
|
+
addLine(state.doc.lineAt(node.from).from, line("lmd-hr"));
|
|
265
|
+
add(node.from, node.to, hide);
|
|
266
|
+
}
|
|
267
|
+
return __foldkitBrandViewResult((true), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#enter");
|
|
268
|
+
}
|
|
269
|
+
if (name === "Table") {
|
|
270
|
+
addLines(node.from, node.to, "lmd-table");
|
|
271
|
+
return __foldkitBrandViewResult((true), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#enter");
|
|
272
|
+
}
|
|
273
|
+
if (name === "ListMark" && parent !== null && isList(parent.parent)) {
|
|
274
|
+
if (activeLine(node.from)) return __foldkitBrandViewResult((true), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#enter");
|
|
275
|
+
if (parent.getChild("Task") === null) replace(node.from, node.to, listMarkWidget(listMarker(state, parent)));
|
|
276
|
+
else hideWithFollowingSpace(node.from, node.to);
|
|
277
|
+
return __foldkitBrandViewResult((true), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#enter");
|
|
278
|
+
}
|
|
279
|
+
if (name === "TaskMarker" && !touched(node.from, node.to)) {
|
|
280
|
+
const isChecked = /x/iu.test(state.sliceDoc(node.from, node.to));
|
|
281
|
+
replace(node.from, node.to, checkboxWidget(isChecked));
|
|
282
|
+
if (isChecked && parent !== null) add(node.to, parent.to, mark("lmd-done"));
|
|
283
|
+
}
|
|
284
|
+
return __foldkitBrandViewResult((true), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#enter");
|
|
285
|
+
}
|
|
286
|
+
});
|
|
287
|
+
for (const match of text.matchAll(STANDALONE_DASHES)) {
|
|
288
|
+
const start = from + match.index;
|
|
289
|
+
const end = start + 2;
|
|
290
|
+
if (!touched(start, end)) {
|
|
291
|
+
let node = syntaxTree(state).resolveInner(start, 1);
|
|
292
|
+
let isPlain = true;
|
|
293
|
+
while (node !== null && isPlain) {
|
|
294
|
+
isPlain = !NOT_PLAIN_TEXT.test(node.name);
|
|
295
|
+
node = node.parent;
|
|
296
|
+
}
|
|
297
|
+
if (isPlain) replace(start, end, typographyWidget("—", false));
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
placed.sort((left, right) => __foldkitBrandViewResult((left.from - right.from || left.decoration.startSide - right.decoration.startSide), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#anonymous~5"));
|
|
302
|
+
const builder = new RangeSetBuilder();
|
|
303
|
+
let lastReplaceEnd = -1;
|
|
304
|
+
for (const { from, to, decoration, isReplace } of placed) {
|
|
305
|
+
const isRangeReplace = from !== to && isReplace;
|
|
306
|
+
if (!isRangeReplace || from >= lastReplaceEnd) {
|
|
307
|
+
builder.add(from, to, decoration);
|
|
308
|
+
if (isRangeReplace) lastReplaceEnd = to;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
return __foldkitBrandViewResult((builder.finish()), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#build");
|
|
312
|
+
};
|
|
313
|
+
const DELIMITER_ROW = /^\s*\|?[\s:|-]+\|?\s*$/u;
|
|
314
|
+
const tableCells = (row) => __foldkitBrandViewResult((row.trim().replaceAll(/^\||\|$/gu, "").split(/(?<!\\)\|/u).map((cell) => __foldkitBrandViewResult((cell.trim().replaceAll(String.raw`\|`, "|")), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#anonymous~6"))), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#tableCells");
|
|
315
|
+
const tableOf = (source) => {
|
|
316
|
+
const table = document.createElement("table");
|
|
317
|
+
const head = table.createTHead();
|
|
318
|
+
const body = table.createTBody();
|
|
319
|
+
const rows = source.split("\n").filter((row) => __foldkitBrandViewResult((row.trim() !== ""), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#anonymous~7"));
|
|
320
|
+
table.className = "lmd-table-view";
|
|
321
|
+
for (const [index, row] of rows.entries()) if (index !== 1 || !DELIMITER_ROW.test(row)) {
|
|
322
|
+
const tableRow = document.createElement("tr");
|
|
323
|
+
for (const text of tableCells(row)) {
|
|
324
|
+
const cell = document.createElement(index === 0 ? "th" : "td");
|
|
325
|
+
cell.textContent = text;
|
|
326
|
+
tableRow.append(cell);
|
|
327
|
+
}
|
|
328
|
+
(index === 0 ? head : body).append(tableRow);
|
|
329
|
+
}
|
|
330
|
+
return __foldkitBrandViewResult((table), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#tableOf");
|
|
331
|
+
};
|
|
332
|
+
const tableWidget = (text) => __foldkitBrandViewResult((new DrawnWidget({
|
|
333
|
+
key: `table:${text}`,
|
|
334
|
+
draw: (view) => {
|
|
335
|
+
const dom = document.createElement("div");
|
|
336
|
+
dom.className = "lmd-table-widget";
|
|
337
|
+
dom.title = TABLE_HINT;
|
|
338
|
+
dom.append(tableOf(text));
|
|
339
|
+
dom.addEventListener("mousedown", (event) => {
|
|
340
|
+
event.preventDefault();
|
|
341
|
+
const row = event.target instanceof Element ? event.target.closest("tr") : null;
|
|
342
|
+
const rows = [...dom.querySelectorAll("tr")];
|
|
343
|
+
const rowIndex = row === null ? -1 : rows.indexOf(row);
|
|
344
|
+
const sourceOffset = rowIndex <= 0 ? 0 : rowIndex + 1;
|
|
345
|
+
const first = view.state.doc.lineAt(view.posAtDOM(dom));
|
|
346
|
+
const target = view.state.doc.line(Math.min(first.number + sourceOffset, view.state.doc.lines));
|
|
347
|
+
view.dispatch({ selection: { anchor: Math.min(target.from + 2, target.to) } });
|
|
348
|
+
view.focus();
|
|
349
|
+
});
|
|
350
|
+
return __foldkitBrandViewResult((dom), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#draw~5");
|
|
351
|
+
},
|
|
352
|
+
estimatedHeight: TABLE_ROW_HEIGHT * text.split("\n").length,
|
|
353
|
+
takesOwnEvents: true
|
|
354
|
+
})), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#tableWidget");
|
|
355
|
+
const lastValueOf = (transaction, type, held) => {
|
|
356
|
+
const last = transaction.effects.findLast((effect) => __foldkitBrandViewResult((effect.is(type)), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#anonymous~9"));
|
|
357
|
+
return __foldkitBrandViewResult((last === void 0 ? held : last.value), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#lastValueOf");
|
|
358
|
+
};
|
|
359
|
+
const setFocus = StateEffect.define();
|
|
360
|
+
const setPointerDown = StateEffect.define();
|
|
361
|
+
const pointerDownField = StateField.define({
|
|
362
|
+
create: () => __foldkitBrandViewResult((false), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#create"),
|
|
363
|
+
update: (isDown, transaction) => __foldkitBrandViewResult((lastValueOf(transaction, setPointerDown, isDown)), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#update")
|
|
364
|
+
});
|
|
365
|
+
const POINTER_RELEASE_EVENTS = [
|
|
366
|
+
"mouseup",
|
|
367
|
+
"dragend",
|
|
368
|
+
"contextmenu"
|
|
369
|
+
];
|
|
370
|
+
const holdRevealUntilPointerRelease = (view) => {
|
|
371
|
+
const { ownerDocument } = view.dom;
|
|
372
|
+
const release = () => {
|
|
373
|
+
for (const name of POINTER_RELEASE_EVENTS) ownerDocument.removeEventListener(name, release);
|
|
374
|
+
setTimeout(() => {
|
|
375
|
+
view.dispatch({ effects: setPointerDown.of(false) });
|
|
376
|
+
}, 0);
|
|
377
|
+
};
|
|
378
|
+
view.dispatch({ effects: setPointerDown.of(true) });
|
|
379
|
+
for (const name of POINTER_RELEASE_EVENTS) ownerDocument.addEventListener(name, release);
|
|
380
|
+
};
|
|
381
|
+
const buildTables = (state, isFocused) => {
|
|
382
|
+
const builder = new RangeSetBuilder();
|
|
383
|
+
syntaxTree(state).iterate({ enter: (node) => {
|
|
384
|
+
if (node.name !== "Table") return __foldkitBrandViewResult((node.name === "Document" || node.name.endsWith("List") || node.name === "ListItem" || node.name === "Blockquote"), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#enter~2");
|
|
385
|
+
const { from } = state.doc.lineAt(node.from);
|
|
386
|
+
const { to } = state.doc.lineAt(node.to);
|
|
387
|
+
const isInside = state.selection.ranges.some((range) => __foldkitBrandViewResult((range.from <= to && range.to >= from), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#anonymous~11"));
|
|
388
|
+
if (from === node.from && !(isFocused && isInside)) builder.add(from, to, Decoration.replace({
|
|
389
|
+
widget: tableWidget(state.sliceDoc(from, to)),
|
|
390
|
+
block: true
|
|
391
|
+
}));
|
|
392
|
+
return __foldkitBrandViewResult((false), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#enter~2");
|
|
393
|
+
} });
|
|
394
|
+
return __foldkitBrandViewResult((builder.finish()), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#buildTables");
|
|
395
|
+
};
|
|
396
|
+
const tablesField = StateField.define({
|
|
397
|
+
create: (state) => (__foldkitBrandViewResult(({
|
|
398
|
+
isFocused: false,
|
|
399
|
+
decorations: buildTables(state, false)
|
|
400
|
+
}), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#create~2")),
|
|
401
|
+
update: (value, transaction) => {
|
|
402
|
+
const isFocused = lastValueOf(transaction, setFocus, value.isFocused);
|
|
403
|
+
const wasDown = transaction.startState.field(pointerDownField);
|
|
404
|
+
const isDown = transaction.state.field(pointerDownField);
|
|
405
|
+
if (isDown && !transaction.docChanged) return __foldkitBrandViewResult(({
|
|
406
|
+
isFocused,
|
|
407
|
+
decorations: value.decorations
|
|
408
|
+
}), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#update~2");
|
|
409
|
+
return __foldkitBrandViewResult((isFocused === value.isFocused && wasDown === isDown && !transaction.docChanged && transaction.selection === void 0 && syntaxTree(transaction.startState) === syntaxTree(transaction.state) ? value : {
|
|
410
|
+
isFocused,
|
|
411
|
+
decorations: buildTables(transaction.state, isFocused)
|
|
412
|
+
}), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#update~2");
|
|
413
|
+
},
|
|
414
|
+
provide: (field) => __foldkitBrandViewResult((EditorView.decorations.from(field, (value) => __foldkitBrandViewResult((value.decorations), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#anonymous~12"))), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#provide")
|
|
415
|
+
});
|
|
416
|
+
const linkHref = (state, node) => {
|
|
417
|
+
const url = node.name === "Link" ? node.getChild("URL") : node;
|
|
418
|
+
if (url === null) return;
|
|
419
|
+
const href = state.sliceDoc(url.from, url.to);
|
|
420
|
+
return __foldkitBrandViewResult((/^www\./iu.test(href) ? `https://${href}` : href), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#linkHref");
|
|
421
|
+
};
|
|
422
|
+
const isLinkNode = (state, node) => __foldkitBrandViewResult((!isPlainBrackets(state, node) && (node.name === "Link" || node.name === "URL" && !isLinkLike(node.parent))), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#isLinkNode");
|
|
423
|
+
const toggleCheckbox = (view, box) => {
|
|
424
|
+
const position = view.posAtDOM(box);
|
|
425
|
+
const text = view.state.sliceDoc(position, position + 3);
|
|
426
|
+
if (!/^\[[ xX]\]$/u.test(text)) return __foldkitBrandViewResult((false), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#toggleCheckbox");
|
|
427
|
+
view.dispatch({ changes: {
|
|
428
|
+
from: position + 1,
|
|
429
|
+
to: position + 2,
|
|
430
|
+
insert: text.charAt(1) === " " ? "x" : " "
|
|
431
|
+
} });
|
|
432
|
+
return __foldkitBrandViewResult((true), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#toggleCheckbox");
|
|
433
|
+
};
|
|
434
|
+
const linkAt = (state, position, side) => {
|
|
435
|
+
for (let node = syntaxTree(state).resolveInner(position, side); node !== null; node = node.parent) if (isLinkNode(state, node)) return __foldkitBrandViewResult((linkHref(state, node)), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#linkAt");
|
|
436
|
+
};
|
|
437
|
+
const openLink = (url) => {
|
|
438
|
+
const href = safeHref(url, document.baseURI);
|
|
439
|
+
if (href !== void 0) window.open(href, "_blank", "noopener,noreferrer");
|
|
440
|
+
};
|
|
441
|
+
const openLinkAtCaret = (view) => {
|
|
442
|
+
const { head } = view.state.selection.main;
|
|
443
|
+
const url = linkAt(view.state, head, 1) ?? linkAt(view.state, head, -1);
|
|
444
|
+
if (url === void 0) return __foldkitBrandViewResult((false), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#openLinkAtCaret");
|
|
445
|
+
openLink(url);
|
|
446
|
+
return __foldkitBrandViewResult((true), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#openLinkAtCaret");
|
|
447
|
+
};
|
|
448
|
+
/** Markdown drawn over its own text, as in Obsidian's Live Preview: the document stays
|
|
449
|
+
* Markdown, and its marks show only around the selection. Redrawing a reveal moves text, so
|
|
450
|
+
* nothing redraws under an IME's composition or a pressed mouse button. */
|
|
451
|
+
const liveMarkdown = () => {
|
|
452
|
+
const preview = ViewPlugin.fromClass(class {
|
|
453
|
+
decorations;
|
|
454
|
+
isStale = false;
|
|
455
|
+
constructor(view) {
|
|
456
|
+
this.decorations = build(view);
|
|
457
|
+
}
|
|
458
|
+
update(update) {
|
|
459
|
+
if (update.view.composing || update.state.field(pointerDownField) && !update.docChanged) {
|
|
460
|
+
this.decorations = this.decorations.map(update.changes);
|
|
461
|
+
this.isStale = true;
|
|
462
|
+
} else if (this.isStale || update.docChanged || update.selectionSet || update.focusChanged || update.viewportChanged || syntaxTree(update.startState) !== syntaxTree(update.state)) {
|
|
463
|
+
this.decorations = build(update.view);
|
|
464
|
+
this.isStale = false;
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
}, {
|
|
468
|
+
decorations: (plugin) => __foldkitBrandViewResult((plugin.decorations), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#decorations"),
|
|
469
|
+
eventObservers: { compositionend: (_, view) => {
|
|
470
|
+
setTimeout(() => {
|
|
471
|
+
view.dispatch({});
|
|
472
|
+
}, 0);
|
|
473
|
+
} },
|
|
474
|
+
eventHandlers: { mousedown: (event, view) => {
|
|
475
|
+
if (event.target instanceof HTMLInputElement && event.target.classList.contains("lmd-check") && toggleCheckbox(view, event.target)) {
|
|
476
|
+
event.preventDefault();
|
|
477
|
+
return __foldkitBrandViewResult((true), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#mousedown");
|
|
478
|
+
}
|
|
479
|
+
if (event.metaKey || event.ctrlKey) {
|
|
480
|
+
const position = view.posAtCoords({
|
|
481
|
+
x: event.clientX,
|
|
482
|
+
y: event.clientY
|
|
483
|
+
});
|
|
484
|
+
const url = position === null ? void 0 : linkAt(view.state, position, 1);
|
|
485
|
+
if (url !== void 0) {
|
|
486
|
+
openLink(url);
|
|
487
|
+
event.preventDefault();
|
|
488
|
+
return __foldkitBrandViewResult((true), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#mousedown");
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
if (event.button === 0) holdRevealUntilPointerRelease(view);
|
|
492
|
+
return __foldkitBrandViewResult((false), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#mousedown");
|
|
493
|
+
} }
|
|
494
|
+
});
|
|
495
|
+
return __foldkitBrandViewResult(([
|
|
496
|
+
pointerDownField,
|
|
497
|
+
preview,
|
|
498
|
+
tablesField,
|
|
499
|
+
Prec.high(keymap.of([{
|
|
500
|
+
key: "Mod-Enter",
|
|
501
|
+
run: openLinkAtCaret
|
|
502
|
+
}])),
|
|
503
|
+
EditorView.focusChangeEffect.of((_, isFocusing) => __foldkitBrandViewResult((setFocus.of(isFocusing)), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#anonymous~14")),
|
|
504
|
+
liveMarkdownTheme
|
|
505
|
+
]), "@gjermundgaraba/pixel-paper/markdown-editor/live/live.js#liveMarkdown");
|
|
506
|
+
};
|
|
507
|
+
export { liveMarkdown };
|