fable-editor 1.2.2 → 1.2.3

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.
@@ -407,7 +407,7 @@ const it = "undo redo | preview print | importword revhistory | fontfamily fonts
407
407
  ["Verdana", "verdana,geneva"],
408
408
  ["Webdings", "webdings"],
409
409
  ["Wingdings", "wingdings,zapf dingbats"]
410
- ], ot = ["8px", "9px", "10px", "11px", "12px", "14px", "16px", "18px", "20px", "24px", "28px", "32px", "36px", "48px", "72px", "96px"], nt = 1, rt = 100, _ = ["1", "1.15", "1.4", "1.5", "1.75", "2", "2.5", "3"], V = ["1px", "2px", "4px", "6px", "8px", "12px"], W = ["0.5px", "1px", "1.5px", "2px", "3px", "4px"], U = [
410
+ ], ot = ["8px", "9px", "10px", "11px", "12px", "14px", "16px", "18px", "20px", "24px", "28px", "32px", "36px", "48px", "72px", "96px"], nt = 1, rt = 100, _ = ["1", "1.15", "1.4", "1.5", "1.75", "2", "2.5", "3"], U = ["1px", "2px", "4px", "6px", "8px", "12px"], V = ["0.5px", "1px", "1.5px", "2px", "3px", "4px"], W = [
411
411
  ["plain", "Plain text"],
412
412
  ["html", "HTML/XML"],
413
413
  ["css", "CSS"],
@@ -1524,7 +1524,7 @@ const it = "undo redo | preview print | importword revhistory | fontfamily fonts
1524
1524
  "🇲🇦"
1525
1525
  ]
1526
1526
  }
1527
- ], Zt = [
1527
+ ], Nt = [
1528
1528
  "©",
1529
1529
  "®",
1530
1530
  "™",
@@ -1810,7 +1810,7 @@ const it = "undo redo | preview print | importword revhistory | fontfamily fonts
1810
1810
  codesampleic: y(
1811
1811
  '<rect x="3.5" y="4" width="17" height="16" rx="2"/><path d="M3.5 8.5h17"/><path d="M9.5 12 7 14.25l2.5 2.25M14.5 12l2.5 2.25-2.5 2.25"/>'
1812
1812
  )
1813
- }, Nt = (p) => `<span class="txt">${p}</span>`, pt = /* @__PURE__ */ new Set([
1813
+ }, Zt = (p) => `<span class="txt">${p}</span>`, pt = /* @__PURE__ */ new Set([
1814
1814
  "p",
1815
1815
  "div",
1816
1816
  "span",
@@ -1954,8 +1954,8 @@ function ft(p) {
1954
1954
  if (!l.length || l[l.length - 1].level < c) {
1955
1955
  const w = p.createElement(m ? "ol" : "ul");
1956
1956
  if (m && g && (w.style.listStyleType = g), l.length) {
1957
- const k = l[l.length - 1].list;
1958
- (k.lastElementChild || k).appendChild(w);
1957
+ const H = l[l.length - 1].list;
1958
+ (H.lastElementChild || H).appendChild(w);
1959
1959
  } else
1960
1960
  o.parentNode.insertBefore(w, o);
1961
1961
  l.push({ list: w, level: c });
@@ -1991,7 +1991,7 @@ function bt(p) {
1991
1991
  e.style.backgroundColor = e.style.backgroundColor || e.getAttribute("bgcolor"), e.removeAttribute("bgcolor");
1992
1992
  });
1993
1993
  }
1994
- function N(p, t) {
1994
+ function Z(p, t) {
1995
1995
  Array.from(p.childNodes).forEach((e) => {
1996
1996
  if (e.nodeType === Node.COMMENT_NODE) {
1997
1997
  e.remove();
@@ -2017,10 +2017,10 @@ function N(p, t) {
2017
2017
  h[c] && (r.style.fontSize = h[c]);
2018
2018
  }
2019
2019
  for (; i.firstChild; ) r.appendChild(i.firstChild);
2020
- i.replaceWith(r), N(r, t);
2020
+ i.replaceWith(r), Z(r, t);
2021
2021
  return;
2022
2022
  }
2023
- for (N(i, t); i.firstChild; ) i.parentNode.insertBefore(i.firstChild, i);
2023
+ for (Z(i, t); i.firstChild; ) i.parentNode.insertBefore(i.firstChild, i);
2024
2024
  i.remove();
2025
2025
  return;
2026
2026
  }
@@ -2043,7 +2043,7 @@ function N(p, t) {
2043
2043
  const o = D(i), n = [];
2044
2044
  for (const [r, c] of Object.entries(o))
2045
2045
  mt.has(r) && (/expression|javascript|url\s*\(\s*['"]?\s*file:/i.test(c) || r === "font-weight" && /^(400|normal)$/i.test(c) || r === "font-style" && /^normal$/i.test(c) || r === "text-decoration" && /^none$/i.test(c) || n.push(r + ":" + c));
2046
- if (n.length ? i.setAttribute("style", n.join(";")) : i.removeAttribute("style"), i.removeAttribute("class"), N(i, t), s === "span" && !i.attributes.length) {
2046
+ if (n.length ? i.setAttribute("style", n.join(";")) : i.removeAttribute("style"), i.removeAttribute("class"), Z(i, t), s === "span" && !i.attributes.length) {
2047
2047
  for (; i.firstChild; ) i.parentNode.insertBefore(i.firstChild, i);
2048
2048
  i.remove();
2049
2049
  }
@@ -2101,7 +2101,7 @@ function Ct(p) {
2101
2101
  }
2102
2102
  function wt(p, t = "ltr") {
2103
2103
  const e = yt(p), i = new DOMParser().parseFromString(ut(p), "text/html");
2104
- xt(i, e), /class="?Mso|mso-|urn:schemas-microsoft-com/i.test(i.body.innerHTML) && ft(i), vt(i), bt(i), N(i.body, i), Ct(i);
2104
+ xt(i, e), /class="?Mso|mso-|urn:schemas-microsoft-com/i.test(i.body.innerHTML) && ft(i), vt(i), bt(i), Z(i.body, i), Ct(i);
2105
2105
  const s = (l) => {
2106
2106
  var o;
2107
2107
  return l && l.tagName === "P" && !((o = l.textContent) != null && o.trim()) && !l.querySelector("img,table");
@@ -2292,7 +2292,7 @@ class Lt {
2292
2292
  return e + "</tbody></table>";
2293
2293
  }
2294
2294
  }
2295
- async function Ht(p) {
2295
+ async function kt(p) {
2296
2296
  const t = p instanceof ArrayBuffer ? p : await p.arrayBuffer(), e = Mt(t), i = new TextDecoder(), s = async (u) => {
2297
2297
  const v = e.get(u);
2298
2298
  return v ? new DOMParser().parseFromString(i.decode(await Q(t, v)), "application/xml") : null;
@@ -2340,7 +2340,7 @@ async function Ht(p) {
2340
2340
  }
2341
2341
  return new Lt(r, d, m).convertBody(n);
2342
2342
  }
2343
- const kt = ["nw", "ne", "sw", "se"], F = ["img-left", "img-right", "img-top", "img-center"], O = {
2343
+ const Ht = ["nw", "ne", "sw", "se"], O = ["img-left", "img-right", "img-top", "img-center"], F = {
2344
2344
  "img-left": "tplimgleft",
2345
2345
  "img-right": "tplimgright",
2346
2346
  "img-top": "tplimgtop",
@@ -2352,7 +2352,7 @@ const kt = ["nw", "ne", "sw", "se"], F = ["img-left", "img-right", "img-top", "i
2352
2352
  "img-center": a.tplcenter
2353
2353
  }, At = ".tox,.pop,.tblctx,.imgctx,.selctx,.dlg";
2354
2354
  let E = null, I = null, $ = 0, K = !1;
2355
- function Z() {
2355
+ function N() {
2356
2356
  clearTimeout($), I = null, E && E.classList.remove("show");
2357
2357
  }
2358
2358
  function qt(p) {
@@ -2374,14 +2374,14 @@ function Bt() {
2374
2374
  K || (K = !0, document.addEventListener("mouseover", (p) => {
2375
2375
  const t = p.target, e = t.closest ? t.closest("[title],[data-tip]") : null;
2376
2376
  if (!e || !e.closest(At) || e.closest(".earea")) {
2377
- e !== I && Z();
2377
+ e !== I && N();
2378
2378
  return;
2379
2379
  }
2380
2380
  const i = e.getAttribute("title");
2381
2381
  i && (e.dataset.tip = i, e.removeAttribute("title"), e.getAttribute("aria-label") || e.setAttribute("aria-label", i)), e !== I && qt(e);
2382
2382
  }), document.addEventListener("mouseout", (p) => {
2383
- I && !I.contains(p.relatedTarget) && Z();
2384
- }), document.addEventListener("mousedown", Z, !0), addEventListener("scroll", Z, !0));
2383
+ I && !I.contains(p.relatedTarget) && N();
2384
+ }), document.addEventListener("mousedown", N, !0), addEventListener("scroll", N, !0));
2385
2385
  }
2386
2386
  const A = class A {
2387
2387
  constructor(t) {
@@ -2466,7 +2466,7 @@ const A = class A {
2466
2466
  }), this.on(this.ed, "input", () => {
2467
2467
  this.refreshState(), this.onChange(), this.positionTableHandles(), this.positionImageHandles(), this.positionImgPhCtx(), this.positionTplCtx(), this.positionVphCtx(), this.positionVidCtx(), this.positionCodeCtx();
2468
2468
  }), this.on(this.ed, "keydown", (t) => {
2469
- t.altKey && t.key === "0" && (t.preventDefault(), this.helpDlg()), (t.key === "Delete" || t.key === "Backspace") && this.phActive && (t.preventDefault(), this.removeImgPlaceholder()), (t.key === "Delete" || t.key === "Backspace") && this.vphActive && (t.preventDefault(), this.removeVphPlaceholder()), t.key === "`" && !t.ctrlKey && !t.metaKey && !t.altKey && this.tryCodeTyping(t);
2469
+ t.altKey && t.key === "0" && (t.preventDefault(), this.helpDlg()), (t.key === "Delete" || t.key === "Backspace") && this.phActive && (t.preventDefault(), this.removeImgPlaceholder()), (t.key === "Delete" || t.key === "Backspace") && this.vphActive && (t.preventDefault(), this.removeVphPlaceholder()), t.key === "`" && !t.ctrlKey && !t.metaKey && !t.altKey && this.tryCodeTyping(t), t.key === "Enter" && !t.shiftKey && !t.ctrlKey && !t.metaKey && !t.altKey && this.tryExitBlockquote(t);
2470
2470
  }), this.on(this.ed, "paste", (t) => this.handlePaste(t)), this.on(this.ed, "drop", (t) => {
2471
2471
  var l, o, n, r;
2472
2472
  t.preventDefault();
@@ -2590,7 +2590,7 @@ const A = class A {
2590
2590
  this.ed.focus();
2591
2591
  }
2592
2592
  async importWordFile(t) {
2593
- const e = await Ht(t);
2593
+ const e = await kt(t);
2594
2594
  this.recordRevision(), this.setContent(e), this.recordRevision();
2595
2595
  }
2596
2596
  restoreDraft() {
@@ -2638,6 +2638,20 @@ const A = class A {
2638
2638
  }
2639
2639
  return null;
2640
2640
  }
2641
+ /** Enter on an empty last line inside a blockquote exits it into a plain paragraph, mirroring how lists exit on an empty item. */
2642
+ tryExitBlockquote(t) {
2643
+ const e = window.getSelection();
2644
+ if (!e || !e.isCollapsed || !e.anchorNode || !this.ed.contains(e.anchorNode)) return;
2645
+ const i = this.closestBlock(e.anchorNode);
2646
+ if (!i || i.tagName === "BLOCKQUOTE" || (i.textContent || "").trim() !== "") return;
2647
+ const s = i.closest("blockquote");
2648
+ if (!s || !this.ed.contains(s) || i !== s.lastElementChild) return;
2649
+ t.preventDefault();
2650
+ const l = document.createElement("p");
2651
+ l.appendChild(document.createElement("br")), s.after(l), i.remove(), s.firstElementChild || s.remove();
2652
+ const o = document.createRange();
2653
+ o.setStart(l, 0), o.collapse(!0), e.removeAllRanges(), e.addRange(o), this.saveSel(), this.onChange();
2654
+ }
2641
2655
  selectedBlocks() {
2642
2656
  const t = window.getSelection();
2643
2657
  if (!t || !t.rangeCount || !this.ed.contains(t.anchorNode)) return [];
@@ -3005,10 +3019,10 @@ const A = class A {
3005
3019
  this.popup(t, (e) => this.menuItems(e, this.blockStyleItems("lineHeight", _)));
3006
3020
  }
3007
3021
  wordSpacingMenu(t) {
3008
- this.popup(t, (e) => this.menuItems(e, this.blockStyleItems("wordSpacing", V)));
3022
+ this.popup(t, (e) => this.menuItems(e, this.blockStyleItems("wordSpacing", U)));
3009
3023
  }
3010
3024
  letterSpacingMenu(t) {
3011
- this.popup(t, (e) => this.menuItems(e, this.blockStyleItems("letterSpacing", W)));
3025
+ this.popup(t, (e) => this.menuItems(e, this.blockStyleItems("letterSpacing", V)));
3012
3026
  }
3013
3027
  closestAnchor() {
3014
3028
  const t = window.getSelection();
@@ -3302,8 +3316,8 @@ const A = class A {
3302
3316
  { label: this.t("blocks"), subBuild: (s) => this.menuItems(s, this.blockItems()) },
3303
3317
  { label: this.t("align"), subBuild: (s) => this.menuItems(s, this.alignItems()) },
3304
3318
  { label: this.t("lineheight"), icon: a.lineheight, subBuild: (s) => this.menuItems(s, this.blockStyleItems("lineHeight", _)) },
3305
- { label: this.t("wordspacing"), icon: a.wordspacing, subBuild: (s) => this.menuItems(s, this.blockStyleItems("wordSpacing", V)) },
3306
- { label: this.t("letterspacing"), icon: a.letterspacing, subBuild: (s) => this.menuItems(s, this.blockStyleItems("letterSpacing", W)) },
3319
+ { label: this.t("wordspacing"), icon: a.wordspacing, subBuild: (s) => this.menuItems(s, this.blockStyleItems("wordSpacing", U)) },
3320
+ { label: this.t("letterspacing"), icon: a.letterspacing, subBuild: (s) => this.menuItems(s, this.blockStyleItems("letterSpacing", V)) },
3307
3321
  "|",
3308
3322
  { label: this.t("forecolor"), icon: a.palette, subBuild: (s) => this.buildPaletteInto(s, this.foreColor, (l) => this.applyColor("fore", l)) },
3309
3323
  { label: this.t("backcolor"), icon: a.backcolor, subBuild: (s) => this.buildPaletteInto(s, this.backColor, (l) => this.applyColor("back", l)) },
@@ -3481,20 +3495,20 @@ const A = class A {
3481
3495
  this.dialog(
3482
3496
  this.t("tablepropsttl"),
3483
3497
  (C) => {
3484
- const M = (w, k) => {
3498
+ const M = (w, H) => {
3485
3499
  const L = document.createElement("div");
3486
3500
  L.style.cssText = n;
3487
- const H = document.createElement("span");
3488
- H.style.cssText = r, H.textContent = this.t(w), L.append(H, k), C.appendChild(L);
3501
+ const k = document.createElement("span");
3502
+ k.style.cssText = r, k.textContent = this.t(w), L.append(k, H), C.appendChild(L);
3489
3503
  };
3490
3504
  e = document.createElement("input"), e.type = "text", e.style.cssText = c, e.placeholder = "e.g. 600px or 100%", e.value = d, M("tblwidth", e), i = document.createElement("input"), i.type = "number", i.min = "0", i.style.cssText = c, i.value = String(m), M("tblcellpadding", i), s = document.createElement("input"), s.type = "number", s.min = "0", s.style.cssText = c, s.value = String(g), M("tblcellspacing", s), l = document.createElement("input"), l.type = "number", l.min = "0", l.style.cssText = c, l.value = String(u), M("tblborder", l), o = document.createElement("select"), o.style.cssText = c, [
3491
3505
  ["", "alignnone"],
3492
3506
  ["left", "alignleft"],
3493
3507
  ["center", "aligncenter"],
3494
3508
  ["right", "alignright"]
3495
- ].forEach(([w, k]) => {
3509
+ ].forEach(([w, H]) => {
3496
3510
  const L = document.createElement("option");
3497
- L.value = w, L.textContent = this.t(k), w === x && (L.selected = !0), o.appendChild(L);
3511
+ L.value = w, L.textContent = this.t(H), w === x && (L.selected = !0), o.appendChild(L);
3498
3512
  }), M("tblalign", o);
3499
3513
  },
3500
3514
  [
@@ -4086,17 +4100,17 @@ const A = class A {
4086
4100
  const w = (L = C.files) == null ? void 0 : L[0];
4087
4101
  if (!w) return;
4088
4102
  x.disabled = !0, x.textContent = this.t("uploading");
4089
- const k = (H) => {
4090
- t.value = H, x.disabled = !1, x.textContent = this.t("uploadvideo");
4103
+ const H = (k) => {
4104
+ t.value = k, x.disabled = !1, x.textContent = this.t("uploadvideo");
4091
4105
  };
4092
4106
  if (this.videoUploadHandler)
4093
- this.videoUploadHandler(w).then(k).catch((H) => {
4107
+ this.videoUploadHandler(w).then(H).catch((k) => {
4094
4108
  var z;
4095
- x.disabled = !1, x.textContent = this.t("uploadfailed"), (z = this.onVideoUploadError) == null || z.call(this, H, w);
4109
+ x.disabled = !1, x.textContent = this.t("uploadfailed"), (z = this.onVideoUploadError) == null || z.call(this, k, w);
4096
4110
  });
4097
4111
  else {
4098
- const H = new FileReader();
4099
- H.onload = () => k(H.result), H.readAsDataURL(w);
4112
+ const k = new FileReader();
4113
+ k.onload = () => H(k.result), k.readAsDataURL(w);
4100
4114
  }
4101
4115
  }), b.append(t, x, C), t.style.flex = "1", v.appendChild(n("vidsource", b));
4102
4116
  const M = document.createElement("div");
@@ -4238,7 +4252,7 @@ const A = class A {
4238
4252
  const l = document.createElement("div");
4239
4253
  l.className = "dfield";
4240
4254
  const o = document.createElement("label");
4241
- o.textContent = this.t("codelang"), e = this.dlgSelect(U, (t == null ? void 0 : t.dataset.lang) || "plain"), l.append(o, e.el), i = document.createElement("textarea"), i.className = "code-input", i.spellcheck = !1, i.value = ((n = t == null ? void 0 : t.querySelector("code")) == null ? void 0 : n.textContent) || "", i.placeholder = "const answer = 42;", s.append(l, i), setTimeout(() => i.focus(), 0);
4255
+ o.textContent = this.t("codelang"), e = this.dlgSelect(W, (t == null ? void 0 : t.dataset.lang) || "plain"), l.append(o, e.el), i = document.createElement("textarea"), i.className = "code-input", i.spellcheck = !1, i.value = ((n = t == null ? void 0 : t.querySelector("code")) == null ? void 0 : n.textContent) || "", i.placeholder = "const answer = 42;", s.append(l, i), setTimeout(() => i.focus(), 0);
4242
4256
  },
4243
4257
  [
4244
4258
  { label: this.t("cancel"), action: () => this.closeDlg() },
@@ -4247,7 +4261,7 @@ const A = class A {
4247
4261
  primary: !0,
4248
4262
  action: () => {
4249
4263
  var n;
4250
- const s = i.value.replace(/\s+$/, ""), l = e.value(), o = ((n = U.find(([r]) => r === l)) == null ? void 0 : n[1]) || l;
4264
+ const s = i.value.replace(/\s+$/, ""), l = e.value(), o = ((n = W.find(([r]) => r === l)) == null ? void 0 : n[1]) || l;
4251
4265
  if (this.closeDlg(), !!s.trim()) {
4252
4266
  if (t) {
4253
4267
  t.dataset.lang = l, t.setAttribute("data-lang-label", o);
@@ -4320,9 +4334,9 @@ const A = class A {
4320
4334
  }
4321
4335
  buildTemplatePickInto(t, e) {
4322
4336
  const i = document.createElement("div");
4323
- i.className = "tplpick", F.forEach((s) => {
4337
+ i.className = "tplpick", O.forEach((s) => {
4324
4338
  const l = document.createElement("button");
4325
- l.type = "button", l.className = "tpltile", l.title = this.t(O[s]), l.innerHTML = this.tplPreviewHTML(s) + `<span class="tpllbl">${this.t(O[s])}</span>`, l.addEventListener("click", () => {
4339
+ l.type = "button", l.className = "tpltile", l.title = this.t(F[s]), l.innerHTML = this.tplPreviewHTML(s) + `<span class="tpllbl">${this.t(F[s])}</span>`, l.addEventListener("click", () => {
4326
4340
  this.closePop(), this.insertTemplate(s), e == null || e();
4327
4341
  }), i.appendChild(l);
4328
4342
  }), t.appendChild(i);
@@ -4341,15 +4355,15 @@ const A = class A {
4341
4355
  }
4342
4356
  renderTplCtxButtons() {
4343
4357
  const t = this.tplCtx, e = this.tplActive;
4344
- !t || !e || (t.innerHTML = "", F.forEach((i) => {
4345
- const s = this.ctxBtn(It[i], this.t(O[i]), () => this.setTplLayout(i));
4358
+ !t || !e || (t.innerHTML = "", O.forEach((i) => {
4359
+ const s = this.ctxBtn(It[i], this.t(F[i]), () => this.setTplLayout(i));
4346
4360
  s.classList.toggle("on", e.classList.contains("tpl-" + i)), t.appendChild(s);
4347
4361
  }), t.append(this.ctxSep(), this.ctxBtn(a.trash, this.t("deltemplate"), () => this.removeTemplate())), this.positionTplCtx());
4348
4362
  }
4349
4363
  setTplLayout(t) {
4350
4364
  const e = this.tplActive;
4351
4365
  if (!e) return;
4352
- F.forEach((l) => e.classList.remove("tpl-" + l)), e.classList.add("tpl-" + t);
4366
+ O.forEach((l) => e.classList.remove("tpl-" + l)), e.classList.add("tpl-" + t);
4353
4367
  const i = e.querySelector(":scope > .tpl-media"), s = e.querySelector(":scope > .tpl-text");
4354
4368
  i && s && (t === "img-center" ? e.appendChild(i) : e.insertBefore(i, s)), this.renderTplCtxButtons(), this.positionImgPhCtx(), this.positionImageHandles(), this.onChange();
4355
4369
  }
@@ -4525,7 +4539,7 @@ const A = class A {
4525
4539
  this.cancelImgHide(), this.imgHandles.forEach((i) => i.remove()), this.imgHandles = [], (t = this.imgCtx) == null || t.remove(), this.imgCtx = null, (e = this.imgActive) == null || e.classList.remove("img-selected"), this.imgActive = null;
4526
4540
  }
4527
4541
  selectImage(t) {
4528
- this.imgActive !== t && (this.clearImageHandles(), this.imgActive = t, t.classList.add("img-selected"), this.imgHandles = kt.map((e) => {
4542
+ this.imgActive !== t && (this.clearImageHandles(), this.imgActive = t, t.classList.add("img-selected"), this.imgHandles = Ht.map((e) => {
4529
4543
  const i = document.createElement("div");
4530
4544
  return i.className = "img-handle img-handle-" + e, i.dataset.corner = e, i.addEventListener("mousedown", (s) => this.startImageResizeDrag(s, e)), i.addEventListener("mouseenter", () => this.cancelImgHide()), i.addEventListener("mouseleave", () => this.scheduleImgHide()), document.body.appendChild(i), i;
4531
4545
  }), this.imgCtx = this.buildImageCtxToolbar(t), this.positionImageHandles());
@@ -4622,7 +4636,22 @@ const A = class A {
4622
4636
  }
4623
4637
  /* ---------------------------------------------------------- selection bubble toolbar */
4624
4638
  toggleBlock(t) {
4625
- this.exec("formatBlock", this.currentBlock() === t ? "<p>" : "<" + t + ">");
4639
+ const e = this.currentBlock() === t;
4640
+ this.exec("formatBlock", e ? "<p>" : "<" + t + ">"), t === "blockquote" && e && this.unwrapBlockquote();
4641
+ }
4642
+ /** Some browsers leave the <blockquote> wrapper in place after formatBlock('<p>'); strip it manually if so. */
4643
+ unwrapBlockquote() {
4644
+ const t = window.getSelection();
4645
+ let e = t && this.ed.contains(t.anchorNode) ? t.anchorNode : null;
4646
+ for (; e && e !== this.ed; ) {
4647
+ if (e.nodeType === 1 && e.tagName === "BLOCKQUOTE") {
4648
+ const i = e, s = i.parentNode;
4649
+ for (; i.firstChild; ) s.insertBefore(i.firstChild, i);
4650
+ s.removeChild(i), this.onChange();
4651
+ return;
4652
+ }
4653
+ e = e.parentNode;
4654
+ }
4626
4655
  }
4627
4656
  clearSelToolbar() {
4628
4657
  var t;
@@ -4685,8 +4714,13 @@ const A = class A {
4685
4714
  currentBlock() {
4686
4715
  const t = window.getSelection();
4687
4716
  if (!t || !t.anchorNode || !this.ed.contains(t.anchorNode)) return "p";
4688
- const e = this.closestBlock(t.anchorNode);
4689
- return e ? e.tagName.toLowerCase().replace("div", "p") : "p";
4717
+ let e = t.anchorNode;
4718
+ for (; e && e !== this.ed; ) {
4719
+ if (e.nodeType === 1 && e.tagName === "BLOCKQUOTE") return "blockquote";
4720
+ e = e.parentNode;
4721
+ }
4722
+ const i = this.closestBlock(t.anchorNode);
4723
+ return i ? i.tagName.toLowerCase().replace("div", "p") : "p";
4690
4724
  }
4691
4725
  /** Element whose computed font reflects the current caret, falling back to the editor root before any selection lands inside it. */
4692
4726
  fontRefEl() {
@@ -4769,14 +4803,14 @@ A.instanceCounter = 0, A.TBR_COLLAPSE_MAX = 992;
4769
4803
  let J = A;
4770
4804
  export {
4771
4805
  j as BLOCKS,
4772
- Zt as CHARS,
4806
+ Nt as CHARS,
4773
4807
  ct as COLORS,
4774
4808
  lt as FONTS,
4775
4809
  J as FableEditor,
4776
4810
  et as I18N,
4777
4811
  a as IC,
4778
4812
  ot as SIZES,
4779
- Nt as TXT,
4813
+ Zt as TXT,
4780
4814
  wt as cleanPastedHTML,
4781
4815
  R as getStrings,
4782
4816
  Tt as normalizeTextPaste