@jackuait/blok 0.10.10 → 0.10.12
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-5Ez9qE7T.mjs → blok-Cb7w54t6.mjs} +1519 -1448
- package/dist/chunks/{constants-BYv7qYbw.mjs → constants-C0aZXxoO.mjs} +1 -1
- package/dist/chunks/{tools-CqBnZUYU.mjs → tools-vS7102lG.mjs} +102 -35
- package/dist/full.mjs +3 -3
- package/dist/react.mjs +2 -2
- package/dist/tools.mjs +2 -2
- package/package.json +1 -1
- package/src/components/modules/api/blocks.ts +9 -4
- package/src/components/modules/blockEvents/composers/keyboardNavigation.ts +29 -6
- package/src/components/modules/blockManager/blockManager.ts +12 -2
- package/src/components/modules/blockManager/operations.ts +189 -9
- package/src/components/modules/caret.ts +57 -0
- package/src/components/modules/drag/operations/DragOperations.ts +10 -3
- package/src/components/utils/data-model-transform.ts +93 -42
- package/src/styles/main.css +5 -0
- package/src/tools/callout/index.ts +39 -4
- package/src/tools/list/data-normalizer.ts +12 -3
- package/src/tools/table/index.ts +59 -7
- package/src/tools/table/table-cell-blocks.ts +90 -3
- package/types/api/blocks.d.ts +2 -1
|
@@ -130,7 +130,7 @@ var a = {
|
|
|
130
130
|
RIGHT: 2,
|
|
131
131
|
BACKWARD: 3,
|
|
132
132
|
FORWARD: 4
|
|
133
|
-
}, l = () => "0.10.
|
|
133
|
+
}, l = () => "0.10.12", u = /* @__PURE__ */ function(e) {
|
|
134
134
|
return e.VERBOSE = "VERBOSE", e.INFO = "INFO", e.WARN = "WARN", e.ERROR = "ERROR", e;
|
|
135
135
|
}({}), d = (e, t, n = "log", r, i = "color: inherit") => {
|
|
136
136
|
let a = typeof console > "u" ? void 0 : console;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as e, $t as t, A as n, At as r, B as i, Bt as a, Ct as o, D as s, Et as c, F as l, Ft as u, G as d, Gt as f, H as p, Ht as m, I as h, It as g, J as _, Jt as v, K as y, Kt as b, L as ee, Lt as x, M as te, Mt as S, Nn as ne, Nt as re, O as ie, Ot as C, P as ae, Pt as oe, Q as se, Qt as ce, R as le, Rn as w, Rt as ue, St as de, Tt as fe, U as pe, Ut as me, V as he, W as ge, Wt as _e, X as ve, Xt as ye, Y as be, Yt as xe, Z as Se, Zt as Ce, _n as we, _t as Te, a as Ee, at as De, bt as Oe, c as ke, cn as T, ct as Ae, d as je, dr as E, dt as Me, en as Ne, et as Pe, f as Fe, ft as Ie, g as Le, gt as Re, h as ze, ht as Be, i as Ve, ir as He, it as Ue, j as We, jt as Ge, k as Ke, kt as qe, l as Je, ln as Ye, lt as Xe, mn as Ze, mt as Qe, n as $e, nt as et, o as tt, ot as nt, p as rt, pn as D, pt as it, q as at, qt as ot, r as st, rn as ct, rt as lt, s as ut, sn as dt, st as ft, t as pt, tt as mt, u as O, un as ht, ur as k, ut as gt, v as _t, vn as vt, vt as yt, wt as bt, xt, z as St, zt as Ct } from "./constants-
|
|
1
|
+
import { $ as e, $t as t, A as n, At as r, B as i, Bt as a, Ct as o, D as s, Et as c, F as l, Ft as u, G as d, Gt as f, H as p, Ht as m, I as h, It as g, J as _, Jt as v, K as y, Kt as b, L as ee, Lt as x, M as te, Mt as S, Nn as ne, Nt as re, O as ie, Ot as C, P as ae, Pt as oe, Q as se, Qt as ce, R as le, Rn as w, Rt as ue, St as de, Tt as fe, U as pe, Ut as me, V as he, W as ge, Wt as _e, X as ve, Xt as ye, Y as be, Yt as xe, Z as Se, Zt as Ce, _n as we, _t as Te, a as Ee, at as De, bt as Oe, c as ke, cn as T, ct as Ae, d as je, dr as E, dt as Me, en as Ne, et as Pe, f as Fe, ft as Ie, g as Le, gt as Re, h as ze, ht as Be, i as Ve, ir as He, it as Ue, j as We, jt as Ge, k as Ke, kt as qe, l as Je, ln as Ye, lt as Xe, mn as Ze, mt as Qe, n as $e, nt as et, o as tt, ot as nt, p as rt, pn as D, pt as it, q as at, qt as ot, r as st, rn as ct, rt as lt, s as ut, sn as dt, st as ft, t as pt, tt as mt, u as O, un as ht, ur as k, ut as gt, v as _t, vn as vt, vt as yt, wt as bt, xt, z as St, zt as Ct } from "./constants-C0aZXxoO.mjs";
|
|
2
2
|
import { t as A } from "./objectSpread2-CWwMYL_U.mjs";
|
|
3
3
|
import { n as j } from "./tw-CqxBf-1Y.mjs";
|
|
4
4
|
//#region src/components/utils/html.ts
|
|
@@ -859,11 +859,27 @@ var Qt = "outline-hidden py-[7px] mt-[2px] mb-px", $t = "outline-hidden pl-0.5 l
|
|
|
859
859
|
depth: 0
|
|
860
860
|
};
|
|
861
861
|
if (En(e)) {
|
|
862
|
-
let
|
|
862
|
+
let { text: t, checked: r } = ((e) => {
|
|
863
|
+
if (typeof e == "string") return {
|
|
864
|
+
text: e,
|
|
865
|
+
checked: !1
|
|
866
|
+
};
|
|
867
|
+
if (typeof e == "object" && e) {
|
|
868
|
+
var t, n, r;
|
|
869
|
+
return {
|
|
870
|
+
text: (t = (n = e.content) == null ? e.text : n) == null ? "" : t,
|
|
871
|
+
checked: (r = e.checked) == null ? !1 : r
|
|
872
|
+
};
|
|
873
|
+
}
|
|
874
|
+
return {
|
|
875
|
+
text: "",
|
|
876
|
+
checked: !1
|
|
877
|
+
};
|
|
878
|
+
})(e.items[0]);
|
|
863
879
|
return A({
|
|
864
|
-
text:
|
|
880
|
+
text: t,
|
|
865
881
|
style: e.style || n,
|
|
866
|
-
checked: !!
|
|
882
|
+
checked: !!r,
|
|
867
883
|
depth: 0
|
|
868
884
|
}, e.start !== void 0 && e.start !== 1 ? { start: e.start } : {});
|
|
869
885
|
}
|
|
@@ -2074,7 +2090,7 @@ var Qt = "outline-hidden py-[7px] mt-[2px] mb-px", $t = "outline-hidden pl-0.5 l
|
|
|
2074
2090
|
constructor(e) {
|
|
2075
2091
|
var t;
|
|
2076
2092
|
this._activeCellWithBlocks = null, this.cellsPendingCheck = /* @__PURE__ */ new Set(), this.pendingCheckScheduled = !1, this.removedBlockCells = /* @__PURE__ */ new Map(), this.deferredEvents = [], this.isExitingTable = !1, this.handleBlockMutation = (e) => {
|
|
2077
|
-
if (this.isStructuralOpActive()) {
|
|
2093
|
+
if (this.isStructuralOpActive() && !this.api.blocks.isSyncingFromYjs) {
|
|
2078
2094
|
this.deferredEvents.push(e);
|
|
2079
2095
|
return;
|
|
2080
2096
|
}
|
|
@@ -2089,28 +2105,36 @@ var Qt = "outline-hidden py-[7px] mt-[2px] mb-px", $t = "outline-hidden pl-0.5 l
|
|
|
2089
2105
|
return;
|
|
2090
2106
|
}
|
|
2091
2107
|
if (t !== "block-added" || n.target.id === this.tableBlockId) return;
|
|
2092
|
-
let r = n.
|
|
2093
|
-
if (r
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2108
|
+
let r = this.model.findCellForBlock(n.target.id);
|
|
2109
|
+
if (r) {
|
|
2110
|
+
let e = this.gridElement.querySelector(`[${I}="${r.row}"][${L}="${r.col}"]`);
|
|
2111
|
+
if (e) {
|
|
2112
|
+
this.claimBlockForCell(e, n.target.id), this.cellsPendingCheck.delete(e);
|
|
2113
|
+
return;
|
|
2114
|
+
}
|
|
2115
|
+
}
|
|
2116
|
+
let i = n.index;
|
|
2117
|
+
if (i === void 0) return;
|
|
2118
|
+
let a = this.findRemovedEntryForIndex(i);
|
|
2119
|
+
if (a && this.isAdjacentToThisTable(i)) {
|
|
2120
|
+
this.claimBlockForCell(a.cell, n.target.id), this.syncBlockToModel(a.cell, n.target.id), this.cellsPendingCheck.delete(a.cell);
|
|
2097
2121
|
return;
|
|
2098
2122
|
}
|
|
2099
|
-
let
|
|
2100
|
-
|
|
2101
|
-
let
|
|
2102
|
-
if (
|
|
2103
|
-
if (!this.gridElement.contains(
|
|
2123
|
+
let o = n.target.holder, s = o.closest(`[${z}]`);
|
|
2124
|
+
s && this.stripPlaceholders(s);
|
|
2125
|
+
let c = s && !this.model.findCellForBlock(n.target.id) ? s.closest(`[${F}]`) : null;
|
|
2126
|
+
if (c && this.syncBlockToModel(c, n.target.id), s) return;
|
|
2127
|
+
if (!this.gridElement.contains(o)) {
|
|
2104
2128
|
let e = this.api.blocks.getBlockIndex(this.tableBlockId), t = e === void 0 ? null : this.api.blocks.getBlockByIndex(e);
|
|
2105
|
-
if (t && !t.holder.contains(
|
|
2106
|
-
let
|
|
2107
|
-
if (!(
|
|
2108
|
-
let s = this.findCellForNewBlock(
|
|
2129
|
+
if (t && !t.holder.contains(o)) return;
|
|
2130
|
+
let r = this.api.blocks.getCurrentBlockIndex(), a = r >= 0 ? this.api.blocks.getBlockByIndex(r) : null;
|
|
2131
|
+
if (!(a != null && this.getOwnedCellForBlock(a.id) !== null)) return;
|
|
2132
|
+
let s = this.findCellForNewBlock(i);
|
|
2109
2133
|
s && (this.claimBlockForCell(s, n.target.id), this.syncBlockToModel(s, n.target.id), this.cellsPendingCheck.delete(s));
|
|
2110
2134
|
return;
|
|
2111
2135
|
}
|
|
2112
|
-
let
|
|
2113
|
-
|
|
2136
|
+
let l = this.findCellForNewBlock(i);
|
|
2137
|
+
l && (this.claimBlockForCell(l, n.target.id), this.syncBlockToModel(l, n.target.id), this.cellsPendingCheck.delete(l));
|
|
2114
2138
|
}, this.handleCellBlankSpaceClick = (e) => {
|
|
2115
2139
|
let t = e.target;
|
|
2116
2140
|
if (!t) return;
|
|
@@ -2270,6 +2294,24 @@ var Qt = "outline-hidden py-[7px] mt-[2px] mb-px", $t = "outline-hidden pl-0.5 l
|
|
|
2270
2294
|
}), n.push(a);
|
|
2271
2295
|
}), n;
|
|
2272
2296
|
}
|
|
2297
|
+
reclaimReferencedBlocks() {
|
|
2298
|
+
this.model.snapshot().content.forEach((e, t) => {
|
|
2299
|
+
e.forEach((e, n) => {
|
|
2300
|
+
if (!R(e) || e.blocks.length === 0) return;
|
|
2301
|
+
let r = this.gridElement.querySelector(`[${I}="${t}"][${L}="${n}"]`);
|
|
2302
|
+
if (!r) return;
|
|
2303
|
+
let i = r.querySelector(`[${z}]`);
|
|
2304
|
+
if (i) for (let t of e.blocks) {
|
|
2305
|
+
let e = this.api.blocks.getBlockIndex, n = this.api.blocks.getBlockByIndex;
|
|
2306
|
+
if (typeof e != "function" || typeof n != "function") return;
|
|
2307
|
+
let a = e(t);
|
|
2308
|
+
if (a === void 0) continue;
|
|
2309
|
+
let o = n(a);
|
|
2310
|
+
o && (i.contains(o.holder) || this.claimBlockForCell(r, t));
|
|
2311
|
+
}
|
|
2312
|
+
});
|
|
2313
|
+
});
|
|
2314
|
+
}
|
|
2273
2315
|
stripPlaceholders(e) {
|
|
2274
2316
|
e.querySelectorAll("[data-blok-placeholder-active]").forEach((e) => {
|
|
2275
2317
|
e.removeAttribute("data-blok-placeholder-active");
|
|
@@ -4927,15 +4969,27 @@ var Ir = (e) => {
|
|
|
4927
4969
|
}
|
|
4928
4970
|
save(e) {
|
|
4929
4971
|
var t;
|
|
4930
|
-
let n = this.model.snapshot(), r = (t = this.blockId) == null ? "" : t;
|
|
4931
|
-
return n.content = n.content.map((e) => e.map((e) => {
|
|
4972
|
+
let n = this.model.snapshot(), r = (t = this.blockId) == null ? "" : t, i = this.gridElement;
|
|
4973
|
+
return n.content = n.content.map((e, t) => e.map((e, n) => {
|
|
4932
4974
|
if (!R(e)) return e;
|
|
4933
|
-
let
|
|
4975
|
+
let a = e.blocks.filter((e) => {
|
|
4934
4976
|
var t, n, i;
|
|
4935
4977
|
let a = (t = (n = this.api.blocks).getById) == null ? void 0 : t.call(n, e);
|
|
4936
4978
|
return a != null && ((i = a.parentId) == null ? "" : i) === r;
|
|
4937
4979
|
});
|
|
4938
|
-
|
|
4980
|
+
if (a.length === 0 && i) {
|
|
4981
|
+
let a = i.querySelector(`[${I}="${t}"][${L}="${n}"]`), o = a == null ? void 0 : a.querySelector(`[${z}]`), s = o ? Array.from(o.querySelectorAll("[data-blok-id]")).map((e) => {
|
|
4982
|
+
var t;
|
|
4983
|
+
return (t = e.getAttribute("data-blok-id")) == null ? "" : t;
|
|
4984
|
+
}).filter((e) => {
|
|
4985
|
+
var t, n, i;
|
|
4986
|
+
if (!e) return !1;
|
|
4987
|
+
let a = (t = (n = this.api.blocks).getById) == null ? void 0 : t.call(n, e);
|
|
4988
|
+
return a != null && ((i = a.parentId) == null ? "" : i) === r;
|
|
4989
|
+
}) : [];
|
|
4990
|
+
if (s.length > 0) return A(A({}, e), {}, { blocks: s });
|
|
4991
|
+
}
|
|
4992
|
+
return A(A({}, e), {}, { blocks: a });
|
|
4939
4993
|
})), n;
|
|
4940
4994
|
}
|
|
4941
4995
|
validate(e) {
|
|
@@ -4962,7 +5016,9 @@ var Ir = (e) => {
|
|
|
4962
5016
|
yi(f, e.content), bi(f, e.content);
|
|
4963
5017
|
return;
|
|
4964
5018
|
}
|
|
4965
|
-
if (o !== this.setDataGeneration
|
|
5019
|
+
if (o !== this.setDataGeneration) return;
|
|
5020
|
+
let p = this.api.blocks.isSyncingFromYjs;
|
|
5021
|
+
if (this.runStructuralOp(() => {
|
|
4966
5022
|
var e, t, n, r;
|
|
4967
5023
|
let i = (e = (t = (n = this.cellBlocks) == null ? void 0 : n.initializeCells((r = this.initialContent) == null ? [] : r)) == null ? this.initialContent : t) == null ? [] : e;
|
|
4968
5024
|
if (o === this.setDataGeneration) {
|
|
@@ -4971,14 +5027,20 @@ var Ir = (e) => {
|
|
|
4971
5027
|
let t = e.querySelectorAll(`[${F}]`).length;
|
|
4972
5028
|
return Array.from({ length: t }, () => ({ blocks: [] }));
|
|
4973
5029
|
});
|
|
4974
|
-
this.model.replaceAll(A(A({}, this.model.snapshot()), {}, { content: e }))
|
|
5030
|
+
this.model.replaceAll(A(A({}, this.model.snapshot()), {}, { content: e }));
|
|
4975
5031
|
} else this.model.replaceAll(A(A({}, this.model.snapshot()), {}, { content: i }));
|
|
4976
5032
|
this.initialContent = null;
|
|
4977
5033
|
}
|
|
4978
|
-
}, !0), o !== this.setDataGeneration)
|
|
5034
|
+
}, !0), o !== this.setDataGeneration) return;
|
|
4979
5035
|
this.initSubsystems(f), l !== null && this.cellSelection !== null && this.cellSelection.selectRange(l), u !== null && this.rowColControls !== null && this.rowColControls.restoreVisibleGrips(u.col, u.row);
|
|
4980
|
-
let
|
|
4981
|
-
yi(f,
|
|
5036
|
+
let m = this.model.snapshot();
|
|
5037
|
+
if (yi(f, m.content), bi(f, m.content), p) {
|
|
5038
|
+
var h;
|
|
5039
|
+
(h = this.cellBlocks) == null || h.reclaimReferencedBlocks(), Promise.resolve().then(() => {
|
|
5040
|
+
var e;
|
|
5041
|
+
o === this.setDataGeneration && ((e = this.cellBlocks) == null || e.reclaimReferencedBlocks());
|
|
5042
|
+
});
|
|
5043
|
+
}
|
|
4982
5044
|
}
|
|
4983
5045
|
onPaste(e) {
|
|
4984
5046
|
var t, n;
|
|
@@ -6316,7 +6378,9 @@ var go = {
|
|
|
6316
6378
|
caution: "red"
|
|
6317
6379
|
}, _o = class {
|
|
6318
6380
|
constructor({ data: e, api: t, readOnly: n, block: r }) {
|
|
6319
|
-
this._dom = null, this._emojiPicker = null, this._colorPicker = null, this.
|
|
6381
|
+
this._dom = null, this._emojiPicker = null, this._colorPicker = null, this._pendingChildText = null, this.api = t, this.readOnly = n;
|
|
6382
|
+
let i = typeof e.__importedText == "string" ? e.__importedText : null;
|
|
6383
|
+
i !== null && i.length > 0 && (this._pendingChildText = i), this._data = this.normalizeData(e), r && (this.blockId = r.id);
|
|
6320
6384
|
}
|
|
6321
6385
|
normalizeData(e) {
|
|
6322
6386
|
let t = e;
|
|
@@ -6353,8 +6417,10 @@ var go = {
|
|
|
6353
6417
|
if (Rt(this._dom.childContainer, e), e.length === 0) {
|
|
6354
6418
|
let e = this.api.blocks.getBlockIndex(this.blockId);
|
|
6355
6419
|
if (e !== void 0) {
|
|
6356
|
-
let t = this.
|
|
6357
|
-
this.
|
|
6420
|
+
let t = this._pendingChildText;
|
|
6421
|
+
this._pendingChildText = null;
|
|
6422
|
+
let n = t !== null && t.length > 0 ? { text: t } : void 0, r = this.api.blocks.insertInsideParent(this.blockId, e + 1, n);
|
|
6423
|
+
this._dom.childContainer.appendChild(r.holder), this.api.caret.setToBlock(r.id, t === null ? "start" : "end");
|
|
6358
6424
|
}
|
|
6359
6425
|
}
|
|
6360
6426
|
}
|
|
@@ -6481,10 +6547,11 @@ var go = {
|
|
|
6481
6547
|
};
|
|
6482
6548
|
}
|
|
6483
6549
|
static get conversionConfig() {
|
|
6484
|
-
return { import: () => ({
|
|
6550
|
+
return { import: (e) => ({
|
|
6485
6551
|
emoji: Wa,
|
|
6486
6552
|
textColor: null,
|
|
6487
|
-
backgroundColor: null
|
|
6553
|
+
backgroundColor: null,
|
|
6554
|
+
__importedText: e
|
|
6488
6555
|
}) };
|
|
6489
6556
|
}
|
|
6490
6557
|
static get pasteConfig() {
|
package/dist/full.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { n as e, t } from "./chunks/blok-
|
|
2
|
-
import { ur as n } from "./chunks/constants-
|
|
1
|
+
import { n as e, t } from "./chunks/blok-Cb7w54t6.mjs";
|
|
2
|
+
import { ur as n } from "./chunks/constants-C0aZXxoO.mjs";
|
|
3
3
|
import { t as r } from "./chunks/objectSpread2-CWwMYL_U.mjs";
|
|
4
|
-
import { a as i, b as a, c as o, g as s, i as c, l, n as u, o as d, s as f, t as p, v as m, y as h } from "./chunks/tools-
|
|
4
|
+
import { a as i, b as a, c as o, g as s, i as c, l, n as u, o as d, s as f, t as p, v as m, y as h } from "./chunks/tools-vS7102lG.mjs";
|
|
5
5
|
//#region src/full.ts
|
|
6
6
|
var g = {
|
|
7
7
|
paragraph: {
|
package/dist/react.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { t as e } from "./chunks/blok-
|
|
2
|
-
import "./chunks/constants-
|
|
1
|
+
import { t as e } from "./chunks/blok-Cb7w54t6.mjs";
|
|
2
|
+
import "./chunks/constants-C0aZXxoO.mjs";
|
|
3
3
|
import { t } from "./chunks/objectSpread2-CWwMYL_U.mjs";
|
|
4
4
|
import { t as n } from "./chunks/objectWithoutProperties-Dci1-l7D.mjs";
|
|
5
5
|
import { forwardRef as r, useEffect as i, useMemo as a, useRef as o, useState as s } from "react";
|
package/dist/tools.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { m as e } from "./chunks/constants-
|
|
2
|
-
import { _ as t, a as n, b as r, c as i, d as a, f as o, g as s, h as c, i as l, l as u, m as d, n as f, o as p, p as m, r as h, s as g, t as _, u as v, v as y, y as b } from "./chunks/tools-
|
|
1
|
+
import { m as e } from "./chunks/constants-C0aZXxoO.mjs";
|
|
2
|
+
import { _ as t, a as n, b as r, c as i, d as a, f as o, g as s, h as c, i as l, l as u, m as d, n as f, o as p, p as m, r as h, s as g, t as _, u as v, v as y, y as b } from "./chunks/tools-vS7102lG.mjs";
|
|
3
3
|
export { u as Bold, c as Callout, v as Code, e as Convert, d as Database, m as DatabaseRow, o as Divider, b as Header, h as InlineCode, i as Italic, g as Link, y as List, p as Marker, r as Paragraph, a as Quote, l as Strikethrough, t as Table, s as Toggle, n as Underline, _ as defaultBlockTools, f as defaultInlineTools };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jackuait/blok",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.12",
|
|
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",
|
|
@@ -436,11 +436,16 @@ export class BlocksAPI extends Module {
|
|
|
436
436
|
* @param insertIndex - flat block index where the new block should appear
|
|
437
437
|
* @returns BlockAPI for the newly created child block
|
|
438
438
|
*/
|
|
439
|
-
private insertInsideParent = (parentId: string, insertIndex: number): BlockAPIInterface => {
|
|
440
|
-
// Force new undo group so this insertion is separate from previous typing
|
|
441
|
-
|
|
439
|
+
private insertInsideParent = (parentId: string, insertIndex: number, childData?: BlockToolData): BlockAPIInterface => {
|
|
440
|
+
// Force new undo group so this insertion is separate from previous typing,
|
|
441
|
+
// UNLESS an enclosing atomic operation (e.g. tool conversion) has asked the
|
|
442
|
+
// block manager to suppress stopCapturing so everything merges into a
|
|
443
|
+
// single undo entry.
|
|
444
|
+
if (!this.Blok.BlockManager.suppressStopCapturing) {
|
|
445
|
+
this.Blok.YjsManager.stopCapturing();
|
|
446
|
+
}
|
|
442
447
|
|
|
443
|
-
const newBlock = this.Blok.BlockManager.insertInsideParent(parentId, insertIndex);
|
|
448
|
+
const newBlock = this.Blok.BlockManager.insertInsideParent(parentId, insertIndex, childData);
|
|
444
449
|
|
|
445
450
|
// NOTE: Do NOT call stopCapturing in a trailing microtask. The operations layer
|
|
446
451
|
// uses extendThroughRAF on its atomic wrapper to keep isSyncingFromYjs true
|
|
@@ -56,6 +56,26 @@ export class KeyboardNavigation extends BlockEventComposer {
|
|
|
56
56
|
return Boolean(currentBlock?.holder?.closest('[data-blok-table-cell-blocks]'));
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
/**
|
|
60
|
+
* Resolve the table-cell-blocks container element that owns the given block,
|
|
61
|
+
* or null if the block is not inside a table cell.
|
|
62
|
+
*/
|
|
63
|
+
private getTableCellContainer(block: Block | null | undefined): HTMLElement | null {
|
|
64
|
+
return block?.holder?.closest<HTMLElement>('[data-blok-table-cell-blocks]') ?? null;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* True when `a` and `b` live inside the same table cell (same
|
|
69
|
+
* `[data-blok-table-cell-blocks]` container). Used to decide whether
|
|
70
|
+
* a Backspace/Delete merge would cross a cell boundary.
|
|
71
|
+
*/
|
|
72
|
+
private areBlocksInSameTableCell(a: Block | null | undefined, b: Block | null | undefined): boolean {
|
|
73
|
+
const cellA = this.getTableCellContainer(a);
|
|
74
|
+
const cellB = this.getTableCellContainer(b);
|
|
75
|
+
|
|
76
|
+
return cellA !== null && cellA === cellB;
|
|
77
|
+
}
|
|
78
|
+
|
|
59
79
|
/**
|
|
60
80
|
* Fully close the toolbar if the current block is NOT inside a table cell.
|
|
61
81
|
* Used for destructive operations (Backspace, Delete, merge) where the
|
|
@@ -363,10 +383,12 @@ export class KeyboardNavigation extends BlockEventComposer {
|
|
|
363
383
|
|
|
364
384
|
/**
|
|
365
385
|
* Don't merge across table cell boundaries.
|
|
366
|
-
* When the caret is at the start of the
|
|
367
|
-
* rather than merging the previous cell's last block into the
|
|
386
|
+
* When the caret is at the start of the FIRST block in a table cell, Backspace
|
|
387
|
+
* must be a no-op rather than merging the previous cell's last block into the
|
|
388
|
+
* current cell. Merges within the same cell (e.g. the user hit Enter to split a
|
|
389
|
+
* paragraph and now wants to undo it) must still work.
|
|
368
390
|
*/
|
|
369
|
-
if (this.isCurrentBlockInsideTableCell) {
|
|
391
|
+
if (this.isCurrentBlockInsideTableCell && !this.areBlocksInSameTableCell(currentBlock, previousBlock)) {
|
|
370
392
|
return;
|
|
371
393
|
}
|
|
372
394
|
|
|
@@ -475,10 +497,11 @@ export class KeyboardNavigation extends BlockEventComposer {
|
|
|
475
497
|
|
|
476
498
|
/**
|
|
477
499
|
* Don't merge across table cell boundaries.
|
|
478
|
-
* When the caret is at the end of the
|
|
479
|
-
* rather than
|
|
500
|
+
* When the caret is at the end of the LAST block in a table cell, Delete must
|
|
501
|
+
* be a no-op rather than pulling the next cell's first block into the current
|
|
502
|
+
* cell. Merges within the same cell must still work.
|
|
480
503
|
*/
|
|
481
|
-
if (this.isCurrentBlockInsideTableCell) {
|
|
504
|
+
if (this.isCurrentBlockInsideTableCell && !this.areBlocksInSameTableCell(currentBlock, nextBlock)) {
|
|
482
505
|
return;
|
|
483
506
|
}
|
|
484
507
|
|
|
@@ -799,13 +799,23 @@ export class BlockManager extends Module {
|
|
|
799
799
|
* @param insertIndex - flat block index where the new block should appear
|
|
800
800
|
* @returns the newly created child block
|
|
801
801
|
*/
|
|
802
|
-
public insertInsideParent(parentId: string, insertIndex: number): Block {
|
|
802
|
+
public insertInsideParent(parentId: string, insertIndex: number, childData?: BlockToolData): Block {
|
|
803
803
|
this._currentBlockIndex = this.operations.currentBlockIndexValue;
|
|
804
|
-
const result = this.operations.insertInsideParent(parentId, insertIndex, this.blocksStore);
|
|
804
|
+
const result = this.operations.insertInsideParent(parentId, insertIndex, this.blocksStore, childData);
|
|
805
805
|
this._currentBlockIndex = this.operations.currentBlockIndexValue;
|
|
806
806
|
return result;
|
|
807
807
|
}
|
|
808
808
|
|
|
809
|
+
/**
|
|
810
|
+
* True when an atomic operation (convert, split, drag, etc.) is in progress
|
|
811
|
+
* and callers should NOT break the current undo group with `stopCapturing()`.
|
|
812
|
+
* Consumed by api-layer wrappers like `insertInsideParent` that normally
|
|
813
|
+
* force a new undo entry.
|
|
814
|
+
*/
|
|
815
|
+
public get suppressStopCapturing(): boolean {
|
|
816
|
+
return this.operations?.suppressStopCapturing ?? false;
|
|
817
|
+
}
|
|
818
|
+
|
|
809
819
|
/**
|
|
810
820
|
* Splits a block by updating the current block's data and inserting a new block.
|
|
811
821
|
* Both operations are grouped into a single undo entry.
|