@sendbird/actionbook-core 0.7.2 → 0.8.1
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 +6 -150
- package/dist/ui/index.d.ts +18 -3
- package/dist/ui/index.js +1377 -163
- package/dist/ui/index.js.map +1 -1
- package/package.json +1 -1
package/dist/ui/index.js
CHANGED
|
@@ -32,9 +32,12 @@ var actionbookSchema = new Schema({
|
|
|
32
32
|
bulletList: {
|
|
33
33
|
content: "listItem+",
|
|
34
34
|
group: "block",
|
|
35
|
-
parseDOM: [
|
|
35
|
+
parseDOM: [
|
|
36
|
+
{ tag: "div.ab-bullet-list" },
|
|
37
|
+
{ tag: "ul" }
|
|
38
|
+
],
|
|
36
39
|
toDOM() {
|
|
37
|
-
return ["
|
|
40
|
+
return ["div", { class: "ab-bullet-list", role: "list" }, 0];
|
|
38
41
|
}
|
|
39
42
|
},
|
|
40
43
|
orderedList: {
|
|
@@ -42,6 +45,12 @@ var actionbookSchema = new Schema({
|
|
|
42
45
|
group: "block",
|
|
43
46
|
attrs: { start: { default: 1 } },
|
|
44
47
|
parseDOM: [
|
|
48
|
+
{
|
|
49
|
+
tag: "div.ab-ordered-list",
|
|
50
|
+
getAttrs(dom) {
|
|
51
|
+
return { start: Number(dom.dataset.start) || 1 };
|
|
52
|
+
}
|
|
53
|
+
},
|
|
45
54
|
{
|
|
46
55
|
tag: "ol",
|
|
47
56
|
getAttrs(dom) {
|
|
@@ -50,13 +59,25 @@ var actionbookSchema = new Schema({
|
|
|
50
59
|
}
|
|
51
60
|
],
|
|
52
61
|
toDOM(node) {
|
|
53
|
-
|
|
62
|
+
const attrs = { class: "ab-ordered-list", role: "list" };
|
|
63
|
+
if (node.attrs.start !== 1) attrs["data-start"] = String(node.attrs.start);
|
|
64
|
+
return ["div", attrs, 0];
|
|
54
65
|
}
|
|
55
66
|
},
|
|
56
67
|
listItem: {
|
|
57
68
|
content: "block+",
|
|
58
69
|
attrs: { checked: { default: null } },
|
|
59
70
|
parseDOM: [
|
|
71
|
+
{
|
|
72
|
+
tag: "div.ab-list-item",
|
|
73
|
+
getAttrs(dom) {
|
|
74
|
+
const el = dom;
|
|
75
|
+
if (el.dataset.checked != null) {
|
|
76
|
+
return { checked: el.dataset.checked === "true" };
|
|
77
|
+
}
|
|
78
|
+
return { checked: null };
|
|
79
|
+
}
|
|
80
|
+
},
|
|
60
81
|
{
|
|
61
82
|
tag: "li",
|
|
62
83
|
getAttrs(dom) {
|
|
@@ -73,10 +94,12 @@ var actionbookSchema = new Schema({
|
|
|
73
94
|
}
|
|
74
95
|
],
|
|
75
96
|
toDOM(node) {
|
|
97
|
+
const attrs = { class: "ab-list-item", role: "listitem" };
|
|
76
98
|
if (node.attrs.checked != null) {
|
|
77
|
-
|
|
99
|
+
attrs.class = "ab-list-item todo-item";
|
|
100
|
+
attrs["data-checked"] = String(node.attrs.checked);
|
|
78
101
|
}
|
|
79
|
-
return ["
|
|
102
|
+
return ["div", attrs, 0];
|
|
80
103
|
},
|
|
81
104
|
defining: true
|
|
82
105
|
},
|
|
@@ -89,6 +112,72 @@ var actionbookSchema = new Schema({
|
|
|
89
112
|
},
|
|
90
113
|
defining: true
|
|
91
114
|
},
|
|
115
|
+
codeBlock: {
|
|
116
|
+
content: "text*",
|
|
117
|
+
group: "block",
|
|
118
|
+
code: true,
|
|
119
|
+
defining: true,
|
|
120
|
+
marks: "",
|
|
121
|
+
attrs: { language: { default: null } },
|
|
122
|
+
parseDOM: [
|
|
123
|
+
{
|
|
124
|
+
tag: "pre",
|
|
125
|
+
preserveWhitespace: "full",
|
|
126
|
+
getAttrs(dom) {
|
|
127
|
+
const code3 = dom.querySelector("code");
|
|
128
|
+
return { language: code3?.getAttribute("data-language") || null };
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
],
|
|
132
|
+
toDOM(node) {
|
|
133
|
+
const attrs = {};
|
|
134
|
+
if (node.attrs.language) attrs["data-language"] = node.attrs.language;
|
|
135
|
+
return ["pre", ["code", attrs, 0]];
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
jinjaIfBlock: {
|
|
139
|
+
content: "jinjaIfBranch+",
|
|
140
|
+
group: "block",
|
|
141
|
+
isolating: true,
|
|
142
|
+
defining: true,
|
|
143
|
+
parseDOM: [{ tag: "div[data-jinja-if-block]" }],
|
|
144
|
+
toDOM() {
|
|
145
|
+
return ["div", { "data-jinja-if-block": "", class: "jinja-if-block" }, 0];
|
|
146
|
+
}
|
|
147
|
+
},
|
|
148
|
+
jinjaIfBranch: {
|
|
149
|
+
content: "block+",
|
|
150
|
+
isolating: true,
|
|
151
|
+
defining: true,
|
|
152
|
+
attrs: {
|
|
153
|
+
branchType: { default: "if" },
|
|
154
|
+
condition: { default: "" }
|
|
155
|
+
},
|
|
156
|
+
parseDOM: [
|
|
157
|
+
{
|
|
158
|
+
tag: "div[data-jinja-branch]",
|
|
159
|
+
getAttrs(dom) {
|
|
160
|
+
const el = dom;
|
|
161
|
+
return {
|
|
162
|
+
branchType: el.getAttribute("data-branch-type") || "if",
|
|
163
|
+
condition: el.getAttribute("data-condition") || ""
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
],
|
|
168
|
+
toDOM(node) {
|
|
169
|
+
return [
|
|
170
|
+
"div",
|
|
171
|
+
{
|
|
172
|
+
"data-jinja-branch": "",
|
|
173
|
+
"data-branch-type": node.attrs.branchType,
|
|
174
|
+
"data-condition": node.attrs.condition,
|
|
175
|
+
class: `jinja-branch jinja-branch-${node.attrs.branchType}`
|
|
176
|
+
},
|
|
177
|
+
0
|
|
178
|
+
];
|
|
179
|
+
}
|
|
180
|
+
},
|
|
92
181
|
horizontalRule: {
|
|
93
182
|
group: "block",
|
|
94
183
|
parseDOM: [{ tag: "hr" }],
|
|
@@ -1996,8 +2085,7 @@ function convertInline2(node) {
|
|
|
1996
2085
|
return assertNever(node);
|
|
1997
2086
|
}
|
|
1998
2087
|
}
|
|
1999
|
-
|
|
2000
|
-
function convertBlockToArray(node, listDepth = 0) {
|
|
2088
|
+
function convertBlockToArray(node) {
|
|
2001
2089
|
if (node.type === "jinjaIfBlock") {
|
|
2002
2090
|
const jNode = node;
|
|
2003
2091
|
const result = [];
|
|
@@ -2005,15 +2093,15 @@ function convertBlockToArray(node, listDepth = 0) {
|
|
|
2005
2093
|
const tagText = branch.branchType === "else" ? "{% else %}" : `{% ${branch.branchType} ${branch.condition ?? ""} %}`.trim();
|
|
2006
2094
|
result.push({ type: "paragraph", content: [{ type: "text", text: tagText }] });
|
|
2007
2095
|
for (const child of branch.content) {
|
|
2008
|
-
result.push(...convertBlockToArray(child
|
|
2096
|
+
result.push(...convertBlockToArray(child));
|
|
2009
2097
|
}
|
|
2010
2098
|
}
|
|
2011
2099
|
result.push({ type: "paragraph", content: [{ type: "text", text: "{% endif %}" }] });
|
|
2012
2100
|
return result;
|
|
2013
2101
|
}
|
|
2014
|
-
return [convertBlock2(node
|
|
2102
|
+
return [convertBlock2(node)];
|
|
2015
2103
|
}
|
|
2016
|
-
function convertBlock2(node
|
|
2104
|
+
function convertBlock2(node) {
|
|
2017
2105
|
switch (node.type) {
|
|
2018
2106
|
case "paragraph":
|
|
2019
2107
|
return {
|
|
@@ -2026,29 +2114,21 @@ function convertBlock2(node, listDepth = 0) {
|
|
|
2026
2114
|
attrs: { level: node.level },
|
|
2027
2115
|
content: node.content.flatMap(convertInlineToArray)
|
|
2028
2116
|
};
|
|
2029
|
-
case "bulletList":
|
|
2030
|
-
if (listDepth >= MAX_LIST_DEPTH) {
|
|
2031
|
-
return flattenListToBlock(node);
|
|
2032
|
-
}
|
|
2117
|
+
case "bulletList":
|
|
2033
2118
|
return {
|
|
2034
2119
|
type: "bulletList",
|
|
2035
|
-
content: node.content.map(
|
|
2120
|
+
content: node.content.map(convertBlock2)
|
|
2036
2121
|
};
|
|
2037
|
-
|
|
2038
|
-
case "orderedList": {
|
|
2039
|
-
if (listDepth >= MAX_LIST_DEPTH) {
|
|
2040
|
-
return flattenListToBlock(node);
|
|
2041
|
-
}
|
|
2122
|
+
case "orderedList":
|
|
2042
2123
|
return {
|
|
2043
2124
|
type: "orderedList",
|
|
2044
2125
|
attrs: { start: node.start },
|
|
2045
|
-
content: node.content.map(
|
|
2126
|
+
content: node.content.map(convertBlock2)
|
|
2046
2127
|
};
|
|
2047
|
-
}
|
|
2048
2128
|
case "listItem": {
|
|
2049
2129
|
const result = {
|
|
2050
2130
|
type: "listItem",
|
|
2051
|
-
content: node.content.flatMap(
|
|
2131
|
+
content: node.content.flatMap(convertBlockToArray)
|
|
2052
2132
|
};
|
|
2053
2133
|
if (node.checked != null) {
|
|
2054
2134
|
result.attrs = { checked: node.checked };
|
|
@@ -2058,7 +2138,7 @@ function convertBlock2(node, listDepth = 0) {
|
|
|
2058
2138
|
case "blockquote":
|
|
2059
2139
|
return {
|
|
2060
2140
|
type: "blockquote",
|
|
2061
|
-
content: node.content.flatMap(
|
|
2141
|
+
content: node.content.flatMap(convertBlockToArray)
|
|
2062
2142
|
};
|
|
2063
2143
|
case "horizontalRule":
|
|
2064
2144
|
return { type: "horizontalRule" };
|
|
@@ -2080,7 +2160,7 @@ function convertBlock2(node, listDepth = 0) {
|
|
|
2080
2160
|
const tagText = branch.branchType === "else" ? "{% else %}" : `{% ${branch.branchType} ${branch.condition ?? ""} %}`.trim();
|
|
2081
2161
|
result.push({ type: "paragraph", content: [{ type: "text", text: tagText }] });
|
|
2082
2162
|
for (const child of branch.content) {
|
|
2083
|
-
result.push(...convertBlockToArray(child
|
|
2163
|
+
result.push(...convertBlockToArray(child));
|
|
2084
2164
|
}
|
|
2085
2165
|
}
|
|
2086
2166
|
result.push({ type: "paragraph", content: [{ type: "text", text: "{% endif %}" }] });
|
|
@@ -2090,36 +2170,10 @@ function convertBlock2(node, listDepth = 0) {
|
|
|
2090
2170
|
return assertNever(node);
|
|
2091
2171
|
}
|
|
2092
2172
|
}
|
|
2093
|
-
function flattenListToBlock(node) {
|
|
2094
|
-
const paragraphs = [];
|
|
2095
|
-
function extractInlines(n) {
|
|
2096
|
-
switch (n.type) {
|
|
2097
|
-
case "paragraph":
|
|
2098
|
-
case "heading":
|
|
2099
|
-
paragraphs.push({
|
|
2100
|
-
type: "paragraph",
|
|
2101
|
-
content: n.content.flatMap(convertInlineToArray)
|
|
2102
|
-
});
|
|
2103
|
-
break;
|
|
2104
|
-
case "listItem":
|
|
2105
|
-
case "blockquote":
|
|
2106
|
-
for (const child of n.content) extractInlines(child);
|
|
2107
|
-
break;
|
|
2108
|
-
case "bulletList":
|
|
2109
|
-
case "orderedList":
|
|
2110
|
-
for (const item of n.content) extractInlines(item);
|
|
2111
|
-
break;
|
|
2112
|
-
default:
|
|
2113
|
-
break;
|
|
2114
|
-
}
|
|
2115
|
-
}
|
|
2116
|
-
extractInlines(node);
|
|
2117
|
-
return paragraphs.length > 0 ? paragraphs[0] : { type: "paragraph", content: [] };
|
|
2118
|
-
}
|
|
2119
2173
|
function toProseMirrorJSON(doc2) {
|
|
2120
2174
|
return {
|
|
2121
2175
|
type: "doc",
|
|
2122
|
-
content: doc2.content.flatMap(
|
|
2176
|
+
content: doc2.content.flatMap(convertBlockToArray)
|
|
2123
2177
|
};
|
|
2124
2178
|
}
|
|
2125
2179
|
function astNodesToJSONContent(nodes) {
|
|
@@ -2210,6 +2264,15 @@ function useEditorView(config) {
|
|
|
2210
2264
|
};
|
|
2211
2265
|
}
|
|
2212
2266
|
|
|
2267
|
+
// src/ui/plugin/historyPlugin.ts
|
|
2268
|
+
import { history } from "prosemirror-history";
|
|
2269
|
+
function createHistoryPlugin() {
|
|
2270
|
+
return {
|
|
2271
|
+
name: "history",
|
|
2272
|
+
plugins: () => [history()]
|
|
2273
|
+
};
|
|
2274
|
+
}
|
|
2275
|
+
|
|
2213
2276
|
// src/ui/plugin/inputRulesPlugin.ts
|
|
2214
2277
|
import { InputRule, wrappingInputRule } from "prosemirror-inputrules";
|
|
2215
2278
|
var BULLET_LIST_RE = /^\s*([-*])\s$/;
|
|
@@ -4322,6 +4385,113 @@ function createJumpPointNodeViewPlugin() {
|
|
|
4322
4385
|
};
|
|
4323
4386
|
}
|
|
4324
4387
|
|
|
4388
|
+
// src/ui/plugin/jumpPointValidationPlugin.ts
|
|
4389
|
+
import { Plugin as Plugin3, PluginKey as PluginKey3 } from "prosemirror-state";
|
|
4390
|
+
import { Decoration as Decoration2, DecorationSet as DecorationSet2 } from "prosemirror-view";
|
|
4391
|
+
var validationKey = new PluginKey3("jumpPointValidation");
|
|
4392
|
+
function buildValidationDecorations(doc2) {
|
|
4393
|
+
const jumpPointIds = /* @__PURE__ */ new Map();
|
|
4394
|
+
const anchorRefs = [];
|
|
4395
|
+
doc2.descendants((node, pos) => {
|
|
4396
|
+
if (node.type.name === "jumpPoint") {
|
|
4397
|
+
const id = node.attrs.id;
|
|
4398
|
+
if (!jumpPointIds.has(id)) jumpPointIds.set(id, []);
|
|
4399
|
+
jumpPointIds.get(id).push(pos);
|
|
4400
|
+
}
|
|
4401
|
+
if (node.isText && node.marks) {
|
|
4402
|
+
for (const mark of node.marks) {
|
|
4403
|
+
if (mark.type.name === "link") {
|
|
4404
|
+
const href = mark.attrs.href;
|
|
4405
|
+
if (href?.startsWith("#")) {
|
|
4406
|
+
anchorRefs.push({ from: pos, to: pos + node.nodeSize, id: href.slice(1) });
|
|
4407
|
+
}
|
|
4408
|
+
}
|
|
4409
|
+
}
|
|
4410
|
+
}
|
|
4411
|
+
});
|
|
4412
|
+
const decorations = [];
|
|
4413
|
+
for (const [, positions] of jumpPointIds) {
|
|
4414
|
+
if (positions.length > 1) {
|
|
4415
|
+
for (const pos of positions) {
|
|
4416
|
+
decorations.push(
|
|
4417
|
+
Decoration2.node(pos, pos + 1, { class: "duplicate-jump-point" })
|
|
4418
|
+
);
|
|
4419
|
+
}
|
|
4420
|
+
}
|
|
4421
|
+
}
|
|
4422
|
+
for (const ref of anchorRefs) {
|
|
4423
|
+
if (!jumpPointIds.has(ref.id)) {
|
|
4424
|
+
decorations.push(
|
|
4425
|
+
Decoration2.inline(ref.from, ref.to, { class: "broken-anchor-ref" })
|
|
4426
|
+
);
|
|
4427
|
+
}
|
|
4428
|
+
}
|
|
4429
|
+
return decorations.length > 0 ? DecorationSet2.create(doc2, decorations) : DecorationSet2.empty;
|
|
4430
|
+
}
|
|
4431
|
+
function createJumpPointValidationPlugin() {
|
|
4432
|
+
return {
|
|
4433
|
+
name: "jumpPointValidation",
|
|
4434
|
+
plugins: () => [
|
|
4435
|
+
new Plugin3({
|
|
4436
|
+
key: validationKey,
|
|
4437
|
+
state: {
|
|
4438
|
+
init(_, state) {
|
|
4439
|
+
return buildValidationDecorations(state.doc);
|
|
4440
|
+
},
|
|
4441
|
+
apply(tr, oldDecos) {
|
|
4442
|
+
if (!tr.docChanged) return oldDecos;
|
|
4443
|
+
return buildValidationDecorations(tr.doc);
|
|
4444
|
+
}
|
|
4445
|
+
},
|
|
4446
|
+
props: {
|
|
4447
|
+
decorations(state) {
|
|
4448
|
+
return validationKey.getState(state);
|
|
4449
|
+
}
|
|
4450
|
+
}
|
|
4451
|
+
})
|
|
4452
|
+
]
|
|
4453
|
+
};
|
|
4454
|
+
}
|
|
4455
|
+
function hasDuplicateJumpPoints(state) {
|
|
4456
|
+
const ids = /* @__PURE__ */ new Set();
|
|
4457
|
+
let hasDup = false;
|
|
4458
|
+
state.doc.descendants((node) => {
|
|
4459
|
+
if (node.type.name === "jumpPoint") {
|
|
4460
|
+
const id = node.attrs.id;
|
|
4461
|
+
if (ids.has(id)) {
|
|
4462
|
+
hasDup = true;
|
|
4463
|
+
return false;
|
|
4464
|
+
}
|
|
4465
|
+
ids.add(id);
|
|
4466
|
+
}
|
|
4467
|
+
});
|
|
4468
|
+
return hasDup;
|
|
4469
|
+
}
|
|
4470
|
+
function hasBrokenAnchorRefs(state) {
|
|
4471
|
+
const jumpPointIds = /* @__PURE__ */ new Set();
|
|
4472
|
+
state.doc.descendants((node) => {
|
|
4473
|
+
if (node.type.name === "jumpPoint") {
|
|
4474
|
+
jumpPointIds.add(node.attrs.id);
|
|
4475
|
+
}
|
|
4476
|
+
});
|
|
4477
|
+
let hasBroken = false;
|
|
4478
|
+
state.doc.descendants((node) => {
|
|
4479
|
+
if (hasBroken) return false;
|
|
4480
|
+
if (node.isText && node.marks) {
|
|
4481
|
+
for (const mark of node.marks) {
|
|
4482
|
+
if (mark.type.name === "link") {
|
|
4483
|
+
const href = mark.attrs.href;
|
|
4484
|
+
if (href?.startsWith("#") && !jumpPointIds.has(href.slice(1))) {
|
|
4485
|
+
hasBroken = true;
|
|
4486
|
+
return false;
|
|
4487
|
+
}
|
|
4488
|
+
}
|
|
4489
|
+
}
|
|
4490
|
+
}
|
|
4491
|
+
});
|
|
4492
|
+
return hasBroken;
|
|
4493
|
+
}
|
|
4494
|
+
|
|
4325
4495
|
// src/ui/plugin/inlineToolTagNodeViewPlugin.tsx
|
|
4326
4496
|
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
4327
4497
|
var RESOURCE_TAG_COLORS2 = {
|
|
@@ -4386,9 +4556,9 @@ function createInlineToolTagNodeViewPlugin() {
|
|
|
4386
4556
|
}
|
|
4387
4557
|
|
|
4388
4558
|
// src/ui/plugin/jinjaDecoration.ts
|
|
4389
|
-
import { Plugin as
|
|
4390
|
-
import { Decoration as
|
|
4391
|
-
var jinjaPluginKey = new
|
|
4559
|
+
import { Plugin as Plugin4, PluginKey as PluginKey4 } from "prosemirror-state";
|
|
4560
|
+
import { Decoration as Decoration3, DecorationSet as DecorationSet3 } from "prosemirror-view";
|
|
4561
|
+
var jinjaPluginKey = new PluginKey4("jinjaDecoration");
|
|
4392
4562
|
var JINJA_TAG_RE = /\{%\s*(if|elif|else|endif)\s*([^%]*?)\s*%\}/g;
|
|
4393
4563
|
function getBlockPositions(doc2) {
|
|
4394
4564
|
const blocks = [];
|
|
@@ -4410,7 +4580,7 @@ function addInlineChipDecorations(doc2, decorations) {
|
|
|
4410
4580
|
const to = from + match[0].length;
|
|
4411
4581
|
const keyword = match[1];
|
|
4412
4582
|
decorations.push(
|
|
4413
|
-
|
|
4583
|
+
Decoration3.inline(from, to, {
|
|
4414
4584
|
class: `jinja-chip jinja-chip-${keyword}`
|
|
4415
4585
|
})
|
|
4416
4586
|
);
|
|
@@ -4451,7 +4621,7 @@ function addStructureBorderDecorations(doc2, blocks, decorations) {
|
|
|
4451
4621
|
const classes = ["jinja-bar", `jinja-bar-${branchType}`];
|
|
4452
4622
|
if (i === first || prevType !== branchType) classes.push("jinja-bar-first");
|
|
4453
4623
|
if (i === last || nextType !== branchType) classes.push("jinja-bar-last");
|
|
4454
|
-
decorations.push(
|
|
4624
|
+
decorations.push(Decoration3.node(block.from, block.to, { class: classes.join(" ") }));
|
|
4455
4625
|
}
|
|
4456
4626
|
}
|
|
4457
4627
|
}
|
|
@@ -4460,14 +4630,14 @@ function buildDecorations2(doc2) {
|
|
|
4460
4630
|
const decorations = [];
|
|
4461
4631
|
addInlineChipDecorations(doc2, decorations);
|
|
4462
4632
|
addStructureBorderDecorations(doc2, blocks, decorations);
|
|
4463
|
-
if (decorations.length === 0) return
|
|
4464
|
-
return
|
|
4633
|
+
if (decorations.length === 0) return DecorationSet3.empty;
|
|
4634
|
+
return DecorationSet3.create(doc2, decorations);
|
|
4465
4635
|
}
|
|
4466
4636
|
function createJinjaDecorationPlugin() {
|
|
4467
4637
|
return {
|
|
4468
4638
|
name: "jinjaDecoration",
|
|
4469
4639
|
plugins: () => [
|
|
4470
|
-
new
|
|
4640
|
+
new Plugin4({
|
|
4471
4641
|
key: jinjaPluginKey,
|
|
4472
4642
|
state: {
|
|
4473
4643
|
init(_, state) {
|
|
@@ -4488,12 +4658,1051 @@ function createJinjaDecorationPlugin() {
|
|
|
4488
4658
|
};
|
|
4489
4659
|
}
|
|
4490
4660
|
|
|
4661
|
+
// src/ui/plugin/jinjaIfBlockPlugin.tsx
|
|
4662
|
+
import { useEffect as useEffect2, useRef as useRef2, useState as useState2 } from "react";
|
|
4663
|
+
import { createRoot as createRoot2 } from "react-dom/client";
|
|
4664
|
+
|
|
4665
|
+
// src/jinja/conditionHighlighter.ts
|
|
4666
|
+
var KEYWORDS = {
|
|
4667
|
+
and: "AND",
|
|
4668
|
+
or: "OR",
|
|
4669
|
+
not: "NOT",
|
|
4670
|
+
in: "IN",
|
|
4671
|
+
is: "IS",
|
|
4672
|
+
True: "BOOL",
|
|
4673
|
+
False: "BOOL",
|
|
4674
|
+
true: "BOOL",
|
|
4675
|
+
false: "BOOL",
|
|
4676
|
+
None: "NONE",
|
|
4677
|
+
null: "NONE"
|
|
4678
|
+
};
|
|
4679
|
+
var CATEGORY_BY_TYPE = {
|
|
4680
|
+
STRING: "value",
|
|
4681
|
+
NUMBER: "value",
|
|
4682
|
+
BOOL: "value",
|
|
4683
|
+
NONE: "value",
|
|
4684
|
+
IDENT: "variable",
|
|
4685
|
+
AND: "operator",
|
|
4686
|
+
OR: "operator",
|
|
4687
|
+
NOT: "operator",
|
|
4688
|
+
IN: "operator",
|
|
4689
|
+
IS: "operator",
|
|
4690
|
+
EQ: "operator",
|
|
4691
|
+
NEQ: "operator",
|
|
4692
|
+
LT: "operator",
|
|
4693
|
+
GT: "operator",
|
|
4694
|
+
LTE: "operator",
|
|
4695
|
+
GTE: "operator",
|
|
4696
|
+
LPAREN: "punctuation",
|
|
4697
|
+
RPAREN: "punctuation"
|
|
4698
|
+
};
|
|
4699
|
+
var NEGATIVE_NUMBER_PRECEDERS = /* @__PURE__ */ new Set([
|
|
4700
|
+
"AND",
|
|
4701
|
+
"OR",
|
|
4702
|
+
"NOT",
|
|
4703
|
+
"IN",
|
|
4704
|
+
"IS",
|
|
4705
|
+
"EQ",
|
|
4706
|
+
"NEQ",
|
|
4707
|
+
"LT",
|
|
4708
|
+
"GT",
|
|
4709
|
+
"LTE",
|
|
4710
|
+
"GTE",
|
|
4711
|
+
"LPAREN"
|
|
4712
|
+
]);
|
|
4713
|
+
function canStartNegativeNumber(tokens) {
|
|
4714
|
+
if (tokens.length === 0) {
|
|
4715
|
+
return true;
|
|
4716
|
+
}
|
|
4717
|
+
const previous = tokens[tokens.length - 1];
|
|
4718
|
+
return NEGATIVE_NUMBER_PRECEDERS.has(previous.type);
|
|
4719
|
+
}
|
|
4720
|
+
function finalizeTokens(input, rawTokens) {
|
|
4721
|
+
const highlighted = [];
|
|
4722
|
+
for (let i = 0; i < rawTokens.length; i++) {
|
|
4723
|
+
const token = rawTokens[i];
|
|
4724
|
+
const next = rawTokens[i + 1];
|
|
4725
|
+
if (token.type === "IS" && next?.type === "NOT") {
|
|
4726
|
+
highlighted.push({
|
|
4727
|
+
text: input.slice(token.start, next.end),
|
|
4728
|
+
start: token.start,
|
|
4729
|
+
end: next.end,
|
|
4730
|
+
category: "operator"
|
|
4731
|
+
});
|
|
4732
|
+
i++;
|
|
4733
|
+
continue;
|
|
4734
|
+
}
|
|
4735
|
+
highlighted.push({
|
|
4736
|
+
text: token.text,
|
|
4737
|
+
start: token.start,
|
|
4738
|
+
end: token.end,
|
|
4739
|
+
category: CATEGORY_BY_TYPE[token.type]
|
|
4740
|
+
});
|
|
4741
|
+
}
|
|
4742
|
+
return highlighted;
|
|
4743
|
+
}
|
|
4744
|
+
function tokenizeCondition(input) {
|
|
4745
|
+
const rawTokens = [];
|
|
4746
|
+
let i = 0;
|
|
4747
|
+
while (i < input.length) {
|
|
4748
|
+
const char = input[i];
|
|
4749
|
+
if (/\s/.test(char)) {
|
|
4750
|
+
i++;
|
|
4751
|
+
continue;
|
|
4752
|
+
}
|
|
4753
|
+
if (char === '"' || char === "'") {
|
|
4754
|
+
const start = i;
|
|
4755
|
+
const quote = char;
|
|
4756
|
+
i++;
|
|
4757
|
+
while (i < input.length) {
|
|
4758
|
+
if (input[i] === "\\" && i + 1 < input.length) {
|
|
4759
|
+
i += 2;
|
|
4760
|
+
continue;
|
|
4761
|
+
}
|
|
4762
|
+
if (input[i] === quote) {
|
|
4763
|
+
i++;
|
|
4764
|
+
rawTokens.push({
|
|
4765
|
+
type: "STRING",
|
|
4766
|
+
text: input.slice(start, i),
|
|
4767
|
+
start,
|
|
4768
|
+
end: i
|
|
4769
|
+
});
|
|
4770
|
+
break;
|
|
4771
|
+
}
|
|
4772
|
+
i++;
|
|
4773
|
+
}
|
|
4774
|
+
if (rawTokens[rawTokens.length - 1]?.start !== start) {
|
|
4775
|
+
return finalizeTokens(input, rawTokens);
|
|
4776
|
+
}
|
|
4777
|
+
continue;
|
|
4778
|
+
}
|
|
4779
|
+
if (/[0-9]/.test(char) || char === "-" && i + 1 < input.length && /[0-9]/.test(input[i + 1]) && canStartNegativeNumber(rawTokens)) {
|
|
4780
|
+
const start = i;
|
|
4781
|
+
if (input[i] === "-") {
|
|
4782
|
+
i++;
|
|
4783
|
+
}
|
|
4784
|
+
while (i < input.length && /[0-9]/.test(input[i])) {
|
|
4785
|
+
i++;
|
|
4786
|
+
}
|
|
4787
|
+
if (i < input.length && input[i] === ".") {
|
|
4788
|
+
i++;
|
|
4789
|
+
while (i < input.length && /[0-9]/.test(input[i])) {
|
|
4790
|
+
i++;
|
|
4791
|
+
}
|
|
4792
|
+
}
|
|
4793
|
+
rawTokens.push({
|
|
4794
|
+
type: "NUMBER",
|
|
4795
|
+
text: input.slice(start, i),
|
|
4796
|
+
start,
|
|
4797
|
+
end: i
|
|
4798
|
+
});
|
|
4799
|
+
continue;
|
|
4800
|
+
}
|
|
4801
|
+
if (/[a-zA-Z_]/.test(char)) {
|
|
4802
|
+
const start = i;
|
|
4803
|
+
i++;
|
|
4804
|
+
while (i < input.length && /[a-zA-Z0-9_.]/.test(input[i])) {
|
|
4805
|
+
i++;
|
|
4806
|
+
}
|
|
4807
|
+
const text2 = input.slice(start, i);
|
|
4808
|
+
rawTokens.push({
|
|
4809
|
+
type: KEYWORDS[text2] ?? "IDENT",
|
|
4810
|
+
text: text2,
|
|
4811
|
+
start,
|
|
4812
|
+
end: i
|
|
4813
|
+
});
|
|
4814
|
+
continue;
|
|
4815
|
+
}
|
|
4816
|
+
if (i + 1 < input.length) {
|
|
4817
|
+
const twoChar = input.slice(i, i + 2);
|
|
4818
|
+
if (twoChar === "==") {
|
|
4819
|
+
rawTokens.push({ type: "EQ", text: twoChar, start: i, end: i + 2 });
|
|
4820
|
+
i += 2;
|
|
4821
|
+
continue;
|
|
4822
|
+
}
|
|
4823
|
+
if (twoChar === "!=") {
|
|
4824
|
+
rawTokens.push({ type: "NEQ", text: twoChar, start: i, end: i + 2 });
|
|
4825
|
+
i += 2;
|
|
4826
|
+
continue;
|
|
4827
|
+
}
|
|
4828
|
+
if (twoChar === "<=") {
|
|
4829
|
+
rawTokens.push({ type: "LTE", text: twoChar, start: i, end: i + 2 });
|
|
4830
|
+
i += 2;
|
|
4831
|
+
continue;
|
|
4832
|
+
}
|
|
4833
|
+
if (twoChar === ">=") {
|
|
4834
|
+
rawTokens.push({ type: "GTE", text: twoChar, start: i, end: i + 2 });
|
|
4835
|
+
i += 2;
|
|
4836
|
+
continue;
|
|
4837
|
+
}
|
|
4838
|
+
}
|
|
4839
|
+
if (char === "<") {
|
|
4840
|
+
rawTokens.push({ type: "LT", text: char, start: i, end: i + 1 });
|
|
4841
|
+
i++;
|
|
4842
|
+
continue;
|
|
4843
|
+
}
|
|
4844
|
+
if (char === ">") {
|
|
4845
|
+
rawTokens.push({ type: "GT", text: char, start: i, end: i + 1 });
|
|
4846
|
+
i++;
|
|
4847
|
+
continue;
|
|
4848
|
+
}
|
|
4849
|
+
if (char === "(") {
|
|
4850
|
+
rawTokens.push({ type: "LPAREN", text: char, start: i, end: i + 1 });
|
|
4851
|
+
i++;
|
|
4852
|
+
continue;
|
|
4853
|
+
}
|
|
4854
|
+
if (char === ")") {
|
|
4855
|
+
rawTokens.push({ type: "RPAREN", text: char, start: i, end: i + 1 });
|
|
4856
|
+
i++;
|
|
4857
|
+
continue;
|
|
4858
|
+
}
|
|
4859
|
+
return finalizeTokens(input, rawTokens);
|
|
4860
|
+
}
|
|
4861
|
+
return finalizeTokens(input, rawTokens);
|
|
4862
|
+
}
|
|
4863
|
+
|
|
4864
|
+
// src/ui/plugin/jinjaIfBlockPlugin.tsx
|
|
4865
|
+
import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
4866
|
+
var PLACEHOLDER_TEXT = "Describe what AI agent should do when this condition is met";
|
|
4867
|
+
var CONDITION_PLACEHOLDER = "Write a condition in natural language";
|
|
4868
|
+
var STYLE_ID = "ab-jinja-if-block-styles";
|
|
4869
|
+
var JINJA_STYLES = `
|
|
4870
|
+
.jinja-if-block {
|
|
4871
|
+
margin: 8px 0;
|
|
4872
|
+
}
|
|
4873
|
+
|
|
4874
|
+
.jinja-branch {
|
|
4875
|
+
position: relative;
|
|
4876
|
+
display: grid;
|
|
4877
|
+
grid-template-areas:
|
|
4878
|
+
"header"
|
|
4879
|
+
"body"
|
|
4880
|
+
"footer";
|
|
4881
|
+
gap: 0;
|
|
4882
|
+
}
|
|
4883
|
+
|
|
4884
|
+
.jinja-branch-controls {
|
|
4885
|
+
display: contents;
|
|
4886
|
+
}
|
|
4887
|
+
|
|
4888
|
+
.jinja-branch-header {
|
|
4889
|
+
grid-area: header;
|
|
4890
|
+
display: flex;
|
|
4891
|
+
align-items: center;
|
|
4892
|
+
gap: 12px;
|
|
4893
|
+
padding: 8px;
|
|
4894
|
+
border: 1px solid #E0E0E0;
|
|
4895
|
+
border-radius: 4px;
|
|
4896
|
+
background: #FFFFFF;
|
|
4897
|
+
}
|
|
4898
|
+
|
|
4899
|
+
.jinja-branch-badge {
|
|
4900
|
+
display: inline-flex;
|
|
4901
|
+
align-items: center;
|
|
4902
|
+
justify-content: center;
|
|
4903
|
+
height: 32px;
|
|
4904
|
+
padding: 0 8px;
|
|
4905
|
+
border-radius: 4px;
|
|
4906
|
+
font-family: "Roboto Mono", monospace;
|
|
4907
|
+
font-size: 13px;
|
|
4908
|
+
font-weight: 700;
|
|
4909
|
+
line-height: 20px;
|
|
4910
|
+
letter-spacing: -0.3px;
|
|
4911
|
+
white-space: nowrap;
|
|
4912
|
+
flex-shrink: 0;
|
|
4913
|
+
}
|
|
4914
|
+
|
|
4915
|
+
.jinja-branch-badge-if,
|
|
4916
|
+
.jinja-branch-badge-elif {
|
|
4917
|
+
background: #E7F1FF;
|
|
4918
|
+
color: #0D0D0D;
|
|
4919
|
+
}
|
|
4920
|
+
|
|
4921
|
+
.jinja-branch-badge-else {
|
|
4922
|
+
background: #F7F7F7;
|
|
4923
|
+
color: #424242;
|
|
4924
|
+
}
|
|
4925
|
+
|
|
4926
|
+
.jinja-branch-condition {
|
|
4927
|
+
flex: 1;
|
|
4928
|
+
min-width: 0;
|
|
4929
|
+
display: flex;
|
|
4930
|
+
flex-wrap: wrap;
|
|
4931
|
+
gap: 8px;
|
|
4932
|
+
align-items: center;
|
|
4933
|
+
width: 100%;
|
|
4934
|
+
padding: 0;
|
|
4935
|
+
margin: 0;
|
|
4936
|
+
background: transparent;
|
|
4937
|
+
border: none;
|
|
4938
|
+
color: #0D0D0D;
|
|
4939
|
+
cursor: text;
|
|
4940
|
+
text-align: left;
|
|
4941
|
+
font-family: "Roboto Mono", monospace;
|
|
4942
|
+
font-size: 13px;
|
|
4943
|
+
line-height: 20px;
|
|
4944
|
+
letter-spacing: -0.3px;
|
|
4945
|
+
white-space: nowrap;
|
|
4946
|
+
}
|
|
4947
|
+
|
|
4948
|
+
.jinja-branch-condition:focus-visible,
|
|
4949
|
+
.jinja-ghost-btn:focus-visible,
|
|
4950
|
+
.jinja-popup-item:focus-visible {
|
|
4951
|
+
outline: 2px solid rgba(98, 16, 204, 0.28);
|
|
4952
|
+
outline-offset: 2px;
|
|
4953
|
+
}
|
|
4954
|
+
|
|
4955
|
+
.jinja-condition-placeholder {
|
|
4956
|
+
color: #A6A6A6;
|
|
4957
|
+
font-family: "Roboto Mono", monospace;
|
|
4958
|
+
font-size: 13px;
|
|
4959
|
+
line-height: 20px;
|
|
4960
|
+
letter-spacing: -0.3px;
|
|
4961
|
+
}
|
|
4962
|
+
|
|
4963
|
+
.jinja-token-variable {
|
|
4964
|
+
color: #4141B2;
|
|
4965
|
+
}
|
|
4966
|
+
|
|
4967
|
+
.jinja-token-operator {
|
|
4968
|
+
color: #858585;
|
|
4969
|
+
}
|
|
4970
|
+
|
|
4971
|
+
.jinja-token-value {
|
|
4972
|
+
color: #0D0D0D;
|
|
4973
|
+
}
|
|
4974
|
+
|
|
4975
|
+
.jinja-token-punctuation {
|
|
4976
|
+
color: #858585;
|
|
4977
|
+
}
|
|
4978
|
+
|
|
4979
|
+
.jinja-otherwise {
|
|
4980
|
+
flex: 1;
|
|
4981
|
+
color: #858585;
|
|
4982
|
+
font-family: "Roboto Mono", monospace;
|
|
4983
|
+
font-size: 13px;
|
|
4984
|
+
line-height: 20px;
|
|
4985
|
+
letter-spacing: -0.3px;
|
|
4986
|
+
}
|
|
4987
|
+
|
|
4988
|
+
.jinja-branch-actions,
|
|
4989
|
+
.jinja-add-footer-actions {
|
|
4990
|
+
position: relative;
|
|
4991
|
+
display: inline-flex;
|
|
4992
|
+
align-items: center;
|
|
4993
|
+
}
|
|
4994
|
+
|
|
4995
|
+
.jinja-branch-body {
|
|
4996
|
+
grid-area: body;
|
|
4997
|
+
display: flex;
|
|
4998
|
+
gap: 12px;
|
|
4999
|
+
padding: 0 8px;
|
|
5000
|
+
min-height: 52px;
|
|
5001
|
+
}
|
|
5002
|
+
|
|
5003
|
+
.jinja-branch-divider-col {
|
|
5004
|
+
width: 32px;
|
|
5005
|
+
flex-shrink: 0;
|
|
5006
|
+
display: flex;
|
|
5007
|
+
align-items: stretch;
|
|
5008
|
+
justify-content: center;
|
|
5009
|
+
}
|
|
5010
|
+
|
|
5011
|
+
.jinja-branch-divider {
|
|
5012
|
+
width: 1px;
|
|
5013
|
+
background: #E0E0E0;
|
|
5014
|
+
}
|
|
5015
|
+
|
|
5016
|
+
/* L-shaped divider for the last branch (ELSE) */
|
|
5017
|
+
.jinja-branch-last .jinja-branch-divider-col {
|
|
5018
|
+
align-items: flex-start;
|
|
5019
|
+
padding-left: 16px;
|
|
5020
|
+
}
|
|
5021
|
+
|
|
5022
|
+
.jinja-branch-last .jinja-branch-divider {
|
|
5023
|
+
width: 16px;
|
|
5024
|
+
height: 28px;
|
|
5025
|
+
background: none;
|
|
5026
|
+
border-left: 1px solid #E0E0E0;
|
|
5027
|
+
border-bottom: 1px solid #E0E0E0;
|
|
5028
|
+
border-bottom-left-radius: 8px;
|
|
5029
|
+
}
|
|
5030
|
+
|
|
5031
|
+
.jinja-branch-content {
|
|
5032
|
+
position: relative;
|
|
5033
|
+
flex: 1;
|
|
5034
|
+
min-width: 0;
|
|
5035
|
+
padding: 16px 0;
|
|
5036
|
+
}
|
|
5037
|
+
|
|
5038
|
+
.jinja-branch-content.jinja-branch-content-empty::before {
|
|
5039
|
+
content: attr(data-placeholder);
|
|
5040
|
+
position: absolute;
|
|
5041
|
+
top: 16px;
|
|
5042
|
+
left: 0;
|
|
5043
|
+
color: #A6A6A6;
|
|
5044
|
+
font-size: 14px;
|
|
5045
|
+
line-height: 20px;
|
|
5046
|
+
pointer-events: none;
|
|
5047
|
+
}
|
|
5048
|
+
|
|
5049
|
+
.jinja-add-footer {
|
|
5050
|
+
grid-area: footer;
|
|
5051
|
+
display: flex;
|
|
5052
|
+
padding: 8px;
|
|
5053
|
+
}
|
|
5054
|
+
|
|
5055
|
+
.jinja-add-footer .jinja-add-footer-col {
|
|
5056
|
+
width: 32px;
|
|
5057
|
+
flex-shrink: 0;
|
|
5058
|
+
display: flex;
|
|
5059
|
+
align-items: center;
|
|
5060
|
+
justify-content: center;
|
|
5061
|
+
}
|
|
5062
|
+
|
|
5063
|
+
.jinja-ghost-btn {
|
|
5064
|
+
width: 24px;
|
|
5065
|
+
height: 24px;
|
|
5066
|
+
display: inline-flex;
|
|
5067
|
+
align-items: center;
|
|
5068
|
+
justify-content: center;
|
|
5069
|
+
padding: 0;
|
|
5070
|
+
border: none;
|
|
5071
|
+
border-radius: 4px;
|
|
5072
|
+
background: transparent;
|
|
5073
|
+
color: #858585;
|
|
5074
|
+
cursor: pointer;
|
|
5075
|
+
}
|
|
5076
|
+
|
|
5077
|
+
.jinja-ghost-btn:hover:not(:disabled) {
|
|
5078
|
+
background: rgba(13, 13, 13, 0.04);
|
|
5079
|
+
}
|
|
5080
|
+
|
|
5081
|
+
.jinja-ghost-btn:disabled {
|
|
5082
|
+
opacity: 0.45;
|
|
5083
|
+
cursor: default;
|
|
5084
|
+
}
|
|
5085
|
+
|
|
5086
|
+
.jinja-popup-menu {
|
|
5087
|
+
position: absolute;
|
|
5088
|
+
z-index: 20;
|
|
5089
|
+
min-width: 200px;
|
|
5090
|
+
padding: 8px 0;
|
|
5091
|
+
background: #FFFFFF;
|
|
5092
|
+
border-radius: 4px;
|
|
5093
|
+
box-shadow: 0px 8px 10px 0px rgba(13,13,13,0.12), 0px 3px 14px 0px rgba(13,13,13,0.08), 0px 3px 5px 0px rgba(13,13,13,0.04);
|
|
5094
|
+
}
|
|
5095
|
+
|
|
5096
|
+
.jinja-popup-item {
|
|
5097
|
+
width: 100%;
|
|
5098
|
+
display: block;
|
|
5099
|
+
padding: 6px 16px;
|
|
5100
|
+
border: none;
|
|
5101
|
+
background: transparent;
|
|
5102
|
+
color: #0D0D0D;
|
|
5103
|
+
text-align: left;
|
|
5104
|
+
cursor: pointer;
|
|
5105
|
+
font-size: 14px;
|
|
5106
|
+
line-height: 20px;
|
|
5107
|
+
letter-spacing: -0.1px;
|
|
5108
|
+
}
|
|
5109
|
+
|
|
5110
|
+
.jinja-popup-item:hover:not(:disabled) {
|
|
5111
|
+
background: rgba(13, 13, 13, 0.04);
|
|
5112
|
+
}
|
|
5113
|
+
|
|
5114
|
+
.jinja-popup-item:disabled {
|
|
5115
|
+
color: #A6A6A6;
|
|
5116
|
+
cursor: default;
|
|
5117
|
+
}
|
|
5118
|
+
|
|
5119
|
+
.jinja-condition-input {
|
|
5120
|
+
width: 100%;
|
|
5121
|
+
min-width: 0;
|
|
5122
|
+
padding: 0;
|
|
5123
|
+
margin: 0;
|
|
5124
|
+
border: none;
|
|
5125
|
+
outline: none;
|
|
5126
|
+
background: transparent;
|
|
5127
|
+
color: #0D0D0D;
|
|
5128
|
+
caret-color: #6210CC;
|
|
5129
|
+
font-family: "Roboto Mono", monospace;
|
|
5130
|
+
font-size: 13px;
|
|
5131
|
+
line-height: 20px;
|
|
5132
|
+
letter-spacing: -0.3px;
|
|
5133
|
+
}
|
|
5134
|
+
|
|
5135
|
+
.jinja-condition-input::placeholder {
|
|
5136
|
+
color: #A6A6A6;
|
|
5137
|
+
}
|
|
5138
|
+
`;
|
|
5139
|
+
var StyleManager = class {
|
|
5140
|
+
static refCount = 0;
|
|
5141
|
+
static styleEl = null;
|
|
5142
|
+
static acquire() {
|
|
5143
|
+
if (this.refCount++ > 0) return;
|
|
5144
|
+
const existing = document.getElementById(STYLE_ID);
|
|
5145
|
+
if (existing instanceof HTMLStyleElement) {
|
|
5146
|
+
this.styleEl = existing;
|
|
5147
|
+
return;
|
|
5148
|
+
}
|
|
5149
|
+
this.styleEl = document.createElement("style");
|
|
5150
|
+
this.styleEl.id = STYLE_ID;
|
|
5151
|
+
this.styleEl.textContent = JINJA_STYLES;
|
|
5152
|
+
document.head.appendChild(this.styleEl);
|
|
5153
|
+
}
|
|
5154
|
+
static release() {
|
|
5155
|
+
if (this.refCount === 0) return;
|
|
5156
|
+
if (--this.refCount > 0) return;
|
|
5157
|
+
if (this.styleEl?.parentNode) {
|
|
5158
|
+
this.styleEl.remove();
|
|
5159
|
+
}
|
|
5160
|
+
this.styleEl = null;
|
|
5161
|
+
}
|
|
5162
|
+
};
|
|
5163
|
+
function getBranchContext(view, nodePos) {
|
|
5164
|
+
try {
|
|
5165
|
+
const { doc: doc2 } = view.state;
|
|
5166
|
+
const resolved = doc2.resolve(nodePos);
|
|
5167
|
+
let blockDepth = -1;
|
|
5168
|
+
for (let depth = resolved.depth; depth >= 0; depth--) {
|
|
5169
|
+
if (resolved.node(depth).type.name === "jinjaIfBlock") {
|
|
5170
|
+
blockDepth = depth;
|
|
5171
|
+
break;
|
|
5172
|
+
}
|
|
5173
|
+
}
|
|
5174
|
+
if (blockDepth < 0) {
|
|
5175
|
+
return null;
|
|
5176
|
+
}
|
|
5177
|
+
const blockNode = resolved.node(blockDepth);
|
|
5178
|
+
const blockPos = blockDepth === 0 ? 0 : resolved.before(blockDepth);
|
|
5179
|
+
let branchOffset = blockPos + 1;
|
|
5180
|
+
for (let index = 0; index < blockNode.childCount; index++) {
|
|
5181
|
+
const branchNode = blockNode.child(index);
|
|
5182
|
+
if (branchOffset === nodePos) {
|
|
5183
|
+
return {
|
|
5184
|
+
blockNode,
|
|
5185
|
+
blockPos,
|
|
5186
|
+
branchNode,
|
|
5187
|
+
branchPos: branchOffset,
|
|
5188
|
+
branchIndex: index
|
|
5189
|
+
};
|
|
5190
|
+
}
|
|
5191
|
+
branchOffset += branchNode.nodeSize;
|
|
5192
|
+
}
|
|
5193
|
+
} catch {
|
|
5194
|
+
return null;
|
|
5195
|
+
}
|
|
5196
|
+
return null;
|
|
5197
|
+
}
|
|
5198
|
+
function isBranchBodyEmpty(node) {
|
|
5199
|
+
if (node.childCount !== 1) return false;
|
|
5200
|
+
const firstChild = node.firstChild;
|
|
5201
|
+
return firstChild?.type.name === "paragraph" && firstChild.content.size === 0;
|
|
5202
|
+
}
|
|
5203
|
+
function isBranchNode(node) {
|
|
5204
|
+
return node?.type.name === "jinjaIfBranch";
|
|
5205
|
+
}
|
|
5206
|
+
function createBranchNode(schema, branchType, condition) {
|
|
5207
|
+
const branchNodeType = schema.nodes.jinjaIfBranch;
|
|
5208
|
+
const paragraphNode = schema.nodes.paragraph?.createAndFill();
|
|
5209
|
+
if (!branchNodeType || !paragraphNode) {
|
|
5210
|
+
return null;
|
|
5211
|
+
}
|
|
5212
|
+
return branchNodeType.create(
|
|
5213
|
+
{
|
|
5214
|
+
branchType,
|
|
5215
|
+
condition: branchType === "else" ? "" : condition
|
|
5216
|
+
},
|
|
5217
|
+
paragraphNode
|
|
5218
|
+
);
|
|
5219
|
+
}
|
|
5220
|
+
function getLastBranchOfBlock(view, nodePos) {
|
|
5221
|
+
const context = getBranchContext(view, nodePos);
|
|
5222
|
+
if (!context || context.blockNode.childCount === 0) {
|
|
5223
|
+
return null;
|
|
5224
|
+
}
|
|
5225
|
+
const index = context.blockNode.childCount - 1;
|
|
5226
|
+
return {
|
|
5227
|
+
index,
|
|
5228
|
+
node: context.blockNode.child(index)
|
|
5229
|
+
};
|
|
5230
|
+
}
|
|
5231
|
+
function getLastNonElseBranchIndex(view, nodePos) {
|
|
5232
|
+
const context = getBranchContext(view, nodePos);
|
|
5233
|
+
if (!context) return -1;
|
|
5234
|
+
for (let i = context.blockNode.childCount - 1; i >= 0; i--) {
|
|
5235
|
+
if (context.blockNode.child(i).attrs.branchType !== "else") return i;
|
|
5236
|
+
}
|
|
5237
|
+
return -1;
|
|
5238
|
+
}
|
|
5239
|
+
function getElseBranch(view, nodePos) {
|
|
5240
|
+
const context = getBranchContext(view, nodePos);
|
|
5241
|
+
if (!context) return false;
|
|
5242
|
+
for (let index = 0; index < context.blockNode.childCount; index++) {
|
|
5243
|
+
if (context.blockNode.child(index).attrs.branchType === "else") {
|
|
5244
|
+
return true;
|
|
5245
|
+
}
|
|
5246
|
+
}
|
|
5247
|
+
return false;
|
|
5248
|
+
}
|
|
5249
|
+
function deleteBlock(view, blockPos) {
|
|
5250
|
+
const blockNode = view.state.doc.nodeAt(blockPos);
|
|
5251
|
+
if (blockNode?.type.name !== "jinjaIfBlock") {
|
|
5252
|
+
return false;
|
|
5253
|
+
}
|
|
5254
|
+
view.dispatch(view.state.tr.delete(blockPos, blockPos + blockNode.nodeSize).scrollIntoView());
|
|
5255
|
+
view.focus();
|
|
5256
|
+
return true;
|
|
5257
|
+
}
|
|
5258
|
+
function insertNewBranch(view, nodePos, branchType, condition = "") {
|
|
5259
|
+
const context = getBranchContext(view, nodePos);
|
|
5260
|
+
if (!context) return false;
|
|
5261
|
+
if (context.branchNode.attrs.branchType === "else") return false;
|
|
5262
|
+
const lastBranch = getLastBranchOfBlock(view, nodePos);
|
|
5263
|
+
if (!lastBranch) return false;
|
|
5264
|
+
if (branchType === "else") {
|
|
5265
|
+
if (getElseBranch(view, nodePos)) return false;
|
|
5266
|
+
if (lastBranch.index !== context.branchIndex) return false;
|
|
5267
|
+
}
|
|
5268
|
+
const newBranch = createBranchNode(view.state.schema, branchType, condition);
|
|
5269
|
+
if (!newBranch) return false;
|
|
5270
|
+
const insertPos = context.branchPos + context.branchNode.nodeSize;
|
|
5271
|
+
view.dispatch(view.state.tr.insert(insertPos, newBranch).scrollIntoView());
|
|
5272
|
+
view.focus();
|
|
5273
|
+
return true;
|
|
5274
|
+
}
|
|
5275
|
+
function deleteBranch(view, nodePos, branchType) {
|
|
5276
|
+
const context = getBranchContext(view, nodePos);
|
|
5277
|
+
if (!context) return false;
|
|
5278
|
+
if (branchType === "if") {
|
|
5279
|
+
if (context.blockNode.childCount === 1) {
|
|
5280
|
+
return deleteBlock(view, context.blockPos);
|
|
5281
|
+
}
|
|
5282
|
+
const nextBranch = context.blockNode.child(context.branchIndex + 1);
|
|
5283
|
+
const promotedCondition = typeof nextBranch.attrs.condition === "string" ? nextBranch.attrs.condition : "";
|
|
5284
|
+
const tr = view.state.tr.delete(context.branchPos, context.branchPos + context.branchNode.nodeSize);
|
|
5285
|
+
tr.setNodeMarkup(context.branchPos, void 0, {
|
|
5286
|
+
...nextBranch.attrs,
|
|
5287
|
+
branchType: "if",
|
|
5288
|
+
condition: promotedCondition
|
|
5289
|
+
});
|
|
5290
|
+
view.dispatch(tr.scrollIntoView());
|
|
5291
|
+
view.focus();
|
|
5292
|
+
return true;
|
|
5293
|
+
}
|
|
5294
|
+
view.dispatch(view.state.tr.delete(context.branchPos, context.branchPos + context.branchNode.nodeSize).scrollIntoView());
|
|
5295
|
+
view.focus();
|
|
5296
|
+
return true;
|
|
5297
|
+
}
|
|
5298
|
+
function renderCondition(condition) {
|
|
5299
|
+
const tokens = tokenizeCondition(condition);
|
|
5300
|
+
const rendered = [];
|
|
5301
|
+
for (let index = 0; index < tokens.length; index++) {
|
|
5302
|
+
const token = tokens[index];
|
|
5303
|
+
rendered.push(
|
|
5304
|
+
/* @__PURE__ */ jsx6("span", { className: `jinja-token-${token.category}`, children: token.text }, `token-${index}-${token.start}`)
|
|
5305
|
+
);
|
|
5306
|
+
}
|
|
5307
|
+
return rendered;
|
|
5308
|
+
}
|
|
5309
|
+
function ConditionDisplay({
|
|
5310
|
+
branchType,
|
|
5311
|
+
condition,
|
|
5312
|
+
editable = true,
|
|
5313
|
+
onConditionChange
|
|
5314
|
+
}) {
|
|
5315
|
+
const [isEditing, setIsEditing] = useState2(false);
|
|
5316
|
+
const [draftValue, setDraftValue] = useState2(condition);
|
|
5317
|
+
const inputRef = useRef2(null);
|
|
5318
|
+
useEffect2(() => {
|
|
5319
|
+
if (!isEditing) {
|
|
5320
|
+
setDraftValue(condition);
|
|
5321
|
+
}
|
|
5322
|
+
}, [condition, isEditing]);
|
|
5323
|
+
useEffect2(() => {
|
|
5324
|
+
if (isEditing) {
|
|
5325
|
+
inputRef.current?.focus();
|
|
5326
|
+
inputRef.current?.select();
|
|
5327
|
+
}
|
|
5328
|
+
}, [isEditing]);
|
|
5329
|
+
if (branchType === "else") {
|
|
5330
|
+
return /* @__PURE__ */ jsx6("span", { className: "jinja-otherwise", children: "Otherwise" });
|
|
5331
|
+
}
|
|
5332
|
+
const commit = () => {
|
|
5333
|
+
setIsEditing(false);
|
|
5334
|
+
if (draftValue !== condition) {
|
|
5335
|
+
onConditionChange(draftValue);
|
|
5336
|
+
}
|
|
5337
|
+
};
|
|
5338
|
+
const cancel = () => {
|
|
5339
|
+
setDraftValue(condition);
|
|
5340
|
+
setIsEditing(false);
|
|
5341
|
+
};
|
|
5342
|
+
if (isEditing && editable) {
|
|
5343
|
+
return /* @__PURE__ */ jsx6(
|
|
5344
|
+
"input",
|
|
5345
|
+
{
|
|
5346
|
+
ref: inputRef,
|
|
5347
|
+
className: "jinja-condition-input",
|
|
5348
|
+
value: draftValue,
|
|
5349
|
+
placeholder: CONDITION_PLACEHOLDER,
|
|
5350
|
+
onChange: (event) => setDraftValue(event.target.value),
|
|
5351
|
+
onBlur: commit,
|
|
5352
|
+
onKeyDown: (event) => {
|
|
5353
|
+
if (event.key === "Enter") {
|
|
5354
|
+
event.preventDefault();
|
|
5355
|
+
commit();
|
|
5356
|
+
}
|
|
5357
|
+
if (event.key === "Escape") {
|
|
5358
|
+
event.preventDefault();
|
|
5359
|
+
cancel();
|
|
5360
|
+
}
|
|
5361
|
+
}
|
|
5362
|
+
}
|
|
5363
|
+
);
|
|
5364
|
+
}
|
|
5365
|
+
return /* @__PURE__ */ jsx6(
|
|
5366
|
+
"button",
|
|
5367
|
+
{
|
|
5368
|
+
type: "button",
|
|
5369
|
+
className: "jinja-branch-condition",
|
|
5370
|
+
onMouseDown: (event) => event.preventDefault(),
|
|
5371
|
+
onClick: () => {
|
|
5372
|
+
if (editable) {
|
|
5373
|
+
setDraftValue(condition);
|
|
5374
|
+
setIsEditing(true);
|
|
5375
|
+
}
|
|
5376
|
+
},
|
|
5377
|
+
children: condition.length > 0 ? renderCondition(condition) : /* @__PURE__ */ jsx6("span", { className: "jinja-condition-placeholder", children: CONDITION_PLACEHOLDER })
|
|
5378
|
+
}
|
|
5379
|
+
);
|
|
5380
|
+
}
|
|
5381
|
+
function BranchPopupMenu({ items, position }) {
|
|
5382
|
+
return /* @__PURE__ */ jsx6(
|
|
5383
|
+
"div",
|
|
5384
|
+
{
|
|
5385
|
+
className: "jinja-popup-menu",
|
|
5386
|
+
style: {
|
|
5387
|
+
top: position.top,
|
|
5388
|
+
left: position.left,
|
|
5389
|
+
right: position.right
|
|
5390
|
+
},
|
|
5391
|
+
role: "menu",
|
|
5392
|
+
children: items.map((item) => /* @__PURE__ */ jsx6(
|
|
5393
|
+
"button",
|
|
5394
|
+
{
|
|
5395
|
+
type: "button",
|
|
5396
|
+
className: "jinja-popup-item",
|
|
5397
|
+
disabled: item.disabled,
|
|
5398
|
+
onMouseDown: (event) => event.preventDefault(),
|
|
5399
|
+
onClick: () => {
|
|
5400
|
+
if (!item.disabled) {
|
|
5401
|
+
item.onSelect();
|
|
5402
|
+
}
|
|
5403
|
+
},
|
|
5404
|
+
role: "menuitem",
|
|
5405
|
+
children: item.label
|
|
5406
|
+
},
|
|
5407
|
+
item.label
|
|
5408
|
+
))
|
|
5409
|
+
}
|
|
5410
|
+
);
|
|
5411
|
+
}
|
|
5412
|
+
function JinjaBranchHeader({
|
|
5413
|
+
branchType,
|
|
5414
|
+
condition,
|
|
5415
|
+
editable = true,
|
|
5416
|
+
onConditionChange,
|
|
5417
|
+
onDelete,
|
|
5418
|
+
onAddBranch,
|
|
5419
|
+
isLastBranch,
|
|
5420
|
+
hasElseBranch
|
|
5421
|
+
}) {
|
|
5422
|
+
const [menuSource, setMenuSource] = useState2(null);
|
|
5423
|
+
const kebabRef = useRef2(null);
|
|
5424
|
+
const footerRef = useRef2(null);
|
|
5425
|
+
useEffect2(() => {
|
|
5426
|
+
if (!menuSource) return;
|
|
5427
|
+
const handlePointerDown = (event) => {
|
|
5428
|
+
const target = event.target;
|
|
5429
|
+
if (!target) return;
|
|
5430
|
+
if (kebabRef.current?.contains(target) || footerRef.current?.contains(target)) {
|
|
5431
|
+
return;
|
|
5432
|
+
}
|
|
5433
|
+
setMenuSource(null);
|
|
5434
|
+
};
|
|
5435
|
+
const handleKeyDown = (event) => {
|
|
5436
|
+
if (event.key === "Escape") {
|
|
5437
|
+
setMenuSource(null);
|
|
5438
|
+
}
|
|
5439
|
+
};
|
|
5440
|
+
document.addEventListener("pointerdown", handlePointerDown, true);
|
|
5441
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
5442
|
+
return () => {
|
|
5443
|
+
document.removeEventListener("pointerdown", handlePointerDown, true);
|
|
5444
|
+
document.removeEventListener("keydown", handleKeyDown);
|
|
5445
|
+
};
|
|
5446
|
+
}, [menuSource]);
|
|
5447
|
+
const menuItems = [];
|
|
5448
|
+
const isOnlyIfBranch = branchType === "if" && isLastBranch && !hasElseBranch;
|
|
5449
|
+
const canAddElif = editable && branchType !== "else" && (branchType === "elif" || isLastBranch);
|
|
5450
|
+
const canAddElse = editable && branchType !== "else" && isLastBranch && !hasElseBranch;
|
|
5451
|
+
if (canAddElif) {
|
|
5452
|
+
menuItems.push({
|
|
5453
|
+
label: "Else if",
|
|
5454
|
+
onSelect: () => onAddBranch("elif")
|
|
5455
|
+
});
|
|
5456
|
+
}
|
|
5457
|
+
if (canAddElse) {
|
|
5458
|
+
menuItems.push({
|
|
5459
|
+
label: "Else",
|
|
5460
|
+
onSelect: () => onAddBranch("else")
|
|
5461
|
+
});
|
|
5462
|
+
}
|
|
5463
|
+
if (editable) {
|
|
5464
|
+
menuItems.push({
|
|
5465
|
+
label: isOnlyIfBranch ? "Delete all" : "Delete",
|
|
5466
|
+
onSelect: onDelete
|
|
5467
|
+
});
|
|
5468
|
+
}
|
|
5469
|
+
const canOpenFooterMenu = editable && isLastBranch && branchType !== "else";
|
|
5470
|
+
const isMenuOpen = (source) => menuSource === source && menuItems.length > 0;
|
|
5471
|
+
return /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
5472
|
+
/* @__PURE__ */ jsxs5("div", { className: "jinja-branch-header", children: [
|
|
5473
|
+
/* @__PURE__ */ jsx6("span", { className: `jinja-branch-badge jinja-branch-badge-${branchType}`, children: branchType === "elif" ? "ELSE IF" : branchType.toUpperCase() }),
|
|
5474
|
+
/* @__PURE__ */ jsx6(
|
|
5475
|
+
ConditionDisplay,
|
|
5476
|
+
{
|
|
5477
|
+
branchType,
|
|
5478
|
+
condition,
|
|
5479
|
+
editable,
|
|
5480
|
+
onConditionChange
|
|
5481
|
+
}
|
|
5482
|
+
),
|
|
5483
|
+
editable ? /* @__PURE__ */ jsxs5("div", { className: "jinja-branch-actions", ref: kebabRef, children: [
|
|
5484
|
+
/* @__PURE__ */ jsx6(
|
|
5485
|
+
"button",
|
|
5486
|
+
{
|
|
5487
|
+
type: "button",
|
|
5488
|
+
className: "jinja-ghost-btn",
|
|
5489
|
+
"aria-label": `${branchType} branch options`,
|
|
5490
|
+
onMouseDown: (event) => event.preventDefault(),
|
|
5491
|
+
onClick: () => {
|
|
5492
|
+
if (menuItems.length > 0) {
|
|
5493
|
+
setMenuSource((current) => current === "kebab" ? null : "kebab");
|
|
5494
|
+
}
|
|
5495
|
+
},
|
|
5496
|
+
children: /* @__PURE__ */ jsxs5("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "currentColor", children: [
|
|
5497
|
+
/* @__PURE__ */ jsx6("circle", { cx: "8", cy: "3", r: "1.5" }),
|
|
5498
|
+
/* @__PURE__ */ jsx6("circle", { cx: "8", cy: "8", r: "1.5" }),
|
|
5499
|
+
/* @__PURE__ */ jsx6("circle", { cx: "8", cy: "13", r: "1.5" })
|
|
5500
|
+
] })
|
|
5501
|
+
}
|
|
5502
|
+
),
|
|
5503
|
+
isMenuOpen("kebab") ? /* @__PURE__ */ jsx6(
|
|
5504
|
+
BranchPopupMenu,
|
|
5505
|
+
{
|
|
5506
|
+
position: { top: 28, right: 0 },
|
|
5507
|
+
items: menuItems.map((item) => ({
|
|
5508
|
+
...item,
|
|
5509
|
+
onSelect: () => {
|
|
5510
|
+
setMenuSource(null);
|
|
5511
|
+
item.onSelect();
|
|
5512
|
+
}
|
|
5513
|
+
}))
|
|
5514
|
+
}
|
|
5515
|
+
) : null
|
|
5516
|
+
] }) : null
|
|
5517
|
+
] }),
|
|
5518
|
+
isLastBranch ? /* @__PURE__ */ jsx6("div", { className: "jinja-add-footer", children: /* @__PURE__ */ jsx6("div", { className: "jinja-add-footer-col", children: /* @__PURE__ */ jsxs5("div", { className: "jinja-add-footer-actions", ref: footerRef, children: [
|
|
5519
|
+
/* @__PURE__ */ jsx6(
|
|
5520
|
+
"button",
|
|
5521
|
+
{
|
|
5522
|
+
type: "button",
|
|
5523
|
+
className: "jinja-ghost-btn",
|
|
5524
|
+
"aria-label": "Add branch",
|
|
5525
|
+
disabled: !canOpenFooterMenu,
|
|
5526
|
+
onMouseDown: (event) => event.preventDefault(),
|
|
5527
|
+
onClick: () => {
|
|
5528
|
+
if (canOpenFooterMenu && menuItems.length > 0) {
|
|
5529
|
+
setMenuSource((current) => current === "footer" ? null : "footer");
|
|
5530
|
+
}
|
|
5531
|
+
},
|
|
5532
|
+
children: /* @__PURE__ */ jsxs5("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", children: [
|
|
5533
|
+
/* @__PURE__ */ jsx6("line", { x1: "8", y1: "3", x2: "8", y2: "13" }),
|
|
5534
|
+
/* @__PURE__ */ jsx6("line", { x1: "3", y1: "8", x2: "13", y2: "8" })
|
|
5535
|
+
] })
|
|
5536
|
+
}
|
|
5537
|
+
),
|
|
5538
|
+
isMenuOpen("footer") ? /* @__PURE__ */ jsx6(
|
|
5539
|
+
BranchPopupMenu,
|
|
5540
|
+
{
|
|
5541
|
+
position: { top: 28, left: 0 },
|
|
5542
|
+
items: menuItems.filter((item) => item.label === "Else if" || item.label === "Else").map((item) => ({
|
|
5543
|
+
...item,
|
|
5544
|
+
onSelect: () => {
|
|
5545
|
+
setMenuSource(null);
|
|
5546
|
+
item.onSelect();
|
|
5547
|
+
}
|
|
5548
|
+
}))
|
|
5549
|
+
}
|
|
5550
|
+
) : null
|
|
5551
|
+
] }) }) }) : null
|
|
5552
|
+
] });
|
|
5553
|
+
}
|
|
5554
|
+
var JinjaIfBlockView = class {
|
|
5555
|
+
dom;
|
|
5556
|
+
contentDOM;
|
|
5557
|
+
constructor() {
|
|
5558
|
+
this.dom = document.createElement("div");
|
|
5559
|
+
this.dom.className = "jinja-if-block";
|
|
5560
|
+
this.dom.setAttribute("data-jinja-if-block", "");
|
|
5561
|
+
this.contentDOM = this.dom;
|
|
5562
|
+
requestAnimationFrame(() => this.notifyChildren());
|
|
5563
|
+
}
|
|
5564
|
+
notifyChildren() {
|
|
5565
|
+
this.dom.querySelectorAll(".jinja-branch").forEach((el) => {
|
|
5566
|
+
el.dispatchEvent(new CustomEvent("jinja-siblings-changed", { bubbles: false }));
|
|
5567
|
+
});
|
|
5568
|
+
}
|
|
5569
|
+
update(node) {
|
|
5570
|
+
if (node.type.name !== "jinjaIfBlock") return false;
|
|
5571
|
+
requestAnimationFrame(() => this.notifyChildren());
|
|
5572
|
+
return true;
|
|
5573
|
+
}
|
|
5574
|
+
};
|
|
5575
|
+
var JinjaIfBranchView = class {
|
|
5576
|
+
dom;
|
|
5577
|
+
contentDOM;
|
|
5578
|
+
headerContainer;
|
|
5579
|
+
root;
|
|
5580
|
+
node;
|
|
5581
|
+
view;
|
|
5582
|
+
getPos;
|
|
5583
|
+
constructor(node, view, getPos) {
|
|
5584
|
+
this.node = node;
|
|
5585
|
+
this.view = view;
|
|
5586
|
+
this.getPos = getPos;
|
|
5587
|
+
StyleManager.acquire();
|
|
5588
|
+
this.dom = document.createElement("div");
|
|
5589
|
+
this.headerContainer = document.createElement("div");
|
|
5590
|
+
const body = document.createElement("div");
|
|
5591
|
+
const dividerColumn = document.createElement("div");
|
|
5592
|
+
const divider = document.createElement("div");
|
|
5593
|
+
this.dom.appendChild(this.headerContainer);
|
|
5594
|
+
this.dom.appendChild(body);
|
|
5595
|
+
this.headerContainer.className = "jinja-branch-controls";
|
|
5596
|
+
this.headerContainer.contentEditable = "false";
|
|
5597
|
+
body.className = "jinja-branch-body";
|
|
5598
|
+
dividerColumn.className = "jinja-branch-divider-col";
|
|
5599
|
+
dividerColumn.contentEditable = "false";
|
|
5600
|
+
divider.className = "jinja-branch-divider";
|
|
5601
|
+
dividerColumn.appendChild(divider);
|
|
5602
|
+
this.contentDOM = document.createElement("div");
|
|
5603
|
+
this.contentDOM.className = "jinja-branch-content";
|
|
5604
|
+
this.contentDOM.setAttribute("data-placeholder", PLACEHOLDER_TEXT);
|
|
5605
|
+
body.appendChild(dividerColumn);
|
|
5606
|
+
body.appendChild(this.contentDOM);
|
|
5607
|
+
this.root = createRoot2(this.headerContainer);
|
|
5608
|
+
this._onSiblingsChanged = () => this.render();
|
|
5609
|
+
this.dom.addEventListener("jinja-siblings-changed", this._onSiblingsChanged);
|
|
5610
|
+
this.syncDOM();
|
|
5611
|
+
this.render();
|
|
5612
|
+
}
|
|
5613
|
+
_onSiblingsChanged = null;
|
|
5614
|
+
syncDOM() {
|
|
5615
|
+
const branchType = this.node.attrs.branchType;
|
|
5616
|
+
this.dom.className = `jinja-branch jinja-branch-${branchType}`;
|
|
5617
|
+
this.dom.setAttribute("data-jinja-branch", "");
|
|
5618
|
+
this.dom.setAttribute("data-branch-type", branchType);
|
|
5619
|
+
this.dom.setAttribute("data-condition", String(this.node.attrs.condition ?? ""));
|
|
5620
|
+
this.contentDOM.classList.toggle("jinja-branch-content-empty", isBranchBodyEmpty(this.node));
|
|
5621
|
+
}
|
|
5622
|
+
render() {
|
|
5623
|
+
const nodePos = this.getPos();
|
|
5624
|
+
if (nodePos == null) return;
|
|
5625
|
+
const lastBranch = getLastBranchOfBlock(this.view, nodePos);
|
|
5626
|
+
const context = getBranchContext(this.view, nodePos);
|
|
5627
|
+
if (!lastBranch || !context) return;
|
|
5628
|
+
const branchType = this.node.attrs.branchType;
|
|
5629
|
+
const condition = String(this.node.attrs.condition ?? "");
|
|
5630
|
+
const isLast = lastBranch.index === context.branchIndex;
|
|
5631
|
+
const lastNonElseIdx = getLastNonElseBranchIndex(this.view, nodePos);
|
|
5632
|
+
const showAddButton = context.branchIndex === lastNonElseIdx;
|
|
5633
|
+
this.dom.classList.toggle("jinja-branch-last", isLast);
|
|
5634
|
+
this.root.render(
|
|
5635
|
+
/* @__PURE__ */ jsx6(
|
|
5636
|
+
JinjaBranchHeader,
|
|
5637
|
+
{
|
|
5638
|
+
branchType,
|
|
5639
|
+
condition,
|
|
5640
|
+
editable: this.view.editable,
|
|
5641
|
+
isLastBranch: showAddButton,
|
|
5642
|
+
hasElseBranch: getElseBranch(this.view, nodePos),
|
|
5643
|
+
onConditionChange: (value) => {
|
|
5644
|
+
const currentPos = this.getPos();
|
|
5645
|
+
if (currentPos == null) return;
|
|
5646
|
+
this.view.dispatch(
|
|
5647
|
+
this.view.state.tr.setNodeMarkup(currentPos, void 0, {
|
|
5648
|
+
...this.node.attrs,
|
|
5649
|
+
condition: value
|
|
5650
|
+
})
|
|
5651
|
+
);
|
|
5652
|
+
this.view.focus();
|
|
5653
|
+
},
|
|
5654
|
+
onDelete: () => {
|
|
5655
|
+
const currentPos = this.getPos();
|
|
5656
|
+
if (currentPos == null) return;
|
|
5657
|
+
deleteBranch(this.view, currentPos, branchType);
|
|
5658
|
+
},
|
|
5659
|
+
onAddBranch: (nextBranchType) => {
|
|
5660
|
+
const currentPos = this.getPos();
|
|
5661
|
+
if (currentPos == null) return;
|
|
5662
|
+
insertNewBranch(this.view, currentPos, nextBranchType, "");
|
|
5663
|
+
}
|
|
5664
|
+
}
|
|
5665
|
+
)
|
|
5666
|
+
);
|
|
5667
|
+
}
|
|
5668
|
+
update(node) {
|
|
5669
|
+
if (!isBranchNode(node)) return false;
|
|
5670
|
+
this.node = node;
|
|
5671
|
+
this.syncDOM();
|
|
5672
|
+
this.render();
|
|
5673
|
+
return true;
|
|
5674
|
+
}
|
|
5675
|
+
stopEvent(event) {
|
|
5676
|
+
const target = event.target;
|
|
5677
|
+
return target != null && this.headerContainer.contains(target);
|
|
5678
|
+
}
|
|
5679
|
+
ignoreMutation(mutation) {
|
|
5680
|
+
return this.headerContainer.contains(mutation.target);
|
|
5681
|
+
}
|
|
5682
|
+
destroy() {
|
|
5683
|
+
if (this._onSiblingsChanged) {
|
|
5684
|
+
this.dom.removeEventListener("jinja-siblings-changed", this._onSiblingsChanged);
|
|
5685
|
+
}
|
|
5686
|
+
StyleManager.release();
|
|
5687
|
+
setTimeout(() => this.root.unmount(), 0);
|
|
5688
|
+
}
|
|
5689
|
+
};
|
|
5690
|
+
function createJinjaIfBlockPlugin() {
|
|
5691
|
+
return {
|
|
5692
|
+
name: "jinjaIfBlock",
|
|
5693
|
+
nodeViews: () => ({
|
|
5694
|
+
jinjaIfBlock: (() => new JinjaIfBlockView()),
|
|
5695
|
+
jinjaIfBranch: ((node, view, getPos) => new JinjaIfBranchView(node, view, getPos))
|
|
5696
|
+
})
|
|
5697
|
+
};
|
|
5698
|
+
}
|
|
5699
|
+
|
|
4491
5700
|
// src/ui/plugin/linkPlugin.ts
|
|
4492
5701
|
import { InputRule as InputRule2, inputRules as inputRules2 } from "prosemirror-inputrules";
|
|
4493
|
-
import { Plugin as
|
|
5702
|
+
import { Plugin as Plugin5, PluginKey as PluginKey5, TextSelection as TextSelection2 } from "prosemirror-state";
|
|
4494
5703
|
var LINK_INPUT_RE = /\[([^\]]*)\]\(([^)\s]*?)(?:\s+"([^"]*)")?\)$/;
|
|
4495
5704
|
var LINK_FULL_RE = /^\[([^\]]*)\]\(([^)\s]*?)(?:\s+"([^"]*)")?\)$/;
|
|
4496
|
-
var linkEditKey = new
|
|
5705
|
+
var linkEditKey = new PluginKey5("linkEdit");
|
|
4497
5706
|
function getMarkRange($pos, type) {
|
|
4498
5707
|
const { parentOffset } = $pos;
|
|
4499
5708
|
let child = $pos.parent.childAfter(parentOffset);
|
|
@@ -4541,7 +5750,7 @@ function explodeLinkToRaw(state) {
|
|
|
4541
5750
|
return tr;
|
|
4542
5751
|
}
|
|
4543
5752
|
function createLinkEditPlugin() {
|
|
4544
|
-
return new
|
|
5753
|
+
return new Plugin5({
|
|
4545
5754
|
key: linkEditKey,
|
|
4546
5755
|
state: {
|
|
4547
5756
|
init: () => ({ rawRange: null }),
|
|
@@ -4611,8 +5820,8 @@ function createLinkInputRule() {
|
|
|
4611
5820
|
);
|
|
4612
5821
|
}
|
|
4613
5822
|
function createLinkClickPlugin() {
|
|
4614
|
-
return new
|
|
4615
|
-
key: new
|
|
5823
|
+
return new Plugin5({
|
|
5824
|
+
key: new PluginKey5("linkClick"),
|
|
4616
5825
|
props: {
|
|
4617
5826
|
handleDOMEvents: {
|
|
4618
5827
|
click: (_view, event) => {
|
|
@@ -4664,8 +5873,8 @@ function createLinkPlugin() {
|
|
|
4664
5873
|
}
|
|
4665
5874
|
|
|
4666
5875
|
// src/ui/plugin/dragHandlePlugin.ts
|
|
4667
|
-
import { Plugin as
|
|
4668
|
-
var PLUGIN_KEY = new
|
|
5876
|
+
import { Plugin as Plugin6, PluginKey as PluginKey6 } from "prosemirror-state";
|
|
5877
|
+
var PLUGIN_KEY = new PluginKey6("dragHandle");
|
|
4669
5878
|
var GRIP_SVG = `<svg width="12" height="12" viewBox="0 0 12 12" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
|
|
4670
5879
|
<circle cx="4" cy="2.5" r="1.2"/><circle cx="8" cy="2.5" r="1.2"/>
|
|
4671
5880
|
<circle cx="4" cy="6" r="1.2"/><circle cx="8" cy="6" r="1.2"/>
|
|
@@ -4753,7 +5962,7 @@ var STYLES = (
|
|
|
4753
5962
|
}
|
|
4754
5963
|
`
|
|
4755
5964
|
);
|
|
4756
|
-
var
|
|
5965
|
+
var StyleManager2 = class {
|
|
4757
5966
|
static refCount = 0;
|
|
4758
5967
|
static sheet = null;
|
|
4759
5968
|
static styleEl = null;
|
|
@@ -4880,7 +6089,7 @@ var DragHandleController = class {
|
|
|
4880
6089
|
globalCleanup = null;
|
|
4881
6090
|
constructor(view) {
|
|
4882
6091
|
this.view = view;
|
|
4883
|
-
|
|
6092
|
+
StyleManager2.acquire();
|
|
4884
6093
|
const parent = view.dom.parentNode;
|
|
4885
6094
|
const pos = getComputedStyle(parent).position;
|
|
4886
6095
|
if (pos === "static" || pos === "") parent.style.position = "relative";
|
|
@@ -4938,7 +6147,7 @@ var DragHandleController = class {
|
|
|
4938
6147
|
}
|
|
4939
6148
|
this.liveRegion.remove();
|
|
4940
6149
|
this.layer.remove();
|
|
4941
|
-
|
|
6150
|
+
StyleManager2.release();
|
|
4942
6151
|
}
|
|
4943
6152
|
// ── Private: update pipeline ──
|
|
4944
6153
|
scheduleUpdate() {
|
|
@@ -5289,7 +6498,7 @@ function createDragHandlePlugin() {
|
|
|
5289
6498
|
plugins: () => {
|
|
5290
6499
|
let controller = null;
|
|
5291
6500
|
return [
|
|
5292
|
-
new
|
|
6501
|
+
new Plugin6({
|
|
5293
6502
|
key: PLUGIN_KEY,
|
|
5294
6503
|
view(editorView) {
|
|
5295
6504
|
controller = new DragHandleController(editorView);
|
|
@@ -5412,8 +6621,8 @@ function createTodoNodeViewPlugin() {
|
|
|
5412
6621
|
}
|
|
5413
6622
|
|
|
5414
6623
|
// src/ui/plugin/slashCommandPlugin.ts
|
|
5415
|
-
import { Plugin as
|
|
5416
|
-
var slashCommandKey = new
|
|
6624
|
+
import { Plugin as Plugin7, PluginKey as PluginKey7 } from "prosemirror-state";
|
|
6625
|
+
var slashCommandKey = new PluginKey7("slashCommand");
|
|
5417
6626
|
var TRIGGER_RE = /(?:^|\s)(\/[^\s]*)$/;
|
|
5418
6627
|
function deriveState(state, dismissedFrom) {
|
|
5419
6628
|
const { selection } = state;
|
|
@@ -5436,7 +6645,7 @@ function deriveState(state, dismissedFrom) {
|
|
|
5436
6645
|
};
|
|
5437
6646
|
}
|
|
5438
6647
|
function createSlashCommandPlugin() {
|
|
5439
|
-
const plugin = new
|
|
6648
|
+
const plugin = new Plugin7({
|
|
5440
6649
|
key: slashCommandKey,
|
|
5441
6650
|
state: {
|
|
5442
6651
|
init(_, state) {
|
|
@@ -5480,9 +6689,9 @@ function createSlashCommandPlugin() {
|
|
|
5480
6689
|
}
|
|
5481
6690
|
|
|
5482
6691
|
// src/ui/components/SlashCommandMenu.tsx
|
|
5483
|
-
import { useEffect as
|
|
6692
|
+
import { useEffect as useEffect3, useRef as useRef3, useState as useState3 } from "react";
|
|
5484
6693
|
import { createPortal } from "react-dom";
|
|
5485
|
-
import { jsx as
|
|
6694
|
+
import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
5486
6695
|
function filterItems(items, query) {
|
|
5487
6696
|
if (!query) return items;
|
|
5488
6697
|
const q = query.toLowerCase();
|
|
@@ -5506,23 +6715,23 @@ var VPORT_MARGIN = 8;
|
|
|
5506
6715
|
var MENU_WIDTH = 280;
|
|
5507
6716
|
var MAX_MENU_H = 320;
|
|
5508
6717
|
function SlashCommandMenu({ view, editorState, items }) {
|
|
5509
|
-
const [selectedIndex, setSelectedIndex] =
|
|
5510
|
-
const listRef =
|
|
6718
|
+
const [selectedIndex, setSelectedIndex] = useState3(0);
|
|
6719
|
+
const listRef = useRef3(null);
|
|
5511
6720
|
const pluginState = editorState ? slashCommandKey.getState(editorState) : void 0;
|
|
5512
6721
|
const active = pluginState?.active ?? false;
|
|
5513
6722
|
const range = pluginState?.range ?? null;
|
|
5514
6723
|
const query = pluginState?.query ?? "";
|
|
5515
6724
|
const filtered = filterItems(items, query);
|
|
5516
|
-
|
|
6725
|
+
useEffect3(() => {
|
|
5517
6726
|
setSelectedIndex(0);
|
|
5518
6727
|
}, [query, active]);
|
|
5519
|
-
|
|
6728
|
+
useEffect3(() => {
|
|
5520
6729
|
const list = listRef.current;
|
|
5521
6730
|
if (!list) return;
|
|
5522
6731
|
const item = list.children[selectedIndex];
|
|
5523
6732
|
item?.scrollIntoView({ block: "nearest" });
|
|
5524
6733
|
}, [selectedIndex]);
|
|
5525
|
-
|
|
6734
|
+
useEffect3(() => {
|
|
5526
6735
|
if (!active || !view) return;
|
|
5527
6736
|
const onKeyDown = (e) => {
|
|
5528
6737
|
if (e.key === "ArrowDown") {
|
|
@@ -5558,7 +6767,7 @@ function SlashCommandMenu({ view, editorState, items }) {
|
|
|
5558
6767
|
top = coords.top - MAX_MENU_H - 4;
|
|
5559
6768
|
}
|
|
5560
6769
|
return createPortal(
|
|
5561
|
-
/* @__PURE__ */
|
|
6770
|
+
/* @__PURE__ */ jsx7(
|
|
5562
6771
|
"div",
|
|
5563
6772
|
{
|
|
5564
6773
|
style: {
|
|
@@ -5575,7 +6784,7 @@ function SlashCommandMenu({ view, editorState, items }) {
|
|
|
5575
6784
|
zIndex: 1100,
|
|
5576
6785
|
animation: "ab-float-in 0.12s ease"
|
|
5577
6786
|
},
|
|
5578
|
-
children: /* @__PURE__ */
|
|
6787
|
+
children: /* @__PURE__ */ jsx7("div", { ref: listRef, children: filtered.length === 0 ? /* @__PURE__ */ jsx7(
|
|
5579
6788
|
"div",
|
|
5580
6789
|
{
|
|
5581
6790
|
style: {
|
|
@@ -5585,7 +6794,7 @@ function SlashCommandMenu({ view, editorState, items }) {
|
|
|
5585
6794
|
},
|
|
5586
6795
|
children: "No results"
|
|
5587
6796
|
}
|
|
5588
|
-
) : filtered.map((item, i) => /* @__PURE__ */
|
|
6797
|
+
) : filtered.map((item, i) => /* @__PURE__ */ jsx7(
|
|
5589
6798
|
SlashMenuItem,
|
|
5590
6799
|
{
|
|
5591
6800
|
item,
|
|
@@ -5607,7 +6816,7 @@ function SlashCommandMenu({ view, editorState, items }) {
|
|
|
5607
6816
|
);
|
|
5608
6817
|
}
|
|
5609
6818
|
function SlashMenuItem({ item, selected, onMouseEnter, onMouseDown }) {
|
|
5610
|
-
return /* @__PURE__ */
|
|
6819
|
+
return /* @__PURE__ */ jsxs6(
|
|
5611
6820
|
"button",
|
|
5612
6821
|
{
|
|
5613
6822
|
style: {
|
|
@@ -5623,7 +6832,7 @@ function SlashMenuItem({ item, selected, onMouseEnter, onMouseDown }) {
|
|
|
5623
6832
|
onMouseEnter,
|
|
5624
6833
|
onMouseDown,
|
|
5625
6834
|
children: [
|
|
5626
|
-
item.icon !== void 0 && /* @__PURE__ */
|
|
6835
|
+
item.icon !== void 0 && /* @__PURE__ */ jsx7(
|
|
5627
6836
|
"span",
|
|
5628
6837
|
{
|
|
5629
6838
|
style: {
|
|
@@ -5643,8 +6852,8 @@ function SlashMenuItem({ item, selected, onMouseEnter, onMouseDown }) {
|
|
|
5643
6852
|
children: item.icon
|
|
5644
6853
|
}
|
|
5645
6854
|
),
|
|
5646
|
-
/* @__PURE__ */
|
|
5647
|
-
/* @__PURE__ */
|
|
6855
|
+
/* @__PURE__ */ jsxs6("span", { style: { display: "flex", flexDirection: "column", gap: 1, minWidth: 0 }, children: [
|
|
6856
|
+
/* @__PURE__ */ jsx7(
|
|
5648
6857
|
"span",
|
|
5649
6858
|
{
|
|
5650
6859
|
style: {
|
|
@@ -5658,7 +6867,7 @@ function SlashMenuItem({ item, selected, onMouseEnter, onMouseDown }) {
|
|
|
5658
6867
|
children: item.title
|
|
5659
6868
|
}
|
|
5660
6869
|
),
|
|
5661
|
-
item.description && /* @__PURE__ */
|
|
6870
|
+
item.description && /* @__PURE__ */ jsx7(
|
|
5662
6871
|
"span",
|
|
5663
6872
|
{
|
|
5664
6873
|
style: {
|
|
@@ -5678,8 +6887,8 @@ function SlashMenuItem({ item, selected, onMouseEnter, onMouseDown }) {
|
|
|
5678
6887
|
}
|
|
5679
6888
|
|
|
5680
6889
|
// src/ui/components/JinjaTreeView.tsx
|
|
5681
|
-
import { useState as
|
|
5682
|
-
import { jsx as
|
|
6890
|
+
import { useState as useState4 } from "react";
|
|
6891
|
+
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
5683
6892
|
var BRANCH_COLORS = {
|
|
5684
6893
|
if: "#6366f1",
|
|
5685
6894
|
elif: "#f59e0b",
|
|
@@ -5699,21 +6908,21 @@ function BranchNode({
|
|
|
5699
6908
|
const blockCount = branch.blockEndIndex - branch.blockStartIndex;
|
|
5700
6909
|
const preview = getBlockPreview(doc2, branch.blockStartIndex, branch.blockEndIndex);
|
|
5701
6910
|
const connector = isLast ? "\u2514\u2500" : "\u251C\u2500";
|
|
5702
|
-
return /* @__PURE__ */
|
|
5703
|
-
/* @__PURE__ */
|
|
6911
|
+
return /* @__PURE__ */ jsxs7("div", { className: "jinja-tree-branch", children: [
|
|
6912
|
+
/* @__PURE__ */ jsxs7("span", { className: "jinja-tree-connector", children: [
|
|
5704
6913
|
connector,
|
|
5705
6914
|
" "
|
|
5706
6915
|
] }),
|
|
5707
|
-
/* @__PURE__ */
|
|
6916
|
+
/* @__PURE__ */ jsxs7("span", { className: "jinja-tree-badge", style: { color, borderColor: color }, children: [
|
|
5708
6917
|
"[",
|
|
5709
6918
|
branch.type,
|
|
5710
6919
|
"]"
|
|
5711
6920
|
] }),
|
|
5712
|
-
branch.condition && /* @__PURE__ */
|
|
6921
|
+
branch.condition && /* @__PURE__ */ jsxs7("span", { className: "jinja-tree-condition", children: [
|
|
5713
6922
|
" ",
|
|
5714
6923
|
branch.condition
|
|
5715
6924
|
] }),
|
|
5716
|
-
/* @__PURE__ */
|
|
6925
|
+
/* @__PURE__ */ jsxs7("span", { className: "jinja-tree-meta", children: [
|
|
5717
6926
|
" ",
|
|
5718
6927
|
blockCount,
|
|
5719
6928
|
" block",
|
|
@@ -5723,23 +6932,23 @@ function BranchNode({
|
|
|
5723
6932
|
] });
|
|
5724
6933
|
}
|
|
5725
6934
|
function StructureNode({ structure, doc: doc2 }) {
|
|
5726
|
-
const [expanded, setExpanded] =
|
|
6935
|
+
const [expanded, setExpanded] = useState4(true);
|
|
5727
6936
|
const firstBranch = structure.branches[0];
|
|
5728
6937
|
const label = firstBranch?.condition ? `if ${firstBranch.condition}` : "if";
|
|
5729
|
-
return /* @__PURE__ */
|
|
5730
|
-
/* @__PURE__ */
|
|
6938
|
+
return /* @__PURE__ */ jsxs7("div", { className: "jinja-tree-structure", children: [
|
|
6939
|
+
/* @__PURE__ */ jsxs7(
|
|
5731
6940
|
"button",
|
|
5732
6941
|
{
|
|
5733
6942
|
className: "jinja-tree-toggle",
|
|
5734
6943
|
onClick: () => setExpanded(!expanded),
|
|
5735
6944
|
type: "button",
|
|
5736
6945
|
children: [
|
|
5737
|
-
/* @__PURE__ */
|
|
5738
|
-
/* @__PURE__ */
|
|
6946
|
+
/* @__PURE__ */ jsx8("span", { className: "jinja-tree-arrow", children: expanded ? "\u25BC" : "\u25B6" }),
|
|
6947
|
+
/* @__PURE__ */ jsx8("span", { className: "jinja-tree-label", children: label })
|
|
5739
6948
|
]
|
|
5740
6949
|
}
|
|
5741
6950
|
),
|
|
5742
|
-
expanded && /* @__PURE__ */
|
|
6951
|
+
expanded && /* @__PURE__ */ jsx8("div", { className: "jinja-tree-branches", children: structure.branches.map((branch, i) => /* @__PURE__ */ jsx8(
|
|
5743
6952
|
BranchNode,
|
|
5744
6953
|
{
|
|
5745
6954
|
branch,
|
|
@@ -5753,15 +6962,15 @@ function StructureNode({ structure, doc: doc2 }) {
|
|
|
5753
6962
|
function JinjaTreeView({ doc: doc2, className }) {
|
|
5754
6963
|
const structures = analyzeJinjaBlocks(doc2);
|
|
5755
6964
|
if (structures.length === 0) return null;
|
|
5756
|
-
return /* @__PURE__ */
|
|
6965
|
+
return /* @__PURE__ */ jsx8("div", { className: `jinja-tree ${className || ""}`, children: structures.map((structure) => /* @__PURE__ */ jsx8(StructureNode, { structure, doc: doc2 }, structure.id)) });
|
|
5757
6966
|
}
|
|
5758
6967
|
|
|
5759
6968
|
// src/ui/components/FloatingMenu.tsx
|
|
5760
|
-
import { useCallback as useCallback2, useEffect as
|
|
6969
|
+
import { useCallback as useCallback2, useEffect as useEffect4, useRef as useRef4, useState as useState5 } from "react";
|
|
5761
6970
|
import { createPortal as createPortal2 } from "react-dom";
|
|
5762
6971
|
import { setBlockType, toggleMark as toggleMark2, wrapIn } from "prosemirror-commands";
|
|
5763
6972
|
import { wrapInList as wrapInList2 } from "prosemirror-schema-list";
|
|
5764
|
-
import { Fragment as
|
|
6973
|
+
import { Fragment as Fragment3, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
5765
6974
|
var { paragraph: paragraph2, heading: heading2, bulletList: bulletList3, orderedList: orderedList3, blockquote: blockquote2 } = actionbookSchema.nodes;
|
|
5766
6975
|
var {
|
|
5767
6976
|
bold: bold2,
|
|
@@ -5849,8 +7058,8 @@ var BTN_RESET2 = {
|
|
|
5849
7058
|
lineHeight: 1
|
|
5850
7059
|
};
|
|
5851
7060
|
function TBtn({ children, active, title, onMouseDown, style }) {
|
|
5852
|
-
const [hover, setHover] =
|
|
5853
|
-
return /* @__PURE__ */
|
|
7061
|
+
const [hover, setHover] = useState5(false);
|
|
7062
|
+
return /* @__PURE__ */ jsx9(
|
|
5854
7063
|
"button",
|
|
5855
7064
|
{
|
|
5856
7065
|
...{ [FLOAT_ATTR]: "" },
|
|
@@ -5881,13 +7090,13 @@ function TBtn({ children, active, title, onMouseDown, style }) {
|
|
|
5881
7090
|
);
|
|
5882
7091
|
}
|
|
5883
7092
|
function Divider() {
|
|
5884
|
-
return /* @__PURE__ */
|
|
7093
|
+
return /* @__PURE__ */ jsx9("div", { style: { width: 1, height: 18, background: "rgba(0,0,0,0.07)", margin: "0 2px", flexShrink: 0 } });
|
|
5885
7094
|
}
|
|
5886
7095
|
function BlockTypeDropdown({ view, state, label }) {
|
|
5887
|
-
const [open, setOpen] =
|
|
5888
|
-
const btnRef =
|
|
5889
|
-
const [hover, setHover] =
|
|
5890
|
-
|
|
7096
|
+
const [open, setOpen] = useState5(false);
|
|
7097
|
+
const btnRef = useRef4(null);
|
|
7098
|
+
const [hover, setHover] = useState5(false);
|
|
7099
|
+
useEffect4(() => {
|
|
5891
7100
|
if (!open) return;
|
|
5892
7101
|
const onDown = (e) => {
|
|
5893
7102
|
if (!e.target.closest(`[${FLOAT_ATTR}]`)) {
|
|
@@ -5940,8 +7149,8 @@ function BlockTypeDropdown({ view, state, label }) {
|
|
|
5940
7149
|
} }
|
|
5941
7150
|
];
|
|
5942
7151
|
const btnRect = btnRef.current?.getBoundingClientRect();
|
|
5943
|
-
return /* @__PURE__ */
|
|
5944
|
-
/* @__PURE__ */
|
|
7152
|
+
return /* @__PURE__ */ jsxs8(Fragment3, { children: [
|
|
7153
|
+
/* @__PURE__ */ jsxs8(
|
|
5945
7154
|
"button",
|
|
5946
7155
|
{
|
|
5947
7156
|
ref: btnRef,
|
|
@@ -5969,12 +7178,12 @@ function BlockTypeDropdown({ view, state, label }) {
|
|
|
5969
7178
|
},
|
|
5970
7179
|
children: [
|
|
5971
7180
|
label,
|
|
5972
|
-
/* @__PURE__ */
|
|
7181
|
+
/* @__PURE__ */ jsx9("span", { style: { fontSize: 8, opacity: 0.6 }, children: "\u25BE" })
|
|
5973
7182
|
]
|
|
5974
7183
|
}
|
|
5975
7184
|
),
|
|
5976
7185
|
open && btnRect && createPortal2(
|
|
5977
|
-
/* @__PURE__ */
|
|
7186
|
+
/* @__PURE__ */ jsx9(
|
|
5978
7187
|
"div",
|
|
5979
7188
|
{
|
|
5980
7189
|
...{ [FLOAT_ATTR]: "" },
|
|
@@ -5990,7 +7199,7 @@ function BlockTypeDropdown({ view, state, label }) {
|
|
|
5990
7199
|
minWidth: 168,
|
|
5991
7200
|
animation: "ab-float-in 0.12s ease"
|
|
5992
7201
|
},
|
|
5993
|
-
children: items.map((item) => /* @__PURE__ */
|
|
7202
|
+
children: items.map((item) => /* @__PURE__ */ jsx9(DropdownItem, { item, onRun: () => setOpen(false) }, item.label))
|
|
5994
7203
|
}
|
|
5995
7204
|
),
|
|
5996
7205
|
document.body
|
|
@@ -5998,8 +7207,8 @@ function BlockTypeDropdown({ view, state, label }) {
|
|
|
5998
7207
|
] });
|
|
5999
7208
|
}
|
|
6000
7209
|
function DropdownItem({ item, onRun }) {
|
|
6001
|
-
const [hover, setHover] =
|
|
6002
|
-
return /* @__PURE__ */
|
|
7210
|
+
const [hover, setHover] = useState5(false);
|
|
7211
|
+
return /* @__PURE__ */ jsxs8(
|
|
6003
7212
|
"button",
|
|
6004
7213
|
{
|
|
6005
7214
|
...{ [FLOAT_ATTR]: "" },
|
|
@@ -6026,16 +7235,16 @@ function DropdownItem({ item, onRun }) {
|
|
|
6026
7235
|
transition: "background 0.1s"
|
|
6027
7236
|
},
|
|
6028
7237
|
children: [
|
|
6029
|
-
/* @__PURE__ */
|
|
7238
|
+
/* @__PURE__ */ jsx9("span", { style: { width: 24, flexShrink: 0, textAlign: "center", fontWeight: 700, fontSize: 12, fontFamily: "monospace", color: "#6366f1" }, children: item.shortLabel }),
|
|
6030
7239
|
item.label
|
|
6031
7240
|
]
|
|
6032
7241
|
}
|
|
6033
7242
|
);
|
|
6034
7243
|
}
|
|
6035
7244
|
function SelectionToolbar({ view, state, selectionRect }) {
|
|
6036
|
-
const [linkMode, setLinkMode] =
|
|
6037
|
-
const [linkHref, setLinkHref] =
|
|
6038
|
-
const inputRef =
|
|
7245
|
+
const [linkMode, setLinkMode] = useState5(false);
|
|
7246
|
+
const [linkHref, setLinkHref] = useState5("");
|
|
7247
|
+
const inputRef = useRef4(null);
|
|
6039
7248
|
const isBold = hasMark(state, bold2);
|
|
6040
7249
|
const isItalic = hasMark(state, italic2);
|
|
6041
7250
|
const isUnderline = hasMark(state, underline2);
|
|
@@ -6087,7 +7296,7 @@ function SelectionToolbar({ view, state, selectionRect }) {
|
|
|
6087
7296
|
view.dispatch(view.state.tr.removeMark(from, to, linkMark));
|
|
6088
7297
|
view.focus();
|
|
6089
7298
|
};
|
|
6090
|
-
return /* @__PURE__ */
|
|
7299
|
+
return /* @__PURE__ */ jsx9(
|
|
6091
7300
|
"div",
|
|
6092
7301
|
{
|
|
6093
7302
|
...{ [FLOAT_ATTR]: "" },
|
|
@@ -6110,9 +7319,9 @@ function SelectionToolbar({ view, state, selectionRect }) {
|
|
|
6110
7319
|
},
|
|
6111
7320
|
children: linkMode ? (
|
|
6112
7321
|
/* ── Link input mode ── */
|
|
6113
|
-
/* @__PURE__ */
|
|
6114
|
-
/* @__PURE__ */
|
|
6115
|
-
/* @__PURE__ */
|
|
7322
|
+
/* @__PURE__ */ jsxs8(Fragment3, { children: [
|
|
7323
|
+
/* @__PURE__ */ jsx9("span", { style: { fontSize: 13, color: "#9ca3af", paddingLeft: 4, flexShrink: 0 }, children: "\u2197" }),
|
|
7324
|
+
/* @__PURE__ */ jsx9(
|
|
6116
7325
|
"input",
|
|
6117
7326
|
{
|
|
6118
7327
|
ref: inputRef,
|
|
@@ -6143,7 +7352,7 @@ function SelectionToolbar({ view, state, selectionRect }) {
|
|
|
6143
7352
|
}
|
|
6144
7353
|
}
|
|
6145
7354
|
),
|
|
6146
|
-
/* @__PURE__ */
|
|
7355
|
+
/* @__PURE__ */ jsx9(
|
|
6147
7356
|
TBtn,
|
|
6148
7357
|
{
|
|
6149
7358
|
title: "Apply (Enter)",
|
|
@@ -6155,7 +7364,7 @@ function SelectionToolbar({ view, state, selectionRect }) {
|
|
|
6155
7364
|
children: "\u21B5"
|
|
6156
7365
|
}
|
|
6157
7366
|
),
|
|
6158
|
-
/* @__PURE__ */
|
|
7367
|
+
/* @__PURE__ */ jsx9(
|
|
6159
7368
|
TBtn,
|
|
6160
7369
|
{
|
|
6161
7370
|
title: "Cancel (Esc)",
|
|
@@ -6171,8 +7380,8 @@ function SelectionToolbar({ view, state, selectionRect }) {
|
|
|
6171
7380
|
] })
|
|
6172
7381
|
) : (
|
|
6173
7382
|
/* ── Normal toolbar mode ── */
|
|
6174
|
-
/* @__PURE__ */
|
|
6175
|
-
/* @__PURE__ */
|
|
7383
|
+
/* @__PURE__ */ jsxs8(Fragment3, { children: [
|
|
7384
|
+
/* @__PURE__ */ jsx9(
|
|
6176
7385
|
TBtn,
|
|
6177
7386
|
{
|
|
6178
7387
|
active: isBold,
|
|
@@ -6182,7 +7391,7 @@ function SelectionToolbar({ view, state, selectionRect }) {
|
|
|
6182
7391
|
children: "B"
|
|
6183
7392
|
}
|
|
6184
7393
|
),
|
|
6185
|
-
/* @__PURE__ */
|
|
7394
|
+
/* @__PURE__ */ jsx9(
|
|
6186
7395
|
TBtn,
|
|
6187
7396
|
{
|
|
6188
7397
|
active: isItalic,
|
|
@@ -6192,7 +7401,7 @@ function SelectionToolbar({ view, state, selectionRect }) {
|
|
|
6192
7401
|
children: "I"
|
|
6193
7402
|
}
|
|
6194
7403
|
),
|
|
6195
|
-
/* @__PURE__ */
|
|
7404
|
+
/* @__PURE__ */ jsx9(
|
|
6196
7405
|
TBtn,
|
|
6197
7406
|
{
|
|
6198
7407
|
active: isUnderline,
|
|
@@ -6202,7 +7411,7 @@ function SelectionToolbar({ view, state, selectionRect }) {
|
|
|
6202
7411
|
children: "U"
|
|
6203
7412
|
}
|
|
6204
7413
|
),
|
|
6205
|
-
/* @__PURE__ */
|
|
7414
|
+
/* @__PURE__ */ jsx9(
|
|
6206
7415
|
TBtn,
|
|
6207
7416
|
{
|
|
6208
7417
|
active: isStrike,
|
|
@@ -6212,7 +7421,7 @@ function SelectionToolbar({ view, state, selectionRect }) {
|
|
|
6212
7421
|
children: "S"
|
|
6213
7422
|
}
|
|
6214
7423
|
),
|
|
6215
|
-
/* @__PURE__ */
|
|
7424
|
+
/* @__PURE__ */ jsx9(
|
|
6216
7425
|
TBtn,
|
|
6217
7426
|
{
|
|
6218
7427
|
active: isCode,
|
|
@@ -6222,7 +7431,7 @@ function SelectionToolbar({ view, state, selectionRect }) {
|
|
|
6222
7431
|
children: "`\xB7`"
|
|
6223
7432
|
}
|
|
6224
7433
|
),
|
|
6225
|
-
/* @__PURE__ */
|
|
7434
|
+
/* @__PURE__ */ jsx9(
|
|
6226
7435
|
TBtn,
|
|
6227
7436
|
{
|
|
6228
7437
|
active: isLink,
|
|
@@ -6232,8 +7441,8 @@ function SelectionToolbar({ view, state, selectionRect }) {
|
|
|
6232
7441
|
children: "\u2197"
|
|
6233
7442
|
}
|
|
6234
7443
|
),
|
|
6235
|
-
/* @__PURE__ */
|
|
6236
|
-
/* @__PURE__ */
|
|
7444
|
+
/* @__PURE__ */ jsx9(Divider, {}),
|
|
7445
|
+
/* @__PURE__ */ jsx9(BlockTypeDropdown, { view, state, label: blockLabel })
|
|
6237
7446
|
] })
|
|
6238
7447
|
)
|
|
6239
7448
|
}
|
|
@@ -6323,7 +7532,7 @@ var BLOCK_ITEMS = [
|
|
|
6323
7532
|
}
|
|
6324
7533
|
];
|
|
6325
7534
|
function EmptyParaHandle({ view, cursorPos }) {
|
|
6326
|
-
const [menuOpen, setMenuOpen] =
|
|
7535
|
+
const [menuOpen, setMenuOpen] = useState5(false);
|
|
6327
7536
|
const coords = view.coordsAtPos(cursorPos);
|
|
6328
7537
|
const lineH = Math.max(coords.bottom - coords.top, 18);
|
|
6329
7538
|
const btnSize = 22;
|
|
@@ -6331,7 +7540,7 @@ function EmptyParaHandle({ view, cursorPos }) {
|
|
|
6331
7540
|
const btnTop = coords.top + (lineH - btnSize) / 2;
|
|
6332
7541
|
const menuLeft = Math.max(VPORT_MARGIN2, btnLeft);
|
|
6333
7542
|
const menuTop = btnTop + btnSize + 4;
|
|
6334
|
-
|
|
7543
|
+
useEffect4(() => {
|
|
6335
7544
|
if (!menuOpen) return;
|
|
6336
7545
|
const onDown = (e) => {
|
|
6337
7546
|
if (!e.target.closest(`[${FLOAT_ATTR}]`)) {
|
|
@@ -6341,8 +7550,8 @@ function EmptyParaHandle({ view, cursorPos }) {
|
|
|
6341
7550
|
document.addEventListener("mousedown", onDown, true);
|
|
6342
7551
|
return () => document.removeEventListener("mousedown", onDown, true);
|
|
6343
7552
|
}, [menuOpen]);
|
|
6344
|
-
return /* @__PURE__ */
|
|
6345
|
-
/* @__PURE__ */
|
|
7553
|
+
return /* @__PURE__ */ jsxs8(Fragment3, { children: [
|
|
7554
|
+
/* @__PURE__ */ jsx9(
|
|
6346
7555
|
"button",
|
|
6347
7556
|
{
|
|
6348
7557
|
...{ [FLOAT_ATTR]: "" },
|
|
@@ -6374,7 +7583,7 @@ function EmptyParaHandle({ view, cursorPos }) {
|
|
|
6374
7583
|
children: "+"
|
|
6375
7584
|
}
|
|
6376
7585
|
),
|
|
6377
|
-
menuOpen && /* @__PURE__ */
|
|
7586
|
+
menuOpen && /* @__PURE__ */ jsx9(
|
|
6378
7587
|
"div",
|
|
6379
7588
|
{
|
|
6380
7589
|
...{ [FLOAT_ATTR]: "" },
|
|
@@ -6390,7 +7599,7 @@ function EmptyParaHandle({ view, cursorPos }) {
|
|
|
6390
7599
|
minWidth: 168,
|
|
6391
7600
|
animation: "ab-float-in 0.12s ease"
|
|
6392
7601
|
},
|
|
6393
|
-
children: BLOCK_ITEMS.map((item) => /* @__PURE__ */
|
|
7602
|
+
children: BLOCK_ITEMS.map((item) => /* @__PURE__ */ jsx9(
|
|
6394
7603
|
BlockMenuItem,
|
|
6395
7604
|
{
|
|
6396
7605
|
item,
|
|
@@ -6408,8 +7617,8 @@ function BlockMenuItem({
|
|
|
6408
7617
|
view,
|
|
6409
7618
|
onRun
|
|
6410
7619
|
}) {
|
|
6411
|
-
const [hover, setHover] =
|
|
6412
|
-
return /* @__PURE__ */
|
|
7620
|
+
const [hover, setHover] = useState5(false);
|
|
7621
|
+
return /* @__PURE__ */ jsxs8(
|
|
6413
7622
|
"button",
|
|
6414
7623
|
{
|
|
6415
7624
|
...{ [FLOAT_ATTR]: "" },
|
|
@@ -6435,7 +7644,7 @@ function BlockMenuItem({
|
|
|
6435
7644
|
transition: "background 0.1s"
|
|
6436
7645
|
},
|
|
6437
7646
|
children: [
|
|
6438
|
-
/* @__PURE__ */
|
|
7647
|
+
/* @__PURE__ */ jsx9(
|
|
6439
7648
|
"span",
|
|
6440
7649
|
{
|
|
6441
7650
|
style: {
|
|
@@ -6456,11 +7665,11 @@ function BlockMenuItem({
|
|
|
6456
7665
|
);
|
|
6457
7666
|
}
|
|
6458
7667
|
function FloatingMenu({ view, editorState }) {
|
|
6459
|
-
const [showEmptyHandle, setShowEmptyHandle] =
|
|
6460
|
-
const dwellTimerRef =
|
|
6461
|
-
const lastEmptyPosRef =
|
|
6462
|
-
const [, setScrollTick] =
|
|
6463
|
-
|
|
7668
|
+
const [showEmptyHandle, setShowEmptyHandle] = useState5(false);
|
|
7669
|
+
const dwellTimerRef = useRef4(null);
|
|
7670
|
+
const lastEmptyPosRef = useRef4(null);
|
|
7671
|
+
const [, setScrollTick] = useState5(0);
|
|
7672
|
+
useEffect4(() => {
|
|
6464
7673
|
const editorDom = view?.dom;
|
|
6465
7674
|
if (!editorDom) return;
|
|
6466
7675
|
const container = editorDom.closest(".editor-shell") ?? editorDom.parentElement;
|
|
@@ -6469,7 +7678,7 @@ function FloatingMenu({ view, editorState }) {
|
|
|
6469
7678
|
container.addEventListener("scroll", onScroll, { passive: true });
|
|
6470
7679
|
return () => container.removeEventListener("scroll", onScroll);
|
|
6471
7680
|
}, [view]);
|
|
6472
|
-
|
|
7681
|
+
useEffect4(() => {
|
|
6473
7682
|
const id = "ab-float-keyframes";
|
|
6474
7683
|
if (document.getElementById(id)) return;
|
|
6475
7684
|
const style = document.createElement("style");
|
|
@@ -6499,8 +7708,8 @@ function FloatingMenu({ view, editorState }) {
|
|
|
6499
7708
|
}
|
|
6500
7709
|
const selectionRect = hasSelection ? getSelectionDOMRect() : null;
|
|
6501
7710
|
return createPortal2(
|
|
6502
|
-
/* @__PURE__ */
|
|
6503
|
-
hasSelection && selectionRect && /* @__PURE__ */
|
|
7711
|
+
/* @__PURE__ */ jsxs8(Fragment3, { children: [
|
|
7712
|
+
hasSelection && selectionRect && /* @__PURE__ */ jsx9(
|
|
6504
7713
|
SelectionToolbar,
|
|
6505
7714
|
{
|
|
6506
7715
|
view,
|
|
@@ -6508,23 +7717,23 @@ function FloatingMenu({ view, editorState }) {
|
|
|
6508
7717
|
selectionRect
|
|
6509
7718
|
}
|
|
6510
7719
|
),
|
|
6511
|
-
!hasSelection && showEmptyHandle && emptyPos !== null && /* @__PURE__ */
|
|
7720
|
+
!hasSelection && showEmptyHandle && emptyPos !== null && /* @__PURE__ */ jsx9(EmptyParaHandle, { view, cursorPos: emptyPos })
|
|
6512
7721
|
] }),
|
|
6513
7722
|
document.body
|
|
6514
7723
|
);
|
|
6515
7724
|
}
|
|
6516
7725
|
|
|
6517
7726
|
// src/ui/plugin/inlineSuggestPlugin.ts
|
|
6518
|
-
import { Plugin as
|
|
6519
|
-
import { Decoration as
|
|
6520
|
-
var inlineSuggestKey = new
|
|
7727
|
+
import { Plugin as Plugin8, PluginKey as PluginKey8 } from "prosemirror-state";
|
|
7728
|
+
import { Decoration as Decoration4, DecorationSet as DecorationSet4 } from "prosemirror-view";
|
|
7729
|
+
var inlineSuggestKey = new PluginKey8("inlineSuggest");
|
|
6521
7730
|
var DEBOUNCE_MS = 600;
|
|
6522
7731
|
function createInlineSuggestPlugin(provider, endpoint, options) {
|
|
6523
7732
|
const { onContextChange } = options ?? {};
|
|
6524
7733
|
return {
|
|
6525
7734
|
name: "inlineSuggest",
|
|
6526
7735
|
plugins: () => [
|
|
6527
|
-
new
|
|
7736
|
+
new Plugin8({
|
|
6528
7737
|
key: inlineSuggestKey,
|
|
6529
7738
|
state: {
|
|
6530
7739
|
init: () => ({ suggestion: null, anchorPos: null }),
|
|
@@ -6540,13 +7749,13 @@ function createInlineSuggestPlugin(provider, endpoint, options) {
|
|
|
6540
7749
|
props: {
|
|
6541
7750
|
decorations(state) {
|
|
6542
7751
|
const ps = inlineSuggestKey.getState(state);
|
|
6543
|
-
if (!ps?.suggestion || !state.selection.empty) return
|
|
7752
|
+
if (!ps?.suggestion || !state.selection.empty) return DecorationSet4.empty;
|
|
6544
7753
|
const ghost = document.createElement("span");
|
|
6545
7754
|
ghost.textContent = ps.suggestion;
|
|
6546
7755
|
ghost.style.cssText = "color: rgba(0,0,0,0.3); pointer-events: none; user-select: none;";
|
|
6547
7756
|
ghost.setAttribute("aria-hidden", "true");
|
|
6548
|
-
return
|
|
6549
|
-
|
|
7757
|
+
return DecorationSet4.create(state.doc, [
|
|
7758
|
+
Decoration4.widget(state.selection.from, ghost, {
|
|
6550
7759
|
side: 1,
|
|
6551
7760
|
key: "inline-suggest"
|
|
6552
7761
|
})
|
|
@@ -6687,12 +7896,15 @@ export {
|
|
|
6687
7896
|
convertBlock2 as convertBlock,
|
|
6688
7897
|
convertInline2 as convertInline,
|
|
6689
7898
|
createDragHandlePlugin,
|
|
7899
|
+
createHistoryPlugin,
|
|
6690
7900
|
createInlineSuggestPlugin,
|
|
6691
7901
|
createInlineToolTagNodeViewPlugin,
|
|
6692
7902
|
createInputRulesPlugin,
|
|
6693
7903
|
createJinjaDecorationPlugin,
|
|
7904
|
+
createJinjaIfBlockPlugin,
|
|
6694
7905
|
createJumpPointAdjacentPlugin,
|
|
6695
7906
|
createJumpPointNodeViewPlugin,
|
|
7907
|
+
createJumpPointValidationPlugin,
|
|
6696
7908
|
createKeymapPlugin,
|
|
6697
7909
|
createLinkPlugin,
|
|
6698
7910
|
createMarkdownClipboardPlugin,
|
|
@@ -6700,6 +7912,8 @@ export {
|
|
|
6700
7912
|
createReactNodeView,
|
|
6701
7913
|
createSlashCommandPlugin,
|
|
6702
7914
|
createTodoNodeViewPlugin,
|
|
7915
|
+
hasBrokenAnchorRefs,
|
|
7916
|
+
hasDuplicateJumpPoints,
|
|
6703
7917
|
inlineSuggestKey,
|
|
6704
7918
|
slashCommandKey,
|
|
6705
7919
|
toProseMirrorJSON,
|