@jackuait/blok 0.10.11 → 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-CX_pZ_qq.mjs → blok-Cb7w54t6.mjs} +81 -38
- package/dist/chunks/{constants-lxerM-Xa.mjs → constants-C0aZXxoO.mjs} +1 -1
- package/dist/chunks/{tools-CMNxZqJC.mjs → tools-vS7102lG.mjs} +83 -32
- 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/styles/main.css +5 -0
- package/src/tools/callout/index.ts +39 -4
- 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
|
|
@@ -2090,7 +2090,7 @@ var Qt = "outline-hidden py-[7px] mt-[2px] mb-px", $t = "outline-hidden pl-0.5 l
|
|
|
2090
2090
|
constructor(e) {
|
|
2091
2091
|
var t;
|
|
2092
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) => {
|
|
2093
|
-
if (this.isStructuralOpActive()) {
|
|
2093
|
+
if (this.isStructuralOpActive() && !this.api.blocks.isSyncingFromYjs) {
|
|
2094
2094
|
this.deferredEvents.push(e);
|
|
2095
2095
|
return;
|
|
2096
2096
|
}
|
|
@@ -2105,28 +2105,36 @@ var Qt = "outline-hidden py-[7px] mt-[2px] mb-px", $t = "outline-hidden pl-0.5 l
|
|
|
2105
2105
|
return;
|
|
2106
2106
|
}
|
|
2107
2107
|
if (t !== "block-added" || n.target.id === this.tableBlockId) return;
|
|
2108
|
-
let r = n.
|
|
2109
|
-
if (r
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
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);
|
|
2113
2121
|
return;
|
|
2114
2122
|
}
|
|
2115
|
-
let
|
|
2116
|
-
|
|
2117
|
-
let
|
|
2118
|
-
if (
|
|
2119
|
-
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)) {
|
|
2120
2128
|
let e = this.api.blocks.getBlockIndex(this.tableBlockId), t = e === void 0 ? null : this.api.blocks.getBlockByIndex(e);
|
|
2121
|
-
if (t && !t.holder.contains(
|
|
2122
|
-
let
|
|
2123
|
-
if (!(
|
|
2124
|
-
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);
|
|
2125
2133
|
s && (this.claimBlockForCell(s, n.target.id), this.syncBlockToModel(s, n.target.id), this.cellsPendingCheck.delete(s));
|
|
2126
2134
|
return;
|
|
2127
2135
|
}
|
|
2128
|
-
let
|
|
2129
|
-
|
|
2136
|
+
let l = this.findCellForNewBlock(i);
|
|
2137
|
+
l && (this.claimBlockForCell(l, n.target.id), this.syncBlockToModel(l, n.target.id), this.cellsPendingCheck.delete(l));
|
|
2130
2138
|
}, this.handleCellBlankSpaceClick = (e) => {
|
|
2131
2139
|
let t = e.target;
|
|
2132
2140
|
if (!t) return;
|
|
@@ -2286,6 +2294,24 @@ var Qt = "outline-hidden py-[7px] mt-[2px] mb-px", $t = "outline-hidden pl-0.5 l
|
|
|
2286
2294
|
}), n.push(a);
|
|
2287
2295
|
}), n;
|
|
2288
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
|
+
}
|
|
2289
2315
|
stripPlaceholders(e) {
|
|
2290
2316
|
e.querySelectorAll("[data-blok-placeholder-active]").forEach((e) => {
|
|
2291
2317
|
e.removeAttribute("data-blok-placeholder-active");
|
|
@@ -4943,15 +4969,27 @@ var Ir = (e) => {
|
|
|
4943
4969
|
}
|
|
4944
4970
|
save(e) {
|
|
4945
4971
|
var t;
|
|
4946
|
-
let n = this.model.snapshot(), r = (t = this.blockId) == null ? "" : t;
|
|
4947
|
-
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) => {
|
|
4948
4974
|
if (!R(e)) return e;
|
|
4949
|
-
let
|
|
4975
|
+
let a = e.blocks.filter((e) => {
|
|
4950
4976
|
var t, n, i;
|
|
4951
4977
|
let a = (t = (n = this.api.blocks).getById) == null ? void 0 : t.call(n, e);
|
|
4952
4978
|
return a != null && ((i = a.parentId) == null ? "" : i) === r;
|
|
4953
4979
|
});
|
|
4954
|
-
|
|
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 });
|
|
4955
4993
|
})), n;
|
|
4956
4994
|
}
|
|
4957
4995
|
validate(e) {
|
|
@@ -4978,7 +5016,9 @@ var Ir = (e) => {
|
|
|
4978
5016
|
yi(f, e.content), bi(f, e.content);
|
|
4979
5017
|
return;
|
|
4980
5018
|
}
|
|
4981
|
-
if (o !== this.setDataGeneration
|
|
5019
|
+
if (o !== this.setDataGeneration) return;
|
|
5020
|
+
let p = this.api.blocks.isSyncingFromYjs;
|
|
5021
|
+
if (this.runStructuralOp(() => {
|
|
4982
5022
|
var e, t, n, r;
|
|
4983
5023
|
let i = (e = (t = (n = this.cellBlocks) == null ? void 0 : n.initializeCells((r = this.initialContent) == null ? [] : r)) == null ? this.initialContent : t) == null ? [] : e;
|
|
4984
5024
|
if (o === this.setDataGeneration) {
|
|
@@ -4987,14 +5027,20 @@ var Ir = (e) => {
|
|
|
4987
5027
|
let t = e.querySelectorAll(`[${F}]`).length;
|
|
4988
5028
|
return Array.from({ length: t }, () => ({ blocks: [] }));
|
|
4989
5029
|
});
|
|
4990
|
-
this.model.replaceAll(A(A({}, this.model.snapshot()), {}, { content: e }))
|
|
5030
|
+
this.model.replaceAll(A(A({}, this.model.snapshot()), {}, { content: e }));
|
|
4991
5031
|
} else this.model.replaceAll(A(A({}, this.model.snapshot()), {}, { content: i }));
|
|
4992
5032
|
this.initialContent = null;
|
|
4993
5033
|
}
|
|
4994
|
-
}, !0), o !== this.setDataGeneration)
|
|
5034
|
+
}, !0), o !== this.setDataGeneration) return;
|
|
4995
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);
|
|
4996
|
-
let
|
|
4997
|
-
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
|
+
}
|
|
4998
5044
|
}
|
|
4999
5045
|
onPaste(e) {
|
|
5000
5046
|
var t, n;
|
|
@@ -6332,7 +6378,9 @@ var go = {
|
|
|
6332
6378
|
caution: "red"
|
|
6333
6379
|
}, _o = class {
|
|
6334
6380
|
constructor({ data: e, api: t, readOnly: n, block: r }) {
|
|
6335
|
-
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);
|
|
6336
6384
|
}
|
|
6337
6385
|
normalizeData(e) {
|
|
6338
6386
|
let t = e;
|
|
@@ -6369,8 +6417,10 @@ var go = {
|
|
|
6369
6417
|
if (Rt(this._dom.childContainer, e), e.length === 0) {
|
|
6370
6418
|
let e = this.api.blocks.getBlockIndex(this.blockId);
|
|
6371
6419
|
if (e !== void 0) {
|
|
6372
|
-
let t = this.
|
|
6373
|
-
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");
|
|
6374
6424
|
}
|
|
6375
6425
|
}
|
|
6376
6426
|
}
|
|
@@ -6497,10 +6547,11 @@ var go = {
|
|
|
6497
6547
|
};
|
|
6498
6548
|
}
|
|
6499
6549
|
static get conversionConfig() {
|
|
6500
|
-
return { import: () => ({
|
|
6550
|
+
return { import: (e) => ({
|
|
6501
6551
|
emoji: Wa,
|
|
6502
6552
|
textColor: null,
|
|
6503
|
-
backgroundColor: null
|
|
6553
|
+
backgroundColor: null,
|
|
6554
|
+
__importedText: e
|
|
6504
6555
|
}) };
|
|
6505
6556
|
}
|
|
6506
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.
|