fable-editor 1.2.7 → 1.2.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.
@@ -1917,7 +1917,7 @@ const st = "undo redo | preview print | importword revhistory | fontfamily fonts
1917
1917
  th: ["width", "valign"],
1918
1918
  table: ["width", "cellpadding", "cellspacing"]
1919
1919
  };
1920
- function P(p) {
1920
+ function D(p) {
1921
1921
  const t = {}, e = p.getAttribute && p.getAttribute("style");
1922
1922
  return e && e.split(";").forEach((i) => {
1923
1923
  const s = i.indexOf(":");
@@ -1954,13 +1954,13 @@ function vt(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 });
1962
1962
  }
1963
- const u = p.createElement("li"), v = P(n), b = ["text-align", "direction", "unicode-bidi", "color", "font-size", "font-family", "background-color"].filter((w) => v[w]).map((w) => w + ":" + v[w]).join(";");
1963
+ const u = p.createElement("li"), v = D(n), b = ["text-align", "direction", "unicode-bidi", "color", "font-size", "font-family", "background-color"].filter((w) => v[w]).map((w) => w + ":" + v[w]).join(";");
1964
1964
  for (b && u.setAttribute("style", b), n.getAttribute("dir") && u.setAttribute("dir", n.getAttribute("dir")); n.firstChild; ) u.appendChild(n.firstChild);
1965
1965
  l[l.length - 1].list.appendChild(u), n.remove();
1966
1966
  });
@@ -1975,7 +1975,7 @@ function bt(p) {
1975
1975
  function yt(p) {
1976
1976
  p.querySelectorAll("table").forEach((t) => {
1977
1977
  const e = t;
1978
- P(e)["border-collapse"] || (e.style.borderCollapse = "collapse");
1978
+ D(e)["border-collapse"] || (e.style.borderCollapse = "collapse");
1979
1979
  }), p.querySelectorAll("[align]").forEach((t) => {
1980
1980
  const e = t, i = e.getAttribute("align").toLowerCase();
1981
1981
  e.tagName.toLowerCase() === "table" ? i === "center" ? (e.style.marginLeft = e.style.marginLeft || "auto", e.style.marginRight = e.style.marginRight || "auto") : i === "right" ? e.style.marginLeft = e.style.marginLeft || "auto" : i === "left" && (e.style.marginRight = e.style.marginRight || "auto") : ["left", "right", "center", "justify"].includes(i) && (e.style.textAlign = e.style.textAlign || i, Array.from(e.children).forEach((s) => {
@@ -2040,7 +2040,7 @@ function Z(p, t) {
2040
2040
  return;
2041
2041
  }
2042
2042
  }
2043
- const o = P(i), n = [];
2043
+ const o = D(i), n = [];
2044
2044
  for (const [r, c] of Object.entries(o))
2045
2045
  ut.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
2046
  if (n.length ? i.setAttribute("style", n.join(";")) : i.removeAttribute("style"), i.removeAttribute("class"), Z(i, t), s === "span" && !i.attributes.length) {
@@ -2084,7 +2084,7 @@ function Ct(p, t) {
2084
2084
  });
2085
2085
  });
2086
2086
  }), e.forEach((i, s) => {
2087
- const l = P(s), o = s.hasAttribute("dir"), n = s.hasAttribute("align"), r = Object.entries(i).filter(([d]) => !(d in l || (d === "direction" || d === "unicode-bidi") && o || d === "text-align" && (n || o) || (d === "background" || d === "background-color") && s.hasAttribute("bgcolor")));
2087
+ const l = D(s), o = s.hasAttribute("dir"), n = s.hasAttribute("align"), r = Object.entries(i).filter(([d]) => !(d in l || (d === "direction" || d === "unicode-bidi") && o || d === "text-align" && (n || o) || (d === "background" || d === "background-color") && s.hasAttribute("bgcolor")));
2088
2088
  if (!r.length) return;
2089
2089
  const c = r.map(([d, m]) => d + ":" + m).join(";"), h = s.getAttribute("style");
2090
2090
  s.setAttribute("style", h ? c + ";" + h : c);
@@ -2114,7 +2114,7 @@ function Mt(p) {
2114
2114
  const t = tt(p).replace(/\r/g, ""), e = (i) => i.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
2115
2115
  return /\n/.test(t) ? t.split(/\n{2,}/).map((i) => `<p dir="auto">${e(i).replace(/\n/g, "<br>") || "<br>"}</p>`).join("") : e(t);
2116
2116
  }
2117
- function Et(p) {
2117
+ function St(p) {
2118
2118
  const t = new DataView(p), e = /* @__PURE__ */ new Map();
2119
2119
  let i = -1;
2120
2120
  for (let n = p.byteLength - 22; n >= Math.max(0, p.byteLength - 22 - 65535); n--)
@@ -2141,7 +2141,7 @@ async function Q(p, t) {
2141
2141
  const n = new Blob([o]).stream().pipeThrough(new DecompressionStream("deflate-raw"));
2142
2142
  return new Uint8Array(await new Response(n).arrayBuffer());
2143
2143
  }
2144
- const G = (p) => p.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;"), D = (p, t) => Array.from(p.children).filter((e) => e.localName === t), E = (p, ...t) => {
2144
+ const Y = (p) => p.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;"), P = (p, t) => Array.from(p.children).filter((e) => e.localName === t), S = (p, ...t) => {
2145
2145
  let e = p;
2146
2146
  for (const i of t) {
2147
2147
  if (!e) return null;
@@ -2154,11 +2154,11 @@ const G = (p) => p.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&
2154
2154
  if (e.localName === t) return e.value;
2155
2155
  return "";
2156
2156
  }, B = (p, t) => {
2157
- const e = p ? E(p, t) : null;
2157
+ const e = p ? S(p, t) : null;
2158
2158
  if (!e) return !1;
2159
2159
  const i = T(e);
2160
2160
  return i !== "false" && i !== "0";
2161
- }, Y = {
2161
+ }, G = {
2162
2162
  yellow: "#FFFF00",
2163
2163
  green: "#00FF00",
2164
2164
  cyan: "#00FFFF",
@@ -2175,7 +2175,7 @@ const G = (p) => p.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&
2175
2175
  lightGray: "#D3D3D3",
2176
2176
  black: "#000000",
2177
2177
  white: "#FFFFFF"
2178
- }, St = {
2178
+ }, Et = {
2179
2179
  png: "image/png",
2180
2180
  jpg: "image/jpeg",
2181
2181
  jpeg: "image/jpeg",
@@ -2189,7 +2189,7 @@ function Lt(p) {
2189
2189
  t += String.fromCharCode(...p.subarray(e, e + 32768));
2190
2190
  return btoa(t);
2191
2191
  }
2192
- class Ht {
2192
+ class kt {
2193
2193
  constructor(t, e, i) {
2194
2194
  this.rels = t, this.images = e, this.numFmt = i;
2195
2195
  }
@@ -2214,20 +2214,20 @@ class Ht {
2214
2214
  return s(0), e || "<p><br></p>";
2215
2215
  }
2216
2216
  paraList(t) {
2217
- const e = E(t, "pPr", "numPr");
2217
+ const e = S(t, "pPr", "numPr");
2218
2218
  if (!e) return null;
2219
- const i = T(E(e, "numId"));
2219
+ const i = T(S(e, "numId"));
2220
2220
  if (!i || i === "0") return null;
2221
- const s = parseInt(T(E(e, "ilvl")) || "0", 10) || 0;
2221
+ const s = parseInt(T(S(e, "ilvl")) || "0", 10) || 0;
2222
2222
  return { type: this.numFmt.get(i) || "ul", ilvl: Math.min(s, 8) };
2223
2223
  }
2224
2224
  convertPara(t) {
2225
- const e = E(t, "pPr"), i = T(E(t, "pPr", "pStyle"));
2225
+ const e = S(t, "pPr"), i = T(S(t, "pPr", "pStyle"));
2226
2226
  let s = "p";
2227
2227
  const l = /^Heading([1-6])$/i.exec(i);
2228
2228
  l ? s = "h" + l[1] : /^Title$/i.test(i) && (s = "h1");
2229
- const o = [], n = T(E(t, "pPr", "jc"));
2230
- n === "center" ? o.push("text-align:center") : n === "right" || n === "end" ? o.push("text-align:right") : (n === "both" || n === "distribute") && o.push("text-align:justify"), e && E(e, "bidi") && o.push("direction:rtl");
2229
+ const o = [], n = T(S(t, "pPr", "jc"));
2230
+ n === "center" ? o.push("text-align:center") : n === "right" || n === "end" ? o.push("text-align:right") : (n === "both" || n === "distribute") && o.push("text-align:justify"), e && S(e, "bidi") && o.push("direction:rtl");
2231
2231
  const r = this.runsOf(t), c = o.length ? ` style="${o.join(";")}"` : "";
2232
2232
  return `<${s}${c}>${r || "<br>"}</${s}>`;
2233
2233
  }
@@ -2240,25 +2240,25 @@ class Ht {
2240
2240
  const l = T(i, "anchor");
2241
2241
  !s && l && (s = "#" + l);
2242
2242
  const o = this.runsOf(i);
2243
- e += s ? `<a href="${G(s)}">${o}</a>` : o;
2243
+ e += s ? `<a href="${Y(s)}">${o}</a>` : o;
2244
2244
  } else (i.localName === "smartTag" || i.localName === "ins") && (e += this.runsOf(i));
2245
2245
  return e;
2246
2246
  }
2247
2247
  convertRun(t) {
2248
- const e = E(t, "rPr");
2248
+ const e = S(t, "rPr");
2249
2249
  let i = "";
2250
2250
  for (const d of Array.from(t.children))
2251
- d.localName === "t" ? i += G(d.textContent || "") : d.localName === "br" || d.localName === "cr" ? i += "<br>" : d.localName === "tab" ? i += "&emsp;" : (d.localName === "drawing" || d.localName === "pict" || d.localName === "object") && (i += this.convertImage(d));
2251
+ d.localName === "t" ? i += Y(d.textContent || "") : d.localName === "br" || d.localName === "cr" ? i += "<br>" : d.localName === "tab" ? i += "&emsp;" : (d.localName === "drawing" || d.localName === "pict" || d.localName === "object") && (i += this.convertImage(d));
2252
2252
  if (!i) return "";
2253
- const s = [], l = T(e ? E(e, "color") : null);
2253
+ const s = [], l = T(e ? S(e, "color") : null);
2254
2254
  l && l !== "auto" && s.push("color:#" + l);
2255
- const o = T(e ? E(e, "highlight") : null);
2256
- o && Y[o] && s.push("background-color:" + Y[o]);
2257
- const n = parseFloat(T(e ? E(e, "sz") : null));
2255
+ const o = T(e ? S(e, "highlight") : null);
2256
+ o && G[o] && s.push("background-color:" + G[o]);
2257
+ const n = parseFloat(T(e ? S(e, "sz") : null));
2258
2258
  n && s.push("font-size:" + Math.round(n / 2 * (4 / 3)) + "px");
2259
- const r = e ? E(e, "rFonts") : null, c = T(r, "ascii") || T(r, "cs");
2260
- c && s.push(`font-family:'${c}'`), s.length && (i = `<span style="${s.join(";")}">${i}</span>`), B(e, "b") && (i = `<strong>${i}</strong>`), B(e, "i") && (i = `<em>${i}</em>`), B(e, "u") && T(E(e, "u")) !== "none" && (i = `<u>${i}</u>`), B(e, "strike") && (i = `<s>${i}</s>`);
2261
- const h = T(e ? E(e, "vertAlign") : null);
2259
+ const r = e ? S(e, "rFonts") : null, c = T(r, "ascii") || T(r, "cs");
2260
+ c && s.push(`font-family:'${c}'`), s.length && (i = `<span style="${s.join(";")}">${i}</span>`), B(e, "b") && (i = `<strong>${i}</strong>`), B(e, "i") && (i = `<em>${i}</em>`), B(e, "u") && T(S(e, "u")) !== "none" && (i = `<u>${i}</u>`), B(e, "strike") && (i = `<s>${i}</s>`);
2261
+ const h = T(e ? S(e, "vertAlign") : null);
2262
2262
  return h === "superscript" ? i = `<sup>${i}</sup>` : h === "subscript" && (i = `<sub>${i}</sub>`), i;
2263
2263
  }
2264
2264
  convertImage(t) {
@@ -2278,10 +2278,10 @@ class Ht {
2278
2278
  }
2279
2279
  convertTable(t) {
2280
2280
  let e = '<table style="border-collapse:collapse;width:100%"><tbody>';
2281
- for (const i of D(t, "tr")) {
2281
+ for (const i of P(t, "tr")) {
2282
2282
  e += "<tr>";
2283
- for (const s of D(i, "tc")) {
2284
- const l = parseInt(T(E(s, "tcPr", "gridSpan")) || "1", 10) || 1, o = l > 1 ? ` colspan="${l}"` : "";
2283
+ for (const s of P(i, "tc")) {
2284
+ const l = parseInt(T(S(s, "tcPr", "gridSpan")) || "1", 10) || 1, o = l > 1 ? ` colspan="${l}"` : "";
2285
2285
  let n = "";
2286
2286
  for (const r of Array.from(s.children))
2287
2287
  r.localName === "p" ? n += this.convertPara(r) : r.localName === "tbl" && (n += this.convertTable(r));
@@ -2292,8 +2292,8 @@ class Ht {
2292
2292
  return e + "</tbody></table>";
2293
2293
  }
2294
2294
  }
2295
- async function kt(p) {
2296
- const t = p instanceof ArrayBuffer ? p : await p.arrayBuffer(), e = Et(t), i = new TextDecoder(), s = async (u) => {
2295
+ async function Ht(p) {
2296
+ const t = p instanceof ArrayBuffer ? p : await p.arrayBuffer(), e = St(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;
2299
2299
  }, l = await s("word/document.xml"), o = l == null ? void 0 : l.getElementsByTagName("*");
@@ -2317,7 +2317,7 @@ async function kt(p) {
2317
2317
  for (const [u, v] of c) {
2318
2318
  const b = v.startsWith("/") ? v.slice(1) : "word/" + v.replace(/^\.\//, ""), x = e.get(b);
2319
2319
  if (!x) continue;
2320
- const C = (b.split(".").pop() || "").toLowerCase(), M = St[C];
2320
+ const C = (b.split(".").pop() || "").toLowerCase(), M = Et[C];
2321
2321
  if (M)
2322
2322
  try {
2323
2323
  d.set(u, `data:${M};base64,${Lt(await Q(t, x))}`);
@@ -2329,16 +2329,16 @@ async function kt(p) {
2329
2329
  const u = /* @__PURE__ */ new Map(), v = Array.from(g.getElementsByTagName("*"));
2330
2330
  for (const b of v) {
2331
2331
  if (b.localName !== "abstractNum") continue;
2332
- const x = T(b, "abstractNumId"), C = D(b, "lvl").find((w) => T(w, "ilvl") === "0") || D(b, "lvl")[0], M = C ? T(E(C, "numFmt")) : "";
2332
+ const x = T(b, "abstractNumId"), C = P(b, "lvl").find((w) => T(w, "ilvl") === "0") || P(b, "lvl")[0], M = C ? T(S(C, "numFmt")) : "";
2333
2333
  u.set(x, M === "bullet" ? "ul" : "ol");
2334
2334
  }
2335
2335
  for (const b of v) {
2336
2336
  if (b.localName !== "num") continue;
2337
- const x = T(b, "numId"), C = T(E(b, "abstractNumId"));
2337
+ const x = T(b, "numId"), C = T(S(b, "abstractNumId"));
2338
2338
  m.set(x, u.get(C) || "ul");
2339
2339
  }
2340
2340
  }
2341
- return new Ht(r, d, m).convertBody(n);
2341
+ return new kt(r, d, m).convertBody(n);
2342
2342
  }
2343
2343
  const At = ["nw", "ne", "sw", "se"], F = ["img-left", "img-right", "img-top", "img-center"], O = {
2344
2344
  "img-left": "tplimgleft",
@@ -2351,23 +2351,23 @@ const At = ["nw", "ne", "sw", "se"], F = ["img-left", "img-right", "img-top", "i
2351
2351
  "img-top": a.tpltop,
2352
2352
  "img-center": a.tplcenter
2353
2353
  }, qt = ".tox,.pop,.tblctx,.imgctx,.selctx,.dlg";
2354
- let S = null, A = null, $ = 0, K = !1;
2354
+ let E = null, A = null, $ = 0, K = !1;
2355
2355
  function N() {
2356
- clearTimeout($), A = null, S && S.classList.remove("show");
2356
+ clearTimeout($), A = null, E && E.classList.remove("show");
2357
2357
  }
2358
2358
  function Bt(p) {
2359
2359
  const t = p.dataset.tip;
2360
2360
  if (!t) return;
2361
2361
  A = p, clearTimeout($);
2362
- const e = S && S.classList.contains("show") ? 60 : 350;
2362
+ const e = E && E.classList.contains("show") ? 60 : 350;
2363
2363
  $ = window.setTimeout(() => {
2364
2364
  if (A !== p || !document.contains(p)) return;
2365
- S || (S = document.createElement("div"), S.className = "etip", document.body.appendChild(S)), S.textContent = t, S.classList.add("show");
2366
- const i = p.getBoundingClientRect(), s = S.offsetWidth, l = S.offsetHeight;
2365
+ E || (E = document.createElement("div"), E.className = "etip", document.body.appendChild(E)), E.textContent = t, E.classList.add("show");
2366
+ const i = p.getBoundingClientRect(), s = E.offsetWidth, l = E.offsetHeight;
2367
2367
  let o = i.left + i.width / 2 - s / 2;
2368
2368
  o = Math.max(6, Math.min(o, innerWidth - s - 6));
2369
2369
  let n = i.bottom + 7;
2370
- n + l > innerHeight - 6 && (n = i.top - l - 7), S.style.left = o + "px", S.style.top = n + "px";
2370
+ n + l > innerHeight - 6 && (n = i.top - l - 7), E.style.left = o + "px", E.style.top = n + "px";
2371
2371
  }, e);
2372
2372
  }
2373
2373
  function Nt() {
@@ -2383,11 +2383,11 @@ function Nt() {
2383
2383
  A && !A.contains(p.relatedTarget) && N();
2384
2384
  }), document.addEventListener("mousedown", N, !0), addEventListener("scroll", N, !0));
2385
2385
  }
2386
- const Zt = /[\u0590-\u05FF\u0600-\u06FF\u0750-\u077F\u0780-\u07BF\u08A0-\u08FF\uFB1D-\uFB4F\uFB50-\uFDFF\uFE70-\uFEFF]/, Dt = new RegExp("\\p{L}", "u"), Pt = "p,div,li,td,th,blockquote,h1,h2,h3,h4,h5,h6,pre,figcaption";
2386
+ const Zt = /[\u0590-\u05FF\u0600-\u06FF\u0750-\u077F\u0780-\u07BF\u08A0-\u08FF\uFB1D-\uFB4F\uFB50-\uFDFF\uFE70-\uFEFF]/, Pt = new RegExp("\\p{L}", "u"), Dt = "p,div,li,td,th,blockquote,h1,h2,h3,h4,h5,h6,pre,figcaption";
2387
2387
  function Rt(p) {
2388
2388
  for (const t of p) {
2389
2389
  if (Zt.test(t)) return "rtl";
2390
- if (Dt.test(t)) return "ltr";
2390
+ if (Pt.test(t)) return "ltr";
2391
2391
  }
2392
2392
  return null;
2393
2393
  }
@@ -2405,7 +2405,7 @@ function et(p) {
2405
2405
  }
2406
2406
  const I = class I {
2407
2407
  constructor(t) {
2408
- this.lang = "en", this.contentClass = "fable-content-" + I.instanceCounter++, this.contentStyleEl = null, this.savedRange = null, this.foreColor = "#000000", this.backColor = "#FACC15", this.openPop = null, this.openSubEl = null, this.popAnchor = null, this.dlgOvl = null, this.tblActive = null, this.tblCorner = null, this.tblColBars = [], this.tblCtx = null, this.tblCellMark = null, this.tblOpMark = null, this.tblOpMarkKind = null, this.imgActive = null, this.imgHandles = [], this.imgCtx = null, this.imgHideTimer = null, this.phActive = null, this.phCtx = null, this.phUploadTarget = null, this.vidActive = null, this.vidCtx = null, this.vidHideTimer = null, this.vphActive = null, this.vphCtx = null, this.vphUploadTarget = null, this.selCtx = null, this.tbrMore = null, this.tbrExpanded = !1, this.codeActive = null, this.codeCtx = null, this.tplActive = null, this.tplCtx = null, this.revisions = [], this.revTimer = null, this.draftTimer = null, this.draftStorageKey = "", this.listeners = [], this.isDestroyed = !1, this.options = {
2408
+ this.lang = "en", this.contentClass = "fable-content-" + I.instanceCounter++, this.contentStyleEl = null, this.savedRange = null, this.foreColor = "#000000", this.backColor = "#FACC15", this.openPop = null, this.subStack = [], this.popAnchor = null, this.dlgOvl = null, this.tblActive = null, this.tblCorner = null, this.tblColBars = [], this.tblCtx = null, this.tblCellMark = null, this.tblOpMark = null, this.tblOpMarkKind = null, this.imgActive = null, this.imgHandles = [], this.imgCtx = null, this.imgHideTimer = null, this.phActive = null, this.phCtx = null, this.phUploadTarget = null, this.vidActive = null, this.vidCtx = null, this.vidHideTimer = null, this.vphActive = null, this.vphCtx = null, this.vphUploadTarget = null, this.selCtx = null, this.tbrMore = null, this.tbrExpanded = !1, this.codeActive = null, this.codeCtx = null, this.tplActive = null, this.tplCtx = null, this.revisions = [], this.revTimer = null, this.draftTimer = null, this.draftStorageKey = "", this.listeners = [], this.isDestroyed = !1, this.options = {
2409
2409
  target: t.target,
2410
2410
  language: t.language || "en",
2411
2411
  height: t.height ?? 302,
@@ -2477,7 +2477,7 @@ const I = class I {
2477
2477
  /* ---------------------------------------------------------- event binding */
2478
2478
  bindEvents() {
2479
2479
  if (this.onDoc("mousedown", (t) => {
2480
- this.openPop && !this.openPop.contains(t.target) && !this.popAnchor.contains(t.target) && !(this.openSubEl && this.openSubEl.contains(t.target)) && this.closePop();
2480
+ this.openPop && !this.openPop.contains(t.target) && !this.popAnchor.contains(t.target) && !this.subContains(t.target) && this.closePop();
2481
2481
  }), this.onDoc("keydown", (t) => {
2482
2482
  t.key === "Escape" && (this.closePop(), this.closeDlg());
2483
2483
  }), this.onDoc("selectionchange", () => {
@@ -2532,8 +2532,10 @@ const I = class I {
2532
2532
  this.positionTableHandles(), this.positionImageHandles(), this.positionImgPhCtx(), this.positionTplCtx(), this.positionVphCtx(), this.positionVidCtx(), this.positionCodeCtx();
2533
2533
  }), this.onWin(
2534
2534
  "scroll",
2535
- () => {
2536
- this.closePop(), this.positionTableHandles(), this.positionImageHandles(), this.positionImgPhCtx(), this.positionTplCtx(), this.positionVphCtx(), this.positionVidCtx(), this.positionCodeCtx(), this.repositionSelToolbar();
2535
+ (t) => {
2536
+ var s;
2537
+ const e = t.target;
2538
+ e instanceof Node && ((((s = this.openPop) == null ? void 0 : s.contains(e)) ?? !1) || this.subContains(e)) || this.closePop(), this.positionTableHandles(), this.positionImageHandles(), this.positionImgPhCtx(), this.positionTplCtx(), this.positionVphCtx(), this.positionVidCtx(), this.positionCodeCtx(), this.repositionSelToolbar();
2537
2539
  },
2538
2540
  !0
2539
2541
  ), this.onWin("resize", () => {
@@ -2581,7 +2583,7 @@ const I = class I {
2581
2583
  const t = (e = this.docInput.files) == null ? void 0 : e[0];
2582
2584
  t && this.importWordFile(t).catch(() => alert(this.t("importfail")));
2583
2585
  }), this.onDoc("mousedown", (t) => {
2584
- this.ed.contains(t.target) || t.target === this.tblCorner || this.tblColBars.includes(t.target) || this.tblCtx && this.tblCtx.contains(t.target) || this.imgHandles.includes(t.target) || this.imgCtx && this.imgCtx.contains(t.target) || this.phCtx && this.phCtx.contains(t.target) || this.tplCtx && this.tplCtx.contains(t.target) || this.selCtx && this.selCtx.contains(t.target) || this.vphCtx && this.vphCtx.contains(t.target) || this.vidCtx && this.vidCtx.contains(t.target) || this.codeCtx && this.codeCtx.contains(t.target) || this.openPop && this.openPop.contains(t.target) || this.openSubEl && this.openSubEl.contains(t.target) || (this.clearTableHandles(), this.clearImageHandles(), this.clearImgPlaceholderSel(), this.clearTplSel(), this.clearVphPlaceholderSel(), this.clearVidHandles(), this.clearCodeSel(), this.clearSelToolbar());
2586
+ this.ed.contains(t.target) || t.target === this.tblCorner || this.tblColBars.includes(t.target) || this.tblCtx && this.tblCtx.contains(t.target) || this.imgHandles.includes(t.target) || this.imgCtx && this.imgCtx.contains(t.target) || this.phCtx && this.phCtx.contains(t.target) || this.tplCtx && this.tplCtx.contains(t.target) || this.selCtx && this.selCtx.contains(t.target) || this.vphCtx && this.vphCtx.contains(t.target) || this.vidCtx && this.vidCtx.contains(t.target) || this.codeCtx && this.codeCtx.contains(t.target) || this.openPop && this.openPop.contains(t.target) || this.subContains(t.target) || (this.clearTableHandles(), this.clearImageHandles(), this.clearImgPlaceholderSel(), this.clearTplSel(), this.clearVphPlaceholderSel(), this.clearVidHandles(), this.clearCodeSel(), this.clearSelToolbar());
2585
2587
  });
2586
2588
  }
2587
2589
  on(t, e, i) {
@@ -2622,7 +2624,7 @@ const I = class I {
2622
2624
  if (n !== "rtl" && n !== "ltr") return;
2623
2625
  const r = n;
2624
2626
  i || (i = r), /text-align\s*:/i.test(o.getAttribute("style") || "") || t(o, `text-align:${r === "rtl" ? "right" : "left"}`);
2625
- }), e.querySelectorAll(Pt).forEach((o) => {
2627
+ }), e.querySelectorAll(Dt).forEach((o) => {
2626
2628
  const n = (o.getAttribute("dir") || "").toLowerCase();
2627
2629
  if (n === "rtl" || n === "ltr") return;
2628
2630
  const r = Rt(et(o));
@@ -2649,7 +2651,7 @@ const I = class I {
2649
2651
  this.ed.focus();
2650
2652
  }
2651
2653
  async importWordFile(t) {
2652
- const e = await kt(t);
2654
+ const e = await Ht(t);
2653
2655
  this.recordRevision(), this.setContent(e), this.recordRevision();
2654
2656
  }
2655
2657
  restoreDraft() {
@@ -2787,24 +2789,42 @@ const I = class I {
2787
2789
  }
2788
2790
  /* ---------------------------------------------------------- popups / menus */
2789
2791
  closeSub() {
2790
- var t;
2791
- (t = this.openSubEl) == null || t.remove(), this.openSubEl = null;
2792
+ this.closeSubFrom(0);
2793
+ }
2794
+ /** Removes stacked flyouts from `level` (0 = shallowest) onward, keeping
2795
+ * anything shallower - e.g. hovering a sibling item inside the "Cell"
2796
+ * flyout should drop a deeper "Cell background" flyout but keep "Cell"
2797
+ * itself and the top-level popup it bridges to. */
2798
+ closeSubFrom(t) {
2799
+ for (; this.subStack.length > t; ) this.subStack.pop().remove();
2800
+ }
2801
+ /** True if `node` is inside any currently-open flyout submenu (any depth). */
2802
+ subContains(t) {
2803
+ return this.subStack.some((e) => e.contains(t));
2804
+ }
2805
+ /** 0 for the top-level popup itself; otherwise this container's depth in
2806
+ * the flyout stack + 1. Used to know how many deeper flyouts to close
2807
+ * when opening or hovering within `container`. */
2808
+ subLevelOf(t) {
2809
+ if (t === this.openPop) return 0;
2810
+ const e = this.subStack.indexOf(t);
2811
+ return e === -1 ? this.subStack.length : e + 1;
2792
2812
  }
2793
2813
  closePop() {
2794
2814
  var t;
2795
2815
  this.closeSub(), this.openPop && (this.openPop.remove(), this.openPop = null, (t = this.popAnchor) == null || t.classList.remove("open"), this.popAnchor = null, this.setOpTarget(null));
2796
2816
  }
2797
2817
  openSubFor(t, e) {
2798
- this.closeSub();
2799
- const i = document.createElement("div");
2800
- i.className = "pop sub", i.dir = this.dir(), t.subBuild ? t.subBuild(i) : t.sub && this.menuItems(i, t.sub), i.addEventListener("mousedown", (r) => {
2801
- r.target.tagName !== "INPUT" && r.preventDefault();
2802
- }), document.body.appendChild(i);
2803
- const s = e.getBoundingClientRect();
2804
- let o = this.dir() === "rtl" ? s.left - i.offsetWidth + 2 : s.right - 2;
2805
- o = Math.max(8, Math.min(o + scrollX, scrollX + innerWidth - i.offsetWidth - 8));
2806
- let n = s.top + scrollY - 6;
2807
- n = Math.max(8 + scrollY, Math.min(n, scrollY + innerHeight - i.offsetHeight - 8)), i.style.left = o + "px", i.style.top = n + "px", this.openSubEl = i;
2818
+ const i = e.getBoundingClientRect(), s = e.closest(".pop");
2819
+ this.closeSubFrom(s ? this.subLevelOf(s) : 0);
2820
+ const l = document.createElement("div");
2821
+ l.className = "pop sub", l.dir = this.dir(), t.subBuild ? t.subBuild(l) : t.sub && this.menuItems(l, t.sub), l.addEventListener("mousedown", (c) => {
2822
+ c.target.tagName !== "INPUT" && c.preventDefault();
2823
+ }), document.body.appendChild(l);
2824
+ let n = this.dir() === "rtl" ? i.left - l.offsetWidth + 2 : i.right - 2;
2825
+ n = Math.max(8, Math.min(n + scrollX, scrollX + innerWidth - l.offsetWidth - 8));
2826
+ let r = i.top + scrollY - 6;
2827
+ r = Math.max(8 + scrollY, Math.min(r, scrollY + innerHeight - l.offsetHeight - 8)), l.style.left = n + "px", l.style.top = r + "px", this.subStack.push(l);
2808
2828
  }
2809
2829
  popup(t, e, i) {
2810
2830
  if (this.openPop && this.popAnchor === t) {
@@ -2815,10 +2835,12 @@ const I = class I {
2815
2835
  const s = document.createElement("div");
2816
2836
  s.className = "pop" + (i ? " " + i : ""), s.dir = this.dir(), e(s), document.body.appendChild(s);
2817
2837
  const l = t.getBoundingClientRect();
2818
- s.style.minWidth = Math.max(160, Math.round(l.width)) + "px", s.style.top = l.bottom + scrollY + 2 + "px";
2819
- let n = this.dir() === "rtl" ? l.right - s.offsetWidth : l.left;
2820
- n = Math.max(8, Math.min(n + scrollX, scrollX + innerWidth - s.offsetWidth - 8)), s.style.left = n + "px", s.addEventListener("mousedown", (r) => {
2821
- r.target.tagName !== "INPUT" && r.preventDefault();
2838
+ s.style.minWidth = Math.max(160, Math.round(l.width)) + "px";
2839
+ let o = l.bottom + scrollY + 2;
2840
+ o = Math.max(8 + scrollY, Math.min(o, scrollY + innerHeight - s.offsetHeight - 8)), s.style.top = o + "px";
2841
+ let r = this.dir() === "rtl" ? l.right - s.offsetWidth : l.left;
2842
+ r = Math.max(8, Math.min(r + scrollX, scrollX + innerWidth - s.offsetWidth - 8)), s.style.left = r + "px", s.addEventListener("mousedown", (c) => {
2843
+ c.target.tagName !== "INPUT" && c.preventDefault();
2822
2844
  }), this.openPop = s, this.popAnchor = t, t.classList.add("open");
2823
2845
  }
2824
2846
  menuItems(t, e) {
@@ -2832,7 +2854,7 @@ const I = class I {
2832
2854
  i.action && (this.closePop(), i.action());
2833
2855
  }), l.addEventListener("mouseenter", () => {
2834
2856
  var o;
2835
- s ? this.openSubFor(i, l) : this.openSubEl && t !== this.openSubEl && this.closeSub(), (o = i.hover) == null || o.call(i, !0);
2857
+ s ? this.openSubFor(i, l) : this.closeSubFrom(this.subLevelOf(t)), (o = i.hover) == null || o.call(i, !0);
2836
2858
  }), l.addEventListener("mouseleave", () => {
2837
2859
  var o;
2838
2860
  return (o = i.hover) == null ? void 0 : o.call(i, !1);
@@ -3211,8 +3233,8 @@ const I = class I {
3211
3233
  * (the quick color chips); everything else yields one. */
3212
3234
  buildToolbarRegistry() {
3213
3235
  const t = this.tbtn(a.tableic, this.t("quicktable"), () => this.tableGrid(t)), e = {
3214
- undo: () => this.tbtn(a.undo, this.t("undo"), () => this.exec("undo")),
3215
- redo: () => this.tbtn(a.redo, this.t("redo"), () => this.exec("redo")),
3236
+ undo: () => this.tbtn(a.undo, this.t("undo"), () => this.exec("undo"), "undo"),
3237
+ redo: () => this.tbtn(a.redo, this.t("redo"), () => this.exec("redo"), "redo"),
3216
3238
  preview: () => this.tbtn(a.prevw, this.t("preview"), () => this.previewDlg()),
3217
3239
  print: () => this.tbtn(a.printic, this.t("print"), () => this.printDoc()),
3218
3240
  importword: () => this.tbtn(a.wordic, this.t("importword"), () => this.pickWordDoc()),
@@ -3554,20 +3576,20 @@ const I = class I {
3554
3576
  this.dialog(
3555
3577
  this.t("tablepropsttl"),
3556
3578
  (C) => {
3557
- const M = (w, k) => {
3579
+ const M = (w, H) => {
3558
3580
  const L = document.createElement("div");
3559
3581
  L.style.cssText = n;
3560
- const H = document.createElement("span");
3561
- H.style.cssText = r, H.textContent = this.t(w), L.append(H, k), C.appendChild(L);
3582
+ const k = document.createElement("span");
3583
+ k.style.cssText = r, k.textContent = this.t(w), L.append(k, H), C.appendChild(L);
3562
3584
  };
3563
3585
  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, [
3564
3586
  ["", "alignnone"],
3565
3587
  ["left", "alignleft"],
3566
3588
  ["center", "aligncenter"],
3567
3589
  ["right", "alignright"]
3568
- ].forEach(([w, k]) => {
3590
+ ].forEach(([w, H]) => {
3569
3591
  const L = document.createElement("option");
3570
- L.value = w, L.textContent = this.t(k), w === x && (L.selected = !0), o.appendChild(L);
3592
+ L.value = w, L.textContent = this.t(H), w === x && (L.selected = !0), o.appendChild(L);
3571
3593
  }), M("tblalign", o);
3572
3594
  },
3573
3595
  [
@@ -4159,17 +4181,17 @@ const I = class I {
4159
4181
  const w = (L = C.files) == null ? void 0 : L[0];
4160
4182
  if (!w) return;
4161
4183
  x.disabled = !0, x.textContent = this.t("uploading");
4162
- const k = (H) => {
4163
- t.value = H, x.disabled = !1, x.textContent = this.t("uploadvideo");
4184
+ const H = (k) => {
4185
+ t.value = k, x.disabled = !1, x.textContent = this.t("uploadvideo");
4164
4186
  };
4165
4187
  if (this.videoUploadHandler)
4166
- this.videoUploadHandler(w).then(k).catch((H) => {
4188
+ this.videoUploadHandler(w).then(H).catch((k) => {
4167
4189
  var _;
4168
- x.disabled = !1, x.textContent = this.t("uploadfailed"), (_ = this.onVideoUploadError) == null || _.call(this, H, w);
4190
+ x.disabled = !1, x.textContent = this.t("uploadfailed"), (_ = this.onVideoUploadError) == null || _.call(this, k, w);
4169
4191
  });
4170
4192
  else {
4171
- const H = new FileReader();
4172
- H.onload = () => k(H.result), H.readAsDataURL(w);
4193
+ const k = new FileReader();
4194
+ k.onload = () => H(k.result), k.readAsDataURL(w);
4173
4195
  }
4174
4196
  }), b.append(t, x, C), t.style.flex = "1", v.appendChild(n("vidsource", b));
4175
4197
  const M = document.createElement("div");