@jackuait/blok 0.6.0-beta.6 → 0.6.0-beta.8
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-BOtlKwVO.mjs → blok-bzxy6Olq.mjs} +187 -173
- package/dist/chunks/{i18next-loader-CJNShSyT.mjs → i18next-loader-CzL6YHyQ.mjs} +1 -1
- package/dist/chunks/{index-BUAPAChM.mjs → index-DSSrx_Co.mjs} +1 -1
- package/dist/chunks/{inline-tool-convert-UoYdJJic.mjs → inline-tool-convert-D4SXxjDd.mjs} +1 -1
- package/dist/full.mjs +2 -2
- package/dist/tools.mjs +39 -39
- package/package.json +1 -1
- package/src/components/modules/api/blocks.ts +18 -0
- package/src/components/modules/rectangleSelection.ts +6 -3
- package/src/components/modules/saver.ts +3 -2
- package/src/components/modules/toolbar/index.ts +52 -16
- package/src/components/modules/toolbar/plus-button.ts +22 -1
- package/src/tools/table/table-add-controls.ts +1 -1
- package/src/tools/table/table-cell-blocks.ts +6 -0
- package/types/api/blocks.d.ts +8 -0
|
@@ -278,7 +278,7 @@ const d = {
|
|
|
278
278
|
DELETE: 46
|
|
279
279
|
}, Ae = {
|
|
280
280
|
LEFT: 0
|
|
281
|
-
}, Se = 650, Wt = () => "0.6.0-beta.
|
|
281
|
+
}, Se = 650, Wt = () => "0.6.0-beta.8";
|
|
282
282
|
var Vt = /* @__PURE__ */ ((n) => (n.VERBOSE = "VERBOSE", n.INFO = "INFO", n.WARN = "WARN", n.ERROR = "ERROR", n))(Vt || {});
|
|
283
283
|
const V = (n, t, e = "log", o, s = "color: inherit") => {
|
|
284
284
|
const i = typeof console == "undefined" ? void 0 : console;
|
package/dist/full.mjs
CHANGED
|
@@ -12,8 +12,8 @@ var e = (a, l, o) => l in a ? n(a, l, { enumerable: !0, configurable: !0, writab
|
|
|
12
12
|
}, r = (a, l) => t(a, c(l));
|
|
13
13
|
import { Link as p, Italic as f, Bold as I, List as k, Header as u, Paragraph as B } from "./tools.mjs";
|
|
14
14
|
import { defaultBlockTools as v, defaultInlineTools as A } from "./tools.mjs";
|
|
15
|
-
import { B as H, v as P } from "./chunks/blok-
|
|
16
|
-
import { D as _ } from "./chunks/inline-tool-convert-
|
|
15
|
+
import { B as H, v as P } from "./chunks/blok-bzxy6Olq.mjs";
|
|
16
|
+
import { D as _ } from "./chunks/inline-tool-convert-D4SXxjDd.mjs";
|
|
17
17
|
const m = {
|
|
18
18
|
paragraph: {
|
|
19
19
|
class: B,
|
package/dist/tools.mjs
CHANGED
|
@@ -10,8 +10,8 @@ var Tt = (i, t, e) => t in i ? ke(i, t, { enumerable: !0, configurable: !0, writ
|
|
|
10
10
|
Le.call(t, e) && Tt(i, e, t[e]);
|
|
11
11
|
return i;
|
|
12
12
|
}, tt = (i, t) => xe(i, Te(t));
|
|
13
|
-
import { t as v, D as E, am as Be, an as Ie, _ as Ne, ao as De, ap as
|
|
14
|
-
import { ab as xo } from "./chunks/inline-tool-convert-
|
|
13
|
+
import { t as v, D as E, am as Be, an as Ie, _ as Ne, ao as De, ap as Pe, aq as He, ar as _e, as as Oe, at as Me, au as Qt, av as te, aw as ee, o as We, p as Rt, a5 as Lt, a3 as $e, ax as Ge, J as ne, Q as se, P as F, ay as qe, az as Fe, a0 as oe, aA as ze, aB as Ve, aC as Ue, aD as Ke, aE as je, z as P, aF as Xe, aG as Ye, S as et, aH as Ze, l as Je, a8 as Qe } from "./chunks/inline-tool-convert-D4SXxjDd.mjs";
|
|
14
|
+
import { ab as xo } from "./chunks/inline-tool-convert-D4SXxjDd.mjs";
|
|
15
15
|
const ie = (i) => {
|
|
16
16
|
if (!i || !i.includes("data-blok-fake-background"))
|
|
17
17
|
return i;
|
|
@@ -550,8 +550,8 @@ const O = class O {
|
|
|
550
550
|
};
|
|
551
551
|
O.BASE_STYLES = "py-[3px] px-[2px] m-0 !leading-[1.3] outline-none [&_p]:!p-0 [&_p]:!m-0 [&_div]:!p-0 [&_div]:!m-0", O.DEFAULT_LEVELS = [
|
|
552
552
|
{ number: 1, tag: "H1", nameKey: "tools.header.heading1", name: "Heading 1", icon: De, styles: "text-4xl font-bold mt-8 mb-1" },
|
|
553
|
-
{ number: 2, tag: "H2", nameKey: "tools.header.heading2", name: "Heading 2", icon:
|
|
554
|
-
{ number: 3, tag: "H3", nameKey: "tools.header.heading3", name: "Heading 3", icon:
|
|
553
|
+
{ number: 2, tag: "H2", nameKey: "tools.header.heading2", name: "Heading 2", icon: Pe, styles: "text-3xl font-semibold mt-6 mb-px" },
|
|
554
|
+
{ number: 3, tag: "H3", nameKey: "tools.header.heading3", name: "Heading 3", icon: He, styles: "text-2xl font-semibold mt-4 mb-px" },
|
|
555
555
|
{ number: 4, tag: "H4", nameKey: "tools.header.heading4", name: "Heading 4", icon: _e, styles: "text-xl font-semibold mt-3 mb-px" },
|
|
556
556
|
{ number: 5, tag: "H5", nameKey: "tools.header.heading5", name: "Heading 5", icon: Oe, styles: "text-base font-semibold mt-3 mb-px" },
|
|
557
557
|
{ number: 6, tag: "H6", nameKey: "tools.header.heading6", name: "Heading 6", icon: Me, styles: "text-sm font-semibold mt-3 mb-px" }
|
|
@@ -728,7 +728,7 @@ const z = 24, rn = "outline-none py-[3px] mt-[2px] mb-px", ln = "outline-none pl
|
|
|
728
728
|
return !1;
|
|
729
729
|
const e = Object.entries(i).find(([n]) => n === "items");
|
|
730
730
|
return e === void 0 ? !1 : Array.isArray(e[1]);
|
|
731
|
-
}, Ln = (i) => typeof i == "object" && i !== null, Bn = (i) => typeof i == "string" ? i : "", In = (i, t) => i === "unordered" || i === "ordered" || i === "checklist" ? i : t, Nn = (i) => !!i, Dn = (i, t) => typeof i == "number" ? i : t,
|
|
731
|
+
}, Ln = (i) => typeof i == "object" && i !== null, Bn = (i) => typeof i == "string" ? i : "", In = (i, t) => i === "unordered" || i === "ordered" || i === "checklist" ? i : t, Nn = (i) => !!i, Dn = (i, t) => typeof i == "number" ? i : t, Pn = (i, t) => {
|
|
732
732
|
const e = t.defaultStyle || "unordered";
|
|
733
733
|
if (!i || typeof i != "object")
|
|
734
734
|
return {
|
|
@@ -822,7 +822,7 @@ class ce {
|
|
|
822
822
|
return n ? Math.round(parseInt(n[1], 10) / z) : 0;
|
|
823
823
|
}
|
|
824
824
|
}
|
|
825
|
-
const
|
|
825
|
+
const Hn = (i, t) => {
|
|
826
826
|
if (!i) return null;
|
|
827
827
|
if (t === "checklist") {
|
|
828
828
|
const n = i.querySelector("[contenteditable]");
|
|
@@ -849,7 +849,7 @@ const Pn = (i, t) => {
|
|
|
849
849
|
n.style
|
|
850
850
|
);
|
|
851
851
|
return l === null ? 1 : o.getBlockStartValue(l);
|
|
852
|
-
},
|
|
852
|
+
}, Pt = (i, t, e, n, s, o) => {
|
|
853
853
|
const l = Mn(i, t, n, e, s, o) + i;
|
|
854
854
|
return o.formatNumber(l, t);
|
|
855
855
|
}, Wn = (i, t, e, n) => n.findGroupStart(i, t, e), ue = (i, t, e, n) => {
|
|
@@ -1412,7 +1412,7 @@ const Yn = (i) => i instanceof HTMLElement, Zn = /* @__PURE__ */ new Set([
|
|
|
1412
1412
|
style: "unordered",
|
|
1413
1413
|
checked: !1
|
|
1414
1414
|
})
|
|
1415
|
-
}),
|
|
1415
|
+
}), Ht = [
|
|
1416
1416
|
{
|
|
1417
1417
|
name: "bulletedList",
|
|
1418
1418
|
titleKey: "bulletedList",
|
|
@@ -1471,11 +1471,11 @@ class vo {
|
|
|
1471
1471
|
return typeof t == "object" && t !== null && "event" in t && typeof t.event == "object" && t.event !== null && "type" in t.event && typeof t.event.type == "string";
|
|
1472
1472
|
}
|
|
1473
1473
|
normalizeData(t) {
|
|
1474
|
-
return
|
|
1474
|
+
return Pn(t, this._settings);
|
|
1475
1475
|
}
|
|
1476
1476
|
get availableStyles() {
|
|
1477
1477
|
const t = this._settings.styles;
|
|
1478
|
-
return !t || t.length === 0 ?
|
|
1478
|
+
return !t || t.length === 0 ? Ht : Ht.filter((e) => t.includes(e.style));
|
|
1479
1479
|
}
|
|
1480
1480
|
get itemColor() {
|
|
1481
1481
|
return this._settings.itemColor;
|
|
@@ -1535,7 +1535,7 @@ class vo {
|
|
|
1535
1535
|
const t = (o = this._element) == null ? void 0 : o.querySelector("[data-list-marker]");
|
|
1536
1536
|
if (!t)
|
|
1537
1537
|
return;
|
|
1538
|
-
const e = this.getDepth(), n = Dt(this.blockId, e, this._data.style, this.api.blocks, this.markerCalculator), s =
|
|
1538
|
+
const e = this.getDepth(), n = Dt(this.blockId, e, this._data.style, this.api.blocks, this.markerCalculator), s = Pt(n, e, this._data, this.blockId, this.api.blocks, this.markerCalculator);
|
|
1539
1539
|
t.textContent = s;
|
|
1540
1540
|
}
|
|
1541
1541
|
updateSiblingListMarkers() {
|
|
@@ -1548,7 +1548,7 @@ class vo {
|
|
|
1548
1548
|
const n = (s = this._element) == null ? void 0 : s.querySelector('[aria-hidden="true"]');
|
|
1549
1549
|
if (n instanceof HTMLElement)
|
|
1550
1550
|
if (e === "ordered") {
|
|
1551
|
-
const o = Dt(this.blockId, t, this._data.style, this.api.blocks, this.markerCalculator), r =
|
|
1551
|
+
const o = Dt(this.blockId, t, this._data.style, this.api.blocks, this.markerCalculator), r = Pt(o, t, this._data, this.blockId, this.api.blocks, this.markerCalculator);
|
|
1552
1552
|
n.textContent = r;
|
|
1553
1553
|
} else {
|
|
1554
1554
|
const o = On(t, this.markerCalculator);
|
|
@@ -1638,7 +1638,7 @@ class vo {
|
|
|
1638
1638
|
e instanceof HTMLInputElement && (this._data.checked = e.checked);
|
|
1639
1639
|
}
|
|
1640
1640
|
getContentElement() {
|
|
1641
|
-
return
|
|
1641
|
+
return Hn(this._element, this._data.style);
|
|
1642
1642
|
}
|
|
1643
1643
|
renderSettings() {
|
|
1644
1644
|
return vn(this.availableStyles, this._data.style, this.api.i18n.t, (t) => this.setStyle(t));
|
|
@@ -1824,7 +1824,7 @@ class ds {
|
|
|
1824
1824
|
return (r == null ? void 0 : r.offsetHeight) || 30;
|
|
1825
1825
|
}
|
|
1826
1826
|
if (this.getNewColumnWidth)
|
|
1827
|
-
return this.getNewColumnWidth();
|
|
1827
|
+
return this.getNewColumnWidth() || 100;
|
|
1828
1828
|
const e = this.grid.querySelector("[data-blok-table-row]");
|
|
1829
1829
|
if (!e)
|
|
1830
1830
|
return 100;
|
|
@@ -1886,7 +1886,7 @@ class ds {
|
|
|
1886
1886
|
e && (e.setAttribute("width", $t), e.setAttribute("height", $t), e.setAttribute("viewBox", "0 0 24 24"), e.classList.add("text-gray-500", "pointer-events-none"));
|
|
1887
1887
|
}
|
|
1888
1888
|
}
|
|
1889
|
-
const g = "data-blok-table-row", u = "data-blok-table-cell",
|
|
1889
|
+
const g = "data-blok-table-row", u = "data-blok-table-cell", H = 1, nt = `${H}px solid #d1d5db`, hs = [
|
|
1890
1890
|
"flex"
|
|
1891
1891
|
], us = [
|
|
1892
1892
|
"py-1",
|
|
@@ -2189,7 +2189,7 @@ class fs {
|
|
|
2189
2189
|
return;
|
|
2190
2190
|
const d = c.getAttribute("data-blok-id");
|
|
2191
2191
|
d && this.api.caret.setToBlock(d, "end");
|
|
2192
|
-
}, this.api = t.api, this.gridElement = t.gridElement, this.onNavigateToCell = t.onNavigateToCell, this.api.events.on("block changed", this.handleBlockMutation), this.gridElement.addEventListener("click", this.handleCellBlankSpaceClick);
|
|
2192
|
+
}, this.api = t.api, this.gridElement = t.gridElement, this.tableBlockId = t.tableBlockId, this.onNavigateToCell = t.onNavigateToCell, this.api.events.on("block changed", this.handleBlockMutation), this.gridElement.addEventListener("click", this.handleCellBlankSpaceClick);
|
|
2193
2193
|
}
|
|
2194
2194
|
/**
|
|
2195
2195
|
* Get the currently active cell that contains blocks
|
|
@@ -2314,7 +2314,7 @@ class fs {
|
|
|
2314
2314
|
a.push({ blocks: f });
|
|
2315
2315
|
else {
|
|
2316
2316
|
const m = typeof c == "string" ? c : "", C = this.api.blocks.insert("paragraph", { text: m }, {}, this.api.blocks.getBlocksCount(), !1);
|
|
2317
|
-
p.appendChild(C.holder), a.push({ blocks: [C.id] });
|
|
2317
|
+
p.appendChild(C.holder), this.api.blocks.setBlockParent(C.id, this.tableBlockId), a.push({ blocks: [C.id] });
|
|
2318
2318
|
}
|
|
2319
2319
|
this.stripPlaceholders(p);
|
|
2320
2320
|
}), n.push(a);
|
|
@@ -2342,7 +2342,7 @@ class fs {
|
|
|
2342
2342
|
if (o === void 0)
|
|
2343
2343
|
continue;
|
|
2344
2344
|
const r = this.api.blocks.getBlockByIndex(o);
|
|
2345
|
-
r && (t.appendChild(r.holder), n.push(s));
|
|
2345
|
+
r && (t.appendChild(r.holder), this.api.blocks.setBlockParent(s, this.tableBlockId), n.push(s));
|
|
2346
2346
|
}
|
|
2347
2347
|
return n;
|
|
2348
2348
|
}
|
|
@@ -2357,7 +2357,7 @@ class fs {
|
|
|
2357
2357
|
if (s === void 0)
|
|
2358
2358
|
return;
|
|
2359
2359
|
const o = this.api.blocks.getBlockByIndex(s);
|
|
2360
|
-
o && (n.appendChild(o.holder), this.stripPlaceholders(n));
|
|
2360
|
+
o && (n.appendChild(o.holder), this.api.blocks.setBlockParent(e, this.tableBlockId), this.stripPlaceholders(n));
|
|
2361
2361
|
}
|
|
2362
2362
|
/**
|
|
2363
2363
|
* Given a new block's index, find which cell it should belong to
|
|
@@ -2386,7 +2386,7 @@ class fs {
|
|
|
2386
2386
|
if (!e || e.querySelector("[data-blok-id]") !== null)
|
|
2387
2387
|
return;
|
|
2388
2388
|
const s = this.api.blocks.insert("paragraph", { text: "" }, {}, this.api.blocks.getBlocksCount(), !0);
|
|
2389
|
-
e.appendChild(s.holder), this.stripPlaceholders(e);
|
|
2389
|
+
e.appendChild(s.holder), this.api.blocks.setBlockParent(s.id, this.tableBlockId), this.stripPlaceholders(e);
|
|
2390
2390
|
}
|
|
2391
2391
|
/**
|
|
2392
2392
|
* If the removed block's holder is currently inside a cell of this table,
|
|
@@ -2714,7 +2714,7 @@ const U = (i) => {
|
|
|
2714
2714
|
);
|
|
2715
2715
|
}, ct = (i, t) => {
|
|
2716
2716
|
const e = t.reduce((o, r) => o + r, 0), n = i;
|
|
2717
|
-
n.style.width = `${e +
|
|
2717
|
+
n.style.width = `${e + H}px`, i.querySelectorAll(`[${g}]`).forEach((o) => {
|
|
2718
2718
|
o.querySelectorAll(`[${u}]`).forEach((l, a) => {
|
|
2719
2719
|
if (a < t.length) {
|
|
2720
2720
|
const c = l;
|
|
@@ -2785,7 +2785,7 @@ const U = (i) => {
|
|
|
2785
2785
|
return [];
|
|
2786
2786
|
const s = i.querySelectorAll(`[${g}]`)[e];
|
|
2787
2787
|
return s ? (o = t == null ? void 0 : t.getBlockIdsFromCells(s.querySelectorAll(`[${u}]`))) != null ? o : [] : [];
|
|
2788
|
-
},
|
|
2788
|
+
}, Ps = (i, t, e) => {
|
|
2789
2789
|
var o;
|
|
2790
2790
|
if (!i)
|
|
2791
2791
|
return [];
|
|
@@ -2814,7 +2814,7 @@ const U = (i) => {
|
|
|
2814
2814
|
i.querySelectorAll(`[${u}]`).forEach((n) => {
|
|
2815
2815
|
t == null || t.ensureCellHasBlock(n);
|
|
2816
2816
|
});
|
|
2817
|
-
},
|
|
2817
|
+
}, Hs = (i, t, e) => {
|
|
2818
2818
|
const n = i.querySelectorAll(`[${g}]`);
|
|
2819
2819
|
t.forEach((s, o) => {
|
|
2820
2820
|
const r = n[o];
|
|
@@ -2929,7 +2929,7 @@ class Gs {
|
|
|
2929
2929
|
}
|
|
2930
2930
|
createHandle(t) {
|
|
2931
2931
|
const e = document.createElement("div"), n = this.getHandleLeftPx(t);
|
|
2932
|
-
return e.setAttribute(Ft, ""), e.setAttribute("data-col", String(t)), e.style.position = "absolute", e.style.top = `-${
|
|
2932
|
+
return e.setAttribute(Ft, ""), e.setAttribute("data-col", String(t)), e.style.position = "absolute", e.style.top = `-${H}px`, e.style.bottom = "0px", e.style.width = `${Ct}px`, e.style.left = `${n - Ct / 2}px`, e.style.cursor = "col-resize", e.style.zIndex = "2", e.style.background = "linear-gradient(to right, transparent 7px, #3b82f6 7px, #3b82f6 9px, transparent 9px)", e.style.opacity = "0", e.style.transition = "opacity 150ms ease", e.setAttribute("contenteditable", "false"), e.addEventListener("mouseenter", () => {
|
|
2933
2933
|
this.isDragging || (e.style.opacity = "1");
|
|
2934
2934
|
}), e.addEventListener("mouseleave", () => {
|
|
2935
2935
|
this.isDragging || (e.style.opacity = "0");
|
|
@@ -2971,7 +2971,7 @@ class Gs {
|
|
|
2971
2971
|
}
|
|
2972
2972
|
applyWidths() {
|
|
2973
2973
|
const t = this.colWidths.reduce((n, s) => n + s, 0);
|
|
2974
|
-
this.gridEl.style.width = `${t +
|
|
2974
|
+
this.gridEl.style.width = `${t + H}px`, this.gridEl.querySelectorAll(`[${Ws}]`).forEach((n) => {
|
|
2975
2975
|
n.querySelectorAll(`[${Ms}]`).forEach((o, r) => {
|
|
2976
2976
|
if (r < this.colWidths.length) {
|
|
2977
2977
|
const l = o;
|
|
@@ -3138,10 +3138,10 @@ class js {
|
|
|
3138
3138
|
this.dropIndicator = document.createElement("div");
|
|
3139
3139
|
const t = this.dropIndicator.style;
|
|
3140
3140
|
if (t.position = "absolute", t.backgroundColor = "#3b82f6", t.borderRadius = "1.5px", t.zIndex = "5", t.pointerEvents = "none", this.dropIndicator.setAttribute("contenteditable", "false"), this.dragType === "row")
|
|
3141
|
-
t.height = "3px", t.left = `${-
|
|
3141
|
+
t.height = "3px", t.left = `${-H}px`, t.right = "0", t.transition = "top 100ms ease";
|
|
3142
3142
|
else {
|
|
3143
3143
|
const e = this.grid.querySelectorAll(`[${g}]`), n = e[e.length - 1], s = n ? n.offsetTop + n.offsetHeight : 0;
|
|
3144
|
-
t.width = "3px", t.top = `${-
|
|
3144
|
+
t.width = "3px", t.top = `${-H}px`, t.height = `${s + H}px`, t.transition = "left 100ms ease";
|
|
3145
3145
|
}
|
|
3146
3146
|
this.grid.appendChild(this.dropIndicator);
|
|
3147
3147
|
}
|
|
@@ -3530,12 +3530,12 @@ class ao {
|
|
|
3530
3530
|
if (o + 1 >= n.length)
|
|
3531
3531
|
return;
|
|
3532
3532
|
const r = (n[o] + n[o + 1]) / 2, l = s.style;
|
|
3533
|
-
l.top = `${-
|
|
3533
|
+
l.top = `${-H / 2}px`, l.left = `${r}px`;
|
|
3534
3534
|
}), this.rowGrips.forEach((s, o) => {
|
|
3535
3535
|
if (o >= t.length)
|
|
3536
3536
|
return;
|
|
3537
3537
|
const r = t[o], l = r.offsetTop + r.offsetHeight / 2, a = s.style;
|
|
3538
|
-
a.left = `${-
|
|
3538
|
+
a.left = `${-H / 2}px`, a.top = `${l}px`;
|
|
3539
3539
|
});
|
|
3540
3540
|
}
|
|
3541
3541
|
/**
|
|
@@ -3745,7 +3745,7 @@ class So {
|
|
|
3745
3745
|
const t = this.element.firstElementChild;
|
|
3746
3746
|
if (t) {
|
|
3747
3747
|
if (this.readOnly) {
|
|
3748
|
-
|
|
3748
|
+
Hs(t, this.data.content, this.api);
|
|
3749
3749
|
return;
|
|
3750
3750
|
}
|
|
3751
3751
|
if (this.data.content = (n = (e = this.cellBlocks) == null ? void 0 : e.initializeCells(this.data.content)) != null ? n : this.data.content, this.isNewTable && G(t, this.cellBlocks), this.data.initialColWidth === void 0) {
|
|
@@ -3810,7 +3810,7 @@ class So {
|
|
|
3810
3810
|
return Ds(this.element, this.cellBlocks, t);
|
|
3811
3811
|
}
|
|
3812
3812
|
getBlockIdsInColumn(t) {
|
|
3813
|
-
return
|
|
3813
|
+
return Ps(this.element, this.cellBlocks, t);
|
|
3814
3814
|
}
|
|
3815
3815
|
initAddControls(t) {
|
|
3816
3816
|
var n;
|
|
@@ -4140,7 +4140,7 @@ const q = (i) => {
|
|
|
4140
4140
|
*/
|
|
4141
4141
|
synchronize(t) {
|
|
4142
4142
|
var r, l;
|
|
4143
|
-
const e = (r = t == null ? void 0 : t.anchorNode) != null ? r : t == null ? void 0 : t.focusNode, n = e && e.nodeType === Node.ELEMENT_NODE ? e : e == null ? void 0 : e.parentElement, s = (l = n == null ? void 0 : n.closest(
|
|
4143
|
+
const e = (r = t == null ? void 0 : t.anchorNode) != null ? r : t == null ? void 0 : t.focusNode, n = e && e.nodeType === Node.ELEMENT_NODE ? e : e == null ? void 0 : e.parentElement, s = (l = n == null ? void 0 : n.closest(P(E.editor))) != null ? l : n == null ? void 0 : n.ownerDocument;
|
|
4144
4144
|
if (!s)
|
|
4145
4145
|
return;
|
|
4146
4146
|
const o = `strong[${S.COLLAPSED_ACTIVE}="true"]`;
|
|
@@ -4178,7 +4178,7 @@ const q = (i) => {
|
|
|
4178
4178
|
const e = (r = t == null ? void 0 : t.anchorNode) != null ? r : t == null ? void 0 : t.focusNode;
|
|
4179
4179
|
if (!e)
|
|
4180
4180
|
return;
|
|
4181
|
-
const n = e.nodeType === Node.ELEMENT_NODE ? e : e.parentElement, s = n == null ? void 0 : n.closest(
|
|
4181
|
+
const n = e.nodeType === Node.ELEMENT_NODE ? e : e.parentElement, s = n == null ? void 0 : n.closest(P(E.editor));
|
|
4182
4182
|
if (!s)
|
|
4183
4183
|
return;
|
|
4184
4184
|
s.querySelectorAll(`strong[${S.COLLAPSED_LENGTH}]`).forEach((l) => {
|
|
@@ -4513,8 +4513,8 @@ class R {
|
|
|
4513
4513
|
const n = e.nodeType === Node.ELEMENT_NODE ? e : e.parentElement;
|
|
4514
4514
|
if (!n)
|
|
4515
4515
|
return null;
|
|
4516
|
-
const s = (l = n.closest('[data-blok-component="paragraph"]')) != null ? l : n.closest(
|
|
4517
|
-
return s || n.closest(
|
|
4516
|
+
const s = (l = n.closest('[data-blok-component="paragraph"]')) != null ? l : n.closest(P(E.elementContent));
|
|
4517
|
+
return s || n.closest(P(E.editor));
|
|
4518
4518
|
}
|
|
4519
4519
|
}
|
|
4520
4520
|
const T = class T {
|
|
@@ -4921,7 +4921,7 @@ const Co = (i, t) => {
|
|
|
4921
4921
|
const t = window.getSelection();
|
|
4922
4922
|
if (!t)
|
|
4923
4923
|
return;
|
|
4924
|
-
const e = t.anchorNode, n = (e == null ? void 0 : e.nodeType) === Node.ELEMENT_NODE ? e : e == null ? void 0 : e.parentElement, s = n == null ? void 0 : n.closest(
|
|
4924
|
+
const e = t.anchorNode, n = (e == null ? void 0 : e.nodeType) === Node.ELEMENT_NODE ? e : e == null ? void 0 : e.parentElement, s = n == null ? void 0 : n.closest(P(E.editor));
|
|
4925
4925
|
if (!s)
|
|
4926
4926
|
return;
|
|
4927
4927
|
const o = s.querySelector("[data-blok-testid=inline-toolbar]");
|
|
@@ -4976,7 +4976,7 @@ const Co = (i, t) => {
|
|
|
4976
4976
|
*/
|
|
4977
4977
|
static findBlokScopeFromNode(t) {
|
|
4978
4978
|
const e = t.nodeType === Node.ELEMENT_NODE ? t : t.parentElement;
|
|
4979
|
-
return !e || typeof e.closest != "function" ? null : e.closest(`${
|
|
4979
|
+
return !e || typeof e.closest != "function" ? null : e.closest(`${P(E.interface)}, ${P(E.editor)}`);
|
|
4980
4980
|
}
|
|
4981
4981
|
/**
|
|
4982
4982
|
* Get a bold element at the boundary of a collapsed range
|
|
@@ -5020,7 +5020,7 @@ const Co = (i, t) => {
|
|
|
5020
5020
|
if (!e)
|
|
5021
5021
|
return !1;
|
|
5022
5022
|
const n = e.nodeType === Node.ELEMENT_NODE ? e : e.parentElement;
|
|
5023
|
-
return !!(n != null && n.closest(
|
|
5023
|
+
return !!(n != null && n.closest(P(E.editor)));
|
|
5024
5024
|
}
|
|
5025
5025
|
/**
|
|
5026
5026
|
* Get HTML content of a range with bold tags removed
|
|
@@ -5366,7 +5366,7 @@ const j = class j {
|
|
|
5366
5366
|
*/
|
|
5367
5367
|
getButtonElement() {
|
|
5368
5368
|
const t = document.querySelector(
|
|
5369
|
-
`${
|
|
5369
|
+
`${P(E.interface, Qe)} [data-blok-item-name="link"]`
|
|
5370
5370
|
);
|
|
5371
5371
|
return t && t !== this.nodes.button && (t.addEventListener("click", this.handleButtonClick, !0), this.nodes.button = t), t;
|
|
5372
5372
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jackuait/blok",
|
|
3
|
-
"version": "0.6.0-beta.
|
|
3
|
+
"version": "0.6.0-beta.8",
|
|
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",
|
|
@@ -38,6 +38,7 @@ export class BlocksAPI extends Module {
|
|
|
38
38
|
update: this.update,
|
|
39
39
|
composeBlockData: this.composeBlockData,
|
|
40
40
|
convert: this.convert,
|
|
41
|
+
setBlockParent: (blockId: string, parentId: string | null): void => this.setBlockParent(blockId, parentId),
|
|
41
42
|
stopBlockMutationWatching: (index: number): void => this.stopBlockMutationWatching(index),
|
|
42
43
|
splitBlock: this.splitBlock,
|
|
43
44
|
};
|
|
@@ -376,6 +377,23 @@ export class BlocksAPI extends Module {
|
|
|
376
377
|
return blocksToInsert.map((block) => new BlockAPI(block));
|
|
377
378
|
};
|
|
378
379
|
|
|
380
|
+
/**
|
|
381
|
+
* Sets the parent of a block, updating both the block's parentId and the parent's contentIds.
|
|
382
|
+
* @param blockId - id of the block to reparent
|
|
383
|
+
* @param parentId - id of the new parent block, or null for root level
|
|
384
|
+
*/
|
|
385
|
+
private setBlockParent(blockId: string, parentId: string | null): void {
|
|
386
|
+
const block = this.Blok.BlockManager.getBlockById(blockId);
|
|
387
|
+
|
|
388
|
+
if (block === undefined) {
|
|
389
|
+
logLabeled('There is no block with id `' + blockId + '`', 'warn');
|
|
390
|
+
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
this.Blok.BlockManager.setBlockParent(block, parentId);
|
|
395
|
+
}
|
|
396
|
+
|
|
379
397
|
/**
|
|
380
398
|
* Stops mutation watching on a block at the specified index.
|
|
381
399
|
* This is used to prevent spurious block-changed events during block replacement.
|
|
@@ -140,11 +140,14 @@ export class RectangleSelection extends Module {
|
|
|
140
140
|
const pointerX = pageX - scrollLeft;
|
|
141
141
|
|
|
142
142
|
/**
|
|
143
|
-
* Check if pointer is within
|
|
143
|
+
* Check if pointer is within the content area's horizontal bounds.
|
|
144
144
|
* This determines whether we should close the toolbar when starting selection.
|
|
145
|
-
* Clicks outside the
|
|
145
|
+
* Clicks outside the content area (to the left or right, in the margin/toolbar zone)
|
|
146
|
+
* should NOT close the toolbar. Uses UI.contentRect which queries the first block's
|
|
147
|
+
* content element and caches the result.
|
|
146
148
|
*/
|
|
147
|
-
const
|
|
149
|
+
const contentRect = this.Blok.UI.contentRect;
|
|
150
|
+
const withinEditorHorizontally = pointerX >= contentRect.left && pointerX <= contentRect.right;
|
|
148
151
|
|
|
149
152
|
const elemWhereSelectionStart = document.elementFromPoint(pageX - scrollLeft, pointerY);
|
|
150
153
|
|
|
@@ -125,7 +125,9 @@ export class Saver extends Module {
|
|
|
125
125
|
const extractedBlocks: OutputData['blocks'] = [];
|
|
126
126
|
|
|
127
127
|
allExtractedData.forEach(({ id, tool, data, tunes, isValid, parentId, contentIds }) => {
|
|
128
|
-
|
|
128
|
+
const hasParent = parentId !== undefined && parentId !== null;
|
|
129
|
+
|
|
130
|
+
if (!isValid && !hasParent) {
|
|
129
131
|
log(`Block «${tool}» skipped because saved data is invalid`);
|
|
130
132
|
|
|
131
133
|
return;
|
|
@@ -151,7 +153,6 @@ export class Saver extends Module {
|
|
|
151
153
|
}
|
|
152
154
|
|
|
153
155
|
const isTunesEmpty = tunes === undefined || isEmpty(tunes);
|
|
154
|
-
const hasParent = parentId !== undefined && parentId !== null;
|
|
155
156
|
const hasContent = contentIds !== undefined && contentIds.length > 0;
|
|
156
157
|
|
|
157
158
|
const output: OutputData['blocks'][number] = {
|
|
@@ -85,6 +85,13 @@ export class Toolbar extends Module<ToolbarNodes> {
|
|
|
85
85
|
*/
|
|
86
86
|
private explicitlyClosed: boolean = false;
|
|
87
87
|
|
|
88
|
+
/**
|
|
89
|
+
* Flag to track if the current hovered block was resolved from a table cell block.
|
|
90
|
+
* When true, the toolbar suppresses plus button, settings toggler, and
|
|
91
|
+
* prevents overriding the current block when the toolbox opens.
|
|
92
|
+
*/
|
|
93
|
+
private hoveredBlockIsFromTableCell: boolean = false;
|
|
94
|
+
|
|
88
95
|
/**
|
|
89
96
|
* Toolbox class instance
|
|
90
97
|
* It will be created in requestIdleCallback so it can be null in some period of time
|
|
@@ -215,8 +222,10 @@ export class Toolbar extends Module<ToolbarNodes> {
|
|
|
215
222
|
|
|
216
223
|
/**
|
|
217
224
|
* Set current block to cover the case when the Toolbar showed near hovered Block but caret is set to another Block.
|
|
225
|
+
* Skip this when the hovered block was resolved from a table cell, so the toolbox
|
|
226
|
+
* can detect the original cell block and hide restricted tools (e.g., table, header).
|
|
218
227
|
*/
|
|
219
|
-
if (this.hoveredBlock) {
|
|
228
|
+
if (this.hoveredBlock && !this.hoveredBlockIsFromTableCell) {
|
|
220
229
|
this.Blok.BlockManager.currentBlock = this.hoveredBlock;
|
|
221
230
|
}
|
|
222
231
|
|
|
@@ -326,13 +335,14 @@ export class Toolbar extends Module<ToolbarNodes> {
|
|
|
326
335
|
return;
|
|
327
336
|
}
|
|
328
337
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
338
|
+
/**
|
|
339
|
+
* Track whether the original block is inside a table cell.
|
|
340
|
+
* Check the DOM directly rather than relying on resolution success,
|
|
341
|
+
* so that the flag is correct even when resolution falls back to the original block.
|
|
342
|
+
*/
|
|
343
|
+
this.hoveredBlockIsFromTableCell = unresolvedBlock.holder.closest('[data-blok-table-cell-blocks]') !== null;
|
|
333
344
|
|
|
334
|
-
|
|
335
|
-
}
|
|
345
|
+
const targetBlock = this.resolveTableCellBlock(unresolvedBlock);
|
|
336
346
|
|
|
337
347
|
/** Clean up draggable on previous block if any */
|
|
338
348
|
if (this.hoveredBlock && this.hoveredBlock !== targetBlock) {
|
|
@@ -351,6 +361,19 @@ export class Toolbar extends Module<ToolbarNodes> {
|
|
|
351
361
|
return;
|
|
352
362
|
}
|
|
353
363
|
|
|
364
|
+
/**
|
|
365
|
+
* Suppress toolbar buttons when the block is inside a table cell.
|
|
366
|
+
* The toolbar still positions itself for toolbox/slash-search purposes,
|
|
367
|
+
* but plus button and settings toggler remain hidden.
|
|
368
|
+
*/
|
|
369
|
+
const displayValue = this.hoveredBlockIsFromTableCell ? 'none' : '';
|
|
370
|
+
|
|
371
|
+
plusButton.style.display = displayValue;
|
|
372
|
+
|
|
373
|
+
if (settingsToggler) {
|
|
374
|
+
settingsToggler.style.display = displayValue;
|
|
375
|
+
}
|
|
376
|
+
|
|
354
377
|
const targetBlockHolder = targetBlock.holder;
|
|
355
378
|
const { isMobile } = this.Blok.UI;
|
|
356
379
|
|
|
@@ -456,12 +479,22 @@ export class Toolbar extends Module<ToolbarNodes> {
|
|
|
456
479
|
this.positioner.setHoveredTarget(null); // No target for multi-block selection
|
|
457
480
|
this.positioner.resetCachedPosition(); // Reset cached position when moving to a new block
|
|
458
481
|
|
|
459
|
-
const { wrapper, plusButton } = this.nodes;
|
|
482
|
+
const { wrapper, plusButton, settingsToggler } = this.nodes;
|
|
460
483
|
|
|
461
484
|
if (!wrapper || !plusButton) {
|
|
462
485
|
return;
|
|
463
486
|
}
|
|
464
487
|
|
|
488
|
+
/**
|
|
489
|
+
* Restore plus button and settings toggler visibility for multi-block selection,
|
|
490
|
+
* in case they were hidden for table cell blocks.
|
|
491
|
+
*/
|
|
492
|
+
plusButton.style.display = '';
|
|
493
|
+
|
|
494
|
+
if (settingsToggler) {
|
|
495
|
+
settingsToggler.style.display = '';
|
|
496
|
+
}
|
|
497
|
+
|
|
465
498
|
const targetBlockHolder = targetBlock.holder;
|
|
466
499
|
|
|
467
500
|
const toolbarY = this.positioner.calculateToolbarY(
|
|
@@ -476,9 +509,6 @@ export class Toolbar extends Module<ToolbarNodes> {
|
|
|
476
509
|
this.positioner.moveToY(this.nodes, toolbarY);
|
|
477
510
|
targetBlockHolder.appendChild(wrapper);
|
|
478
511
|
|
|
479
|
-
/** Set up draggable on the target block using the settings toggler as drag handle */
|
|
480
|
-
const { settingsToggler } = this.nodes;
|
|
481
|
-
|
|
482
512
|
if (settingsToggler && !this.Blok.ReadOnly.isEnabled) {
|
|
483
513
|
targetBlock.setupDraggable(settingsToggler, this.Blok.DragManager);
|
|
484
514
|
}
|
|
@@ -521,18 +551,24 @@ export class Toolbar extends Module<ToolbarNodes> {
|
|
|
521
551
|
* to prevent toolbar from reopening on subsequent block-hovered events
|
|
522
552
|
*/
|
|
523
553
|
this.hoveredBlock = null;
|
|
554
|
+
this.hoveredBlockIsFromTableCell = false;
|
|
524
555
|
// Only set explicitlyClosed if not explicitly disabled (e.g., when called from toolbox after block insertion)
|
|
525
556
|
if (options?.setExplicitlyClosed !== false) {
|
|
526
557
|
this.explicitlyClosed = true;
|
|
527
558
|
}
|
|
528
559
|
|
|
529
560
|
/**
|
|
530
|
-
* Restore plus button
|
|
561
|
+
* Restore plus button and settings toggler visibility
|
|
562
|
+
* in case they were hidden for table cell blocks
|
|
531
563
|
*/
|
|
532
564
|
if (this.nodes.plusButton) {
|
|
533
565
|
this.nodes.plusButton.style.display = '';
|
|
534
566
|
}
|
|
535
567
|
|
|
568
|
+
if (this.nodes.settingsToggler) {
|
|
569
|
+
this.nodes.settingsToggler.style.display = '';
|
|
570
|
+
}
|
|
571
|
+
|
|
536
572
|
/**
|
|
537
573
|
* Reset the content offset transform
|
|
538
574
|
*/
|
|
@@ -566,9 +602,9 @@ export class Toolbar extends Module<ToolbarNodes> {
|
|
|
566
602
|
* Uses the DOM attribute directly to avoid cross-module dependency on the table tool.
|
|
567
603
|
*
|
|
568
604
|
* @param block - the block to resolve
|
|
569
|
-
* @returns the parent table block if inside a cell, the original block otherwise
|
|
605
|
+
* @returns the parent table block if inside a cell, the original block otherwise
|
|
570
606
|
*/
|
|
571
|
-
private resolveTableCellBlock(block: Block): Block
|
|
607
|
+
private resolveTableCellBlock(block: Block): Block {
|
|
572
608
|
const cellBlocksContainer = block.holder.closest('[data-blok-table-cell-blocks]');
|
|
573
609
|
|
|
574
610
|
if (!cellBlocksContainer) {
|
|
@@ -578,10 +614,10 @@ export class Toolbar extends Module<ToolbarNodes> {
|
|
|
578
614
|
const tableBlockHolder = cellBlocksContainer.closest('[data-blok-testid="block-wrapper"]');
|
|
579
615
|
|
|
580
616
|
if (!tableBlockHolder) {
|
|
581
|
-
return
|
|
617
|
+
return block;
|
|
582
618
|
}
|
|
583
619
|
|
|
584
|
-
return this.Blok.BlockManager.getBlockByChildNode(tableBlockHolder) ??
|
|
620
|
+
return this.Blok.BlockManager.getBlockByChildNode(tableBlockHolder) ?? block;
|
|
585
621
|
}
|
|
586
622
|
|
|
587
623
|
/**
|
|
@@ -173,12 +173,33 @@ export class PlusButtonHandler {
|
|
|
173
173
|
const hoveredBlockIndex = hoveredBlock !== null
|
|
174
174
|
? BlockManager.getBlockIndex(hoveredBlock)
|
|
175
175
|
: BlockManager.currentBlockIndex;
|
|
176
|
-
const
|
|
176
|
+
const baseInsertIndex = insertAbove ? hoveredBlockIndex : hoveredBlockIndex + 1;
|
|
177
|
+
|
|
178
|
+
// When inserting below, skip past any blocks nested inside another block's
|
|
179
|
+
// DOM (e.g. paragraph blocks inside table cells). The block array may
|
|
180
|
+
// interleave nested blocks from multiple parents, so check whether each
|
|
181
|
+
// block's holder lives inside any block-wrapper ancestor rather than only
|
|
182
|
+
// the hovered block's holder.
|
|
183
|
+
const blocksAfterInsert = BlockManager.blocks.slice(baseInsertIndex);
|
|
184
|
+
const isNested = (block: Block): boolean =>
|
|
185
|
+
block.holder.parentElement?.closest('[data-blok-testid="block-wrapper"]') !== null;
|
|
186
|
+
const firstNonNestedOffset = !insertAbove && hoveredBlock && blocksAfterInsert.length > 0
|
|
187
|
+
? blocksAfterInsert.findIndex((block) => !isNested(block))
|
|
188
|
+
: 0;
|
|
189
|
+
const insertIndex = baseInsertIndex + (firstNonNestedOffset === -1 ? blocksAfterInsert.length : firstNonNestedOffset);
|
|
177
190
|
|
|
178
191
|
const targetBlock = isEmptyParagraph || startsWithSlash
|
|
179
192
|
? hoveredBlock
|
|
180
193
|
: BlockManager.insertDefaultBlockAtIndex(insertIndex, true);
|
|
181
194
|
|
|
195
|
+
// The DOM insertion may place the new block's holder inside a nested
|
|
196
|
+
// container (e.g. a table cell) because the previous block in the array
|
|
197
|
+
// is inside another block's DOM. Move the holder to be a sibling after
|
|
198
|
+
// the hovered block so it becomes a top-level block.
|
|
199
|
+
if (targetBlock !== hoveredBlock && isNested(targetBlock)) {
|
|
200
|
+
hoveredBlock?.holder.after(targetBlock.holder);
|
|
201
|
+
}
|
|
202
|
+
|
|
182
203
|
// Insert "/" or position caret after existing one
|
|
183
204
|
if (startsWithSlash) {
|
|
184
205
|
Caret.setToBlock(targetBlock, Caret.positions.DEFAULT, 1);
|