@jackuait/blok 0.7.0-beta.3 → 0.7.0-beta.4
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-BlyYiZTm.mjs → blok-B0pAWdVk.mjs} +20 -16
- package/dist/chunks/{constants-DEy4jBO5.mjs → constants-DmDwNSTM.mjs} +1 -1
- package/dist/chunks/{i18next-loader-Cfbv-x6v.mjs → i18next-loader-v9SlYZ0i.mjs} +1 -1
- package/dist/chunks/{index-Cu1w-sLZ.mjs → index-DHLWzZaA.mjs} +1 -1
- package/dist/full.mjs +2 -2
- package/dist/tools.mjs +71 -48
- package/package.json +1 -1
- package/src/components/modules/blockManager/operations.ts +28 -1
- package/src/tools/table/index.ts +38 -0
package/dist/blok.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { B as s, v as a } from "./chunks/blok-
|
|
2
|
-
import { D as A } from "./chunks/constants-
|
|
1
|
+
import { B as s, v as a } from "./chunks/blok-B0pAWdVk.mjs";
|
|
2
|
+
import { D as A } from "./chunks/constants-DmDwNSTM.mjs";
|
|
3
3
|
export {
|
|
4
4
|
s as Blok,
|
|
5
5
|
A as DATA_ATTR,
|
|
@@ -20,7 +20,7 @@ var To = (s, t) => {
|
|
|
20
20
|
return e;
|
|
21
21
|
};
|
|
22
22
|
var xe = (s, t, e) => xo(s, typeof t != "symbol" ? t + "" : t, e);
|
|
23
|
-
import { L as lo, l as S, c as Ji, i as ut, a as m, S as w, D as y, t as R, b as _, P as X, E as yn, g as pt, d as Qi, e as pr, f as Yo, h as $o, j as Fe, k as nt, m as wt, s as tl, n as ao, o as Bn, p as el, q as ol, r as gr, u as nl, v as I, w as Ko, x as Ae, y as ee, z as as, F as ie, A as Wo, B as wn, C as cs, G as Vo, H as V, I as ds, J as co, K as lt, M as sl, N as rl, O as je, Q as fr, R as hs, T as il, U as ll, V as Go, W as Ue, X as le, Y as Et, Z as kr, _ as Rt, $, a0 as Xo, a1 as Pt, a2 as al, a3 as cl, a4 as us, a5 as dl, a6 as hl, a7 as ul, a8 as pl, a9 as gl, aa as br, ab as fl, ac as mr, ad as vr, ae as St, af as kl, ag as yr, ah as Br, ai as bl, aj as ml, ak as vl, al as yl, am as Bl, an as wl, ao as xl, ap as wr, aq as Tl, ar as ps, as as Il, at as Sl, au as Cl, av as El, aw as Ml, ax as Al, ay as Dl } from "./constants-
|
|
23
|
+
import { L as lo, l as S, c as Ji, i as ut, a as m, S as w, D as y, t as R, b as _, P as X, E as yn, g as pt, d as Qi, e as pr, f as Yo, h as $o, j as Fe, k as nt, m as wt, s as tl, n as ao, o as Bn, p as el, q as ol, r as gr, u as nl, v as I, w as Ko, x as Ae, y as ee, z as as, F as ie, A as Wo, B as wn, C as cs, G as Vo, H as V, I as ds, J as co, K as lt, M as sl, N as rl, O as je, Q as fr, R as hs, T as il, U as ll, V as Go, W as Ue, X as le, Y as Et, Z as kr, _ as Rt, $, a0 as Xo, a1 as Pt, a2 as al, a3 as cl, a4 as us, a5 as dl, a6 as hl, a7 as ul, a8 as pl, a9 as gl, aa as br, ab as fl, ac as mr, ad as vr, ae as St, af as kl, ag as yr, ah as Br, ai as bl, aj as ml, ak as vl, al as yl, am as Bl, an as wl, ao as xl, ap as wr, aq as Tl, ar as ps, as as Il, at as Sl, au as Cl, av as El, aw as Ml, ax as Al, ay as Dl } from "./constants-DmDwNSTM.mjs";
|
|
24
24
|
var Io, gs;
|
|
25
25
|
function Rl() {
|
|
26
26
|
if (gs) return Io;
|
|
@@ -1847,7 +1847,7 @@ class ql {
|
|
|
1847
1847
|
* @returns {Promise<NotifierModule>} loaded notifier module
|
|
1848
1848
|
*/
|
|
1849
1849
|
loadNotifierModule() {
|
|
1850
|
-
return this.notifierModule !== null ? Promise.resolve(this.notifierModule) : (this.loadingPromise === null && (this.loadingPromise = import("./index-
|
|
1850
|
+
return this.notifierModule !== null ? Promise.resolve(this.notifierModule) : (this.loadingPromise === null && (this.loadingPromise = import("./index-DHLWzZaA.mjs").then((t) => {
|
|
1851
1851
|
const e = t;
|
|
1852
1852
|
if (!this.isNotifierModule(e))
|
|
1853
1853
|
throw new Error('notifier module does not expose a "show" method.');
|
|
@@ -10293,9 +10293,10 @@ class ph {
|
|
|
10293
10293
|
id: o,
|
|
10294
10294
|
tool: e.name,
|
|
10295
10295
|
data: { text: l },
|
|
10296
|
+
needToFocus: !1,
|
|
10296
10297
|
skipYjsSync: !0
|
|
10297
10298
|
}, t);
|
|
10298
|
-
return e.parentId !== null && this.hierarchy.setBlockParent(c, e.parentId), c;
|
|
10299
|
+
return this.currentBlockIndex = n, e.parentId !== null && this.hierarchy.setBlockParent(c, e.parentId), c;
|
|
10299
10300
|
});
|
|
10300
10301
|
}
|
|
10301
10302
|
/**
|
|
@@ -10333,10 +10334,10 @@ class ph {
|
|
|
10333
10334
|
tool: o,
|
|
10334
10335
|
data: n,
|
|
10335
10336
|
index: r,
|
|
10336
|
-
needToFocus: !
|
|
10337
|
+
needToFocus: !1,
|
|
10337
10338
|
skipYjsSync: !0
|
|
10338
10339
|
}, i);
|
|
10339
|
-
return l.parentId !== null && this.hierarchy.setBlockParent(d, l.parentId), d;
|
|
10340
|
+
return this.currentBlockIndex = r, l.parentId !== null && this.hierarchy.setBlockParent(d, l.parentId), d;
|
|
10340
10341
|
});
|
|
10341
10342
|
}
|
|
10342
10343
|
/**
|
|
@@ -10370,20 +10371,23 @@ class ph {
|
|
|
10370
10371
|
* @param blocksStore - The blocks store to modify
|
|
10371
10372
|
*/
|
|
10372
10373
|
async paste(t, e, o = !1, n) {
|
|
10373
|
-
|
|
10374
|
+
var a, c, d;
|
|
10375
|
+
const r = o ? null : (c = (a = this.currentBlock) == null ? void 0 : a.parentId) != null ? c : null, i = this.yjsSync.withAtomicOperation(() => this.insert({
|
|
10374
10376
|
tool: t,
|
|
10375
10377
|
replace: o,
|
|
10378
|
+
needToFocus: !1,
|
|
10376
10379
|
skipYjsSync: !0
|
|
10377
10380
|
}, n));
|
|
10378
|
-
await
|
|
10379
|
-
|
|
10380
|
-
});
|
|
10381
|
-
const
|
|
10382
|
-
return
|
|
10383
|
-
id:
|
|
10384
|
-
type:
|
|
10385
|
-
data:
|
|
10386
|
-
|
|
10381
|
+
this.currentBlockIndex = this.repository.getBlockIndex(i), await i.ready, this.yjsSync.withAtomicOperation(() => {
|
|
10382
|
+
i.call(Y.ON_PASTE, e), i.refreshToolRootElement();
|
|
10383
|
+
}), !o && r !== null && this.hierarchy.setBlockParent(i, r);
|
|
10384
|
+
const l = await i.save();
|
|
10385
|
+
return l !== void 0 && this.dependencies.YjsManager.addBlock({
|
|
10386
|
+
id: i.id,
|
|
10387
|
+
type: i.name,
|
|
10388
|
+
data: l.data,
|
|
10389
|
+
parent: (d = i.parentId) != null ? d : void 0
|
|
10390
|
+
}, this.repository.getBlockIndex(i)), i;
|
|
10387
10391
|
}
|
|
10388
10392
|
/**
|
|
10389
10393
|
* Moves the current block up by one position
|
|
@@ -13822,7 +13826,7 @@ class $h extends T {
|
|
|
13822
13826
|
async ensureI18nextLoaded(t, e) {
|
|
13823
13827
|
if (this.i18nextWrapper !== null)
|
|
13824
13828
|
return;
|
|
13825
|
-
const { loadI18next: o } = await import("./i18next-loader-
|
|
13829
|
+
const { loadI18next: o } = await import("./i18next-loader-v9SlYZ0i.mjs");
|
|
13826
13830
|
this.i18nextWrapper = await o(t, e);
|
|
13827
13831
|
}
|
|
13828
13832
|
/**
|
|
@@ -286,7 +286,7 @@ const f = {
|
|
|
286
286
|
DELETE: 46
|
|
287
287
|
}, Eo = {
|
|
288
288
|
LEFT: 0
|
|
289
|
-
}, xo = 650, me = () => "0.7.0-beta.
|
|
289
|
+
}, xo = 650, me = () => "0.7.0-beta.4";
|
|
290
290
|
var ve = /* @__PURE__ */ ((s) => (s.VERBOSE = "VERBOSE", s.INFO = "INFO", s.WARN = "WARN", s.ERROR = "ERROR", s))(ve || {});
|
|
291
291
|
const Q = (s, t, e = "log", o, n = "color: inherit") => {
|
|
292
292
|
const r = typeof console == "undefined" ? void 0 : console;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ae as i, t as u } from "./constants-
|
|
1
|
+
import { ae as i, t as u } from "./constants-DmDwNSTM.mjs";
|
|
2
2
|
const b = {
|
|
3
3
|
success: '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="8" cy="8" r="6.25"/><path d="M5.5 8.25l1.75 1.75 3.25-3.5"/></svg>',
|
|
4
4
|
error: '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="8" cy="8" r="6.25"/><path d="M8 5.25v3"/><circle cx="8" cy="10.75" r="0.5" fill="currentColor" stroke="none"/></svg>',
|
package/dist/full.mjs
CHANGED
|
@@ -12,8 +12,8 @@ var e = (o, l, a) => l in o ? n(o, l, { enumerable: !0, configurable: !0, writab
|
|
|
12
12
|
}, i = (o, l) => t(o, c(l));
|
|
13
13
|
import { Marker as d, Link as p, Italic as I, Bold as f, List as m, Header as u, Paragraph as B } from "./tools.mjs";
|
|
14
14
|
import { Toggle as A, defaultBlockTools as M, defaultInlineTools as D } from "./tools.mjs";
|
|
15
|
-
import { B as P, v as R } from "./chunks/blok-
|
|
16
|
-
import { D as j } from "./chunks/constants-
|
|
15
|
+
import { B as P, v as R } from "./chunks/blok-B0pAWdVk.mjs";
|
|
16
|
+
import { D as j } from "./chunks/constants-DmDwNSTM.mjs";
|
|
17
17
|
const L = {
|
|
18
18
|
paragraph: {
|
|
19
19
|
class: B,
|
package/dist/tools.mjs
CHANGED
|
@@ -10,8 +10,8 @@ var Ft = (r, t, e) => t in r ? Ye(r, t, { enumerable: !0, configurable: !0, writ
|
|
|
10
10
|
Qe.call(t, e) && Ft(r, e, t[e]);
|
|
11
11
|
return r;
|
|
12
12
|
}, V = (r, t) => Xe(r, Ze(t));
|
|
13
|
-
import { t as w, D as B, az as tn, aA as en, ar as D, aB as ke, aC as Dt, aD as nn, aE as Mt, aF as on, aG as sn, aa as rn, aH as ln, aI as an, aJ as cn, aK as dn, aL as hn, aM as un, aN as pn, aO as gn, aP as fn, aQ as Ee, aR as Ae, aS as xe, n as mn, o as qt, ah as zt, af as Cn, aT as bn, aU as Vt, P as F, aV as Te, aW as yn, aX as vn, X as Re, a1 as Be, aY as Sn, aZ as wn, a_ as kn, ac as
|
|
14
|
-
import { ao as
|
|
13
|
+
import { t as w, D as B, az as tn, aA as en, ar as D, aB as ke, aC as Dt, aD as nn, aE as Mt, aF as on, aG as sn, aa as rn, aH as ln, aI as an, aJ as cn, aK as dn, aL as hn, aM as un, aN as pn, aO as gn, aP as fn, aQ as Ee, aR as Ae, aS as xe, n as mn, o as qt, ah as zt, af as Cn, aT as bn, aU as Vt, P as F, aV as Te, aW as yn, aX as vn, X as Re, a1 as Be, aY as Sn, aZ as wn, a_ as kn, ac as Ie, a$ as En, b0 as An, b1 as xn, b2 as Tn, b3 as Rn, b4 as Bn, O as Kt, b5 as In, b6 as Ut, b7 as jt, b8 as Yt, R as Ln, b9 as Dn, x as Hn, ba as Xt, bb as Pn, K as $, bc as On, bd as Nn, S as lt, be as _n, l as Mn, ak as Gn } from "./chunks/constants-DmDwNSTM.mjs";
|
|
14
|
+
import { ao as Li } from "./chunks/constants-DmDwNSTM.mjs";
|
|
15
15
|
const Gt = (r) => {
|
|
16
16
|
if (!r || !r.includes("data-blok-fake-background"))
|
|
17
17
|
return r;
|
|
@@ -260,9 +260,9 @@ let Zt = ht;
|
|
|
260
260
|
const Kn = (r) => {
|
|
261
261
|
const { data: t, readOnly: e, isOpen: n, keydownHandler: o, onArrowClick: s } = r, i = document.createElement("div");
|
|
262
262
|
i.className = w(nn, Dt), i.setAttribute(B.tool, Mt), i.setAttribute(D.toggleOpen, String(n));
|
|
263
|
-
const l =
|
|
263
|
+
const l = Le(n, s), a = Un(t, e, o);
|
|
264
264
|
return i.appendChild(l), i.appendChild(a), { wrapper: i, arrowElement: l, contentElement: a };
|
|
265
|
-
},
|
|
265
|
+
}, Le = (r, t, e = {}) => {
|
|
266
266
|
const n = document.createElement("span");
|
|
267
267
|
return n.className = en, n.setAttribute(D.toggleArrow, ""), n.setAttribute(B.mutationFree, "true"), n.setAttribute("role", "button"), n.setAttribute("tabindex", "0"), n.setAttribute("aria-label", r ? "Collapse" : "Expand"), n.setAttribute("aria-expanded", String(r)), e.contentEditableFalse === !0 && (n.contentEditable = "false"), n.innerHTML = ke, r && (n.style.transform = "rotate(90deg)"), n.addEventListener("click", (o) => {
|
|
268
268
|
o.stopPropagation(), t();
|
|
@@ -559,7 +559,7 @@ const Kn = (r) => {
|
|
|
559
559
|
* @returns The arrow element
|
|
560
560
|
*/
|
|
561
561
|
buildArrow() {
|
|
562
|
-
return
|
|
562
|
+
return Le(this._isOpen, () => this.toggleOpen(), { contentEditableFalse: !0 });
|
|
563
563
|
}
|
|
564
564
|
/**
|
|
565
565
|
* Toggle the isToggleable state on/off.
|
|
@@ -701,7 +701,7 @@ P.BASE_STYLES = "py-[3px] px-[2px] m-0 leading-[1.3]! outline-hidden [&_p]:p-0!
|
|
|
701
701
|
{ number: 6, tag: "H6", nameKey: "tools.header.heading6", name: "Heading 6", icon: un, styles: "text-sm font-semibold mt-3 mb-px" }
|
|
702
702
|
];
|
|
703
703
|
let Jt = P;
|
|
704
|
-
const Q = 24, Yn = "outline-hidden py-[3px] mt-[2px] mb-px", Xn = "outline-hidden pl-0.5 leading-[1.6em]", Zn = "flex items-start pl-0.5", Jn = "mt-1 w-4 mr-2 h-4 cursor-pointer accent-current", Qn = "tools.list.placeholder",
|
|
704
|
+
const Q = 24, Yn = "outline-hidden py-[3px] mt-[2px] mb-px", Xn = "outline-hidden pl-0.5 leading-[1.6em]", Zn = "flex items-start pl-0.5", Jn = "mt-1 w-4 mr-2 h-4 cursor-pointer accent-current", Qn = "tools.list.placeholder", I = "list", De = {
|
|
705
705
|
contentContainer: "list-content-container",
|
|
706
706
|
checklistContent: "list-checklist-content"
|
|
707
707
|
}, He = (r, t) => {
|
|
@@ -725,7 +725,7 @@ const Q = 24, Yn = "outline-hidden py-[3px] mt-[2px] mb-px", Xn = "outline-hidde
|
|
|
725
725
|
}, to = (r) => {
|
|
726
726
|
var n;
|
|
727
727
|
const { data: t } = r, e = document.createElement("div");
|
|
728
|
-
return e.className = Yn, e.setAttribute(B.tool,
|
|
728
|
+
return e.className = Yn, e.setAttribute(B.tool, I), e.setAttribute("data-list-style", t.style), e.setAttribute("data-list-depth", String((n = t.depth) != null ? n : 0)), t.start !== void 0 && t.start !== 1 && e.setAttribute("data-list-start", String(t.start)), e;
|
|
729
729
|
}, eo = (r) => {
|
|
730
730
|
var c;
|
|
731
731
|
const { data: t, itemColor: e, itemSize: n, placeholder: o } = r, s = document.createElement("div");
|
|
@@ -925,7 +925,7 @@ class Oe {
|
|
|
925
925
|
if (t === 0)
|
|
926
926
|
return 0;
|
|
927
927
|
const e = this.blocks.getBlockByIndex(t - 1);
|
|
928
|
-
return !e || e.name !==
|
|
928
|
+
return !e || e.name !== I ? 0 : this.getBlockDepth(e) + 1;
|
|
929
929
|
}
|
|
930
930
|
/**
|
|
931
931
|
* Calculate the target depth for a list item dropped at the given index.
|
|
@@ -938,10 +938,10 @@ class Oe {
|
|
|
938
938
|
const { blockIndex: e, currentDepth: n } = t, o = this.getMaxAllowedDepth(e);
|
|
939
939
|
if (n > o)
|
|
940
940
|
return o;
|
|
941
|
-
const s = this.blocks.getBlockByIndex(e + 1), i = s && s.name ===
|
|
941
|
+
const s = this.blocks.getBlockByIndex(e + 1), i = s && s.name === I, l = i ? this.getBlockDepth(s) : 0;
|
|
942
942
|
if (i && l > n && l <= o)
|
|
943
943
|
return l;
|
|
944
|
-
const c = e > 0 ? this.blocks.getBlockByIndex(e - 1) : void 0, d = c && c.name ===
|
|
944
|
+
const c = e > 0 ? this.blocks.getBlockByIndex(e - 1) : void 0, d = c && c.name === I, h = d ? this.getBlockDepth(c) : 0;
|
|
945
945
|
return d && !i && h > n && h <= o ? h : n;
|
|
946
946
|
}
|
|
947
947
|
/**
|
|
@@ -1010,7 +1010,7 @@ const Ao = (r, t) => {
|
|
|
1010
1010
|
return;
|
|
1011
1011
|
const a = Ne(r, e), c = _e(r, n) || "ordered", d = n.getSiblingIndex(l, a, c), u = n.getGroupStartValue(l, a, d, c) + d, p = n.formatNumber(u, a);
|
|
1012
1012
|
i.textContent = p;
|
|
1013
|
-
},
|
|
1013
|
+
}, Io = (r, t, e, n, o, s, i, l) => {
|
|
1014
1014
|
const a = (c) => {
|
|
1015
1015
|
if (c >= t)
|
|
1016
1016
|
return;
|
|
@@ -1019,7 +1019,7 @@ const Ao = (r, t) => {
|
|
|
1019
1019
|
return;
|
|
1020
1020
|
}
|
|
1021
1021
|
const d = s.getBlockByIndex(c);
|
|
1022
|
-
if (!d || d.name !==
|
|
1022
|
+
if (!d || d.name !== I)
|
|
1023
1023
|
return;
|
|
1024
1024
|
const h = Ne(d, i);
|
|
1025
1025
|
if (h < n)
|
|
@@ -1031,11 +1031,11 @@ const Ao = (r, t) => {
|
|
|
1031
1031
|
_e(d, l) === o && (Me(d, s, i, l), a(c + 1));
|
|
1032
1032
|
};
|
|
1033
1033
|
a(r);
|
|
1034
|
-
},
|
|
1034
|
+
}, Lo = (r, t, e) => {
|
|
1035
1035
|
const n = r.getBlocksCount();
|
|
1036
1036
|
Array.from({ length: n }, (o, s) => s).forEach((o) => {
|
|
1037
1037
|
const s = r.getBlockByIndex(o);
|
|
1038
|
-
if (!s || s.name !==
|
|
1038
|
+
if (!s || s.name !== I)
|
|
1039
1039
|
return;
|
|
1040
1040
|
const i = s.holder;
|
|
1041
1041
|
i != null && i.querySelector('[data-list-style="ordered"]') && Me(s, r, t, e);
|
|
@@ -1070,7 +1070,7 @@ const Ao = (r, t) => {
|
|
|
1070
1070
|
const c = i.getRangeAt(0), { beforeContent: d, afterContent: h } = go(l, c), u = e && (g = t.blocks.getBlockIndex(e)) != null ? g : t.blocks.getCurrentBlockIndex();
|
|
1071
1071
|
if (!e) {
|
|
1072
1072
|
l.innerHTML = d, n.text = d;
|
|
1073
|
-
const f = t.blocks.insert(
|
|
1073
|
+
const f = t.blocks.insert(I, {
|
|
1074
1074
|
text: h,
|
|
1075
1075
|
style: n.style,
|
|
1076
1076
|
checked: !1,
|
|
@@ -1082,7 +1082,7 @@ const Ao = (r, t) => {
|
|
|
1082
1082
|
const p = t.blocks.splitBlock(
|
|
1083
1083
|
e,
|
|
1084
1084
|
{ text: d },
|
|
1085
|
-
|
|
1085
|
+
I,
|
|
1086
1086
|
{
|
|
1087
1087
|
text: h,
|
|
1088
1088
|
style: n.style,
|
|
@@ -1126,7 +1126,7 @@ const Ao = (r, t) => {
|
|
|
1126
1126
|
const { api: e, blockId: n, data: o, syncContentFromDOM: s, getDepth: i } = r, l = e.blocks.getCurrentBlockIndex();
|
|
1127
1127
|
if (l === 0) return;
|
|
1128
1128
|
const a = e.blocks.getBlockByIndex(l - 1);
|
|
1129
|
-
if (!a || a.name !==
|
|
1129
|
+
if (!a || a.name !== I) return;
|
|
1130
1130
|
const c = i(), d = t.getBlockDepth(a);
|
|
1131
1131
|
if (c > d) return;
|
|
1132
1132
|
s();
|
|
@@ -1285,7 +1285,7 @@ class We {
|
|
|
1285
1285
|
if (t < 0 || n <= 0)
|
|
1286
1286
|
return t + 1;
|
|
1287
1287
|
const s = this.blocks.getBlockByIndex(t);
|
|
1288
|
-
if (!s || s.name !==
|
|
1288
|
+
if (!s || s.name !== I)
|
|
1289
1289
|
return t + 1;
|
|
1290
1290
|
const i = this.getBlockDepth(s);
|
|
1291
1291
|
if (i < e)
|
|
@@ -1328,7 +1328,7 @@ class We {
|
|
|
1328
1328
|
if (t < 0)
|
|
1329
1329
|
return 0;
|
|
1330
1330
|
const o = this.blocks.getBlockByIndex(t);
|
|
1331
|
-
if (!o || o.name !==
|
|
1331
|
+
if (!o || o.name !== I)
|
|
1332
1332
|
return 0;
|
|
1333
1333
|
const s = this.getBlockDepth(o);
|
|
1334
1334
|
return s < e ? 0 : s > e ? this.countPrecedingAtDepth(t - 1, e, n) : this.getBlockStyle(o) !== n ? 0 : 1 + this.countPrecedingAtDepth(t - 1, e, n);
|
|
@@ -1340,7 +1340,7 @@ class We {
|
|
|
1340
1340
|
if (t < 0)
|
|
1341
1341
|
return e;
|
|
1342
1342
|
const s = this.blocks.getBlockByIndex(t);
|
|
1343
|
-
if (!s || s.name !==
|
|
1343
|
+
if (!s || s.name !== I)
|
|
1344
1344
|
return e;
|
|
1345
1345
|
const i = this.getBlockDepth(s);
|
|
1346
1346
|
return i < n ? e : i > n ? this.findGroupStartRecursive(t - 1, e, n, o) : this.getBlockStyle(s) !== o ? e : this.findGroupStartRecursive(t - 1, t, n, o);
|
|
@@ -1390,7 +1390,7 @@ class Go {
|
|
|
1390
1390
|
const t = this.blocks.getBlocksCount();
|
|
1391
1391
|
for (const e of Array.from({ length: t }, (n, o) => o)) {
|
|
1392
1392
|
const n = this.blocks.getBlockByIndex(e);
|
|
1393
|
-
if (!n || n.name !==
|
|
1393
|
+
if (!n || n.name !== I)
|
|
1394
1394
|
continue;
|
|
1395
1395
|
const o = n.holder;
|
|
1396
1396
|
o != null && o.querySelector('[data-list-style="ordered"]') && this.updateBlockMarker(n);
|
|
@@ -1422,7 +1422,7 @@ class Go {
|
|
|
1422
1422
|
if (l === n)
|
|
1423
1423
|
continue;
|
|
1424
1424
|
const a = this.blocks.getBlockByIndex(l);
|
|
1425
|
-
if (!a || a.name !==
|
|
1425
|
+
if (!a || a.name !== I)
|
|
1426
1426
|
return;
|
|
1427
1427
|
const c = this.depthValidator.getBlockDepth(a);
|
|
1428
1428
|
if (c < o)
|
|
@@ -1672,7 +1672,7 @@ class Ei {
|
|
|
1672
1672
|
}));
|
|
1673
1673
|
}
|
|
1674
1674
|
updateAllOrderedListMarkers() {
|
|
1675
|
-
|
|
1675
|
+
Lo(this.api.blocks, this.depthValidator, this.markerCalculator);
|
|
1676
1676
|
}
|
|
1677
1677
|
updateMarker() {
|
|
1678
1678
|
var s;
|
|
@@ -1685,7 +1685,7 @@ class Ei {
|
|
|
1685
1685
|
updateSiblingListMarkers() {
|
|
1686
1686
|
var i;
|
|
1687
1687
|
const t = this.blockId ? (i = this.api.blocks.getBlockIndex(this.blockId)) != null ? i : this.api.blocks.getCurrentBlockIndex() : this.api.blocks.getCurrentBlockIndex(), e = this.getDepth(), n = this._data.style, o = this.api.blocks.getBlocksCount(), s = Bo(t, e, n, this.markerCalculator);
|
|
1688
|
-
|
|
1688
|
+
Io(s, o, t, e, n, this.api.blocks, this.depthValidator, this.markerCalculator);
|
|
1689
1689
|
}
|
|
1690
1690
|
updateMarkerForDepth(t, e) {
|
|
1691
1691
|
var o;
|
|
@@ -3407,7 +3407,7 @@ const Y = (r) => {
|
|
|
3407
3407
|
s && s.setAttribute("data-blok-table-heading-col", "");
|
|
3408
3408
|
});
|
|
3409
3409
|
}, gt = (r) => !!(/^#[0-9a-f]{3,4}$/i.test(r) || /^#[0-9a-f]{6}([0-9a-f]{2})?$/i.test(r) || /^rgba?\(\s*[\d.]+\s*,\s*[\d.]+\s*,\s*[\d.]+\s*(,\s*[\d.]+\s*)?\)$/i.test(r) || /^hsla?\(\s*[\d.]+\s*,\s*[\d.]+%\s*,\s*[\d.]+%\s*(,\s*[\d.]+\s*)?\)$/i.test(r) || r === "transparent");
|
|
3410
|
-
class
|
|
3410
|
+
class Is {
|
|
3411
3411
|
constructor(t) {
|
|
3412
3412
|
var e, n, o;
|
|
3413
3413
|
this.withHeadingsValue = (e = t == null ? void 0 : t.withHeadings) != null ? e : !1, this.withHeadingColumnValue = (n = t == null ? void 0 : t.withHeadingColumn) != null ? n : !1, this.stretchedValue = (o = t == null ? void 0 : t.stretched) != null ? o : !1, this.colWidthsValue = t != null && t.colWidths ? [...t.colWidths] : void 0, this.initialColWidthValue = t == null ? void 0 : t.initialColWidth, this.contentGrid = this.normalizeContent(t == null ? void 0 : t.content), this.blockCellMap = /* @__PURE__ */ new Map(), this.rebuildBlockCellMap();
|
|
@@ -3736,7 +3736,7 @@ class Ls {
|
|
|
3736
3736
|
return e;
|
|
3737
3737
|
}
|
|
3738
3738
|
}
|
|
3739
|
-
const de = "data-blok-table-resize",
|
|
3739
|
+
const de = "data-blok-table-resize", Ls = "data-blok-table-cell", Ds = "data-blok-table-row", Hs = 50, Bt = 16;
|
|
3740
3740
|
class Ps {
|
|
3741
3741
|
constructor(t, e, n, o, s, i = !1) {
|
|
3742
3742
|
this._enabled = !0, this.isDragging = !1, this.dragStartX = 0, this.dragColIndex = -1, this.startColWidth = 0, this.dragRowCells = null, this.handles = [], this.gridEl = t, this.colWidths = [...e], this.onChange = n, this.onDragStart = o != null ? o : null, this.onDrag = s != null ? s : null, this.needsInitialApply = i, this.boundPointerDown = this.onPointerDown.bind(this), this.boundPointerMove = this.onPointerMove.bind(this), this.boundPointerUp = this.onPointerUp.bind(this), this.gridEl.style.position = "relative", i || this.applyWidths(), this.createHandles(), this.gridEl.addEventListener("pointerdown", this.boundPointerDown);
|
|
@@ -3806,7 +3806,7 @@ class Ps {
|
|
|
3806
3806
|
}
|
|
3807
3807
|
resolveRowCells() {
|
|
3808
3808
|
const t = this.gridEl.querySelectorAll(`[${Ds}]`);
|
|
3809
|
-
return Array.from(t, (e) => Array.from(e.querySelectorAll(`[${
|
|
3809
|
+
return Array.from(t, (e) => Array.from(e.querySelectorAll(`[${Ls}]`)));
|
|
3810
3810
|
}
|
|
3811
3811
|
applyWidths(t = this.resolveRowCells()) {
|
|
3812
3812
|
const e = this.colWidths.reduce((n, o) => n + o, 0);
|
|
@@ -4207,7 +4207,7 @@ const Fs = [
|
|
|
4207
4207
|
], o = t.getColumnCount() > 1, s = [
|
|
4208
4208
|
{ type: F.Separator },
|
|
4209
4209
|
{
|
|
4210
|
-
icon:
|
|
4210
|
+
icon: Ie,
|
|
4211
4211
|
title: t.i18n.t("tools.table.deleteColumn"),
|
|
4212
4212
|
isDestructive: !0,
|
|
4213
4213
|
isDisabled: !o,
|
|
@@ -4252,7 +4252,7 @@ const Fs = [
|
|
|
4252
4252
|
], o = t.getRowCount() > 1, s = [
|
|
4253
4253
|
{ type: F.Separator },
|
|
4254
4254
|
{
|
|
4255
|
-
icon:
|
|
4255
|
+
icon: Ie,
|
|
4256
4256
|
title: t.i18n.t("tools.table.deleteRow"),
|
|
4257
4257
|
isDestructive: !0,
|
|
4258
4258
|
isDisabled: !o,
|
|
@@ -4569,7 +4569,7 @@ class ei {
|
|
|
4569
4569
|
}
|
|
4570
4570
|
}
|
|
4571
4571
|
}
|
|
4572
|
-
const ni = "data-blok-table-haze", Ce = "data-blok-table-haze-visible",
|
|
4572
|
+
const ni = "data-blok-table-haze", Ce = "data-blok-table-haze-visible", It = 1, oi = [
|
|
4573
4573
|
"absolute",
|
|
4574
4574
|
"top-0",
|
|
4575
4575
|
"bottom-0",
|
|
@@ -4634,7 +4634,7 @@ class ri {
|
|
|
4634
4634
|
return;
|
|
4635
4635
|
}
|
|
4636
4636
|
const { scrollLeft: o, scrollWidth: s, clientWidth: i } = t, l = s - i;
|
|
4637
|
-
this.setVisible(this.leftHaze, o >
|
|
4637
|
+
this.setVisible(this.leftHaze, o > It), this.setVisible(this.rightHaze, l > It && o < l - It);
|
|
4638
4638
|
}
|
|
4639
4639
|
setVisible(t, e) {
|
|
4640
4640
|
t && (e ? t.setAttribute(Ce, "") : t.removeAttribute(Ce));
|
|
@@ -4657,7 +4657,7 @@ class Ai {
|
|
|
4657
4657
|
constructor({ data: t, config: e, api: n, readOnly: o, block: s }) {
|
|
4658
4658
|
this.initialContent = null, this.resize = null, this.addControls = null, this.rowColControls = null, this.cellBlocks = null, this.cellSelection = null, this.scrollHaze = null, this.element = null, this.gridElement = null, this.scrollContainer = null, this.gripOverlay = null, this.pendingHighlight = null, this.isNewTable = !1, this.unregisterRestrictedTools = null, this.setDataGeneration = 0, this.structuralOpDepth = 0, this.api = n, this.readOnly = o, this.config = e != null ? e : {};
|
|
4659
4659
|
const i = ae(t, this.config);
|
|
4660
|
-
this.initialContent = i.content, this.grid = new ss({ readOnly: o }), this.model = new
|
|
4660
|
+
this.initialContent = i.content, this.grid = new ss({ readOnly: o }), this.model = new Is(i), this.blockId = s == null ? void 0 : s.id, this.config.restrictedTools !== void 0 && (this.unregisterRestrictedTools = Rn(this.config.restrictedTools));
|
|
4661
4661
|
}
|
|
4662
4662
|
/**
|
|
4663
4663
|
* Execute a function within a structural operation lock.
|
|
@@ -4794,13 +4794,36 @@ class Ai {
|
|
|
4794
4794
|
}) : i;
|
|
4795
4795
|
this.model.replaceAll(V(T({}, this.model.snapshot()), {
|
|
4796
4796
|
content: l
|
|
4797
|
-
})), this.isNewTable && M(t, this.cellBlocks);
|
|
4797
|
+
})), this.isNewTable && M(t, this.cellBlocks), this.removeGhostChildren();
|
|
4798
4798
|
}, !0), this.model.initialColWidth === void 0) {
|
|
4799
4799
|
const i = (o = this.model.colWidths) != null ? o : Y(t);
|
|
4800
4800
|
this.model.setInitialColWidth(i.length > 0 ? As(i) : void 0);
|
|
4801
4801
|
}
|
|
4802
4802
|
this.initSubsystems(t), rt(t, this.model.snapshot().content), this.isNewTable && ((s = this.cellSelection) == null || s.selectRange({ minRow: 0, maxRow: 0, minCol: 0, maxCol: 0 }));
|
|
4803
4803
|
}
|
|
4804
|
+
/**
|
|
4805
|
+
* Remove blocks that claim this table as parent but are not referenced in any cell.
|
|
4806
|
+
*
|
|
4807
|
+
* These "ghost children" can appear when stale data is saved — e.g. a paste or split
|
|
4808
|
+
* creates a child block that never gets placed into a cell. On the next load, the
|
|
4809
|
+
* Renderer creates Block instances for every saved block and appends their holders to
|
|
4810
|
+
* the working area. initializeCells() only claims blocks actually listed in a cell's
|
|
4811
|
+
* `blocks` array, leaving ghosts visible below the table.
|
|
4812
|
+
*
|
|
4813
|
+
* Must be called after initializeCells() and model.replaceAll() so the model's
|
|
4814
|
+
* blockCellMap is fully populated.
|
|
4815
|
+
*/
|
|
4816
|
+
removeGhostChildren() {
|
|
4817
|
+
const t = this.blockId;
|
|
4818
|
+
if (t === void 0)
|
|
4819
|
+
return;
|
|
4820
|
+
const n = this.api.blocks.getChildren(t).filter((o) => this.model.findCellForBlock(o.id) === null).map((o) => ({
|
|
4821
|
+
id: o.id,
|
|
4822
|
+
index: this.api.blocks.getBlockIndex(o.id)
|
|
4823
|
+
})).filter((o) => o.index !== void 0).sort((o, s) => s.index - o.index);
|
|
4824
|
+
for (const { index: o } of n)
|
|
4825
|
+
this.api.blocks.delete(o);
|
|
4826
|
+
}
|
|
4804
4827
|
save(t) {
|
|
4805
4828
|
return this.model.snapshot();
|
|
4806
4829
|
}
|
|
@@ -4867,7 +4890,7 @@ class Ai {
|
|
|
4867
4890
|
const k = (_ = v.getAttribute("style")) != null ? _ : "", x = {}, E = /background-color\s*:\s*([^;]+)/i.exec(k);
|
|
4868
4891
|
E != null && E[1] && (x.color = Kt(E[1].trim(), "bg"));
|
|
4869
4892
|
const A = new RegExp("(?<![a-z-])color\\s*:\\s*([^;]+)", "i").exec(k);
|
|
4870
|
-
A != null && A[1] && !
|
|
4893
|
+
A != null && A[1] && !In(A[1].trim()) && (x.textColor = Kt(A[1].trim(), "text")), C.push(x);
|
|
4871
4894
|
}), m.length > 0 && (o.push(m), s.push(C));
|
|
4872
4895
|
});
|
|
4873
4896
|
const i = e.querySelector("thead") !== null, l = ((u = n[0]) == null ? void 0 : u.querySelector("th")) !== null, a = i || l;
|
|
@@ -5236,7 +5259,7 @@ class Ai {
|
|
|
5236
5259
|
handleGridPaste(t, e) {
|
|
5237
5260
|
if (this.readOnly || !t.clipboardData || t.defaultPrevented)
|
|
5238
5261
|
return;
|
|
5239
|
-
const n = t.clipboardData.getData("text/html"), o =
|
|
5262
|
+
const n = t.clipboardData.getData("text/html"), o = Ln(n), s = o === null ? Dn(n) : null, i = o != null ? o : s;
|
|
5240
5263
|
if (!i || s !== null && new DOMParser().parseFromString(n, "text/html").querySelectorAll("table").length > 1)
|
|
5241
5264
|
return;
|
|
5242
5265
|
const l = document.activeElement;
|
|
@@ -5968,7 +5991,7 @@ const X = (r) => {
|
|
|
5968
5991
|
}
|
|
5969
5992
|
};
|
|
5970
5993
|
G.instance = null;
|
|
5971
|
-
let
|
|
5994
|
+
let L = G;
|
|
5972
5995
|
const vi = {
|
|
5973
5996
|
convertLegacyTags: !0,
|
|
5974
5997
|
normalizeWhitespace: !0,
|
|
@@ -6078,7 +6101,7 @@ class N {
|
|
|
6078
6101
|
* @returns true if the element is empty and doesn't contain the preserved node
|
|
6079
6102
|
*/
|
|
6080
6103
|
isEmptyAndSafe(t) {
|
|
6081
|
-
return !(t.textContent.length === 0) ||
|
|
6104
|
+
return !(t.textContent.length === 0) || L.getInstance().isActivePlaceholder(t) ? !1 : !(this.options.preserveNode && Nt(this.options.preserveNode, t));
|
|
6082
6105
|
}
|
|
6083
6106
|
/**
|
|
6084
6107
|
* Merge a <strong> element with adjacent <strong> siblings
|
|
@@ -6285,7 +6308,7 @@ const Si = (r, t) => {
|
|
|
6285
6308
|
onBeforeInput: (e) => e.inputType !== "formatBold" ? !1 : (N.normalizeAroundSelection(window.getSelection()), !0),
|
|
6286
6309
|
isRelevant: (e) => S.isSelectionInsideBlok(e)
|
|
6287
6310
|
}), S.guardKeydownListenerRegistered || (document.addEventListener("keydown", (e) => {
|
|
6288
|
-
|
|
6311
|
+
L.getInstance().guardBoundaryKeydown(e);
|
|
6289
6312
|
}, !0), S.guardKeydownListenerRegistered = !0), S.ensureMutationObserver()), !0;
|
|
6290
6313
|
}
|
|
6291
6314
|
/**
|
|
@@ -6497,10 +6520,10 @@ const Si = (r, t) => {
|
|
|
6497
6520
|
if (!t || t.rangeCount === 0)
|
|
6498
6521
|
return;
|
|
6499
6522
|
const e = t.getRangeAt(0), n = W(e.startContainer), o = (() => {
|
|
6500
|
-
if (n && n.getAttribute(
|
|
6501
|
-
return
|
|
6523
|
+
if (n && n.getAttribute(L.ATTR.COLLAPSED_ACTIVE) !== "true")
|
|
6524
|
+
return L.getInstance().exit(t, n);
|
|
6502
6525
|
const s = n != null ? n : S.getBoundaryBold(e);
|
|
6503
|
-
return s ?
|
|
6526
|
+
return s ? L.getInstance().exit(t, s) : this.startCollapsedBold(e);
|
|
6504
6527
|
})();
|
|
6505
6528
|
document.dispatchEvent(new Event("selectionchange")), o && (t.removeAllRanges(), t.addRange(o)), N.normalizeAroundSelection(t), this.notifySelectionChange();
|
|
6506
6529
|
}
|
|
@@ -6509,14 +6532,14 @@ const Si = (r, t) => {
|
|
|
6509
6532
|
* @param range - Current collapsed range
|
|
6510
6533
|
*/
|
|
6511
6534
|
startCollapsedBold(t) {
|
|
6512
|
-
const n =
|
|
6535
|
+
const n = L.getInstance().enter(t, (s) => this.mergeAdjacentBold(s)), o = window.getSelection();
|
|
6513
6536
|
return N.normalizeAroundSelection(o), o && n && (o.removeAllRanges(), o.addRange(n)), this.notifySelectionChange(), n;
|
|
6514
6537
|
}
|
|
6515
6538
|
/**
|
|
6516
6539
|
* Notify listeners that the selection state has changed
|
|
6517
6540
|
*/
|
|
6518
6541
|
notifySelectionChange() {
|
|
6519
|
-
|
|
6542
|
+
L.getInstance().enforceLengths(window.getSelection()), document.dispatchEvent(new Event("selectionchange")), this.updateToolbarButtonState();
|
|
6520
6543
|
}
|
|
6521
6544
|
/**
|
|
6522
6545
|
* Ensure inline toolbar button reflects the actual bold state after programmatic toggles
|
|
@@ -6542,7 +6565,7 @@ const Si = (r, t) => {
|
|
|
6542
6565
|
*/
|
|
6543
6566
|
static refreshSelectionState(t) {
|
|
6544
6567
|
const e = window.getSelection();
|
|
6545
|
-
|
|
6568
|
+
L.getInstance().enforceLengths(e), L.getInstance().maintain(), L.getInstance().synchronize(e), N.normalizeAroundSelection(e, { normalizeWhitespace: !1 }), t === "input" && e && L.getInstance().moveCaretAfterBoundaryBold(e);
|
|
6546
6569
|
}
|
|
6547
6570
|
/**
|
|
6548
6571
|
* Ensure mutation observer is registered to convert legacy <b> tags
|
|
@@ -7106,7 +7129,7 @@ const et = class et {
|
|
|
7106
7129
|
};
|
|
7107
7130
|
et.isInline = !0, et.title = "Link", et.titleKey = "link", et.shortcut = "CMD+K";
|
|
7108
7131
|
let ve = et;
|
|
7109
|
-
const ct = (r) => r.tagName === "MARK",
|
|
7132
|
+
const ct = (r) => r.tagName === "MARK", Lt = (r) => J(r, ct), Se = {
|
|
7110
7133
|
color: "background-color",
|
|
7111
7134
|
"background-color": "color"
|
|
7112
7135
|
}, U = class U {
|
|
@@ -7254,7 +7277,7 @@ const ct = (r) => r.tagName === "MARK", It = (r) => J(r, ct), Se = {
|
|
|
7254
7277
|
const t = window.getSelection();
|
|
7255
7278
|
if (!t || t.rangeCount === 0)
|
|
7256
7279
|
return null;
|
|
7257
|
-
const e = t.getRangeAt(0), n =
|
|
7280
|
+
const e = t.getRangeAt(0), n = Lt(e.startContainer);
|
|
7258
7281
|
if (!n)
|
|
7259
7282
|
return null;
|
|
7260
7283
|
const o = n.style.getPropertyValue("color");
|
|
@@ -7274,7 +7297,7 @@ const ct = (r) => r.tagName === "MARK", It = (r) => J(r, ct), Se = {
|
|
|
7274
7297
|
* @param range - The range to check
|
|
7275
7298
|
*/
|
|
7276
7299
|
findContainingMark(t) {
|
|
7277
|
-
const e =
|
|
7300
|
+
const e = Lt(t.startContainer), n = Lt(t.endContainer);
|
|
7278
7301
|
return e && e === n ? e : null;
|
|
7279
7302
|
}
|
|
7280
7303
|
/**
|
|
@@ -7448,7 +7471,7 @@ const Ti = {
|
|
|
7448
7471
|
};
|
|
7449
7472
|
export {
|
|
7450
7473
|
be as Bold,
|
|
7451
|
-
|
|
7474
|
+
Li as Convert,
|
|
7452
7475
|
Jt as Header,
|
|
7453
7476
|
ye as Italic,
|
|
7454
7477
|
ve as Link,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jackuait/blok",
|
|
3
|
-
"version": "0.7.0-beta.
|
|
3
|
+
"version": "0.7.0-beta.4",
|
|
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",
|
|
@@ -750,9 +750,15 @@ export class BlockOperations {
|
|
|
750
750
|
id: newBlockId,
|
|
751
751
|
tool: currentBlock.name,
|
|
752
752
|
data: { text: extractedText },
|
|
753
|
+
needToFocus: false,
|
|
753
754
|
skipYjsSync: true,
|
|
754
755
|
}, blocksStore);
|
|
755
756
|
|
|
757
|
+
// Update currentBlockIndex AFTER insert (and handleBlockMutation) completes.
|
|
758
|
+
// This allows the table cell claiming logic to see the original block as
|
|
759
|
+
// "current" during the mutation event, so it correctly claims the new block.
|
|
760
|
+
this.currentBlockIndex = insertIndex;
|
|
761
|
+
|
|
756
762
|
// Inherit parentId from the split block so nested blocks stay nested
|
|
757
763
|
if (currentBlock.parentId !== null) {
|
|
758
764
|
this.hierarchy.setBlockParent(newBlock, currentBlock.parentId);
|
|
@@ -817,10 +823,15 @@ export class BlockOperations {
|
|
|
817
823
|
tool: newBlockType,
|
|
818
824
|
data: newBlockData,
|
|
819
825
|
index: insertIndex,
|
|
820
|
-
needToFocus:
|
|
826
|
+
needToFocus: false,
|
|
821
827
|
skipYjsSync: true,
|
|
822
828
|
}, blocksStore);
|
|
823
829
|
|
|
830
|
+
// Update currentBlockIndex AFTER insert (and handleBlockMutation) completes.
|
|
831
|
+
// This allows the table cell claiming logic to see the original block as
|
|
832
|
+
// "current" during the mutation event, so it correctly claims the new block.
|
|
833
|
+
this.currentBlockIndex = insertIndex;
|
|
834
|
+
|
|
824
835
|
// Inherit parentId from the split block so nested blocks stay nested
|
|
825
836
|
if (currentBlock.parentId !== null) {
|
|
826
837
|
this.hierarchy.setBlockParent(newBlock, currentBlock.parentId);
|
|
@@ -903,6 +914,12 @@ export class BlockOperations {
|
|
|
903
914
|
replace = false,
|
|
904
915
|
blocksStore: BlocksStore
|
|
905
916
|
): Promise<Block> {
|
|
917
|
+
// Capture predecessor's parentId BEFORE insert (for non-replace, the
|
|
918
|
+
// predecessor is the current block; its parentId should be inherited).
|
|
919
|
+
const predecessorParentId = !replace
|
|
920
|
+
? this.currentBlock?.parentId ?? null
|
|
921
|
+
: null;
|
|
922
|
+
|
|
906
923
|
// Insert block without syncing to Yjs yet.
|
|
907
924
|
// Wrap in atomic operation so that child blocks created during rendered()
|
|
908
925
|
// (e.g., table cell paragraph blocks) also skip Yjs sync.
|
|
@@ -910,10 +927,14 @@ export class BlockOperations {
|
|
|
910
927
|
return this.insert({
|
|
911
928
|
tool: toolName,
|
|
912
929
|
replace,
|
|
930
|
+
needToFocus: false,
|
|
913
931
|
skipYjsSync: true,
|
|
914
932
|
}, blocksStore);
|
|
915
933
|
});
|
|
916
934
|
|
|
935
|
+
// Update currentBlockIndex AFTER insert (and handleBlockMutation) completes.
|
|
936
|
+
this.currentBlockIndex = this.repository.getBlockIndex(block);
|
|
937
|
+
|
|
917
938
|
// Wait for the block to be fully rendered before calling onPaste,
|
|
918
939
|
// because onPaste may change the tool's root element and needs
|
|
919
940
|
// mutation watchers to be bound first.
|
|
@@ -926,6 +947,11 @@ export class BlockOperations {
|
|
|
926
947
|
block.refreshToolRootElement();
|
|
927
948
|
});
|
|
928
949
|
|
|
950
|
+
// Inherit parentId from predecessor for non-replace inserts.
|
|
951
|
+
if (!replace && predecessorParentId !== null) {
|
|
952
|
+
this.hierarchy.setBlockParent(block, predecessorParentId);
|
|
953
|
+
}
|
|
954
|
+
|
|
929
955
|
// Sync final state to Yjs as single operation
|
|
930
956
|
const savedData = await block.save();
|
|
931
957
|
|
|
@@ -934,6 +960,7 @@ export class BlockOperations {
|
|
|
934
960
|
id: block.id,
|
|
935
961
|
type: block.name,
|
|
936
962
|
data: savedData.data,
|
|
963
|
+
parent: block.parentId ?? undefined,
|
|
937
964
|
}, this.repository.getBlockIndex(block));
|
|
938
965
|
}
|
|
939
966
|
|
package/src/tools/table/index.ts
CHANGED
|
@@ -392,6 +392,8 @@ export class Table implements BlockTool {
|
|
|
392
392
|
if (this.isNewTable) {
|
|
393
393
|
populateNewCells(gridEl, this.cellBlocks);
|
|
394
394
|
}
|
|
395
|
+
|
|
396
|
+
this.removeGhostChildren();
|
|
395
397
|
}, true);
|
|
396
398
|
|
|
397
399
|
if (this.model.initialColWidth === undefined) {
|
|
@@ -410,6 +412,42 @@ export class Table implements BlockTool {
|
|
|
410
412
|
}
|
|
411
413
|
}
|
|
412
414
|
|
|
415
|
+
/**
|
|
416
|
+
* Remove blocks that claim this table as parent but are not referenced in any cell.
|
|
417
|
+
*
|
|
418
|
+
* These "ghost children" can appear when stale data is saved — e.g. a paste or split
|
|
419
|
+
* creates a child block that never gets placed into a cell. On the next load, the
|
|
420
|
+
* Renderer creates Block instances for every saved block and appends their holders to
|
|
421
|
+
* the working area. initializeCells() only claims blocks actually listed in a cell's
|
|
422
|
+
* `blocks` array, leaving ghosts visible below the table.
|
|
423
|
+
*
|
|
424
|
+
* Must be called after initializeCells() and model.replaceAll() so the model's
|
|
425
|
+
* blockCellMap is fully populated.
|
|
426
|
+
*/
|
|
427
|
+
private removeGhostChildren(): void {
|
|
428
|
+
const tableId = this.blockId;
|
|
429
|
+
|
|
430
|
+
if (tableId === undefined) {
|
|
431
|
+
return;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
const allChildren = this.api.blocks.getChildren(tableId);
|
|
435
|
+
|
|
436
|
+
// Delete ghost children in reverse index order so removals don't shift indices
|
|
437
|
+
const ghostEntries = allChildren
|
|
438
|
+
.filter(child => this.model.findCellForBlock(child.id) === null)
|
|
439
|
+
.map(child => ({
|
|
440
|
+
id: child.id,
|
|
441
|
+
index: this.api.blocks.getBlockIndex(child.id),
|
|
442
|
+
}))
|
|
443
|
+
.filter((entry): entry is { id: string; index: number } => entry.index !== undefined)
|
|
444
|
+
.sort((a, b) => b.index - a.index);
|
|
445
|
+
|
|
446
|
+
for (const { index } of ghostEntries) {
|
|
447
|
+
void this.api.blocks.delete(index);
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
|
|
413
451
|
public save(_blockContent: HTMLElement): TableData {
|
|
414
452
|
return this.model.snapshot();
|
|
415
453
|
}
|