@jackuait/blok 0.4.3-beta.8 → 0.4.3-beta.9

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 CHANGED
@@ -1,5 +1,5 @@
1
- import { B as s, v as a } from "./chunks/blok-JdFwSTgC.mjs";
2
- import { D as A } from "./chunks/inline-tool-convert-MJUgGURB.mjs";
1
+ import { B as s, v as a } from "./chunks/blok-CU-oiynu.mjs";
2
+ import { D as A } from "./chunks/inline-tool-convert-rak34pCi.mjs";
3
3
  export {
4
4
  s as Blok,
5
5
  A as DATA_ATTR,
@@ -19,7 +19,7 @@ var jt = (a, t) => {
19
19
  t.indexOf(o) < 0 && Fe.call(a, o) && (e[o] = a[o]);
20
20
  return e;
21
21
  };
22
- import { i as N, g as _o, a as f, b as ve, c as E, l as I, S as B, d as zo, e as Uo, D as m, t as C, f as $, h as uo, P as O, j as Ht, k as j, m as A, n as wt, o as ht, p as po, q as Q, T as Xt, r as Ft, s as v, I as Ko, u as Wo, v as ct, w as ne, x as $o, y as Yo, z as jo, A as fo, B as Xo, C as go, E as mo, F as Vo, G as qo, H as Go, J as Zo, K as Jo, L as we, M as _e, N as Qo, O as ze, Q as Ue, R as tn, U as en, V as on, W as nn, X as sn, Y as se, Z as _t, _ as rn, $ as an, a0 as ln, a1 as Ke, a2 as cn, a3 as dn, a4 as hn, a5 as un, a6 as pn, a7 as fn, a8 as gn } from "./inline-tool-convert-MJUgGURB.mjs";
22
+ import { i as N, g as _o, a as f, b as ve, c as E, l as I, S as B, d as zo, e as Uo, D as m, t as C, f as j, h as uo, P as O, j as Ht, k as Y, m as A, n as wt, o as ht, p as po, q as Q, T as Xt, r as Ft, s as v, I as Ko, u as Wo, v as ct, w as ne, x as $o, y as Yo, z as jo, A as fo, B as Xo, C as go, E as mo, F as Vo, G as qo, H as Go, J as Zo, K as Jo, L as we, M as _e, N as Qo, O as ze, Q as Ue, R as tn, U as en, V as on, W as nn, X as sn, Y as se, Z as _t, _ as rn, $ as an, a0 as ln, a1 as Ke, a2 as cn, a3 as dn, a4 as hn, a5 as un, a6 as pn, a7 as fn, a8 as gn } from "./inline-tool-convert-rak34pCi.mjs";
23
23
  function mn(a) {
24
24
  return a && a.__esModule && Object.prototype.hasOwnProperty.call(a, "default") ? a.default : a;
25
25
  }
@@ -463,7 +463,7 @@ const Bn = (a, t) => {
463
463
  const { type: e, target: o, addedNodes: n, removedNodes: s } = a;
464
464
  return a.type === "attributes" && a.attributeName === "data-blok-empty" ? !1 : t.contains(o) ? !0 : e !== "childList" ? !1 : Array.from(n).some((l) => l === t) ? !0 : Array.from(s).some((l) => l === t);
465
465
  }, ie = "redactor dom changed", yt = "block changed", bo = "fake cursor is about to be toggled", ko = "fake cursor have been set", Bt = "blok mobile layout toggled", re = "block-settings-opened", ae = "block-settings-closed", xn = "history:state-changed";
466
- var Y = /* @__PURE__ */ ((a) => (a.RENDERED = "rendered", a.MOVED = "moved", a.UPDATED = "updated", a.REMOVED = "removed", a.ON_PASTE = "onPaste", a))(Y || {});
466
+ var $ = /* @__PURE__ */ ((a) => (a.RENDERED = "rendered", a.MOVED = "moved", a.UPDATED = "updated", a.REMOVED = "removed", a.ON_PASTE = "onPaste", a))($ || {});
467
467
  const z = class z extends Ct {
468
468
  /**
469
469
  * @param options - block constructor options
@@ -1038,7 +1038,7 @@ const z = class z extends Ct {
1038
1038
  * especially when mutation observers haven't been set up yet.
1039
1039
  */
1040
1040
  refreshToolRootElement() {
1041
- const t = this.holder.querySelector($(m.elementContent));
1041
+ const t = this.holder.querySelector(j(m.elementContent));
1042
1042
  if (!t)
1043
1043
  return;
1044
1044
  const e = t.firstElementChild;
@@ -1181,7 +1181,7 @@ class Tn extends T {
1181
1181
  getBlockIndex(t) {
1182
1182
  const e = this.Blok.BlockManager.getBlockById(t);
1183
1183
  if (!e) {
1184
- j("There is no block with id `" + t + "`", "warn");
1184
+ Y("There is no block with id `" + t + "`", "warn");
1185
1185
  return;
1186
1186
  }
1187
1187
  return this.Blok.BlockManager.getBlockIndex(e);
@@ -1193,7 +1193,7 @@ class Tn extends T {
1193
1193
  getBlockByIndex(t) {
1194
1194
  const e = this.Blok.BlockManager.getBlockByIndex(t);
1195
1195
  if (e === void 0) {
1196
- j("There is no block at index `" + t + "`", "warn");
1196
+ Y("There is no block at index `" + t + "`", "warn");
1197
1197
  return;
1198
1198
  }
1199
1199
  return new V(e);
@@ -1204,7 +1204,7 @@ class Tn extends T {
1204
1204
  */
1205
1205
  getById(t) {
1206
1206
  const e = this.Blok.BlockManager.getBlockById(t);
1207
- return e === void 0 ? (j("There is no block with id `" + t + "`", "warn"), null) : new V(e);
1207
+ return e === void 0 ? (Y("There is no block with id `" + t + "`", "warn"), null) : new V(e);
1208
1208
  }
1209
1209
  /**
1210
1210
  * Get Block API object by any child html element
@@ -1213,7 +1213,7 @@ class Tn extends T {
1213
1213
  getBlockByElement(t) {
1214
1214
  const e = this.Blok.BlockManager.getBlock(t);
1215
1215
  if (e === void 0) {
1216
- j("There is no block corresponding to element `" + t + "`", "warn");
1216
+ Y("There is no block corresponding to element `" + t + "`", "warn");
1217
1217
  return;
1218
1218
  }
1219
1219
  return new V(e);
@@ -1233,13 +1233,13 @@ class Tn extends T {
1233
1233
  async delete(t = this.Blok.BlockManager.currentBlockIndex) {
1234
1234
  const e = this.Blok.BlockManager.getBlockByIndex(t);
1235
1235
  if (e === void 0) {
1236
- j(`There is no block at index \`${t}\``, "warn");
1236
+ Y(`There is no block at index \`${t}\``, "warn");
1237
1237
  return;
1238
1238
  }
1239
1239
  try {
1240
1240
  await this.Blok.BlockManager.removeBlock(e);
1241
1241
  } catch (o) {
1242
- j(o, "warn");
1242
+ Y(o, "warn");
1243
1243
  return;
1244
1244
  }
1245
1245
  this.Blok.BlockManager.blocks.length === 0 && this.Blok.BlockManager.insert(), this.Blok.BlockManager.currentBlock && this.Blok.Caret.setToBlock(this.Blok.BlockManager.currentBlock, this.Blok.Caret.positions.END), this.Blok.Toolbar.close();
@@ -1459,7 +1459,7 @@ class Ln {
1459
1459
  * @returns {Promise<NotifierModule>} loaded notifier module
1460
1460
  */
1461
1461
  loadNotifierModule() {
1462
- return this.notifierModule !== null ? Promise.resolve(this.notifierModule) : (this.loadingPromise === null && (this.loadingPromise = import("./index-y3l95XAF.mjs").then((t) => {
1462
+ return this.notifierModule !== null ? Promise.resolve(this.notifierModule) : (this.loadingPromise === null && (this.loadingPromise = import("./index-BsZmlgGN.mjs").then((t) => {
1463
1463
  const e = t;
1464
1464
  if (!this.isNotifierModule(e))
1465
1465
  throw new Error('notifier module does not expose a "show" method.');
@@ -1802,7 +1802,7 @@ class Jn extends T {
1802
1802
  var s, i;
1803
1803
  const t = "Blok's content can not be saved in read-only mode";
1804
1804
  if (this.Blok.ReadOnly.isEnabled)
1805
- throw j(t, "warn"), new Error(t);
1805
+ throw Y(t, "warn"), new Error(t);
1806
1806
  const e = await this.Blok.Saver.save();
1807
1807
  if (e !== void 0)
1808
1808
  return e;
@@ -1939,7 +1939,7 @@ class os extends T {
1939
1939
  */
1940
1940
  toggleBlockSettings(t) {
1941
1941
  if (this.Blok.BlockManager.currentBlockIndex === -1) {
1942
- j("Could't toggle the Toolbar because there is no block selected ", "warn");
1942
+ Y("Could't toggle the Toolbar because there is no block selected ", "warn");
1943
1943
  return;
1944
1944
  }
1945
1945
  (t != null ? t : !this.Blok.BlockSettings.opened) ? (this.Blok.Toolbar.moveAndOpen(), this.Blok.BlockSettings.open()) : this.Blok.BlockSettings.close();
@@ -1950,7 +1950,7 @@ class os extends T {
1950
1950
  */
1951
1951
  toggleToolbox(t) {
1952
1952
  if (this.Blok.BlockManager.currentBlockIndex === -1) {
1953
- j("Could't toggle the Toolbox because there is no block selected ", "warn");
1953
+ Y("Could't toggle the Toolbox because there is no block selected ", "warn");
1954
1954
  return;
1955
1955
  }
1956
1956
  (t != null ? t : !this.Blok.Toolbar.toolbox.opened) ? (this.Blok.Toolbar.moveAndOpen(), this.Blok.Toolbar.toolbox.open()) : this.Blok.Toolbar.toolbox.close();
@@ -6381,7 +6381,7 @@ class _s extends T {
6381
6381
  async ensureI18nextLoaded(t, e) {
6382
6382
  if (this.i18nextWrapper !== null)
6383
6383
  return;
6384
- const { loadI18next: o } = await import("./i18next-loader-D0iIovKH.mjs");
6384
+ const { loadI18next: o } = await import("./i18next-loader-FVUl5b89.mjs");
6385
6385
  this.i18nextWrapper = await o(t, e);
6386
6386
  }
6387
6387
  /**
@@ -7296,7 +7296,7 @@ class ee {
7296
7296
  fromIndex: e,
7297
7297
  toIndex: t
7298
7298
  });
7299
- n.call(Y.MOVED, s);
7299
+ n.call($.MOVED, s);
7300
7300
  }
7301
7301
  /**
7302
7302
  * Insert new Block at passed index
@@ -7310,7 +7310,7 @@ class ee {
7310
7310
  return;
7311
7311
  }
7312
7312
  const n = t > this.length ? this.length : t;
7313
- o && (this.blocks[n].holder.remove(), this.blocks[n].call(Y.REMOVED));
7313
+ o && (this.blocks[n].holder.remove(), this.blocks[n].call($.REMOVED));
7314
7314
  const s = o ? 1 : 0;
7315
7315
  if (this.blocks.splice(n, s, e), n > 0) {
7316
7316
  const r = this.blocks[n - 1];
@@ -7333,7 +7333,7 @@ class ee {
7333
7333
  if (this.blocks[t] === void 0)
7334
7334
  throw Error("Incorrect index");
7335
7335
  const o = this.blocks[t];
7336
- o.holder.replaceWith(e.holder), o.call(Y.REMOVED), this.blocks[t] = e, e.call(Y.RENDERED);
7336
+ o.holder.replaceWith(e.holder), o.call($.REMOVED), this.blocks[t] = e, e.call($.RENDERED);
7337
7337
  }
7338
7338
  /**
7339
7339
  * Inserts several blocks at once
@@ -7345,14 +7345,14 @@ class ee {
7345
7345
  for (const n of t)
7346
7346
  o.appendChild(n.holder);
7347
7347
  if (!this.length) {
7348
- this.blocks.push(...t), this.workingArea.appendChild(o), t.forEach((n) => n.call(Y.RENDERED));
7348
+ this.blocks.push(...t), this.workingArea.appendChild(o), t.forEach((n) => n.call($.RENDERED));
7349
7349
  return;
7350
7350
  }
7351
7351
  if (e > 0) {
7352
7352
  const n = Math.min(e - 1, this.length - 1);
7353
7353
  this.blocks[n].holder.after(o);
7354
7354
  }
7355
- e === 0 && this.workingArea.prepend(o), this.blocks.splice(e, 0, ...t), t.forEach((n) => n.call(Y.RENDERED));
7355
+ e === 0 && this.workingArea.prepend(o), this.blocks.splice(e, 0, ...t), t.forEach((n) => n.call($.RENDERED));
7356
7356
  }
7357
7357
  /**
7358
7358
  * Remove block
@@ -7360,13 +7360,13 @@ class ee {
7360
7360
  */
7361
7361
  remove(t) {
7362
7362
  const e = isNaN(t) ? this.length - 1 : t;
7363
- this.blocks[e].holder.remove(), this.blocks[e].call(Y.REMOVED), this.blocks.splice(e, 1);
7363
+ this.blocks[e].holder.remove(), this.blocks[e].call($.REMOVED), this.blocks.splice(e, 1);
7364
7364
  }
7365
7365
  /**
7366
7366
  * Remove all blocks
7367
7367
  */
7368
7368
  removeAll() {
7369
- this.workingArea.innerHTML = "", this.blocks.forEach((t) => t.call(Y.REMOVED)), this.blocks.length = 0;
7369
+ this.workingArea.innerHTML = "", this.blocks.forEach((t) => t.call($.REMOVED)), this.blocks.length = 0;
7370
7370
  }
7371
7371
  /**
7372
7372
  * Insert Block after passed target
@@ -7401,7 +7401,7 @@ class ee {
7401
7401
  * @param {Block} target — Block related to position
7402
7402
  */
7403
7403
  insertToDOM(t, e, o) {
7404
- e && o !== void 0 ? o.holder.insertAdjacentElement(e, t.holder) : this.workingArea.appendChild(t.holder), t.call(Y.RENDERED);
7404
+ e && o !== void 0 ? o.holder.insertAdjacentElement(e, t.holder) : this.workingArea.appendChild(t.holder), t.call($.RENDERED);
7405
7405
  }
7406
7406
  /**
7407
7407
  * Composes Block event with passed type and details
@@ -7779,7 +7779,7 @@ class Qs extends T {
7779
7779
  replace: o
7780
7780
  });
7781
7781
  try {
7782
- await n.ready, n.call(Y.ON_PASTE, e), n.refreshToolRootElement();
7782
+ await n.ready, n.call($.ON_PASTE, e), n.refreshToolRootElement();
7783
7783
  } catch (s) {
7784
7784
  I(`${t}: onPaste callback call is failed`, "error", s);
7785
7785
  }
@@ -7966,7 +7966,7 @@ class Qs extends T {
7966
7966
  const e = f.isElement(t) ? t : t.parentNode;
7967
7967
  if (!e)
7968
7968
  return;
7969
- const o = this.blocksStore.nodes, n = e.closest($(m.element));
7969
+ const o = this.blocksStore.nodes, n = e.closest(j(m.element));
7970
7970
  if (!n)
7971
7971
  return;
7972
7972
  const s = o.indexOf(n);
@@ -7983,10 +7983,10 @@ class Qs extends T {
7983
7983
  const e = f.isElement(t) ? t : t.parentNode;
7984
7984
  if (!e)
7985
7985
  return;
7986
- const o = e.closest($(m.element));
7986
+ const o = e.closest(j(m.element));
7987
7987
  if (!o)
7988
7988
  return;
7989
- const n = o.closest($(m.editor));
7989
+ const n = o.closest(j(m.editor));
7990
7990
  if (!(n == null ? void 0 : n.isEqualNode(this.Blok.UI.nodes.wrapper)) || !(o instanceof HTMLElement))
7991
7991
  return;
7992
7992
  this.currentBlockIndex = this.blocksStore.nodes.indexOf(o);
@@ -8004,7 +8004,7 @@ class Qs extends T {
8004
8004
  const e = f.isElement(t) ? t : t.parentNode;
8005
8005
  if (!e)
8006
8006
  return;
8007
- const o = e.closest($(m.element));
8007
+ const o = e.closest(j(m.element));
8008
8008
  if (o)
8009
8009
  return this.blocks.find((n) => n.holder === o);
8010
8010
  }
@@ -9578,7 +9578,7 @@ class si extends T {
9578
9578
  * @returns Object with block and holder, or nulls if no valid target found
9579
9579
  */
9580
9580
  findDropTargetBlock(t, e, o) {
9581
- const n = t.closest($(m.element));
9581
+ const n = t.closest(j(m.element));
9582
9582
  if (n)
9583
9583
  return { block: this.Blok.BlockManager.blocks.find((r) => r.holder === n), holder: n };
9584
9584
  const s = this.findBlockInLeftDropZone(e, o);
@@ -10279,18 +10279,21 @@ class ai extends T {
10279
10279
  * Init rect params
10280
10280
  * @param {number} pageX - X coord of mouse
10281
10281
  * @param {number} pageY - Y coord of mouse
10282
+ * @param {boolean} shiftKey - whether Shift key is held for additive selection
10282
10283
  */
10283
- startSelection(t, e) {
10284
- const o = this.getScrollLeft(), n = this.getScrollTop(), s = document.elementFromPoint(t - o, e - n);
10284
+ startSelection(t, e, o = !1) {
10285
+ const { UI: n } = this.Blok, s = n.nodes.redactor;
10285
10286
  if (!s)
10286
10287
  return;
10287
- s.closest($(m.toolbar)) || (this.Blok.BlockSelection.allBlocksSelected = !1, this.clearSelection(), this.stackOfSelected = []);
10288
- const r = [
10289
- $(m.elementContent),
10290
- $(m.toolbar),
10288
+ const i = s.getBoundingClientRect(), r = this.getScrollTop(), l = e - r;
10289
+ if (!(l >= i.top && l <= i.bottom))
10290
+ return;
10291
+ const d = this.getScrollLeft(), h = document.elementFromPoint(t - d, l);
10292
+ !h || (!h.closest(j(m.toolbar)) && !o && (this.Blok.BlockSelection.allBlocksSelected = !1, this.clearSelection(), this.stackOfSelected = []), [
10293
+ j(m.elementContent),
10294
+ j(m.toolbar),
10291
10295
  sn
10292
- ], l = s.closest($(m.editor)), c = r.some((d) => !!s.closest(d));
10293
- !l || c || (this.Blok.Toolbar.close(), this.mousedown = !0, this.startX = t, this.startY = e);
10296
+ ].some((b) => !!h.closest(b))) || (this.Blok.Toolbar.close(), this.mousedown = !0, this.startX = t, this.startY = e);
10294
10297
  }
10295
10298
  /**
10296
10299
  * Clear all params to end selection
@@ -10314,22 +10317,21 @@ class ai extends T {
10314
10317
  * Sets Module necessary event handlers
10315
10318
  */
10316
10319
  enableModuleBindings() {
10317
- const { container: t } = this.genHTML();
10318
- this.listeners.on(t, "mousedown", (n) => {
10319
- this.processMouseDown(n);
10320
+ this.genHTML(), this.listeners.on(document.body, "mousedown", (o) => {
10321
+ this.processMouseDown(o);
10320
10322
  }, !1);
10321
- const e = se((n) => {
10322
- n instanceof MouseEvent && this.processMouseMove(n);
10323
+ const t = se((o) => {
10324
+ o instanceof MouseEvent && this.processMouseMove(o);
10323
10325
  }, 10);
10324
- this.listeners.on(document.body, "mousemove", e, {
10326
+ this.listeners.on(document.body, "mousemove", t, {
10325
10327
  passive: !0
10326
10328
  }), this.listeners.on(document.body, "mouseleave", () => {
10327
10329
  this.processMouseLeave();
10328
10330
  });
10329
- const o = se((n) => {
10330
- this.processScroll(n);
10331
+ const e = se((o) => {
10332
+ this.processScroll(o);
10331
10333
  }, 10);
10332
- this.listeners.on(window, "scroll", o, {
10334
+ this.listeners.on(window, "scroll", e, {
10333
10335
  passive: !0
10334
10336
  }), this.listeners.on(document.body, "mouseup", () => {
10335
10337
  this.processMouseUp();
@@ -10342,7 +10344,7 @@ class ai extends T {
10342
10344
  processMouseDown(t) {
10343
10345
  if (t.button !== this.MAIN_MOUSE_BUTTON)
10344
10346
  return;
10345
- t.target.closest(f.allInputsSelector) !== null || this.startSelection(t.pageX, t.pageY);
10347
+ t.target.closest(f.allInputsSelector) !== null || this.startSelection(t.pageX, t.pageY, t.shiftKey);
10346
10348
  }
10347
10349
  /**
10348
10350
  * Handle mouse move events
@@ -10385,7 +10387,7 @@ class ai extends T {
10385
10387
  * @returns {Record<string, Element>}
10386
10388
  */
10387
10389
  genHTML() {
10388
- const { UI: t } = this.Blok, e = t.nodes.holder.querySelector($(m.editor)), o = f.make("div", [
10390
+ const { UI: t } = this.Blok, e = t.nodes.holder.querySelector(j(m.editor)), o = f.make("div", [
10389
10391
  "fixed",
10390
10392
  "inset-0",
10391
10393
  "z-overlay",
@@ -10432,12 +10434,12 @@ class ai extends T {
10432
10434
  if (e === null)
10433
10435
  return;
10434
10436
  t.pageY !== void 0 && (this.mouseX = t.pageX, this.mouseY = t.pageY);
10435
- const { rightPos: o, leftPos: n, index: s } = this.genInfoForMouseSelection(), i = this.startX > o && this.mouseX > o, r = this.startX < n && this.mouseX < n;
10436
- if (this.rectCrossesBlocks = !(i || r), this.isRectSelectionActivated || (this.rectCrossesBlocks = !1, this.isRectSelectionActivated = !0, this.shrinkRectangleToPoint(), e.style.display = "block"), this.updateRectangleSize(), this.Blok.Toolbar.close(), s === void 0)
10437
+ const { index: o } = this.genInfoForMouseSelection();
10438
+ if (this.rectCrossesBlocks = o !== void 0, this.isRectSelectionActivated || (this.rectCrossesBlocks = !1, this.isRectSelectionActivated = !0, this.shrinkRectangleToPoint(), e.style.display = "block"), this.updateRectangleSize(), this.Blok.Toolbar.close(), o === void 0)
10437
10439
  return;
10438
- this.trySelectNextBlock(s), this.inverseSelection();
10439
- const l = B.get();
10440
- l && l.removeAllRanges();
10440
+ this.trySelectNextBlock(o), this.inverseSelection();
10441
+ const n = B.get();
10442
+ n && n.removeAllRanges();
10441
10443
  }
10442
10444
  /**
10443
10445
  * Shrink rect to singular point
@@ -10476,11 +10478,12 @@ class ai extends T {
10476
10478
  }
10477
10479
  /**
10478
10480
  * Collects information needed to determine the behavior of the rectangle
10481
+ * For page-wide selection, we check blocks at the center X position but at the actual mouse Y position
10479
10482
  * @returns {object} index - index next Block, leftPos - start of left border of Block, rightPos - right border
10480
10483
  */
10481
10484
  genInfoForMouseSelection() {
10482
10485
  var p;
10483
- const e = document.body.offsetWidth / 2, o = this.getScrollTop(), n = this.mouseY - o, s = document.elementFromPoint(e, n), i = (p = this.Blok.BlockManager.lastBlock) == null ? void 0 : p.holder, r = i == null ? void 0 : i.querySelector($(m.elementContent)), c = (r ? Number.parseInt(window.getComputedStyle(r).width, 10) : 0) / 2, d = e - c, h = e + c;
10486
+ const e = document.body.offsetWidth / 2, o = this.getScrollTop(), n = this.mouseY - o, s = document.elementFromPoint(e, n), i = (p = this.Blok.BlockManager.lastBlock) == null ? void 0 : p.holder, r = i == null ? void 0 : i.querySelector(j(m.elementContent)), c = (r ? Number.parseInt(window.getComputedStyle(r).width, 10) : 0) / 2, d = e - c, h = e + c;
10484
10487
  if (!s)
10485
10488
  return {
10486
10489
  index: void 0,
@@ -10667,7 +10670,7 @@ class wi extends T {
10667
10670
  const { tunes: d, id: h, parent: u, content: g } = c, p = c.type, b = o.available.has(p) ? {
10668
10671
  tool: p,
10669
10672
  data: c.data
10670
- } : (j(`Tool «${p}» is not found. Check 'tools' property at the Blok config.`, "warn"), {
10673
+ } : (Y(`Tool «${p}» is not found. Check 'tools' property at the Blok config.`, "warn"), {
10671
10674
  tool: o.stubTool,
10672
10675
  data: this.composeStubDataForTool(p, c.data, h)
10673
10676
  });
@@ -10756,7 +10759,7 @@ class yi extends T {
10756
10759
  } catch (s) {
10757
10760
  this.lastSaveError = s;
10758
10761
  const i = s instanceof Error ? s : new Error(String(s));
10759
- j("Saving failed due to the Error %o", "error", i);
10762
+ Y("Saving failed due to the Error %o", "error", i);
10760
10763
  return;
10761
10764
  }
10762
10765
  }
@@ -1,4 +1,4 @@
1
- import { e as i } from "./blok-JdFwSTgC.mjs";
1
+ import { e as i } from "./blok-CU-oiynu.mjs";
2
2
  const l = async (e, r) => {
3
3
  const n = (await import("./i18next-CugVlwWp.mjs")).default.createInstance(), s = {
4
4
  lng: e,
@@ -1,4 +1,4 @@
1
- import { t as f, q as i } from "./inline-tool-convert-MJUgGURB.mjs";
1
+ import { t as f, q as i } from "./inline-tool-convert-rak34pCi.mjs";
2
2
  const a = {
3
3
  wrapper: i(
4
4
  "fixed z-[2] bottom-5 left-5",
@@ -18,7 +18,7 @@ let nt = (o = 21) => {
18
18
  return t;
19
19
  };
20
20
  var ot = /* @__PURE__ */ ((o) => (o.VERBOSE = "VERBOSE", o.INFO = "INFO", o.WARN = "WARN", o.ERROR = "ERROR", o))(ot || {});
21
- const rt = () => "0.4.3-beta.8", Ct = {
21
+ const rt = () => "0.4.3-beta.9", Ct = {
22
22
  BACKSPACE: 8,
23
23
  TAB: 9,
24
24
  ENTER: 13,
package/dist/full.mjs CHANGED
@@ -10,10 +10,10 @@ var e = (a, l, o) => l in a ? n(a, l, { enumerable: !0, configurable: !0, writab
10
10
  d.call(l, o) && e(a, o, l[o]);
11
11
  return a;
12
12
  }, r = (a, l) => t(a, c(l));
13
- import { B as v, v as A } from "./chunks/blok-JdFwSTgC.mjs";
13
+ import { B as v, v as A } from "./chunks/blok-CU-oiynu.mjs";
14
14
  import { List as p, Header as f, Paragraph as I, Link as k, Italic as u, Bold as B } from "./tools.mjs";
15
15
  import { defaultBlockTools as H, defaultInlineTools as P } from "./tools.mjs";
16
- import { D as _ } from "./chunks/inline-tool-convert-MJUgGURB.mjs";
16
+ import { D as _ } from "./chunks/inline-tool-convert-rak34pCi.mjs";
17
17
  const m = {
18
18
  paragraph: {
19
19
  class: I,
package/dist/tools.mjs CHANGED
@@ -10,8 +10,8 @@ var U = (f, t, e) => t in f ? rt(f, t, { enumerable: !0, configurable: !0, writa
10
10
  at.call(t, e) && U(f, e, t[e]);
11
11
  return f;
12
12
  }, P = (f, t) => st(f, ot(t));
13
- import { t as L, D as g, a9 as nt, aa as lt, ab as G, ac as ct, ad as dt, ae as ut, af as ht, ag as ft, ah as pt, ai as j, aj as $, ak as X, f as A, al as gt, am as mt, S as H, P as Et, an as Tt, l as Ct, J as At } from "./chunks/inline-tool-convert-MJUgGURB.mjs";
14
- import { a0 as Ot } from "./chunks/inline-tool-convert-MJUgGURB.mjs";
13
+ import { t as L, D as g, a9 as nt, aa as lt, ab as G, ac as ct, ad as dt, ae as ut, af as ht, ag as ft, ah as pt, ai as j, aj as $, ak as X, f as A, al as gt, am as mt, S as H, P as Et, an as Tt, l as Ct, J as At } from "./chunks/inline-tool-convert-rak34pCi.mjs";
14
+ import { a0 as Ot } from "./chunks/inline-tool-convert-rak34pCi.mjs";
15
15
  const W = [
16
16
  "empty:before:pointer-events-none",
17
17
  "empty:before:text-gray-text",
@@ -288,17 +288,17 @@ const x = class x {
288
288
  * @returns MenuConfig array
289
289
  */
290
290
  renderSettings() {
291
- const t = this._settings._toolboxEntries;
292
- return t !== void 0 && t.length > 0 ? this.buildSettingsFromToolboxEntries(t) : this.levels.map((e) => {
293
- const n = this.api.i18n.t(e.nameKey), r = n !== e.nameKey ? n : e.name;
291
+ const t = this._settings._toolboxEntries, e = (t == null ? void 0 : t.length) === 1 && t[0].data === void 0;
292
+ return t !== void 0 && t.length > 0 && !e ? this.buildSettingsFromToolboxEntries(t) : this.levels.map((n) => {
293
+ const r = this.api.i18n.t(n.nameKey), s = r !== n.nameKey ? r : n.name;
294
294
  return {
295
- icon: e.icon,
296
- title: r,
297
- onActivate: () => this.setLevel(e.number),
295
+ icon: n.icon,
296
+ title: s,
297
+ onActivate: () => this.setLevel(n.number),
298
298
  closeOnActivate: !0,
299
- isActive: this.currentLevel.number === e.number,
299
+ isActive: this.currentLevel.number === n.number,
300
300
  dataset: {
301
- "blok-header-level": String(e.number)
301
+ "blok-header-level": String(n.number)
302
302
  }
303
303
  };
304
304
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jackuait/blok",
3
- "version": "0.4.3-beta.8",
3
+ "version": "0.4.3-beta.9",
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",
@@ -116,11 +116,29 @@ export class RectangleSelection extends Module {
116
116
  * Init rect params
117
117
  * @param {number} pageX - X coord of mouse
118
118
  * @param {number} pageY - Y coord of mouse
119
+ * @param {boolean} shiftKey - whether Shift key is held for additive selection
119
120
  */
120
- public startSelection(pageX: number, pageY: number): void {
121
- const scrollLeft = this.getScrollLeft();
121
+ public startSelection(pageX: number, pageY: number, shiftKey = false): void {
122
+ const { UI } = this.Blok;
123
+ const redactor = UI.nodes.redactor;
124
+
125
+ if (!redactor) {
126
+ return;
127
+ }
128
+
129
+ const editorRect = redactor.getBoundingClientRect();
122
130
  const scrollTop = this.getScrollTop();
123
- const elemWhereSelectionStart = document.elementFromPoint(pageX - scrollLeft, pageY - scrollTop);
131
+ const pointerY = pageY - scrollTop;
132
+
133
+ // Check if pointer is within editor's vertical bounds
134
+ const withinEditorVertically = pointerY >= editorRect.top && pointerY <= editorRect.bottom;
135
+
136
+ if (!withinEditorVertically) {
137
+ return;
138
+ }
139
+
140
+ const scrollLeft = this.getScrollLeft();
141
+ const elemWhereSelectionStart = document.elementFromPoint(pageX - scrollLeft, pointerY);
124
142
 
125
143
  if (!elemWhereSelectionStart) {
126
144
  return;
@@ -132,7 +150,11 @@ export class RectangleSelection extends Module {
132
150
  */
133
151
  const startsInsideToolbar = elemWhereSelectionStart.closest(createSelector(DATA_ATTR.toolbar));
134
152
 
135
- if (!startsInsideToolbar) {
153
+ /**
154
+ * When Shift is held, preserve existing selection for additive behavior.
155
+ * Otherwise, clear selection state.
156
+ */
157
+ if (!startsInsideToolbar && !shiftKey) {
136
158
  this.Blok.BlockSelection.allBlocksSelected = false;
137
159
  this.clearSelection();
138
160
  this.stackOfSelected = [];
@@ -144,13 +166,12 @@ export class RectangleSelection extends Module {
144
166
  INLINE_TOOLBAR_INTERFACE_SELECTOR,
145
167
  ];
146
168
 
147
- const startsInsideBlok = elemWhereSelectionStart.closest(createSelector(DATA_ATTR.editor));
148
169
  const startsInSelectorToAvoid = selectorsToAvoid.some((selector) => !!elemWhereSelectionStart.closest(selector));
149
170
 
150
171
  /**
151
- * If selection starts outside of the blok or inside the blocks or on Blok UI elements, do not handle it
172
+ * If selection starts inside the blocks content or on Blok UI elements, do not handle it
152
173
  */
153
- if (!startsInsideBlok || startsInSelectorToAvoid) {
174
+ if (startsInSelectorToAvoid) {
154
175
  return;
155
176
  }
156
177
 
@@ -194,9 +215,9 @@ export class RectangleSelection extends Module {
194
215
  * Sets Module necessary event handlers
195
216
  */
196
217
  private enableModuleBindings(): void {
197
- const { container } = this.genHTML();
218
+ this.genHTML();
198
219
 
199
- this.listeners.on(container, 'mousedown', (event: Event) => {
220
+ this.listeners.on(document.body, 'mousedown', (event: Event) => {
200
221
  this.processMouseDown(event as MouseEvent);
201
222
  }, false);
202
223
 
@@ -245,7 +266,7 @@ export class RectangleSelection extends Module {
245
266
  const startedFromContentEditable = (mouseEvent.target as Element).closest($.allInputsSelector) !== null;
246
267
 
247
268
  if (!startedFromContentEditable) {
248
- this.startSelection(mouseEvent.pageX, mouseEvent.pageY);
269
+ this.startSelection(mouseEvent.pageX, mouseEvent.pageY, mouseEvent.shiftKey);
249
270
  }
250
271
  }
251
272
 
@@ -402,13 +423,12 @@ export class RectangleSelection extends Module {
402
423
  this.mouseY = event.pageY;
403
424
  }
404
425
 
405
- const { rightPos, leftPos, index } = this.genInfoForMouseSelection();
406
- // There is not new block in selection
426
+ const { index } = this.genInfoForMouseSelection();
407
427
 
408
- const rectIsOnRighSideOfredactor = this.startX > rightPos && this.mouseX > rightPos;
409
- const rectISOnLeftSideOfRedactor = this.startX < leftPos && this.mouseX < leftPos;
410
-
411
- this.rectCrossesBlocks = !(rectIsOnRighSideOfredactor || rectISOnLeftSideOfRedactor);
428
+ // For page-wide selection: always consider the rectangle as crossing blocks
429
+ // if we have a valid block index. The vertical check in startSelection()
430
+ // already ensures we're within the editor's vertical bounds.
431
+ this.rectCrossesBlocks = index !== undefined;
412
432
 
413
433
  if (!this.isRectSelectionActivated) {
414
434
  this.rectCrossesBlocks = false;
@@ -517,6 +537,7 @@ export class RectangleSelection extends Module {
517
537
 
518
538
  /**
519
539
  * Collects information needed to determine the behavior of the rectangle
540
+ * For page-wide selection, we check blocks at the center X position but at the actual mouse Y position
520
541
  * @returns {object} index - index next Block, leftPos - start of left border of Block, rightPos - right border
521
542
  */
522
543
  private genInfoForMouseSelection(): {index: number | undefined; leftPos: number; rightPos: number} {
@@ -524,6 +545,9 @@ export class RectangleSelection extends Module {
524
545
  const centerOfRedactor = widthOfRedactor / 2;
525
546
  const scrollTop = this.getScrollTop();
526
547
  const y = this.mouseY - scrollTop;
548
+
549
+ // For page-wide selection: check what block is at the center X, but at the mouse's Y position
550
+ // This allows selection to work even when mouse is in the left/right margins
527
551
  const elementUnderMouse = document.elementFromPoint(centerOfRedactor, y);
528
552
  const lastBlockHolder = this.Blok.BlockManager.lastBlock?.holder;
529
553
  const contentElement = lastBlockHolder?.querySelector(createSelector(DATA_ATTR.elementContent));
@@ -206,9 +206,16 @@ export class Header implements BlockTool {
206
206
  /**
207
207
  * If user provided custom toolbox entries, use them to build settings menu.
208
208
  * This ensures block settings match the toolbox configuration.
209
- * Fall back to levels config only when _toolboxEntries is empty.
209
+ * Entries without explicit level data will default to the configured defaultLevel.
210
+ *
211
+ * Only fall back to levels config when _toolboxEntries is not provided or empty,
212
+ * or when using the default single "Heading" toolbox entry (detected by having
213
+ * exactly one entry with no level data).
210
214
  */
211
- if (toolboxEntries !== undefined && toolboxEntries.length > 0) {
215
+ const isDefaultToolboxEntry = toolboxEntries?.length === 1 &&
216
+ toolboxEntries[0].data === undefined;
217
+
218
+ if (toolboxEntries !== undefined && toolboxEntries.length > 0 && !isDefaultToolboxEntry) {
212
219
  return this.buildSettingsFromToolboxEntries(toolboxEntries);
213
220
  }
214
221