@jackuait/blok 0.4.1-beta.12 → 0.4.1-beta.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/blok.mjs +2 -2
- package/dist/chunks/{blok-BU6NwVkN.mjs → blok-Xfgk2kCJ.mjs} +326 -320
- package/dist/chunks/{i18next-loader-D8GzSwio.mjs → i18next-loader-BMO6Rg_l.mjs} +1 -1
- package/dist/chunks/{index-C5e_WLFg.mjs → index-DyPp5v5e.mjs} +1 -1
- package/dist/chunks/{inline-tool-convert-CLUxkCe_.mjs → inline-tool-convert-DhHW7EYl.mjs} +1 -1
- package/dist/full.mjs +2 -2
- package/dist/tools.mjs +43 -26
- package/package.json +25 -7
- package/src/components/modules/ui.ts +10 -6
- package/src/components/utils/data-model-transform.ts +38 -21
- package/src/tools/list/index.ts +23 -0
|
@@ -18,7 +18,7 @@ let nt = (o = 21) => {
|
|
|
18
18
|
return t;
|
|
19
19
|
};
|
|
20
20
|
var ot = /* @__PURE__ */ ((o) => (o.VERBOSE = "VERBOSE", o.INFO = "INFO", o.WARN = "WARN", o.ERROR = "ERROR", o))(ot || {});
|
|
21
|
-
const rt = () => "0.4.1-beta.
|
|
21
|
+
const rt = () => "0.4.1-beta.13", Ct = {
|
|
22
22
|
BACKSPACE: 8,
|
|
23
23
|
TAB: 9,
|
|
24
24
|
ENTER: 13,
|
package/dist/full.mjs
CHANGED
|
@@ -10,10 +10,10 @@ var e = (a, l, o) => l in a ? n(a, l, { enumerable: !0, configurable: !0, writab
|
|
|
10
10
|
d.call(l, o) && e(a, o, l[o]);
|
|
11
11
|
return a;
|
|
12
12
|
}, r = (a, l) => t(a, c(l));
|
|
13
|
-
import { B as v, v as A } from "./chunks/blok-
|
|
13
|
+
import { B as v, v as A } from "./chunks/blok-Xfgk2kCJ.mjs";
|
|
14
14
|
import { List as p, Header as f, Paragraph as I, Link as k, Italic as u, Bold as B } from "./tools.mjs";
|
|
15
15
|
import { defaultBlockTools as H, defaultInlineTools as P } from "./tools.mjs";
|
|
16
|
-
import { D as _ } from "./chunks/inline-tool-convert-
|
|
16
|
+
import { D as _ } from "./chunks/inline-tool-convert-DhHW7EYl.mjs";
|
|
17
17
|
const m = {
|
|
18
18
|
paragraph: {
|
|
19
19
|
class: I,
|
package/dist/tools.mjs
CHANGED
|
@@ -2,7 +2,7 @@ var nt = Object.defineProperty, rt = Object.defineProperties;
|
|
|
2
2
|
var st = Object.getOwnPropertyDescriptors;
|
|
3
3
|
var K = Object.getOwnPropertySymbols;
|
|
4
4
|
var ot = Object.prototype.hasOwnProperty, it = Object.prototype.propertyIsEnumerable;
|
|
5
|
-
var U = (f, t, e) => t in f ? nt(f, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : f[t] = e,
|
|
5
|
+
var U = (f, t, e) => t in f ? nt(f, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : f[t] = e, O = (f, t) => {
|
|
6
6
|
for (var e in t || (t = {}))
|
|
7
7
|
ot.call(t, e) && U(f, e, t[e]);
|
|
8
8
|
if (K)
|
|
@@ -10,8 +10,8 @@ var U = (f, t, e) => t in f ? nt(f, t, { enumerable: !0, configurable: !0, writa
|
|
|
10
10
|
it.call(t, e) && U(f, e, t[e]);
|
|
11
11
|
return f;
|
|
12
12
|
}, P = (f, t) => rt(f, st(t));
|
|
13
|
-
import { t as x, D as m, a9 as et, aa as at, ab as lt, A as ct, ac as dt, ad as ut, ae as ht, af as ft, ag as pt, ah as mt, ai as G, aj as j, ak as $, f as A, al as gt, am as Et, S as H, P as Tt, an as Ct, l as At, J as yt } from "./chunks/inline-tool-convert-
|
|
14
|
-
import { a0 as Dt } from "./chunks/inline-tool-convert-
|
|
13
|
+
import { t as x, D as m, a9 as et, aa as at, ab as lt, A as ct, ac as dt, ad as ut, ae as ht, af as ft, ag as pt, ah as mt, ai as G, aj as j, ak as $, f as A, al as gt, am as Et, S as H, P as Tt, an as Ct, l as At, J as yt } from "./chunks/inline-tool-convert-DhHW7EYl.mjs";
|
|
14
|
+
import { a0 as Dt } from "./chunks/inline-tool-convert-DhHW7EYl.mjs";
|
|
15
15
|
const W = [
|
|
16
16
|
"empty:before:pointer-events-none",
|
|
17
17
|
"empty:before:text-gray-text",
|
|
@@ -555,15 +555,32 @@ const u = class u {
|
|
|
555
555
|
})));
|
|
556
556
|
}, this.api = n, this.readOnly = r, this._settings = e || {}, this._data = this.normalizeData(t), s && (this.blockId = s.id), this._data.style === "ordered" && this.api.events.on("block changed", this.handleBlockChanged);
|
|
557
557
|
}
|
|
558
|
+
/**
|
|
559
|
+
* Legacy list item structure for backward compatibility
|
|
560
|
+
*/
|
|
561
|
+
static isLegacyFormat(t) {
|
|
562
|
+
return typeof t == "object" && t !== null && "items" in t && Array.isArray(t.items);
|
|
563
|
+
}
|
|
558
564
|
normalizeData(t) {
|
|
559
565
|
var n;
|
|
560
566
|
const e = this._settings.defaultStyle || "unordered";
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
+
if (!t || typeof t != "object")
|
|
568
|
+
return {
|
|
569
|
+
text: "",
|
|
570
|
+
style: e,
|
|
571
|
+
checked: !1,
|
|
572
|
+
depth: 0
|
|
573
|
+
};
|
|
574
|
+
if (u.isLegacyFormat(t)) {
|
|
575
|
+
const r = t.items[0], s = (r == null ? void 0 : r.content) || "", o = (r == null ? void 0 : r.checked) || !1;
|
|
576
|
+
return O({
|
|
577
|
+
text: s,
|
|
578
|
+
style: t.style || e,
|
|
579
|
+
checked: !!o,
|
|
580
|
+
depth: 0
|
|
581
|
+
}, t.start !== void 0 && t.start !== 1 ? { start: t.start } : {});
|
|
582
|
+
}
|
|
583
|
+
return O({
|
|
567
584
|
text: t.text || "",
|
|
568
585
|
style: t.style || e,
|
|
569
586
|
checked: !!t.checked,
|
|
@@ -1155,7 +1172,7 @@ const u = class u {
|
|
|
1155
1172
|
charCount: r.charCount,
|
|
1156
1173
|
node: s,
|
|
1157
1174
|
offset: e - r.charCount
|
|
1158
|
-
} : P(
|
|
1175
|
+
} : P(O({}, r), {
|
|
1159
1176
|
charCount: r.charCount + o
|
|
1160
1177
|
});
|
|
1161
1178
|
},
|
|
@@ -1202,7 +1219,7 @@ const u = class u {
|
|
|
1202
1219
|
this.syncContentFromDOM();
|
|
1203
1220
|
const s = n + 1;
|
|
1204
1221
|
this._data.depth = s;
|
|
1205
|
-
const o = await this.api.blocks.update(this.blockId || "", P(
|
|
1222
|
+
const o = await this.api.blocks.update(this.blockId || "", P(O({}, this._data), {
|
|
1206
1223
|
depth: s
|
|
1207
1224
|
}));
|
|
1208
1225
|
this.setCaretToBlockContent(o);
|
|
@@ -1213,7 +1230,7 @@ const u = class u {
|
|
|
1213
1230
|
this.syncContentFromDOM();
|
|
1214
1231
|
const e = t - 1;
|
|
1215
1232
|
this._data.depth = e;
|
|
1216
|
-
const n = await this.api.blocks.update(this.blockId || "", P(
|
|
1233
|
+
const n = await this.api.blocks.update(this.blockId || "", P(O({}, this._data), {
|
|
1217
1234
|
depth: e
|
|
1218
1235
|
}));
|
|
1219
1236
|
this.setCaretToBlockContent(n);
|
|
@@ -2090,7 +2107,7 @@ const i = class i {
|
|
|
2090
2107
|
return;
|
|
2091
2108
|
const s = `strong[${i.DATA_ATTR_COLLAPSED_ACTIVE}="true"]`;
|
|
2092
2109
|
r.querySelectorAll(s).forEach((l) => {
|
|
2093
|
-
var k, I,
|
|
2110
|
+
var k, I, _, z, q;
|
|
2094
2111
|
const d = l.getAttribute(i.DATA_ATTR_PREV_LENGTH), c = l.previousSibling;
|
|
2095
2112
|
if (!d || !c || c.nodeType !== Node.TEXT_NODE)
|
|
2096
2113
|
return;
|
|
@@ -2105,13 +2122,13 @@ const i = class i {
|
|
|
2105
2122
|
const C = E.match(/^[\u00A0\s]+/);
|
|
2106
2123
|
if (C && !l.hasAttribute(i.DATA_ATTR_LEADING_WHITESPACE) && l.setAttribute(i.DATA_ATTR_LEADING_WHITESPACE, C[0]), E.length === 0)
|
|
2107
2124
|
return;
|
|
2108
|
-
const T = (I = l.textContent) != null ? I : "", N = T + E, B = (
|
|
2125
|
+
const T = (I = l.textContent) != null ? I : "", N = T + E, B = (_ = l.getAttribute(i.DATA_ATTR_LEADING_WHITESPACE)) != null ? _ : "", R = B.length > 0 && T.length === 0 && !N.startsWith(B) ? B + N : N, b = document.createTextNode(R);
|
|
2109
2126
|
for (; l.firstChild; )
|
|
2110
2127
|
l.removeChild(l.firstChild);
|
|
2111
2128
|
if (l.appendChild(b), !(t != null && t.isCollapsed) || !i.isNodeWithin(t.focusNode, p))
|
|
2112
2129
|
return;
|
|
2113
|
-
const S = document.createRange(),
|
|
2114
|
-
S.setStart(b,
|
|
2130
|
+
const S = document.createRange(), F = (q = (z = b.textContent) == null ? void 0 : z.length) != null ? q : 0;
|
|
2131
|
+
S.setStart(b, F), S.collapse(!0), t.removeAllRanges(), t.addRange(S);
|
|
2115
2132
|
});
|
|
2116
2133
|
}
|
|
2117
2134
|
/**
|
|
@@ -2320,7 +2337,7 @@ const i = class i {
|
|
|
2320
2337
|
if (!r)
|
|
2321
2338
|
return;
|
|
2322
2339
|
r.querySelectorAll(`strong[${i.DATA_ATTR_COLLAPSED_LENGTH}]`).forEach((a) => {
|
|
2323
|
-
var v, R, b, S,
|
|
2340
|
+
var v, R, b, S, F;
|
|
2324
2341
|
const l = a, d = l.getAttribute(i.DATA_ATTR_COLLAPSED_LENGTH);
|
|
2325
2342
|
if (!d)
|
|
2326
2343
|
return;
|
|
@@ -2331,11 +2348,11 @@ const i = class i {
|
|
|
2331
2348
|
if (B && T) {
|
|
2332
2349
|
const k = N.slice(0, E), I = N.slice(E);
|
|
2333
2350
|
T.textContent = k;
|
|
2334
|
-
const
|
|
2335
|
-
(b = l.parentNode) == null || b.insertBefore(
|
|
2351
|
+
const _ = document.createTextNode(I);
|
|
2352
|
+
(b = l.parentNode) == null || b.insertBefore(_, l.nextSibling);
|
|
2336
2353
|
}
|
|
2337
2354
|
if (B && l.removeAttribute(i.DATA_ATTR_PREV_LENGTH), t != null && t.isCollapsed && g && i.isNodeWithin(t.focusNode, l)) {
|
|
2338
|
-
const k = document.createRange(), I = (
|
|
2355
|
+
const k = document.createRange(), I = (F = (S = g.textContent) == null ? void 0 : S.length) != null ? F : 0;
|
|
2339
2356
|
k.setStart(g, I), k.collapse(!0), t.removeAllRanges(), t.addRange(k);
|
|
2340
2357
|
}
|
|
2341
2358
|
p && l.removeAttribute(i.DATA_ATTR_COLLAPSED_LENGTH);
|
|
@@ -2602,7 +2619,7 @@ const i = class i {
|
|
|
2602
2619
|
};
|
|
2603
2620
|
i.isInline = !0, i.title = "Bold", i.titleKey = "bold", i.shortcutListenerRegistered = !1, i.selectionListenerRegistered = !1, i.inputListenerRegistered = !1, i.beforeInputListenerRegistered = !1, i.globalListenersInitialized = i.initializeGlobalListeners(), i.collapsedExitRecords = /* @__PURE__ */ new Set(), i.markerSequence = 0, i.isProcessingMutation = !1, i.DATA_ATTR_COLLAPSED_LENGTH = "data-blok-bold-collapsed-length", i.DATA_ATTR_COLLAPSED_ACTIVE = "data-blok-bold-collapsed-active", i.DATA_ATTR_PREV_LENGTH = "data-blok-bold-prev-length", i.DATA_ATTR_LEADING_WHITESPACE = "data-blok-bold-leading-ws", i.instances = /* @__PURE__ */ new Set(), i.pendingBoundaryCaretAdjustments = /* @__PURE__ */ new WeakSet(), i.shortcut = "CMD+B";
|
|
2604
2621
|
let Z = i;
|
|
2605
|
-
const
|
|
2622
|
+
const D = class D {
|
|
2606
2623
|
/**
|
|
2607
2624
|
* Sanitizer Rule
|
|
2608
2625
|
* Leave <i> and <em> tags
|
|
@@ -2873,9 +2890,9 @@ const O = class O {
|
|
|
2873
2890
|
n.insertBefore(a, e.nextSibling), n.insertBefore(t, a);
|
|
2874
2891
|
}
|
|
2875
2892
|
};
|
|
2876
|
-
|
|
2877
|
-
let Q =
|
|
2878
|
-
const
|
|
2893
|
+
D.isInline = !0, D.title = "Italic", D.titleKey = "italic", D.shortcut = "CMD+I";
|
|
2894
|
+
let Q = D;
|
|
2895
|
+
const w = class w {
|
|
2879
2896
|
/**
|
|
2880
2897
|
* @param api - Blok API
|
|
2881
2898
|
*/
|
|
@@ -3102,8 +3119,8 @@ const D = class D {
|
|
|
3102
3119
|
t && t.setAttribute(e, n ? "true" : "false");
|
|
3103
3120
|
}
|
|
3104
3121
|
};
|
|
3105
|
-
|
|
3106
|
-
let tt =
|
|
3122
|
+
w.isInline = !0, w.title = "Link", w.titleKey = "link", w.shortcut = "CMD+K";
|
|
3123
|
+
let tt = w;
|
|
3107
3124
|
const vt = {
|
|
3108
3125
|
paragraph: { preserveBlank: !0 },
|
|
3109
3126
|
header: {},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jackuait/blok",
|
|
3
|
-
"version": "0.4.1-beta.
|
|
3
|
+
"version": "0.4.1-beta.13",
|
|
4
4
|
"description": "Blok — headless, highly extensible rich text editor built for developers who need to implement a block-based editing experience (similar to Notion) without building it from scratch",
|
|
5
5
|
"module": "dist/blok.mjs",
|
|
6
6
|
"types": "./types/index.d.ts",
|
|
@@ -96,14 +96,12 @@
|
|
|
96
96
|
"verify:package:local": "npm pack && node scripts/verify-published-package.mjs --local",
|
|
97
97
|
"verify:version": "node scripts/verify-version.mjs",
|
|
98
98
|
"unpublish": "node scripts/unpublish-package.mjs",
|
|
99
|
-
"bundle:track": "node scripts/track-bundle-size.mjs --verbose",
|
|
100
|
-
"bundle:variants": "node scripts/build-bundle-variants.mjs --verbose",
|
|
101
|
-
"bundle:trends": "node scripts/view-bundle-trends.mjs --trends",
|
|
102
|
-
"bundle:history": "node scripts/view-bundle-trends.mjs",
|
|
103
99
|
"perf:analyze": "node scripts/analyze-performance.mjs",
|
|
104
100
|
"perf:compare": "node scripts/analyze-performance.mjs --baseline",
|
|
105
101
|
"perf:dashboard": "node scripts/generate-performance-dashboard.mjs",
|
|
106
|
-
"e2e:validate-categories": "node scripts/validate-test-categories.mjs"
|
|
102
|
+
"e2e:validate-categories": "node scripts/validate-test-categories.mjs",
|
|
103
|
+
"size": "size-limit",
|
|
104
|
+
"size:why": "size-limit --why"
|
|
107
105
|
},
|
|
108
106
|
"author": "JackUait",
|
|
109
107
|
"contributors": [
|
|
@@ -123,6 +121,8 @@
|
|
|
123
121
|
"@playwright/test": "1.57.0",
|
|
124
122
|
"@semantic-release/changelog": "^6.0.3",
|
|
125
123
|
"@semantic-release/git": "^10.0.1",
|
|
124
|
+
"@size-limit/esbuild-why": "^12.0.0",
|
|
125
|
+
"@size-limit/preset-small-lib": "^12.0.0",
|
|
126
126
|
"@storybook/addon-a11y": "10.1.1",
|
|
127
127
|
"@storybook/addon-vitest": "10.1.1",
|
|
128
128
|
"@storybook/global": "5.0.0",
|
|
@@ -150,6 +150,7 @@
|
|
|
150
150
|
"postcss": "8.5.6",
|
|
151
151
|
"rollup-plugin-license": "3.6.0",
|
|
152
152
|
"semantic-release": "^25.0.2",
|
|
153
|
+
"size-limit": "^12.0.0",
|
|
153
154
|
"storybook": "10.1.1",
|
|
154
155
|
"tailwindcss": "3",
|
|
155
156
|
"tslint": "6.1.3",
|
|
@@ -163,5 +164,22 @@
|
|
|
163
164
|
"dependencies": {
|
|
164
165
|
"i18next": "^25.7.3",
|
|
165
166
|
"nanoid": "^5.1.6"
|
|
166
|
-
}
|
|
167
|
+
},
|
|
168
|
+
"size-limit": [
|
|
169
|
+
{
|
|
170
|
+
"name": "Minimum (core only)",
|
|
171
|
+
"path": "src/variants/blok-minimum.ts",
|
|
172
|
+
"limit": "300 KB"
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
"name": "Normal (with tools)",
|
|
176
|
+
"path": "src/blok.ts",
|
|
177
|
+
"limit": "300 KB"
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
"name": "Maximum (all locales)",
|
|
181
|
+
"path": "src/variants/blok-maximum.ts",
|
|
182
|
+
"limit": "300 KB"
|
|
183
|
+
}
|
|
184
|
+
]
|
|
167
185
|
}
|
|
@@ -789,6 +789,16 @@ export class UI extends Module<UINodes> {
|
|
|
789
789
|
return;
|
|
790
790
|
}
|
|
791
791
|
|
|
792
|
+
/**
|
|
793
|
+
* Close BlockSettings first if it's open, regardless of selection state.
|
|
794
|
+
* This prevents navigation mode from being enabled when the user closes block tunes with Escape.
|
|
795
|
+
*/
|
|
796
|
+
if (this.Blok.BlockSettings.opened) {
|
|
797
|
+
this.Blok.BlockSettings.close();
|
|
798
|
+
|
|
799
|
+
return;
|
|
800
|
+
}
|
|
801
|
+
|
|
792
802
|
/**
|
|
793
803
|
* Clear blocks selection by ESC (but not when entering navigation mode)
|
|
794
804
|
*/
|
|
@@ -806,12 +816,6 @@ export class UI extends Module<UINodes> {
|
|
|
806
816
|
return;
|
|
807
817
|
}
|
|
808
818
|
|
|
809
|
-
if (this.Blok.BlockSettings.opened) {
|
|
810
|
-
this.Blok.BlockSettings.close();
|
|
811
|
-
|
|
812
|
-
return;
|
|
813
|
-
}
|
|
814
|
-
|
|
815
819
|
/**
|
|
816
820
|
* If a nested popover is open (like convert-to dropdown),
|
|
817
821
|
* close only the nested popover, not the entire inline toolbar.
|
|
@@ -109,37 +109,49 @@ const expandListItems = (
|
|
|
109
109
|
|
|
110
110
|
childIds.push(itemId);
|
|
111
111
|
|
|
112
|
-
// Recursively expand nested items first to get their IDs
|
|
113
|
-
const nestedChildIds = item.items && item.items.length > 0
|
|
114
|
-
? expandListItems(item.items, itemId, depth + 1, style, undefined, tunes, blocks)
|
|
115
|
-
: [];
|
|
116
|
-
|
|
117
112
|
// Determine if we should include start (only for first root item of ordered lists)
|
|
118
113
|
const includeStart = style === 'ordered' && depth === 0 && index === 0 && start !== undefined && start !== 1;
|
|
119
114
|
|
|
120
|
-
//
|
|
115
|
+
// Check if there are nested items (we'll get their IDs after pushing the parent)
|
|
116
|
+
const hasNestedItems = item.items && item.items.length > 0;
|
|
117
|
+
|
|
118
|
+
// Create the list block (flat model - each item is a separate 'list' block)
|
|
119
|
+
// We'll update with content IDs after processing children
|
|
121
120
|
const itemBlock: OutputBlockData = {
|
|
122
121
|
id: itemId,
|
|
123
|
-
type: '
|
|
122
|
+
type: 'list',
|
|
124
123
|
data: {
|
|
125
124
|
text: item.content,
|
|
126
125
|
checked: item.checked,
|
|
127
126
|
style,
|
|
127
|
+
...(depth > 0 ? { depth } : {}),
|
|
128
128
|
...(includeStart ? { start } : {}),
|
|
129
129
|
},
|
|
130
130
|
...(tunes !== undefined ? { tunes } : {}),
|
|
131
131
|
...(parentId !== undefined ? { parent: parentId } : {}),
|
|
132
|
-
...(nestedChildIds.length > 0 ? { content: nestedChildIds } : {}),
|
|
133
132
|
};
|
|
134
133
|
|
|
134
|
+
// Push parent block first to maintain correct order (parent before children)
|
|
135
135
|
blocks.push(itemBlock);
|
|
136
|
+
|
|
137
|
+
// Now recursively expand nested items (they will be added after the parent)
|
|
138
|
+
if (!hasNestedItems) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const nestedChildIds = expandListItems(item.items!, itemId, depth + 1, style, undefined, tunes, blocks);
|
|
143
|
+
|
|
144
|
+
// Update the parent block with content IDs (only if children exist)
|
|
145
|
+
if (nestedChildIds.length > 0) {
|
|
146
|
+
itemBlock.content = nestedChildIds;
|
|
147
|
+
}
|
|
136
148
|
});
|
|
137
149
|
|
|
138
150
|
return childIds;
|
|
139
151
|
};
|
|
140
152
|
|
|
141
153
|
/**
|
|
142
|
-
* Expand a List block with nested items into flat
|
|
154
|
+
* Expand a List block with nested items into flat list blocks
|
|
143
155
|
*/
|
|
144
156
|
const expandListToHierarchical = (
|
|
145
157
|
listData: LegacyListData,
|
|
@@ -217,7 +229,7 @@ const collectChildItems = (
|
|
|
217
229
|
|
|
218
230
|
for (const childId of contentIds) {
|
|
219
231
|
const childBlock = blockMap.get(childId);
|
|
220
|
-
const isListItem = childBlock && childBlock.type === '
|
|
232
|
+
const isListItem = childBlock && childBlock.type === 'list';
|
|
221
233
|
|
|
222
234
|
if (isListItem) {
|
|
223
235
|
const items = collectListItems(childBlock, blockMap, processedIds);
|
|
@@ -269,7 +281,7 @@ const collectListItems = (
|
|
|
269
281
|
};
|
|
270
282
|
|
|
271
283
|
/**
|
|
272
|
-
* Process a root
|
|
284
|
+
* Process a root list block (flat model) and convert to a legacy List block
|
|
273
285
|
*/
|
|
274
286
|
const processRootListItem = (
|
|
275
287
|
block: OutputBlockData,
|
|
@@ -294,6 +306,13 @@ const processRootListItem = (
|
|
|
294
306
|
return listBlock;
|
|
295
307
|
};
|
|
296
308
|
|
|
309
|
+
/**
|
|
310
|
+
* Check if a block is a flat-model list block (has 'text' field instead of 'items')
|
|
311
|
+
*/
|
|
312
|
+
const isFlatModelListBlock = (block: OutputBlockData): boolean => {
|
|
313
|
+
return block.type === 'list' && block.data?.text !== undefined && block.data?.items === undefined;
|
|
314
|
+
};
|
|
315
|
+
|
|
297
316
|
/**
|
|
298
317
|
* Collapse hierarchical flat-with-references format back to legacy nested format
|
|
299
318
|
* @param blocks - array of flat blocks with parent/content references
|
|
@@ -302,24 +321,21 @@ const processRootListItem = (
|
|
|
302
321
|
export const collapseToLegacy = (blocks: OutputBlockData[]): OutputBlockData[] => {
|
|
303
322
|
// Build a map of blocks by ID for quick lookup
|
|
304
323
|
const blockMap = new Map<BlockId, OutputBlockData>();
|
|
305
|
-
const listItemBlocks: OutputBlockData[] = [];
|
|
306
324
|
|
|
307
325
|
for (const block of blocks) {
|
|
308
326
|
if (block.id) {
|
|
309
327
|
blockMap.set(block.id, block);
|
|
310
328
|
}
|
|
311
|
-
|
|
312
|
-
if (block.type === 'list_item') {
|
|
313
|
-
listItemBlocks.push(block);
|
|
314
|
-
}
|
|
315
329
|
}
|
|
316
330
|
|
|
317
|
-
// If no
|
|
318
|
-
|
|
331
|
+
// If no flat-model list blocks, just strip hierarchy fields and return
|
|
332
|
+
const hasFlatListBlocks = blocks.some(isFlatModelListBlock);
|
|
333
|
+
|
|
334
|
+
if (!hasFlatListBlocks) {
|
|
319
335
|
return blocks.map(stripHierarchyFields);
|
|
320
336
|
}
|
|
321
337
|
|
|
322
|
-
// Process blocks, converting root
|
|
338
|
+
// Process blocks, converting root flat-model list blocks to legacy List blocks
|
|
323
339
|
const result: OutputBlockData[] = [];
|
|
324
340
|
const processedIds = new Set<BlockId>();
|
|
325
341
|
|
|
@@ -330,8 +346,9 @@ export const collapseToLegacy = (blocks: OutputBlockData[]): OutputBlockData[] =
|
|
|
330
346
|
continue;
|
|
331
347
|
}
|
|
332
348
|
|
|
333
|
-
const
|
|
334
|
-
const
|
|
349
|
+
const isFlatListBlock = isFlatModelListBlock(block);
|
|
350
|
+
const isRootListItem = isFlatListBlock && !block.parent;
|
|
351
|
+
const isNonListItem = !isFlatListBlock;
|
|
335
352
|
|
|
336
353
|
if (isRootListItem) {
|
|
337
354
|
const listBlock = processRootListItem(block, blockMap, processedIds);
|
package/src/tools/list/index.ts
CHANGED
|
@@ -185,6 +185,13 @@ export class ListItem implements BlockTool {
|
|
|
185
185
|
|
|
186
186
|
sanitize?: ToolSanitizerConfig | undefined;
|
|
187
187
|
|
|
188
|
+
/**
|
|
189
|
+
* Legacy list item structure for backward compatibility
|
|
190
|
+
*/
|
|
191
|
+
private static isLegacyFormat(data: unknown): data is { items: Array<{ content: string; checked?: boolean }>, style?: ListItemStyle, start?: number } {
|
|
192
|
+
return typeof data === 'object' && data !== null && 'items' in data && Array.isArray((data as { items: unknown }).items);
|
|
193
|
+
}
|
|
194
|
+
|
|
188
195
|
private normalizeData(data: ListItemData | Record<string, never>): ListItemData {
|
|
189
196
|
const defaultStyle = this._settings.defaultStyle || 'unordered';
|
|
190
197
|
|
|
@@ -197,6 +204,22 @@ export class ListItem implements BlockTool {
|
|
|
197
204
|
};
|
|
198
205
|
}
|
|
199
206
|
|
|
207
|
+
// Handle legacy format with items[] array - extract first item's content
|
|
208
|
+
// This provides backward compatibility when legacy data is passed directly to the tool
|
|
209
|
+
if (ListItem.isLegacyFormat(data)) {
|
|
210
|
+
const firstItem = data.items[0];
|
|
211
|
+
const text = firstItem?.content || '';
|
|
212
|
+
const checked = firstItem?.checked || false;
|
|
213
|
+
|
|
214
|
+
return {
|
|
215
|
+
text,
|
|
216
|
+
style: data.style || defaultStyle,
|
|
217
|
+
checked: Boolean(checked),
|
|
218
|
+
depth: 0,
|
|
219
|
+
...(data.start !== undefined && data.start !== 1 ? { start: data.start } : {}),
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
|
|
200
223
|
return {
|
|
201
224
|
text: data.text || '',
|
|
202
225
|
style: data.style || defaultStyle,
|