fable-editor 1.2.8 → 1.3.0
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/angular/core/editor.d.ts +34 -0
- package/dist/angular/core/word-image-paste.d.ts +27 -0
- package/dist/angular/esm2022/core/editor.mjs +201 -5
- package/dist/angular/esm2022/core/word-image-paste.mjs +189 -0
- package/dist/angular/fesm2022/fable-editor.mjs +388 -4
- package/dist/angular/fesm2022/fable-editor.mjs.map +1 -1
- package/dist/core/editor.css +14 -0
- package/dist/core/editor.d.ts +34 -0
- package/dist/core/editor.d.ts.map +1 -1
- package/dist/core/index.cjs +4 -4
- package/dist/core/index.mjs +980 -759
- package/dist/core/word-image-paste.d.ts +28 -0
- package/dist/core/word-image-paste.d.ts.map +1 -0
- package/dist/react/index.cjs +11 -11
- package/dist/react/index.mjs +1107 -886
- package/package.json +1 -1
- package/style.css +14 -0
package/dist/core/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const rt = {
|
|
2
2
|
en: {
|
|
3
3
|
dir: "ltr",
|
|
4
4
|
file: "File",
|
|
@@ -384,10 +384,10 @@ const it = {
|
|
|
384
384
|
emcat_flags: "أعلام"
|
|
385
385
|
}
|
|
386
386
|
};
|
|
387
|
-
function
|
|
388
|
-
return
|
|
387
|
+
function D(d) {
|
|
388
|
+
return rt[d];
|
|
389
389
|
}
|
|
390
|
-
const
|
|
390
|
+
const at = "undo redo | preview print | importword revhistory | fontfamily fontsize | fontsizeincrease fontsizedecrease | bold italic underline strikethrough | forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist | outdent indent | link blockquote code changecase lineheight wordspacing letterspacing | removeformat | blocks | ltr rtl | quickimage quickvideo quicktable codesample template charmap emoji | fullscreen sourcecode", ct = "file edit view insert format tools table help", ht = [
|
|
391
391
|
["Andale Mono", "andale mono,times"],
|
|
392
392
|
["Arial", "arial,helvetica,sans-serif"],
|
|
393
393
|
["Arial Black", "arial black,avant garde"],
|
|
@@ -407,7 +407,7 @@ const st = "undo redo | preview print | importword revhistory | fontfamily fonts
|
|
|
407
407
|
["Verdana", "verdana,geneva"],
|
|
408
408
|
["Webdings", "webdings"],
|
|
409
409
|
["Wingdings", "wingdings,zapf dingbats"]
|
|
410
|
-
],
|
|
410
|
+
], dt = ["8px", "9px", "10px", "11px", "12px", "14px", "16px", "18px", "20px", "24px", "28px", "32px", "36px", "48px", "72px", "96px"], pt = 1, mt = 100, U = ["1", "1.15", "1.4", "1.5", "1.75", "2", "2.5", "3"], W = ["1px", "2px", "4px", "6px", "8px", "12px"], j = ["0.5px", "1px", "1.5px", "2px", "3px", "4px"], V = [
|
|
411
411
|
["plain", "Plain text"],
|
|
412
412
|
["html", "HTML/XML"],
|
|
413
413
|
["css", "CSS"],
|
|
@@ -424,7 +424,7 @@ const st = "undo redo | preview print | importword revhistory | fontfamily fonts
|
|
|
424
424
|
["rust", "Rust"],
|
|
425
425
|
["sql", "SQL"],
|
|
426
426
|
["bash", "Bash/Shell"]
|
|
427
|
-
],
|
|
427
|
+
], X = [
|
|
428
428
|
["p", "para"],
|
|
429
429
|
["h1", "heading1"],
|
|
430
430
|
["h2", "heading2"],
|
|
@@ -433,7 +433,7 @@ const st = "undo redo | preview print | importword revhistory | fontfamily fonts
|
|
|
433
433
|
["h5", "heading5"],
|
|
434
434
|
["h6", "heading6"],
|
|
435
435
|
["pre", "pre"]
|
|
436
|
-
],
|
|
436
|
+
], ut = ["#F76707", "#4263EB", "#CC5DE8"], gt = [
|
|
437
437
|
"#FFFFFF",
|
|
438
438
|
"#F4F4F4",
|
|
439
439
|
"#E8EAED",
|
|
@@ -459,7 +459,7 @@ const st = "undo redo | preview print | importword revhistory | fontfamily fonts
|
|
|
459
459
|
"#8E24AA",
|
|
460
460
|
"#C2185B",
|
|
461
461
|
"#6D4C41"
|
|
462
|
-
],
|
|
462
|
+
], ft = [
|
|
463
463
|
{
|
|
464
464
|
key: "chcat_currency",
|
|
465
465
|
chars: [
|
|
@@ -799,7 +799,7 @@ const st = "undo redo | preview print | importword revhistory | fontfamily fonts
|
|
|
799
799
|
"ة"
|
|
800
800
|
]
|
|
801
801
|
}
|
|
802
|
-
],
|
|
802
|
+
], vt = [
|
|
803
803
|
{
|
|
804
804
|
key: "emcat_smileys",
|
|
805
805
|
chars: [
|
|
@@ -1524,7 +1524,7 @@ const st = "undo redo | preview print | importword revhistory | fontfamily fonts
|
|
|
1524
1524
|
"🇲🇦"
|
|
1525
1525
|
]
|
|
1526
1526
|
}
|
|
1527
|
-
],
|
|
1527
|
+
], Jt = [
|
|
1528
1528
|
"©",
|
|
1529
1529
|
"®",
|
|
1530
1530
|
"™",
|
|
@@ -1573,11 +1573,11 @@ const st = "undo redo | preview print | importword revhistory | fontfamily fonts
|
|
|
1573
1573
|
"ـ",
|
|
1574
1574
|
"٠",
|
|
1575
1575
|
"١"
|
|
1576
|
-
], y = (
|
|
1577
|
-
'<path d="M10 6h10M10 12h10M10 18h10"/>' +
|
|
1576
|
+
], y = (d, t) => `<svg viewBox="${t || "0 0 24 24"}">${d}</svg>`, f = (d) => y(`<path class="f" d="${d}"/>`, "0 -960 960 960"), q = (d, t = 7.5) => y(
|
|
1577
|
+
'<path d="M10 6h10M10 12h10M10 18h10"/>' + d.map(
|
|
1578
1578
|
(e, i) => `<text x="2.5" y="${8.4 + i * 6}" font-size="${t}" stroke="none" fill="#222f3e" font-family="Arial">${e}</text>`
|
|
1579
1579
|
).join("")
|
|
1580
|
-
),
|
|
1580
|
+
), c = {
|
|
1581
1581
|
bold: f(
|
|
1582
1582
|
"M272-200v-560h221q65 0 120 40t55 111q0 51-23 78.5T602-491q25 11 55.5 41t30.5 90q0 89-65 124.5T501-200H272Zm121-112h104q48 0 58.5-24.5T566-372q0-11-10.5-35.5T494-432H393v120Zm0-228h93q33 0 48-17t15-38q0-24-17-39t-44-15h-95v109Z"
|
|
1583
1583
|
),
|
|
@@ -1810,7 +1810,7 @@ const st = "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
|
-
},
|
|
1813
|
+
}, te = (d) => `<span class="txt">${d}</span>`, bt = /* @__PURE__ */ new Set([
|
|
1814
1814
|
"p",
|
|
1815
1815
|
"div",
|
|
1816
1816
|
"span",
|
|
@@ -1852,7 +1852,7 @@ const st = "undo redo | preview print | importword revhistory | fontfamily fonts
|
|
|
1852
1852
|
"figure",
|
|
1853
1853
|
"figcaption",
|
|
1854
1854
|
"mark"
|
|
1855
|
-
]),
|
|
1855
|
+
]), yt = /* @__PURE__ */ new Set([
|
|
1856
1856
|
"text-align",
|
|
1857
1857
|
"direction",
|
|
1858
1858
|
"unicode-bidi",
|
|
@@ -1908,7 +1908,7 @@ const st = "undo redo | preview print | importword revhistory | fontfamily fonts
|
|
|
1908
1908
|
"box-sizing",
|
|
1909
1909
|
"list-style-type",
|
|
1910
1910
|
"white-space"
|
|
1911
|
-
]),
|
|
1911
|
+
]), Q = {
|
|
1912
1912
|
"*": ["dir", "lang", "colspan", "rowspan"],
|
|
1913
1913
|
a: ["href", "target", "rel", "title"],
|
|
1914
1914
|
img: ["src", "alt", "width", "height", "title"],
|
|
@@ -1917,26 +1917,26 @@ 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
|
|
1921
|
-
const t = {}, e =
|
|
1920
|
+
function R(d) {
|
|
1921
|
+
const t = {}, e = d.getAttribute && d.getAttribute("style");
|
|
1922
1922
|
return e && e.split(";").forEach((i) => {
|
|
1923
1923
|
const s = i.indexOf(":");
|
|
1924
1924
|
s < 1 || (t[i.slice(0, s).trim().toLowerCase()] = i.slice(s + 1).trim());
|
|
1925
1925
|
}), t;
|
|
1926
1926
|
}
|
|
1927
|
-
function
|
|
1928
|
-
return
|
|
1927
|
+
function xt(d) {
|
|
1928
|
+
return d.replace(/<!--\[if !supportLists\]-->([\s\S]*?)<!--\[endif\]-->/gi, "$1").replace(/<!--\[if !supportLists\]>([\s\S]*?)<!\[endif\]-->/gi, "$1").replace(/<!\[if !supportLists\]>([\s\S]*?)<!\[endif\]>/gi, "$1").replace(/<!--\[if [\s\S]*?<!\[endif\]-->/gi, "").replace(/<!--[\s\S]*?-->/g, "").replace(/<(script|style|xml|title)[\s\S]*?<\/\1>/gi, "").replace(/<\/?(meta|link)[^>]*>/gi, "").replace(/<\?xml[\s\S]*?\?>/gi, "").replace(/<\/?(o|v|w|m|st1):[^>]*>/gi, "");
|
|
1929
1929
|
}
|
|
1930
|
-
function
|
|
1931
|
-
return /^[0-9]+[\.\)،]/.test(
|
|
1930
|
+
function Ct(d) {
|
|
1931
|
+
return /^[0-9]+[\.\)،]/.test(d) ? { ordered: !0 } : /^[٠-٩۰-۹]+/.test(d) ? { ordered: !0, style: "arabic-indic" } : /^[ivxlc]{2,}[\.\)]/.test(d) ? { ordered: !0, style: "lower-roman" } : /^[IVXLC]{2,}[\.\)]/.test(d) ? { ordered: !0, style: "upper-roman" } : /^[a-z][\.\)]/.test(d) ? { ordered: !0, style: "lower-alpha" } : /^[A-Z][\.\)]/.test(d) ? { ordered: !0, style: "upper-alpha" } : /^[ء-ي][\.\)،-]/.test(d) ? { ordered: !0, style: "arabic-indic" } : { ordered: !1 };
|
|
1932
1932
|
}
|
|
1933
|
-
function
|
|
1933
|
+
function wt(d) {
|
|
1934
1934
|
const t = (s) => {
|
|
1935
1935
|
const l = (s.getAttribute("style") || "") + " " + (s.className || "");
|
|
1936
1936
|
return /mso-list\s*:(?!\s*ignore)/i.test(l) || /MsoListParagraph/i.test(l);
|
|
1937
1937
|
}, e = [];
|
|
1938
1938
|
let i = null;
|
|
1939
|
-
Array.from(
|
|
1939
|
+
Array.from(d.body.querySelectorAll("p")).forEach((s) => {
|
|
1940
1940
|
if (!t(s)) {
|
|
1941
1941
|
i = null;
|
|
1942
1942
|
return;
|
|
@@ -1944,67 +1944,67 @@ function vt(p) {
|
|
|
1944
1944
|
const l = s.previousElementSibling;
|
|
1945
1945
|
i && l && i[i.length - 1] === l ? i.push(s) : (i = [s], e.push(i));
|
|
1946
1946
|
}), e.forEach((s) => {
|
|
1947
|
-
const l = [],
|
|
1948
|
-
s.forEach((
|
|
1949
|
-
var x, C,
|
|
1950
|
-
const
|
|
1947
|
+
const l = [], n = s[0];
|
|
1948
|
+
s.forEach((o) => {
|
|
1949
|
+
var x, C, S;
|
|
1950
|
+
const a = +(((x = (o.getAttribute("style") || "").match(/level(\d+)/i)) == null ? void 0 : x[1]) || 1), h = Array.from(o.querySelectorAll("span")).find(
|
|
1951
1951
|
(w) => /mso-list\s*:\s*ignore/i.test(w.getAttribute("style") || "")
|
|
1952
|
-
),
|
|
1953
|
-
for (h && h.remove(); l.length && l[l.length - 1].level >
|
|
1954
|
-
if (!l.length || l[l.length - 1].level <
|
|
1955
|
-
const w =
|
|
1952
|
+
), p = h ? ((C = h.textContent) == null ? void 0 : C.trim()) || "" : (((S = o.textContent) == null ? void 0 : S.trim().match(/^\S{1,4}/)) || [""])[0], { ordered: m, style: g } = Ct(p);
|
|
1953
|
+
for (h && h.remove(); l.length && l[l.length - 1].level > a; ) l.pop();
|
|
1954
|
+
if (!l.length || l[l.length - 1].level < a) {
|
|
1955
|
+
const w = d.createElement(m ? "ol" : "ul");
|
|
1956
1956
|
if (m && g && (w.style.listStyleType = g), l.length) {
|
|
1957
|
-
const
|
|
1958
|
-
(
|
|
1957
|
+
const k = l[l.length - 1].list;
|
|
1958
|
+
(k.lastElementChild || k).appendChild(w);
|
|
1959
1959
|
} else
|
|
1960
|
-
|
|
1961
|
-
l.push({ list: w, level:
|
|
1960
|
+
n.parentNode.insertBefore(w, n);
|
|
1961
|
+
l.push({ list: w, level: a });
|
|
1962
1962
|
}
|
|
1963
|
-
const u =
|
|
1964
|
-
for (b && u.setAttribute("style", b),
|
|
1965
|
-
l[l.length - 1].list.appendChild(u),
|
|
1963
|
+
const u = d.createElement("li"), v = R(o), b = ["text-align", "direction", "unicode-bidi", "color", "font-size", "font-family", "background-color"].filter((w) => v[w]).map((w) => w + ":" + v[w]).join(";");
|
|
1964
|
+
for (b && u.setAttribute("style", b), o.getAttribute("dir") && u.setAttribute("dir", o.getAttribute("dir")); o.firstChild; ) u.appendChild(o.firstChild);
|
|
1965
|
+
l[l.length - 1].list.appendChild(u), o.remove();
|
|
1966
1966
|
});
|
|
1967
1967
|
});
|
|
1968
1968
|
}
|
|
1969
|
-
function
|
|
1970
|
-
|
|
1969
|
+
function Tt(d) {
|
|
1970
|
+
d.querySelectorAll('b[id^="docs-internal-guid"]').forEach((t) => {
|
|
1971
1971
|
for (; t.firstChild; ) t.parentNode.insertBefore(t.firstChild, t);
|
|
1972
1972
|
t.remove();
|
|
1973
1973
|
});
|
|
1974
1974
|
}
|
|
1975
|
-
function
|
|
1976
|
-
|
|
1975
|
+
function St(d) {
|
|
1976
|
+
d.querySelectorAll("table").forEach((t) => {
|
|
1977
1977
|
const e = t;
|
|
1978
|
-
|
|
1979
|
-
}),
|
|
1978
|
+
R(e)["border-collapse"] || (e.style.borderCollapse = "collapse");
|
|
1979
|
+
}), d.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) => {
|
|
1982
1982
|
if (s.tagName.toLowerCase() !== "table") return;
|
|
1983
1983
|
const l = s;
|
|
1984
1984
|
i === "center" ? (l.style.marginLeft = l.style.marginLeft || "auto", l.style.marginRight = l.style.marginRight || "auto") : i === "right" ? l.style.marginLeft = l.style.marginLeft || "auto" : i === "left" && (l.style.marginRight = l.style.marginRight || "auto");
|
|
1985
1985
|
})), e.removeAttribute("align");
|
|
1986
|
-
}),
|
|
1986
|
+
}), d.querySelectorAll("center table").forEach((t) => {
|
|
1987
1987
|
const e = t;
|
|
1988
1988
|
e.style.marginLeft = e.style.marginLeft || "auto", e.style.marginRight = e.style.marginRight || "auto";
|
|
1989
|
-
}),
|
|
1989
|
+
}), d.querySelectorAll("[bgcolor]").forEach((t) => {
|
|
1990
1990
|
const e = t;
|
|
1991
1991
|
e.style.backgroundColor = e.style.backgroundColor || e.getAttribute("bgcolor"), e.removeAttribute("bgcolor");
|
|
1992
1992
|
});
|
|
1993
1993
|
}
|
|
1994
|
-
function Z(
|
|
1995
|
-
Array.from(
|
|
1994
|
+
function Z(d, t) {
|
|
1995
|
+
Array.from(d.childNodes).forEach((e) => {
|
|
1996
1996
|
if (e.nodeType === Node.COMMENT_NODE) {
|
|
1997
1997
|
e.remove();
|
|
1998
1998
|
return;
|
|
1999
1999
|
}
|
|
2000
2000
|
if (e.nodeType !== Node.ELEMENT_NODE) return;
|
|
2001
2001
|
const i = e, s = i.tagName.toLowerCase();
|
|
2002
|
-
if (!
|
|
2002
|
+
if (!bt.has(s)) {
|
|
2003
2003
|
if (s === "font") {
|
|
2004
2004
|
const r = t.createElement("span");
|
|
2005
2005
|
i.getAttribute("style") && r.setAttribute("style", i.getAttribute("style")), i.getAttribute("color") && (r.style.color = i.getAttribute("color")), i.getAttribute("face") && (r.style.fontFamily = i.getAttribute("face"));
|
|
2006
|
-
const
|
|
2007
|
-
if (
|
|
2006
|
+
const a = i.getAttribute("size");
|
|
2007
|
+
if (a && !r.style.fontSize) {
|
|
2008
2008
|
const h = {
|
|
2009
2009
|
1: "8pt",
|
|
2010
2010
|
2: "10pt",
|
|
@@ -2014,7 +2014,7 @@ function Z(p, t) {
|
|
|
2014
2014
|
6: "24pt",
|
|
2015
2015
|
7: "36pt"
|
|
2016
2016
|
};
|
|
2017
|
-
h[
|
|
2017
|
+
h[a] && (r.style.fontSize = h[a]);
|
|
2018
2018
|
}
|
|
2019
2019
|
for (; i.firstChild; ) r.appendChild(i.firstChild);
|
|
2020
2020
|
i.replaceWith(r), Z(r, t);
|
|
@@ -2024,10 +2024,10 @@ function Z(p, t) {
|
|
|
2024
2024
|
i.remove();
|
|
2025
2025
|
return;
|
|
2026
2026
|
}
|
|
2027
|
-
const l = /* @__PURE__ */ new Set([...
|
|
2027
|
+
const l = /* @__PURE__ */ new Set([...Q["*"] || [], ...Q[s] || []]);
|
|
2028
2028
|
if (Array.from(i.attributes).forEach((r) => {
|
|
2029
|
-
const
|
|
2030
|
-
|
|
2029
|
+
const a = r.name.toLowerCase();
|
|
2030
|
+
a !== "style" && !l.has(a) && i.removeAttribute(r.name);
|
|
2031
2031
|
}), s === "a") {
|
|
2032
2032
|
const r = i.getAttribute("href") || "";
|
|
2033
2033
|
/^(https?:|mailto:|tel:|#)/i.test(r) || i.removeAttribute("href");
|
|
@@ -2035,130 +2035,233 @@ function Z(p, t) {
|
|
|
2035
2035
|
if (s === "img") {
|
|
2036
2036
|
const r = i.getAttribute("src") || "";
|
|
2037
2037
|
if (!/^(https?:|data:image\/|blob:)/i.test(r)) {
|
|
2038
|
-
const
|
|
2039
|
-
|
|
2038
|
+
const a = t.createElement("span");
|
|
2039
|
+
a.textContent = "[local image — paste it separately]", a.setAttribute("style", "color:#a33;font-style:italic;font-size:12px"), i.replaceWith(a);
|
|
2040
2040
|
return;
|
|
2041
2041
|
}
|
|
2042
2042
|
}
|
|
2043
|
-
const
|
|
2044
|
-
for (const [r,
|
|
2045
|
-
|
|
2046
|
-
if (
|
|
2043
|
+
const n = R(i), o = [];
|
|
2044
|
+
for (const [r, a] of Object.entries(n))
|
|
2045
|
+
yt.has(r) && (/expression|javascript|url\s*\(\s*['"]?\s*file:/i.test(a) || r === "font-weight" && /^(400|normal)$/i.test(a) || r === "font-style" && /^normal$/i.test(a) || r === "text-decoration" && /^none$/i.test(a) || o.push(r + ":" + a));
|
|
2046
|
+
if (o.length ? i.setAttribute("style", o.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
|
}
|
|
2050
2050
|
});
|
|
2051
2051
|
}
|
|
2052
|
-
function
|
|
2052
|
+
function Mt(d) {
|
|
2053
2053
|
const t = [], e = /<style[^>]*>([\s\S]*?)<\/style>/gi;
|
|
2054
2054
|
let i;
|
|
2055
|
-
for (; i = e.exec(
|
|
2055
|
+
for (; i = e.exec(d); ) {
|
|
2056
2056
|
let s = i[1].replace(/<!--|-->/g, "").replace(/\/\*[\s\S]*?\*\//g, "");
|
|
2057
2057
|
s = s.replace(/@media[^{]*\{(?:[^{}]*\{[^{}]*\})*[^{}]*\}/gi, ""), s = s.replace(/@[\w-]+[^{]*\{[^{}]*\}/g, "");
|
|
2058
2058
|
let l;
|
|
2059
|
-
const
|
|
2060
|
-
for (; l =
|
|
2061
|
-
const
|
|
2062
|
-
const
|
|
2063
|
-
return
|
|
2059
|
+
const n = /([^{}]+)\{([^}]*)\}/g;
|
|
2060
|
+
for (; l = n.exec(s); ) {
|
|
2061
|
+
const o = l[2].split(";").map((r) => {
|
|
2062
|
+
const a = r.indexOf(":");
|
|
2063
|
+
return a < 1 ? null : [r.slice(0, a).trim().toLowerCase(), r.slice(a + 1).trim()];
|
|
2064
2064
|
}).filter((r) => !!r && !!r[1]);
|
|
2065
|
-
|
|
2065
|
+
o.length && l[1].split(",").map((r) => r.trim()).filter((r) => r && !r.startsWith("@")).forEach((r) => t.push({ sel: r, decls: o }));
|
|
2066
2066
|
}
|
|
2067
2067
|
}
|
|
2068
2068
|
return t;
|
|
2069
2069
|
}
|
|
2070
|
-
function
|
|
2070
|
+
function Et(d, t) {
|
|
2071
2071
|
if (!t.length) return;
|
|
2072
2072
|
const e = /* @__PURE__ */ new Map();
|
|
2073
2073
|
t.forEach(({ sel: i, decls: s }) => {
|
|
2074
2074
|
let l;
|
|
2075
2075
|
try {
|
|
2076
|
-
l =
|
|
2076
|
+
l = d.querySelectorAll(i);
|
|
2077
2077
|
} catch {
|
|
2078
2078
|
return;
|
|
2079
2079
|
}
|
|
2080
|
-
l.forEach((
|
|
2081
|
-
let
|
|
2082
|
-
|
|
2083
|
-
|
|
2080
|
+
l.forEach((n) => {
|
|
2081
|
+
let o = e.get(n);
|
|
2082
|
+
o || (o = {}, e.set(n, o)), s.forEach(([r, a]) => {
|
|
2083
|
+
o[r] = a;
|
|
2084
2084
|
});
|
|
2085
2085
|
});
|
|
2086
2086
|
}), e.forEach((i, s) => {
|
|
2087
|
-
const l =
|
|
2087
|
+
const l = R(s), n = s.hasAttribute("dir"), o = s.hasAttribute("align"), r = Object.entries(i).filter(([p]) => !(p in l || (p === "direction" || p === "unicode-bidi") && n || p === "text-align" && (o || n) || (p === "background" || p === "background-color") && s.hasAttribute("bgcolor")));
|
|
2088
2088
|
if (!r.length) return;
|
|
2089
|
-
const
|
|
2090
|
-
s.setAttribute("style", h ?
|
|
2089
|
+
const a = r.map(([p, m]) => p + ":" + m).join(";"), h = s.getAttribute("style");
|
|
2090
|
+
s.setAttribute("style", h ? a + ";" + h : a);
|
|
2091
2091
|
});
|
|
2092
2092
|
}
|
|
2093
|
-
function
|
|
2094
|
-
return
|
|
2093
|
+
function st(d) {
|
|
2094
|
+
return d.replace(/[ﭐ-﷿ﹰ-ﻼ]+/g, (t) => t.normalize("NFKC"));
|
|
2095
2095
|
}
|
|
2096
|
-
function
|
|
2097
|
-
const t =
|
|
2096
|
+
function Lt(d) {
|
|
2097
|
+
const t = d.createTreeWalker(d.body, NodeFilter.SHOW_TEXT, null);
|
|
2098
2098
|
let e;
|
|
2099
2099
|
for (; e = t.nextNode(); )
|
|
2100
|
-
/[ﭐ-﷿ﹰ-ﻼ]/.test(e.nodeValue || "") && (e.nodeValue =
|
|
2100
|
+
/[ﭐ-﷿ﹰ-ﻼ]/.test(e.nodeValue || "") && (e.nodeValue = st(e.nodeValue || ""));
|
|
2101
2101
|
}
|
|
2102
|
-
function
|
|
2103
|
-
const e =
|
|
2104
|
-
|
|
2102
|
+
function Ht(d, t = "ltr") {
|
|
2103
|
+
const e = Mt(d), i = new DOMParser().parseFromString(xt(d), "text/html");
|
|
2104
|
+
Et(i, e), /class="?Mso|mso-|urn:schemas-microsoft-com/i.test(i.body.innerHTML) && wt(i), Tt(i), St(i), Z(i.body, i), Lt(i);
|
|
2105
2105
|
const s = (l) => {
|
|
2106
|
-
var
|
|
2107
|
-
return l && l.tagName === "P" && !((
|
|
2106
|
+
var n;
|
|
2107
|
+
return l && l.tagName === "P" && !((n = l.textContent) != null && n.trim()) && !l.querySelector("img,table");
|
|
2108
2108
|
};
|
|
2109
2109
|
for (; s(i.body.firstElementChild); ) i.body.firstElementChild.remove();
|
|
2110
2110
|
for (; s(i.body.lastElementChild); ) i.body.lastElementChild.remove();
|
|
2111
2111
|
return i.body.innerHTML.trim();
|
|
2112
2112
|
}
|
|
2113
|
-
function
|
|
2114
|
-
const t =
|
|
2113
|
+
function kt(d) {
|
|
2114
|
+
const t = st(d).replace(/\r/g, ""), e = (i) => i.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
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
|
-
|
|
2118
|
-
|
|
2117
|
+
const At = 10 * 1024 * 1024, lt = /^(https?:|data:image\/|blob:)/i;
|
|
2118
|
+
function G(d, t) {
|
|
2119
|
+
const e = [], i = "{\\" + t;
|
|
2120
|
+
let s = 0;
|
|
2121
|
+
for (; (s = d.indexOf(i, s)) !== -1; ) {
|
|
2122
|
+
const l = d[s + i.length];
|
|
2123
|
+
if (l && /[a-z0-9]/i.test(l)) {
|
|
2124
|
+
s += i.length;
|
|
2125
|
+
continue;
|
|
2126
|
+
}
|
|
2127
|
+
let n = 0, o = s;
|
|
2128
|
+
for (; o < d.length; o++) {
|
|
2129
|
+
const r = d[o];
|
|
2130
|
+
if (r === "\\") {
|
|
2131
|
+
o++;
|
|
2132
|
+
continue;
|
|
2133
|
+
}
|
|
2134
|
+
if (r === "{") n++;
|
|
2135
|
+
else if (r === "}" && (n--, !n))
|
|
2136
|
+
break;
|
|
2137
|
+
}
|
|
2138
|
+
e.push({ start: s, end: o + 1, body: d.slice(s + i.length, o) }), s = o + 1;
|
|
2139
|
+
}
|
|
2140
|
+
return e;
|
|
2141
|
+
}
|
|
2142
|
+
function It(d) {
|
|
2143
|
+
const t = new Uint8Array(d.length / 2);
|
|
2144
|
+
for (let e = 0; e < t.length; e++) t[e] = parseInt(d.substr(e * 2, 2), 16);
|
|
2145
|
+
return t;
|
|
2146
|
+
}
|
|
2147
|
+
function F(d) {
|
|
2148
|
+
let t = "";
|
|
2149
|
+
for (let e = 0; e < d.length; e++) t += String.fromCharCode(d[e]);
|
|
2150
|
+
return btoa(t);
|
|
2151
|
+
}
|
|
2152
|
+
function Y(d, t) {
|
|
2153
|
+
t: for (let e = 0; e + t.length <= d.length; e++) {
|
|
2154
|
+
for (let i = 0; i < t.length; i++) if (d[e + i] !== t[i]) continue t;
|
|
2155
|
+
return e;
|
|
2156
|
+
}
|
|
2157
|
+
return -1;
|
|
2158
|
+
}
|
|
2159
|
+
const qt = [137, 80, 78, 71], Bt = [255, 216, 255];
|
|
2160
|
+
function Nt(d) {
|
|
2161
|
+
let t = null;
|
|
2162
|
+
if (/\\pngblip/.test(d) ? t = "image/png" : /\\jpegblip/.test(d) ? t = "image/jpeg" : (/\\wmetafile\d*/.test(d) || /\\emfblip/.test(d)) && (t = "metafile"), !t) return null;
|
|
2163
|
+
let e = d.replace(/\{[^{}]*\}/g, "").replace(/\\[a-z]+-?\d*\s?/gi, "").replace(/[^0-9a-fA-F]/g, "");
|
|
2164
|
+
if (e.length % 2 && (e = e.slice(0, -1)), !e) return null;
|
|
2165
|
+
const i = It(e);
|
|
2166
|
+
if (t === "metafile") {
|
|
2167
|
+
const s = Y(i, qt);
|
|
2168
|
+
if (s >= 0) return "data:image/png;base64," + F(i.slice(s));
|
|
2169
|
+
const l = Y(i, Bt);
|
|
2170
|
+
return l >= 0 ? "data:image/jpeg;base64," + F(i.slice(l)) : null;
|
|
2171
|
+
}
|
|
2172
|
+
return "data:" + t + ";base64," + F(i);
|
|
2173
|
+
}
|
|
2174
|
+
function Zt(d) {
|
|
2175
|
+
if (!d || d.indexOf("\\pict") === -1) return [];
|
|
2176
|
+
let t = d;
|
|
2177
|
+
G(d, "nonshppict").reverse().forEach((i) => {
|
|
2178
|
+
t = t.slice(0, i.start) + t.slice(i.end);
|
|
2179
|
+
});
|
|
2180
|
+
let e = At;
|
|
2181
|
+
return G(t, "pict").map((i) => {
|
|
2182
|
+
if (e <= 0) return null;
|
|
2183
|
+
const s = Nt(i.body);
|
|
2184
|
+
return s && (e -= s.length * 0.75), s;
|
|
2185
|
+
});
|
|
2186
|
+
}
|
|
2187
|
+
function nt(d, t) {
|
|
2188
|
+
if (!d || !t.length) return { html: d, injected: [] };
|
|
2189
|
+
const e = [];
|
|
2190
|
+
let i = 0;
|
|
2191
|
+
return { html: d.replace(/<img\b[^>]*>/gi, (l) => {
|
|
2192
|
+
const n = (l.match(/\ssrc\s*=\s*["']?([^"'\s>]+)/i) || [])[1] || "";
|
|
2193
|
+
if (lt.test(n)) return l;
|
|
2194
|
+
const o = t[i++];
|
|
2195
|
+
return o ? (e.push(o), /\ssrc\s*=\s*["']/i.test(l) ? l.replace(/(\ssrc\s*=\s*)(["'])[^"']*\2/i, '$1"' + o + '"') : l.replace(/(\ssrc\s*=\s*)[^\s>]+/i, '$1"' + o + '"')) : l;
|
|
2196
|
+
}), injected: e };
|
|
2197
|
+
}
|
|
2198
|
+
function Pt(d, t) {
|
|
2199
|
+
return !d || !t ? { html: d, injected: [] } : nt(d, Zt(t));
|
|
2200
|
+
}
|
|
2201
|
+
function Rt(d) {
|
|
2202
|
+
const t = d.match(/<img\b[^>]*>/gi);
|
|
2203
|
+
return t ? t.filter((e) => {
|
|
2204
|
+
const i = (e.match(/\ssrc\s*=\s*["']?([^"'\s>]+)/i) || [])[1] || "";
|
|
2205
|
+
return !lt.test(i);
|
|
2206
|
+
}).length : 0;
|
|
2207
|
+
}
|
|
2208
|
+
function Dt(d, t) {
|
|
2209
|
+
const e = d.match(/^data:([^;,]+);base64,(.*)$/);
|
|
2210
|
+
if (!e) return null;
|
|
2211
|
+
const i = (e[1].split("/")[1] || "png").replace(/[^a-z0-9]/gi, "") || "png";
|
|
2212
|
+
try {
|
|
2213
|
+
const s = atob(e[2]), l = new Uint8Array(s.length);
|
|
2214
|
+
for (let n = 0; n < s.length; n++) l[n] = s.charCodeAt(n);
|
|
2215
|
+
return new File([l], t + "." + (i === "jpeg" ? "jpg" : i), { type: e[1] });
|
|
2216
|
+
} catch {
|
|
2217
|
+
return null;
|
|
2218
|
+
}
|
|
2219
|
+
}
|
|
2220
|
+
function Ft(d) {
|
|
2221
|
+
const t = new DataView(d), e = /* @__PURE__ */ new Map();
|
|
2119
2222
|
let i = -1;
|
|
2120
|
-
for (let
|
|
2121
|
-
if (t.getUint32(
|
|
2122
|
-
i =
|
|
2223
|
+
for (let o = d.byteLength - 22; o >= Math.max(0, d.byteLength - 22 - 65535); o--)
|
|
2224
|
+
if (t.getUint32(o, !0) === 101010256) {
|
|
2225
|
+
i = o;
|
|
2123
2226
|
break;
|
|
2124
2227
|
}
|
|
2125
2228
|
if (i < 0) throw new Error("EOCD not found");
|
|
2126
2229
|
const s = t.getUint16(i + 10, !0);
|
|
2127
2230
|
let l = t.getUint32(i + 16, !0);
|
|
2128
|
-
const
|
|
2129
|
-
for (let
|
|
2130
|
-
const r = t.getUint16(l + 10, !0),
|
|
2131
|
-
e.set(u, { name: u, method: r, compSize:
|
|
2231
|
+
const n = new TextDecoder();
|
|
2232
|
+
for (let o = 0; o < s && t.getUint32(l, !0) === 33639248; o++) {
|
|
2233
|
+
const r = t.getUint16(l + 10, !0), a = t.getUint32(l + 20, !0), h = t.getUint16(l + 28, !0), p = t.getUint16(l + 30, !0), m = t.getUint16(l + 32, !0), g = t.getUint32(l + 42, !0), u = n.decode(new Uint8Array(d, l + 46, h));
|
|
2234
|
+
e.set(u, { name: u, method: r, compSize: a, localOffset: g }), l += 46 + h + p + m;
|
|
2132
2235
|
}
|
|
2133
2236
|
return e;
|
|
2134
2237
|
}
|
|
2135
|
-
async function
|
|
2136
|
-
const e = new DataView(
|
|
2238
|
+
async function K(d, t) {
|
|
2239
|
+
const e = new DataView(d, t.localOffset);
|
|
2137
2240
|
if (e.getUint32(0, !0) !== 67324752) throw new Error("Bad local header");
|
|
2138
|
-
const i = e.getUint16(26, !0), s = e.getUint16(28, !0), l = t.localOffset + 30 + i + s,
|
|
2139
|
-
if (t.method === 0) return
|
|
2241
|
+
const i = e.getUint16(26, !0), s = e.getUint16(28, !0), l = t.localOffset + 30 + i + s, n = new Uint8Array(d.slice(l, l + t.compSize));
|
|
2242
|
+
if (t.method === 0) return n;
|
|
2140
2243
|
if (t.method !== 8) throw new Error("Unsupported compression method " + t.method);
|
|
2141
|
-
const
|
|
2142
|
-
return new Uint8Array(await new Response(
|
|
2244
|
+
const o = new Blob([n]).stream().pipeThrough(new DecompressionStream("deflate-raw"));
|
|
2245
|
+
return new Uint8Array(await new Response(o).arrayBuffer());
|
|
2143
2246
|
}
|
|
2144
|
-
const
|
|
2145
|
-
let e =
|
|
2247
|
+
const J = (d) => d.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """), P = (d, t) => Array.from(d.children).filter((e) => e.localName === t), M = (d, ...t) => {
|
|
2248
|
+
let e = d;
|
|
2146
2249
|
for (const i of t) {
|
|
2147
2250
|
if (!e) return null;
|
|
2148
2251
|
e = Array.from(e.children).find((s) => s.localName === i) || null;
|
|
2149
2252
|
}
|
|
2150
2253
|
return e;
|
|
2151
|
-
}, T = (
|
|
2152
|
-
if (!
|
|
2153
|
-
for (const e of Array.from(
|
|
2254
|
+
}, T = (d, t = "val") => {
|
|
2255
|
+
if (!d) return "";
|
|
2256
|
+
for (const e of Array.from(d.attributes))
|
|
2154
2257
|
if (e.localName === t) return e.value;
|
|
2155
2258
|
return "";
|
|
2156
|
-
}, B = (
|
|
2157
|
-
const e =
|
|
2259
|
+
}, B = (d, t) => {
|
|
2260
|
+
const e = d ? M(d, t) : null;
|
|
2158
2261
|
if (!e) return !1;
|
|
2159
2262
|
const i = T(e);
|
|
2160
2263
|
return i !== "false" && i !== "0";
|
|
2161
|
-
},
|
|
2264
|
+
}, tt = {
|
|
2162
2265
|
yellow: "#FFFF00",
|
|
2163
2266
|
green: "#00FF00",
|
|
2164
2267
|
cyan: "#00FFFF",
|
|
@@ -2175,7 +2278,7 @@ const Y = (p) => p.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, "&
|
|
|
2175
2278
|
lightGray: "#D3D3D3",
|
|
2176
2279
|
black: "#000000",
|
|
2177
2280
|
white: "#FFFFFF"
|
|
2178
|
-
},
|
|
2281
|
+
}, Ot = {
|
|
2179
2282
|
png: "image/png",
|
|
2180
2283
|
jpg: "image/jpeg",
|
|
2181
2284
|
jpeg: "image/jpeg",
|
|
@@ -2183,13 +2286,13 @@ const Y = (p) => p.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, "&
|
|
|
2183
2286
|
bmp: "image/bmp",
|
|
2184
2287
|
webp: "image/webp"
|
|
2185
2288
|
};
|
|
2186
|
-
function
|
|
2289
|
+
function $t(d) {
|
|
2187
2290
|
let t = "";
|
|
2188
|
-
for (let e = 0; e <
|
|
2189
|
-
t += String.fromCharCode(...
|
|
2291
|
+
for (let e = 0; e < d.length; e += 32768)
|
|
2292
|
+
t += String.fromCharCode(...d.subarray(e, e + 32768));
|
|
2190
2293
|
return btoa(t);
|
|
2191
2294
|
}
|
|
2192
|
-
class
|
|
2295
|
+
class _t {
|
|
2193
2296
|
constructor(t, e, i) {
|
|
2194
2297
|
this.rels = t, this.images = e, this.numFmt = i;
|
|
2195
2298
|
}
|
|
@@ -2200,12 +2303,12 @@ class kt {
|
|
|
2200
2303
|
};
|
|
2201
2304
|
for (const l of Array.from(t.children))
|
|
2202
2305
|
if (l.localName === "p") {
|
|
2203
|
-
const
|
|
2204
|
-
if (
|
|
2205
|
-
const
|
|
2206
|
-
for (; i.length >
|
|
2207
|
-
for (i.length ===
|
|
2208
|
-
e += `<${
|
|
2306
|
+
const n = this.paraList(l);
|
|
2307
|
+
if (n) {
|
|
2308
|
+
const o = n.ilvl + 1;
|
|
2309
|
+
for (; i.length > o; ) e += `</${i.pop()}>`;
|
|
2310
|
+
for (i.length === o && i[o - 1] !== n.type && (e += `</${i.pop()}>`); i.length < o; )
|
|
2311
|
+
e += `<${n.type}>`, i.push(n.type);
|
|
2209
2312
|
e += `<li>${this.runsOf(l) || "<br>"}</li>`;
|
|
2210
2313
|
continue;
|
|
2211
2314
|
}
|
|
@@ -2214,22 +2317,22 @@ class kt {
|
|
|
2214
2317
|
return s(0), e || "<p><br></p>";
|
|
2215
2318
|
}
|
|
2216
2319
|
paraList(t) {
|
|
2217
|
-
const e =
|
|
2320
|
+
const e = M(t, "pPr", "numPr");
|
|
2218
2321
|
if (!e) return null;
|
|
2219
|
-
const i = T(
|
|
2322
|
+
const i = T(M(e, "numId"));
|
|
2220
2323
|
if (!i || i === "0") return null;
|
|
2221
|
-
const s = parseInt(T(
|
|
2324
|
+
const s = parseInt(T(M(e, "ilvl")) || "0", 10) || 0;
|
|
2222
2325
|
return { type: this.numFmt.get(i) || "ul", ilvl: Math.min(s, 8) };
|
|
2223
2326
|
}
|
|
2224
2327
|
convertPara(t) {
|
|
2225
|
-
const e =
|
|
2328
|
+
const e = M(t, "pPr"), i = T(M(t, "pPr", "pStyle"));
|
|
2226
2329
|
let s = "p";
|
|
2227
2330
|
const l = /^Heading([1-6])$/i.exec(i);
|
|
2228
2331
|
l ? s = "h" + l[1] : /^Title$/i.test(i) && (s = "h1");
|
|
2229
|
-
const
|
|
2230
|
-
|
|
2231
|
-
const r = this.runsOf(t),
|
|
2232
|
-
return `<${s}${
|
|
2332
|
+
const n = [], o = T(M(t, "pPr", "jc"));
|
|
2333
|
+
o === "center" ? n.push("text-align:center") : o === "right" || o === "end" ? n.push("text-align:right") : (o === "both" || o === "distribute") && n.push("text-align:justify"), e && M(e, "bidi") && n.push("direction:rtl");
|
|
2334
|
+
const r = this.runsOf(t), a = n.length ? ` style="${n.join(";")}"` : "";
|
|
2335
|
+
return `<${s}${a}>${r || "<br>"}</${s}>`;
|
|
2233
2336
|
}
|
|
2234
2337
|
runsOf(t) {
|
|
2235
2338
|
let e = "";
|
|
@@ -2239,88 +2342,88 @@ class kt {
|
|
|
2239
2342
|
let s = this.rels.get(T(i, "id")) || "";
|
|
2240
2343
|
const l = T(i, "anchor");
|
|
2241
2344
|
!s && l && (s = "#" + l);
|
|
2242
|
-
const
|
|
2243
|
-
e += s ? `<a href="${
|
|
2345
|
+
const n = this.runsOf(i);
|
|
2346
|
+
e += s ? `<a href="${J(s)}">${n}</a>` : n;
|
|
2244
2347
|
} else (i.localName === "smartTag" || i.localName === "ins") && (e += this.runsOf(i));
|
|
2245
2348
|
return e;
|
|
2246
2349
|
}
|
|
2247
2350
|
convertRun(t) {
|
|
2248
|
-
const e =
|
|
2351
|
+
const e = M(t, "rPr");
|
|
2249
2352
|
let i = "";
|
|
2250
|
-
for (const
|
|
2251
|
-
|
|
2353
|
+
for (const p of Array.from(t.children))
|
|
2354
|
+
p.localName === "t" ? i += J(p.textContent || "") : p.localName === "br" || p.localName === "cr" ? i += "<br>" : p.localName === "tab" ? i += " " : (p.localName === "drawing" || p.localName === "pict" || p.localName === "object") && (i += this.convertImage(p));
|
|
2252
2355
|
if (!i) return "";
|
|
2253
|
-
const s = [], l = T(e ?
|
|
2356
|
+
const s = [], l = T(e ? M(e, "color") : null);
|
|
2254
2357
|
l && l !== "auto" && s.push("color:#" + l);
|
|
2255
|
-
const
|
|
2256
|
-
|
|
2257
|
-
const
|
|
2258
|
-
|
|
2259
|
-
const r = e ?
|
|
2260
|
-
|
|
2261
|
-
const h = T(e ?
|
|
2358
|
+
const n = T(e ? M(e, "highlight") : null);
|
|
2359
|
+
n && tt[n] && s.push("background-color:" + tt[n]);
|
|
2360
|
+
const o = parseFloat(T(e ? M(e, "sz") : null));
|
|
2361
|
+
o && s.push("font-size:" + Math.round(o / 2 * (4 / 3)) + "px");
|
|
2362
|
+
const r = e ? M(e, "rFonts") : null, a = T(r, "ascii") || T(r, "cs");
|
|
2363
|
+
a && s.push(`font-family:'${a}'`), 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(M(e, "u")) !== "none" && (i = `<u>${i}</u>`), B(e, "strike") && (i = `<s>${i}</s>`);
|
|
2364
|
+
const h = T(e ? M(e, "vertAlign") : null);
|
|
2262
2365
|
return h === "superscript" ? i = `<sup>${i}</sup>` : h === "subscript" && (i = `<sub>${i}</sub>`), i;
|
|
2263
2366
|
}
|
|
2264
2367
|
convertImage(t) {
|
|
2265
2368
|
let e = "", i = 0;
|
|
2266
|
-
const s = (
|
|
2267
|
-
if (
|
|
2268
|
-
const r = parseFloat(
|
|
2369
|
+
const s = (o) => {
|
|
2370
|
+
if (o.localName === "blip" && (e = e || T(o, "embed") || T(o, "link")), o.localName === "imagedata" && (e = e || T(o, "id")), o.localName === "extent") {
|
|
2371
|
+
const r = parseFloat(o.getAttribute("cx") || "0");
|
|
2269
2372
|
r && (i = Math.round(r / 9525));
|
|
2270
2373
|
}
|
|
2271
|
-
for (const r of Array.from(
|
|
2374
|
+
for (const r of Array.from(o.children)) s(r);
|
|
2272
2375
|
};
|
|
2273
2376
|
if (s(t), !e) return "";
|
|
2274
2377
|
const l = this.images.get(e);
|
|
2275
2378
|
if (!l) return "";
|
|
2276
|
-
const
|
|
2277
|
-
return `<img src="${l}" alt=""${
|
|
2379
|
+
const n = i ? ` width="${i}"` : "";
|
|
2380
|
+
return `<img src="${l}" alt=""${n}>`;
|
|
2278
2381
|
}
|
|
2279
2382
|
convertTable(t) {
|
|
2280
2383
|
let e = '<table style="border-collapse:collapse;width:100%"><tbody>';
|
|
2281
2384
|
for (const i of P(t, "tr")) {
|
|
2282
2385
|
e += "<tr>";
|
|
2283
2386
|
for (const s of P(i, "tc")) {
|
|
2284
|
-
const l = parseInt(T(
|
|
2285
|
-
let
|
|
2387
|
+
const l = parseInt(T(M(s, "tcPr", "gridSpan")) || "1", 10) || 1, n = l > 1 ? ` colspan="${l}"` : "";
|
|
2388
|
+
let o = "";
|
|
2286
2389
|
for (const r of Array.from(s.children))
|
|
2287
|
-
r.localName === "p" ?
|
|
2288
|
-
e += `<td style="border:1px solid #b9c2cc"${
|
|
2390
|
+
r.localName === "p" ? o += this.convertPara(r) : r.localName === "tbl" && (o += this.convertTable(r));
|
|
2391
|
+
e += `<td style="border:1px solid #b9c2cc"${n}>${o || "<br>"}</td>`;
|
|
2289
2392
|
}
|
|
2290
2393
|
e += "</tr>";
|
|
2291
2394
|
}
|
|
2292
2395
|
return e + "</tbody></table>";
|
|
2293
2396
|
}
|
|
2294
2397
|
}
|
|
2295
|
-
async function
|
|
2296
|
-
const t =
|
|
2398
|
+
async function zt(d) {
|
|
2399
|
+
const t = d instanceof ArrayBuffer ? d : await d.arrayBuffer(), e = Ft(t), i = new TextDecoder(), s = async (u) => {
|
|
2297
2400
|
const v = e.get(u);
|
|
2298
|
-
return v ? new DOMParser().parseFromString(i.decode(await
|
|
2299
|
-
}, l = await s("word/document.xml"),
|
|
2300
|
-
let
|
|
2301
|
-
if (
|
|
2302
|
-
for (const u of Array.from(
|
|
2401
|
+
return v ? new DOMParser().parseFromString(i.decode(await K(t, v)), "application/xml") : null;
|
|
2402
|
+
}, l = await s("word/document.xml"), n = l == null ? void 0 : l.getElementsByTagName("*");
|
|
2403
|
+
let o = null;
|
|
2404
|
+
if (n) {
|
|
2405
|
+
for (const u of Array.from(n))
|
|
2303
2406
|
if (u.localName === "body") {
|
|
2304
|
-
|
|
2407
|
+
o = u;
|
|
2305
2408
|
break;
|
|
2306
2409
|
}
|
|
2307
2410
|
}
|
|
2308
|
-
if (!
|
|
2309
|
-
const r = /* @__PURE__ */ new Map(),
|
|
2411
|
+
if (!o) throw new Error("word/document.xml missing or invalid");
|
|
2412
|
+
const r = /* @__PURE__ */ new Map(), a = /* @__PURE__ */ new Map(), h = await s("word/_rels/document.xml.rels");
|
|
2310
2413
|
if (h)
|
|
2311
2414
|
for (const u of Array.from(h.getElementsByTagName("*"))) {
|
|
2312
2415
|
if (u.localName !== "Relationship") continue;
|
|
2313
2416
|
const v = u.getAttribute("Id") || "", b = u.getAttribute("Target") || "", x = u.getAttribute("Type") || "";
|
|
2314
|
-
/hyperlink/i.test(x) ? r.set(v, b) : /image/i.test(x) &&
|
|
2417
|
+
/hyperlink/i.test(x) ? r.set(v, b) : /image/i.test(x) && a.set(v, b);
|
|
2315
2418
|
}
|
|
2316
|
-
const
|
|
2317
|
-
for (const [u, v] of
|
|
2419
|
+
const p = /* @__PURE__ */ new Map();
|
|
2420
|
+
for (const [u, v] of a) {
|
|
2318
2421
|
const b = v.startsWith("/") ? v.slice(1) : "word/" + v.replace(/^\.\//, ""), x = e.get(b);
|
|
2319
2422
|
if (!x) continue;
|
|
2320
|
-
const C = (b.split(".").pop() || "").toLowerCase(),
|
|
2321
|
-
if (
|
|
2423
|
+
const C = (b.split(".").pop() || "").toLowerCase(), S = Ot[C];
|
|
2424
|
+
if (S)
|
|
2322
2425
|
try {
|
|
2323
|
-
|
|
2426
|
+
p.set(u, `data:${S};base64,${$t(await K(t, x))}`);
|
|
2324
2427
|
} catch {
|
|
2325
2428
|
}
|
|
2326
2429
|
}
|
|
@@ -2329,77 +2432,77 @@ async function Ht(p) {
|
|
|
2329
2432
|
const u = /* @__PURE__ */ new Map(), v = Array.from(g.getElementsByTagName("*"));
|
|
2330
2433
|
for (const b of v) {
|
|
2331
2434
|
if (b.localName !== "abstractNum") continue;
|
|
2332
|
-
const x = T(b, "abstractNumId"), C = P(b, "lvl").find((w) => T(w, "ilvl") === "0") || P(b, "lvl")[0],
|
|
2333
|
-
u.set(x,
|
|
2435
|
+
const x = T(b, "abstractNumId"), C = P(b, "lvl").find((w) => T(w, "ilvl") === "0") || P(b, "lvl")[0], S = C ? T(M(C, "numFmt")) : "";
|
|
2436
|
+
u.set(x, S === "bullet" ? "ul" : "ol");
|
|
2334
2437
|
}
|
|
2335
2438
|
for (const b of v) {
|
|
2336
2439
|
if (b.localName !== "num") continue;
|
|
2337
|
-
const x = T(b, "numId"), C = T(
|
|
2440
|
+
const x = T(b, "numId"), C = T(M(b, "abstractNumId"));
|
|
2338
2441
|
m.set(x, u.get(C) || "ul");
|
|
2339
2442
|
}
|
|
2340
2443
|
}
|
|
2341
|
-
return new
|
|
2444
|
+
return new _t(r, p, m).convertBody(o);
|
|
2342
2445
|
}
|
|
2343
|
-
const
|
|
2446
|
+
const Ut = ["nw", "ne", "sw", "se"], O = ["img-left", "img-right", "img-top", "img-center"], $ = {
|
|
2344
2447
|
"img-left": "tplimgleft",
|
|
2345
2448
|
"img-right": "tplimgright",
|
|
2346
2449
|
"img-top": "tplimgtop",
|
|
2347
2450
|
"img-center": "tplimgcenter"
|
|
2348
|
-
},
|
|
2349
|
-
"img-left":
|
|
2350
|
-
"img-right":
|
|
2351
|
-
"img-top":
|
|
2352
|
-
"img-center":
|
|
2353
|
-
},
|
|
2354
|
-
let E = null, A = null,
|
|
2451
|
+
}, Wt = {
|
|
2452
|
+
"img-left": c.tplleft,
|
|
2453
|
+
"img-right": c.tplright,
|
|
2454
|
+
"img-top": c.tpltop,
|
|
2455
|
+
"img-center": c.tplcenter
|
|
2456
|
+
}, jt = ".tox,.pop,.tblctx,.imgctx,.selctx,.dlg";
|
|
2457
|
+
let E = null, A = null, _ = 0, et = !1;
|
|
2355
2458
|
function N() {
|
|
2356
|
-
clearTimeout(
|
|
2459
|
+
clearTimeout(_), A = null, E && E.classList.remove("show");
|
|
2357
2460
|
}
|
|
2358
|
-
function
|
|
2359
|
-
const t =
|
|
2461
|
+
function Vt(d) {
|
|
2462
|
+
const t = d.dataset.tip;
|
|
2360
2463
|
if (!t) return;
|
|
2361
|
-
A =
|
|
2464
|
+
A = d, clearTimeout(_);
|
|
2362
2465
|
const e = E && E.classList.contains("show") ? 60 : 350;
|
|
2363
|
-
|
|
2364
|
-
if (A !==
|
|
2466
|
+
_ = window.setTimeout(() => {
|
|
2467
|
+
if (A !== d || !document.contains(d)) return;
|
|
2365
2468
|
E || (E = document.createElement("div"), E.className = "etip", document.body.appendChild(E)), E.textContent = t, E.classList.add("show");
|
|
2366
|
-
const i =
|
|
2367
|
-
let
|
|
2368
|
-
|
|
2369
|
-
let
|
|
2370
|
-
|
|
2469
|
+
const i = d.getBoundingClientRect(), s = E.offsetWidth, l = E.offsetHeight;
|
|
2470
|
+
let n = i.left + i.width / 2 - s / 2;
|
|
2471
|
+
n = Math.max(6, Math.min(n, innerWidth - s - 6));
|
|
2472
|
+
let o = i.bottom + 7;
|
|
2473
|
+
o + l > innerHeight - 6 && (o = i.top - l - 7), E.style.left = n + "px", E.style.top = o + "px";
|
|
2371
2474
|
}, e);
|
|
2372
2475
|
}
|
|
2373
|
-
function
|
|
2374
|
-
|
|
2375
|
-
const t =
|
|
2376
|
-
if (!e || !e.closest(
|
|
2476
|
+
function Xt() {
|
|
2477
|
+
et || (et = !0, document.addEventListener("mouseover", (d) => {
|
|
2478
|
+
const t = d.target, e = t.closest ? t.closest("[title],[data-tip]") : null;
|
|
2479
|
+
if (!e || !e.closest(jt) || e.closest(".earea")) {
|
|
2377
2480
|
e !== A && N();
|
|
2378
2481
|
return;
|
|
2379
2482
|
}
|
|
2380
2483
|
const i = e.getAttribute("title");
|
|
2381
|
-
i && (e.dataset.tip = i, e.removeAttribute("title"), e.getAttribute("aria-label") || e.setAttribute("aria-label", i)), e !== A &&
|
|
2382
|
-
}), document.addEventListener("mouseout", (
|
|
2383
|
-
A && !A.contains(
|
|
2484
|
+
i && (e.dataset.tip = i, e.removeAttribute("title"), e.getAttribute("aria-label") || e.setAttribute("aria-label", i)), e !== A && Vt(e);
|
|
2485
|
+
}), document.addEventListener("mouseout", (d) => {
|
|
2486
|
+
A && !A.contains(d.relatedTarget) && N();
|
|
2384
2487
|
}), document.addEventListener("mousedown", N, !0), addEventListener("scroll", N, !0));
|
|
2385
2488
|
}
|
|
2386
|
-
const
|
|
2387
|
-
function
|
|
2388
|
-
for (const t of
|
|
2389
|
-
if (
|
|
2390
|
-
if (
|
|
2489
|
+
const Qt = /[\u0590-\u05FF\u0600-\u06FF\u0750-\u077F\u0780-\u07BF\u08A0-\u08FF\uFB1D-\uFB4F\uFB50-\uFDFF\uFE70-\uFEFF]/, Gt = new RegExp("\\p{L}", "u"), Yt = "p,div,li,td,th,blockquote,h1,h2,h3,h4,h5,h6,pre,figcaption";
|
|
2490
|
+
function Kt(d) {
|
|
2491
|
+
for (const t of d) {
|
|
2492
|
+
if (Qt.test(t)) return "rtl";
|
|
2493
|
+
if (Gt.test(t)) return "ltr";
|
|
2391
2494
|
}
|
|
2392
2495
|
return null;
|
|
2393
2496
|
}
|
|
2394
|
-
function
|
|
2497
|
+
function ot(d) {
|
|
2395
2498
|
let t = "";
|
|
2396
|
-
return
|
|
2499
|
+
return d.childNodes.forEach((e) => {
|
|
2397
2500
|
if (e.nodeType === Node.TEXT_NODE)
|
|
2398
2501
|
t += e.nodeValue || "";
|
|
2399
2502
|
else if (e.nodeType === Node.ELEMENT_NODE) {
|
|
2400
2503
|
const i = e, s = (i.getAttribute("dir") || "").toLowerCase();
|
|
2401
2504
|
if (s === "rtl" || s === "ltr") return;
|
|
2402
|
-
t +=
|
|
2505
|
+
t += ot(i);
|
|
2403
2506
|
}
|
|
2404
2507
|
}), t;
|
|
2405
2508
|
}
|
|
@@ -2419,20 +2522,20 @@ const I = class I {
|
|
|
2419
2522
|
statusbar: t.statusbar ?? !0,
|
|
2420
2523
|
readonly: t.readonly ?? !1,
|
|
2421
2524
|
draftKey: t.draftKey ?? (typeof location < "u" ? location.pathname : "default"),
|
|
2422
|
-
fontFamilyFormats: t.fontFamilyFormats ??
|
|
2525
|
+
fontFamilyFormats: t.fontFamilyFormats ?? ht,
|
|
2423
2526
|
imageFileTypes: t.imageFileTypes ?? ["image/jpeg", "image/jpg", "image/png", "image/gif", "image/bmp", "image/webp"],
|
|
2424
2527
|
videoFileTypes: t.videoFileTypes ?? ["video/mp4", "video/webm", "video/ogg"]
|
|
2425
|
-
}, this.imageUploadHandler = t.imageUploadHandler, this.onImageUploadError = t.onImageUploadError, this.videoUploadHandler = t.videoUploadHandler, this.onVideoUploadError = t.onVideoUploadError, this.contentStyle = t.contentStyle, this.applyTheme(t), this.lang = this.options.language, this.draftStorageKey = "tmclone-draft:" + this.options.draftKey, this.initDOM(), this.bindEvents(), this.initUI(), this.recordRevision(), this.options.onReady(this);
|
|
2528
|
+
}, this.imageUploadHandler = t.imageUploadHandler, this.onImageUploadError = t.onImageUploadError, this.videoUploadHandler = t.videoUploadHandler, this.onVideoUploadError = t.onVideoUploadError, this.contentStyle = t.contentStyle, this.applyTheme(t), this.lang = this.options.language, this.draftStorageKey = "tmclone-draft:" + this.options.draftKey, this.initDOM(), this.bindEvents(), this.initUI(), this.recordRevision(), this.stampExistingImages(), this.options.onReady(this);
|
|
2426
2529
|
}
|
|
2427
2530
|
t(t) {
|
|
2428
|
-
const e =
|
|
2531
|
+
const e = D(this.lang)[t];
|
|
2429
2532
|
return typeof e == "string" ? e : e.join(",");
|
|
2430
2533
|
}
|
|
2431
2534
|
tArr(t) {
|
|
2432
|
-
return
|
|
2535
|
+
return D(this.lang)[t];
|
|
2433
2536
|
}
|
|
2434
2537
|
dir() {
|
|
2435
|
-
return
|
|
2538
|
+
return D(this.lang).dir;
|
|
2436
2539
|
}
|
|
2437
2540
|
/* ---------------------------------------------------------- DOM setup */
|
|
2438
2541
|
initDOM() {
|
|
@@ -2445,7 +2548,7 @@ const I = class I {
|
|
|
2445
2548
|
</span>
|
|
2446
2549
|
`, this.sbHelp = this.statusbar.querySelector(".mid"), this.sbWords = this.statusbar.querySelector(".words");
|
|
2447
2550
|
const e = this.statusbar.querySelector(".grip");
|
|
2448
|
-
this.bindGrip(e), this.shell.appendChild(this.menubar), this.shell.appendChild(this.toolbar), this.shell.appendChild(this.ed), this.shell.appendChild(this.statusbar), this.contentStyle && (this.contentStyleEl = document.createElement("style"), this.contentStyleEl.textContent = this.scopeContentStyle(this.contentStyle), this.shell.appendChild(this.contentStyleEl)), t.appendChild(this.shell),
|
|
2551
|
+
this.bindGrip(e), this.shell.appendChild(this.menubar), this.shell.appendChild(this.toolbar), this.shell.appendChild(this.ed), this.shell.appendChild(this.statusbar), this.contentStyle && (this.contentStyleEl = document.createElement("style"), this.contentStyleEl.textContent = this.scopeContentStyle(this.contentStyle), this.shell.appendChild(this.contentStyleEl)), t.appendChild(this.shell), Xt(), this.options.statusbar || (this.statusbar.style.display = "none"), this.imgInput = document.createElement("input"), this.imgInput.type = "file", this.imgInput.accept = this.options.imageFileTypes.join(","), this.imgInput.style.display = "none", t.appendChild(this.imgInput), this.vidInput = document.createElement("input"), this.vidInput.type = "file", this.vidInput.accept = this.options.videoFileTypes.join(","), this.vidInput.style.display = "none", t.appendChild(this.vidInput), this.docInput = document.createElement("input"), this.docInput.type = "file", this.docInput.accept = ".docx,application/vnd.openxmlformats-officedocument.wordprocessingml.document", this.docInput.style.display = "none", t.appendChild(this.docInput);
|
|
2449
2552
|
}
|
|
2450
2553
|
/** Theme options land as CSS variables on the document root rather than the editor
|
|
2451
2554
|
* shell, because dialogs, popups and floating context toolbars are appended to
|
|
@@ -2465,12 +2568,12 @@ const I = class I {
|
|
|
2465
2568
|
let e = 0, i = 0;
|
|
2466
2569
|
const s = (l) => {
|
|
2467
2570
|
e = l.clientY, i = this.ed.offsetHeight, l.preventDefault();
|
|
2468
|
-
const
|
|
2571
|
+
const n = (r) => {
|
|
2469
2572
|
this.ed.style.height = Math.max(120, i + r.clientY - e) + "px";
|
|
2470
|
-
},
|
|
2471
|
-
window.removeEventListener("mousemove",
|
|
2573
|
+
}, o = () => {
|
|
2574
|
+
window.removeEventListener("mousemove", n), window.removeEventListener("mouseup", o);
|
|
2472
2575
|
};
|
|
2473
|
-
window.addEventListener("mousemove",
|
|
2576
|
+
window.addEventListener("mousemove", n), window.addEventListener("mouseup", o);
|
|
2474
2577
|
};
|
|
2475
2578
|
t.addEventListener("mousedown", s), this.listeners.push(() => t.removeEventListener("mousedown", s));
|
|
2476
2579
|
}
|
|
@@ -2488,46 +2591,46 @@ const I = class I {
|
|
|
2488
2591
|
}), this.on(this.ed, "keydown", (t) => {
|
|
2489
2592
|
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);
|
|
2490
2593
|
}), this.on(this.ed, "paste", (t) => this.handlePaste(t)), this.on(this.ed, "drop", (t) => {
|
|
2491
|
-
var l,
|
|
2594
|
+
var l, n, o, r;
|
|
2492
2595
|
t.preventDefault();
|
|
2493
2596
|
const e = t.target, i = (l = e.closest) == null ? void 0 : l.call(e, ".img-ph:not(.vid-ph)");
|
|
2494
2597
|
if (i && this.ed.contains(i) && !this.options.readonly) {
|
|
2495
|
-
const
|
|
2496
|
-
|
|
2598
|
+
const a = Array.from(((n = t.dataTransfer) == null ? void 0 : n.files) || []).find((h) => h.type.startsWith("image/"));
|
|
2599
|
+
a && this.readImageFileInto(a, i);
|
|
2497
2600
|
return;
|
|
2498
2601
|
}
|
|
2499
|
-
const s = (
|
|
2602
|
+
const s = (o = e.closest) == null ? void 0 : o.call(e, ".vid-ph");
|
|
2500
2603
|
if (s && this.ed.contains(s) && !this.options.readonly) {
|
|
2501
|
-
const
|
|
2502
|
-
|
|
2604
|
+
const a = Array.from(((r = t.dataTransfer) == null ? void 0 : r.files) || []).find((h) => h.type.startsWith("video/"));
|
|
2605
|
+
a && this.readVideoFileInto(a, s);
|
|
2503
2606
|
}
|
|
2504
2607
|
}), this.on(this.ed, "dragover", (t) => t.preventDefault()), this.on(this.ed, "mousedown", (t) => {
|
|
2505
|
-
var h,
|
|
2608
|
+
var h, p, m, g, u, v, b;
|
|
2506
2609
|
const e = t.target, i = (h = e.closest) == null ? void 0 : h.call(e, "table");
|
|
2507
2610
|
i && this.ed.contains(i) ? this.selectTableForResize(i) : this.clearTableHandles();
|
|
2508
|
-
const s = (
|
|
2611
|
+
const s = (p = e.closest) == null ? void 0 : p.call(e, ".img-ph:not(.vid-ph)");
|
|
2509
2612
|
s && this.ed.contains(s) && !this.options.readonly ? (t.preventDefault(), this.ed.focus(), this.selectImgPlaceholder(s)) : this.clearImgPlaceholderSel();
|
|
2510
2613
|
const l = (m = e.closest) == null ? void 0 : m.call(e, ".vid-ph");
|
|
2511
2614
|
l && this.ed.contains(l) && !this.options.readonly ? (t.preventDefault(), this.ed.focus(), this.selectVphPlaceholder(l)) : this.clearVphPlaceholderSel();
|
|
2512
|
-
const
|
|
2513
|
-
|
|
2514
|
-
const
|
|
2515
|
-
|
|
2615
|
+
const n = (g = e.closest) == null ? void 0 : g.call(e, ".tpl");
|
|
2616
|
+
n && this.ed.contains(n) && !this.options.readonly ? this.selectTemplate(n) : this.clearTplSel();
|
|
2617
|
+
const o = (u = e.closest) == null ? void 0 : u.call(e, "pre.code-block");
|
|
2618
|
+
o && this.ed.contains(o) && !this.options.readonly ? (t.preventDefault(), this.selectCodeEl(o)) : this.clearCodeSel();
|
|
2516
2619
|
const r = (v = e.closest) == null ? void 0 : v.call(e, "img");
|
|
2517
2620
|
r && this.ed.contains(r) && !this.options.readonly ? (t.preventDefault(), this.selectImage(r)) : this.clearImageHandles();
|
|
2518
|
-
const
|
|
2519
|
-
|
|
2621
|
+
const a = (b = e.closest) == null ? void 0 : b.call(e, "video, .video-embed");
|
|
2622
|
+
a && this.ed.contains(a) && !this.options.readonly ? (t.preventDefault(), this.selectVideo(a)) : this.clearVidHandles();
|
|
2520
2623
|
}), this.on(this.ed, "mouseover", (t) => {
|
|
2521
2624
|
var i, s;
|
|
2522
2625
|
if (this.options.readonly) return;
|
|
2523
2626
|
const e = (s = (i = t.target).closest) == null ? void 0 : s.call(i, "img");
|
|
2524
2627
|
e && this.ed.contains(e) && (this.cancelImgHide(), this.selectImage(e));
|
|
2525
2628
|
}), this.on(this.ed, "mouseout", (t) => {
|
|
2526
|
-
var s, l,
|
|
2629
|
+
var s, l, n, o;
|
|
2527
2630
|
const e = (l = (s = t.target).closest) == null ? void 0 : l.call(s, "img");
|
|
2528
2631
|
if (!e) return;
|
|
2529
2632
|
const i = t.relatedTarget;
|
|
2530
|
-
i && ((
|
|
2633
|
+
i && ((n = this.imgCtx) != null && n.contains(i) || this.imgHandles.some((r) => r.contains(i)) || ((o = i.closest) == null ? void 0 : o.call(i, "img")) === e) || this.scheduleImgHide();
|
|
2531
2634
|
}), this.on(this.ed, "scroll", () => {
|
|
2532
2635
|
this.positionTableHandles(), this.positionImageHandles(), this.positionImgPhCtx(), this.positionTplCtx(), this.positionVphCtx(), this.positionVidCtx(), this.positionCodeCtx();
|
|
2533
2636
|
}), this.onWin(
|
|
@@ -2555,11 +2658,7 @@ const I = class I {
|
|
|
2555
2658
|
}
|
|
2556
2659
|
const i = new FileReader();
|
|
2557
2660
|
i.onload = () => {
|
|
2558
|
-
this.restoreSel(),
|
|
2559
|
-
"insertHTML",
|
|
2560
|
-
!1,
|
|
2561
|
-
`<img src="${i.result}" title="${t.name.replace(/"/g, "")}" alt="">`
|
|
2562
|
-
), this.onChange();
|
|
2661
|
+
this.restoreSel(), this.insertImageHTML(i.result, t.name.replace(/"/g, "")), this.onChange();
|
|
2563
2662
|
}, i.readAsDataURL(t);
|
|
2564
2663
|
}), this.on(this.vidInput, "change", () => {
|
|
2565
2664
|
var s;
|
|
@@ -2613,33 +2712,41 @@ const I = class I {
|
|
|
2613
2712
|
* content with no strongly-directional character anywhere falls back to the
|
|
2614
2713
|
* editor's current direction. */
|
|
2615
2714
|
getContentForEmail() {
|
|
2616
|
-
const t = (o,
|
|
2617
|
-
const
|
|
2618
|
-
o.setAttribute("style",
|
|
2715
|
+
const t = (o, r) => {
|
|
2716
|
+
const a = (o.getAttribute("style") || "").trim();
|
|
2717
|
+
o.setAttribute("style", a ? a.replace(/;?$/, "; ") + r : r);
|
|
2619
2718
|
}, e = document.createElement("div");
|
|
2620
2719
|
e.innerHTML = this.ed.innerHTML;
|
|
2621
2720
|
let i = null;
|
|
2622
2721
|
e.querySelectorAll("[dir]").forEach((o) => {
|
|
2623
|
-
const
|
|
2624
|
-
if (
|
|
2625
|
-
const
|
|
2626
|
-
i || (i =
|
|
2627
|
-
}), e.querySelectorAll(
|
|
2628
|
-
const
|
|
2629
|
-
if (
|
|
2630
|
-
const
|
|
2631
|
-
if (!
|
|
2632
|
-
i || (i =
|
|
2633
|
-
const
|
|
2634
|
-
t(o,
|
|
2722
|
+
const r = (o.getAttribute("dir") || "").toLowerCase();
|
|
2723
|
+
if (r !== "rtl" && r !== "ltr") return;
|
|
2724
|
+
const a = r;
|
|
2725
|
+
i || (i = a), /text-align\s*:/i.test(o.getAttribute("style") || "") || t(o, `text-align:${a === "rtl" ? "right" : "left"}`);
|
|
2726
|
+
}), e.querySelectorAll(Yt).forEach((o) => {
|
|
2727
|
+
const r = (o.getAttribute("dir") || "").toLowerCase();
|
|
2728
|
+
if (r === "rtl" || r === "ltr") return;
|
|
2729
|
+
const a = Kt(ot(o));
|
|
2730
|
+
if (!a) return;
|
|
2731
|
+
i || (i = a), o.setAttribute("dir", a);
|
|
2732
|
+
const h = /text-align\s*:/i.test(o.getAttribute("style") || "");
|
|
2733
|
+
t(o, h ? `direction:${a}` : `direction:${a};text-align:${a === "rtl" ? "right" : "left"}`);
|
|
2734
|
+
});
|
|
2735
|
+
const s = this.ed.querySelectorAll("img");
|
|
2736
|
+
e.querySelectorAll("img").forEach((o, r) => {
|
|
2737
|
+
if (o.closest(".tpl-media")) return;
|
|
2738
|
+
const a = s[r], h = Math.round((a == null ? void 0 : a.getBoundingClientRect().width) || 0);
|
|
2739
|
+
h > 0 && !o.getAttribute("width") && o.setAttribute("width", String(h));
|
|
2740
|
+
const p = o.getAttribute("style") || "";
|
|
2741
|
+
h > 0 && !/(^|;)\s*width\s*:/i.test(p) && t(o, `width:${h}px`), /max-width\s*:/i.test(o.getAttribute("style") || "") || t(o, "max-width:100%"), /(^|;)\s*height\s*:/i.test(o.getAttribute("style") || "") || t(o, "height:auto");
|
|
2635
2742
|
});
|
|
2636
|
-
const
|
|
2743
|
+
const l = i || this.ed.getAttribute("dir") || this.dir();
|
|
2637
2744
|
return e.querySelectorAll("table:not([dir])").forEach((o) => {
|
|
2638
|
-
o.setAttribute("dir",
|
|
2639
|
-
}), `<div dir="${
|
|
2745
|
+
o.setAttribute("dir", l), /direction\s*:/i.test(o.getAttribute("style") || "") || t(o, `direction:${l}`);
|
|
2746
|
+
}), `<div dir="${l}" style="direction:${l};text-align:${l === "rtl" ? "right" : "left"}">${e.innerHTML}</div>`;
|
|
2640
2747
|
}
|
|
2641
2748
|
setContent(t) {
|
|
2642
|
-
this.ed.innerHTML = t || "<p><br></p>", this.refreshState(), this.clearTableHandles(), this.clearImageHandles(), this.clearImgPlaceholderSel(), this.clearTplSel(), this.clearVphPlaceholderSel(), this.clearVidHandles(), this.clearCodeSel(), this.clearSelToolbar(), this.onChange();
|
|
2749
|
+
this.ed.innerHTML = t || "<p><br></p>", this.refreshState(), this.clearTableHandles(), this.clearImageHandles(), this.clearImgPlaceholderSel(), this.clearTplSel(), this.clearVphPlaceholderSel(), this.clearVidHandles(), this.clearCodeSel(), this.clearSelToolbar(), this.onChange(), this.stampExistingImages();
|
|
2643
2750
|
}
|
|
2644
2751
|
insertContent(t) {
|
|
2645
2752
|
this.restoreSel(), document.execCommand("insertHTML", !1, t), this.saveSel(), this.refreshState(), this.onChange();
|
|
@@ -2651,7 +2758,7 @@ const I = class I {
|
|
|
2651
2758
|
this.ed.focus();
|
|
2652
2759
|
}
|
|
2653
2760
|
async importWordFile(t) {
|
|
2654
|
-
const e = await
|
|
2761
|
+
const e = await zt(t);
|
|
2655
2762
|
this.recordRevision(), this.setContent(e), this.recordRevision();
|
|
2656
2763
|
}
|
|
2657
2764
|
restoreDraft() {
|
|
@@ -2710,8 +2817,8 @@ const I = class I {
|
|
|
2710
2817
|
t.preventDefault();
|
|
2711
2818
|
const l = document.createElement("p");
|
|
2712
2819
|
l.appendChild(document.createElement("br")), s.after(l), i.remove(), s.firstElementChild || s.remove();
|
|
2713
|
-
const
|
|
2714
|
-
|
|
2820
|
+
const n = document.createRange();
|
|
2821
|
+
n.setStart(l, 0), n.collapse(!0), e.removeAllRanges(), e.addRange(n), this.saveSel(), this.onChange();
|
|
2715
2822
|
}
|
|
2716
2823
|
selectedBlocks() {
|
|
2717
2824
|
const t = window.getSelection();
|
|
@@ -2761,30 +2868,30 @@ const I = class I {
|
|
|
2761
2868
|
s.className = "revprev";
|
|
2762
2869
|
const l = document.createElement("button");
|
|
2763
2870
|
l.type = "button", l.className = "revrestore", l.textContent = this.t("restore");
|
|
2764
|
-
let
|
|
2765
|
-
const
|
|
2871
|
+
let n = this.revisions.length - 1;
|
|
2872
|
+
const o = new Intl.DateTimeFormat(this.lang === "ar" ? "ar-AE" : "en-GB", {
|
|
2766
2873
|
year: "numeric",
|
|
2767
2874
|
month: "short",
|
|
2768
2875
|
day: "numeric",
|
|
2769
2876
|
hour: "2-digit",
|
|
2770
2877
|
minute: "2-digit",
|
|
2771
2878
|
second: "2-digit"
|
|
2772
|
-
}), r = {},
|
|
2773
|
-
|
|
2879
|
+
}), r = {}, a = (h) => {
|
|
2880
|
+
n = h, this.revisions.forEach((p, m) => {
|
|
2774
2881
|
var g;
|
|
2775
2882
|
return (g = r[m]) == null ? void 0 : g.classList.toggle("on", m === h);
|
|
2776
2883
|
}), s.innerHTML = this.revisions[h].html, l.disabled = h === this.revisions.length - 1;
|
|
2777
2884
|
};
|
|
2778
2885
|
for (let h = this.revisions.length - 1; h >= 0; h--) {
|
|
2779
|
-
const
|
|
2886
|
+
const p = this.revisions[h], m = document.createElement("button");
|
|
2780
2887
|
m.type = "button";
|
|
2781
|
-
const g = (new DOMParser().parseFromString(
|
|
2782
|
-
m.innerHTML = `<span>${v ? this.t("currentver") :
|
|
2888
|
+
const g = (new DOMParser().parseFromString(p.html, "text/html").body.textContent || "").trim(), u = g ? g.split(/\s+/).length : 0, v = h === this.revisions.length - 1;
|
|
2889
|
+
m.innerHTML = `<span>${v ? this.t("currentver") : o.format(new Date(p.time))}</span><span class="wc">${u} ${this.t("words")}</span>`, m.addEventListener("click", () => a(h)), r[h] = m, i.appendChild(m);
|
|
2783
2890
|
}
|
|
2784
2891
|
i.append(l), l.addEventListener("click", () => {
|
|
2785
|
-
const h = this.revisions[
|
|
2892
|
+
const h = this.revisions[n];
|
|
2786
2893
|
h && (this.recordRevision(), this.setContent(h.html), this.recordRevision(), this.closeDlg());
|
|
2787
|
-
}), e.append(i, s), t.appendChild(e),
|
|
2894
|
+
}), e.append(i, s), t.appendChild(e), a(n);
|
|
2788
2895
|
});
|
|
2789
2896
|
}
|
|
2790
2897
|
/* ---------------------------------------------------------- popups / menus */
|
|
@@ -2818,13 +2925,13 @@ const I = class I {
|
|
|
2818
2925
|
const i = e.getBoundingClientRect(), s = e.closest(".pop");
|
|
2819
2926
|
this.closeSubFrom(s ? this.subLevelOf(s) : 0);
|
|
2820
2927
|
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", (
|
|
2822
|
-
|
|
2928
|
+
l.className = "pop sub", l.dir = this.dir(), t.subBuild ? t.subBuild(l) : t.sub && this.menuItems(l, t.sub), l.addEventListener("mousedown", (a) => {
|
|
2929
|
+
a.target.tagName !== "INPUT" && a.preventDefault();
|
|
2823
2930
|
}), document.body.appendChild(l);
|
|
2824
|
-
let
|
|
2825
|
-
|
|
2931
|
+
let o = this.dir() === "rtl" ? i.left - l.offsetWidth + 2 : i.right - 2;
|
|
2932
|
+
o = Math.max(8, Math.min(o + scrollX, scrollX + innerWidth - l.offsetWidth - 8));
|
|
2826
2933
|
let r = i.top + scrollY - 6;
|
|
2827
|
-
r = Math.max(8 + scrollY, Math.min(r, scrollY + innerHeight - l.offsetHeight - 8)), l.style.left =
|
|
2934
|
+
r = Math.max(8 + scrollY, Math.min(r, scrollY + innerHeight - l.offsetHeight - 8)), l.style.left = o + "px", l.style.top = r + "px", this.subStack.push(l);
|
|
2828
2935
|
}
|
|
2829
2936
|
popup(t, e, i) {
|
|
2830
2937
|
if (this.openPop && this.popAnchor === t) {
|
|
@@ -2836,11 +2943,11 @@ const I = class I {
|
|
|
2836
2943
|
s.className = "pop" + (i ? " " + i : ""), s.dir = this.dir(), e(s), document.body.appendChild(s);
|
|
2837
2944
|
const l = t.getBoundingClientRect();
|
|
2838
2945
|
s.style.minWidth = Math.max(160, Math.round(l.width)) + "px";
|
|
2839
|
-
let
|
|
2840
|
-
|
|
2946
|
+
let n = l.bottom + scrollY + 2;
|
|
2947
|
+
n = Math.max(8 + scrollY, Math.min(n, scrollY + innerHeight - s.offsetHeight - 8)), s.style.top = n + "px";
|
|
2841
2948
|
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", (
|
|
2843
|
-
|
|
2949
|
+
r = Math.max(8, Math.min(r + scrollX, scrollX + innerWidth - s.offsetWidth - 8)), s.style.left = r + "px", s.addEventListener("mousedown", (a) => {
|
|
2950
|
+
a.target.tagName !== "INPUT" && a.preventDefault();
|
|
2844
2951
|
}), this.openPop = s, this.popAnchor = t, t.classList.add("open");
|
|
2845
2952
|
}
|
|
2846
2953
|
menuItems(t, e) {
|
|
@@ -2850,44 +2957,44 @@ const I = class I {
|
|
|
2850
2957
|
return;
|
|
2851
2958
|
}
|
|
2852
2959
|
const s = !!(i.sub || i.subBuild), l = document.createElement("button");
|
|
2853
|
-
l.className = "mi" + (i.on ? " on" : ""), l.innerHTML = `<span class="ic">${i.icon || ""}</span><span class="prev" ${i.previewStyle ? `style="${i.previewStyle}"` : ""}>${i.label}</span>${i.shortcut ? `<span class="sc">${i.shortcut}</span>` : ""}${s ? `<span class="subarrow">${
|
|
2960
|
+
l.className = "mi" + (i.on ? " on" : ""), l.innerHTML = `<span class="ic">${i.icon || ""}</span><span class="prev" ${i.previewStyle ? `style="${i.previewStyle}"` : ""}>${i.label}</span>${i.shortcut ? `<span class="sc">${i.shortcut}</span>` : ""}${s ? `<span class="subarrow">${c.chev}</span>` : ""}`, l.addEventListener("click", () => {
|
|
2854
2961
|
i.action && (this.closePop(), i.action());
|
|
2855
2962
|
}), l.addEventListener("mouseenter", () => {
|
|
2856
|
-
var
|
|
2857
|
-
s ? this.openSubFor(i, l) : this.closeSubFrom(this.subLevelOf(t)), (
|
|
2963
|
+
var n;
|
|
2964
|
+
s ? this.openSubFor(i, l) : this.closeSubFrom(this.subLevelOf(t)), (n = i.hover) == null || n.call(i, !0);
|
|
2858
2965
|
}), l.addEventListener("mouseleave", () => {
|
|
2859
|
-
var
|
|
2860
|
-
return (
|
|
2966
|
+
var n;
|
|
2967
|
+
return (n = i.hover) == null ? void 0 : n.call(i, !1);
|
|
2861
2968
|
}), t.appendChild(l);
|
|
2862
2969
|
});
|
|
2863
2970
|
}
|
|
2864
2971
|
/* ---------------------------------------------------------- toolbar builders */
|
|
2865
2972
|
tbtn(t, e, i, s) {
|
|
2866
2973
|
const l = document.createElement("button");
|
|
2867
|
-
return l.className = "tbtn", l.type = "button", l.title = e, l.innerHTML = t, s && (l.dataset.id = s), l.addEventListener("mousedown", (
|
|
2974
|
+
return l.className = "tbtn", l.type = "button", l.title = e, l.innerHTML = t, s && (l.dataset.id = s), l.addEventListener("mousedown", (n) => n.preventDefault()), l.addEventListener("click", i), l;
|
|
2868
2975
|
}
|
|
2869
2976
|
/** Font-size increase / decrease step button. */
|
|
2870
2977
|
stepBtn(t) {
|
|
2871
|
-
const e = t > 0 ? "+" : "−", i = t > 0 ?
|
|
2978
|
+
const e = t > 0 ? "+" : "−", i = t > 0 ? c.fontsizeup : c.fontsizedown, s = this.tbtn(i, this.t("fontsize") + " " + e, () => this.stepFontSize(t));
|
|
2872
2979
|
return s.addEventListener("mousedown", () => this.saveSel()), s;
|
|
2873
2980
|
}
|
|
2874
2981
|
/** Toolbar icon button that opens a popup menu anchored to itself. */
|
|
2875
2982
|
menuTbtn(t, e, i, s) {
|
|
2876
2983
|
const l = this.tbtn(t, e, () => i(l), s);
|
|
2877
|
-
return l.classList.add("hasmenu"), l.insertAdjacentHTML("beforeend",
|
|
2984
|
+
return l.classList.add("hasmenu"), l.insertAdjacentHTML("beforeend", c.chev), l.addEventListener("mousedown", () => this.saveSel()), l;
|
|
2878
2985
|
}
|
|
2879
2986
|
/** Quick text-color chips plus a "more" chip that opens the full palette. */
|
|
2880
2987
|
colorChips() {
|
|
2881
2988
|
const t = (s) => {
|
|
2882
2989
|
const l = document.createElement("button");
|
|
2883
|
-
return l.type = "button", l.className = "cchip", l.title = s, l.addEventListener("mousedown", (
|
|
2884
|
-
|
|
2990
|
+
return l.type = "button", l.className = "cchip", l.title = s, l.addEventListener("mousedown", (n) => {
|
|
2991
|
+
n.preventDefault(), this.saveSel();
|
|
2885
2992
|
}), l;
|
|
2886
|
-
}, e =
|
|
2993
|
+
}, e = ut.map((s) => {
|
|
2887
2994
|
const l = t(this.t("forecolor"));
|
|
2888
2995
|
return l.style.background = s, l.addEventListener("click", () => this.applyColor("fore", s)), l;
|
|
2889
2996
|
}), i = t(this.t("forecolor"));
|
|
2890
|
-
return i.classList.add("more"), i.dataset.cb = "fore", i.innerHTML =
|
|
2997
|
+
return i.classList.add("more"), i.dataset.cb = "fore", i.innerHTML = c.chev, i.addEventListener("click", () => this.colorMenu(i, "fore")), [...e, i];
|
|
2891
2998
|
}
|
|
2892
2999
|
group(...t) {
|
|
2893
3000
|
const e = document.createElement("div");
|
|
@@ -2897,45 +3004,45 @@ const I = class I {
|
|
|
2897
3004
|
}
|
|
2898
3005
|
tsel(t, e, i, s) {
|
|
2899
3006
|
const l = document.createElement("button");
|
|
2900
|
-
return l.className = "tsel " + t, l.type = "button", l.dataset.id = e, l.innerHTML = `<span class="lbl empty">${i || ""}</span>${
|
|
2901
|
-
|
|
3007
|
+
return l.className = "tsel " + t, l.type = "button", l.dataset.id = e, l.innerHTML = `<span class="lbl empty">${i || ""}</span>${c.chev}`, l.addEventListener("mousedown", (n) => {
|
|
3008
|
+
n.preventDefault(), this.saveSel();
|
|
2902
3009
|
}), l.addEventListener("click", () => s(l)), l;
|
|
2903
3010
|
}
|
|
2904
3011
|
setListStyle(t, e) {
|
|
2905
|
-
var l,
|
|
3012
|
+
var l, n;
|
|
2906
3013
|
this.restoreSel();
|
|
2907
3014
|
const i = window.getSelection();
|
|
2908
3015
|
if (!i) return;
|
|
2909
3016
|
let s = (l = this.closestBlock(i.anchorNode)) == null ? void 0 : l.closest(t);
|
|
2910
|
-
s || (this.exec(t === "ol" ? "insertOrderedList" : "insertUnorderedList"), s = (
|
|
3017
|
+
s || (this.exec(t === "ol" ? "insertOrderedList" : "insertUnorderedList"), s = (n = this.closestBlock(i.anchorNode)) == null ? void 0 : n.closest(t)), s && (s.style.listStyleType = e), this.saveSel(), this.onChange();
|
|
2911
3018
|
}
|
|
2912
3019
|
listMenu(t, e) {
|
|
2913
|
-
var
|
|
3020
|
+
var a;
|
|
2914
3021
|
const i = e === "ol" ? "insertOrderedList" : "insertUnorderedList", s = e === "ol" ? [
|
|
2915
|
-
["lower-alpha",
|
|
2916
|
-
["lower-roman",
|
|
2917
|
-
["upper-alpha",
|
|
2918
|
-
["upper-roman",
|
|
3022
|
+
["lower-alpha", c.ol_alpha],
|
|
3023
|
+
["lower-roman", c.ol_roman],
|
|
3024
|
+
["upper-alpha", c.ol_alphau],
|
|
3025
|
+
["upper-roman", c.ol_romanu]
|
|
2919
3026
|
] : [
|
|
2920
|
-
["circle",
|
|
2921
|
-
["square",
|
|
2922
|
-
], l = this.tArr(e === "ol" ? "liststyles_ol" : "liststyles_ul").slice(1),
|
|
3027
|
+
["circle", c.ul_circle],
|
|
3028
|
+
["square", c.ul_square]
|
|
3029
|
+
], l = this.tArr(e === "ol" ? "liststyles_ol" : "liststyles_ul").slice(1), n = window.getSelection(), o = n ? (a = this.closestBlock(n.anchorNode)) == null ? void 0 : a.closest(e) : null, r = o ? o.style.listStyleType : "";
|
|
2923
3030
|
this.popup(t, (h) => {
|
|
2924
3031
|
this.menuItems(h, [
|
|
2925
3032
|
{
|
|
2926
3033
|
label: this.t(e === "ol" ? "numlist" : "bullist"),
|
|
2927
|
-
icon: e === "ol" ?
|
|
3034
|
+
icon: e === "ol" ? c.numlist : c.bullist,
|
|
2928
3035
|
on: document.queryCommandState(i),
|
|
2929
3036
|
action: () => this.exec(i)
|
|
2930
3037
|
}
|
|
2931
3038
|
]), h.insertAdjacentHTML("beforeend", '<div class="sep"></div>');
|
|
2932
|
-
const
|
|
2933
|
-
|
|
3039
|
+
const p = document.createElement("div");
|
|
3040
|
+
p.className = "mi-grid", s.forEach(([m, g], u) => {
|
|
2934
3041
|
const v = document.createElement("button");
|
|
2935
3042
|
v.className = "mi" + (r === m ? " on" : ""), v.innerHTML = `<span class="ic">${g}</span><span class="prev">${l[u]}</span>`, v.addEventListener("click", () => {
|
|
2936
3043
|
this.closePop(), this.setListStyle(e, m);
|
|
2937
|
-
}),
|
|
2938
|
-
}), h.appendChild(
|
|
3044
|
+
}), p.appendChild(v);
|
|
3045
|
+
}), h.appendChild(p);
|
|
2939
3046
|
});
|
|
2940
3047
|
}
|
|
2941
3048
|
/** Shared color-picker popup body — swatch grid plus the current-color /
|
|
@@ -2943,26 +3050,26 @@ const I = class I {
|
|
|
2943
3050
|
* table cell-background menu all show the identical popup. */
|
|
2944
3051
|
buildPaletteInto(t, e, i) {
|
|
2945
3052
|
const s = document.createElement("div");
|
|
2946
|
-
s.className = "cpal",
|
|
3053
|
+
s.className = "cpal", gt.forEach((p) => {
|
|
2947
3054
|
const m = document.createElement("button");
|
|
2948
|
-
m.type = "button", m.style.background =
|
|
2949
|
-
this.closePop(), i(
|
|
3055
|
+
m.type = "button", m.style.background = p, m.title = p, m.addEventListener("click", () => {
|
|
3056
|
+
this.closePop(), i(p);
|
|
2950
3057
|
}), s.appendChild(m);
|
|
2951
3058
|
}), t.appendChild(s), t.insertAdjacentHTML("beforeend", '<div class="sep"></div>');
|
|
2952
3059
|
const l = document.createElement("div");
|
|
2953
3060
|
l.className = "cfoot";
|
|
2954
|
-
const
|
|
2955
|
-
|
|
3061
|
+
const n = /^#[0-9a-f]{6}$/i.test(e) ? e : "#000000", o = document.createElement("div");
|
|
3062
|
+
o.className = "cswatch cur", o.title = this.t("currentcolor"), o.style.background = n, o.innerHTML = c.check;
|
|
2956
3063
|
const r = document.createElement("button");
|
|
2957
3064
|
r.type = "button", r.className = "cswatch nocolor", r.title = this.t("removecolor"), r.addEventListener("click", () => {
|
|
2958
3065
|
this.closePop(), i(null);
|
|
2959
3066
|
});
|
|
2960
|
-
const
|
|
2961
|
-
|
|
3067
|
+
const a = document.createElement("label");
|
|
3068
|
+
a.className = "cswatch cwheel", a.title = this.t("customcolor"), a.innerHTML = c.palette;
|
|
2962
3069
|
const h = document.createElement("input");
|
|
2963
|
-
h.type = "color", h.value =
|
|
3070
|
+
h.type = "color", h.value = n, h.addEventListener("change", () => {
|
|
2964
3071
|
this.closePop(), i(h.value);
|
|
2965
|
-
}),
|
|
3072
|
+
}), a.appendChild(h), l.append(o, r, a), t.appendChild(l);
|
|
2966
3073
|
}
|
|
2967
3074
|
colorMenu(t, e) {
|
|
2968
3075
|
this.popup(
|
|
@@ -2992,7 +3099,7 @@ const I = class I {
|
|
|
2992
3099
|
this.popup(t, (e) => this.menuItems(e, this.fontItems()));
|
|
2993
3100
|
}
|
|
2994
3101
|
sizeItems() {
|
|
2995
|
-
return
|
|
3102
|
+
return dt.map((t) => ({
|
|
2996
3103
|
label: t,
|
|
2997
3104
|
on: this.currentSize() === t,
|
|
2998
3105
|
action: () => this.applyFontSize(t)
|
|
@@ -3008,19 +3115,19 @@ const I = class I {
|
|
|
3008
3115
|
const t = window.getSelection();
|
|
3009
3116
|
if (!t) return;
|
|
3010
3117
|
if (!t.rangeCount) {
|
|
3011
|
-
const
|
|
3012
|
-
|
|
3118
|
+
const n = document.createRange();
|
|
3119
|
+
n.selectNodeContents(this.ed), n.collapse(!0), t.addRange(n);
|
|
3013
3120
|
}
|
|
3014
3121
|
if (!t.isCollapsed) return;
|
|
3015
3122
|
const e = t.getRangeAt(0), i = e.startContainer;
|
|
3016
3123
|
if (i.nodeType === 3) {
|
|
3017
|
-
const
|
|
3018
|
-
let
|
|
3019
|
-
for (;
|
|
3020
|
-
for (; r <
|
|
3021
|
-
if (r >
|
|
3022
|
-
const
|
|
3023
|
-
|
|
3124
|
+
const n = i.data;
|
|
3125
|
+
let o = e.startOffset, r = e.startOffset;
|
|
3126
|
+
for (; o > 0 && /\S/.test(n[o - 1]); ) o--;
|
|
3127
|
+
for (; r < n.length && /\S/.test(n[r]); ) r++;
|
|
3128
|
+
if (r > o) {
|
|
3129
|
+
const a = document.createRange();
|
|
3130
|
+
a.setStart(i, o), a.setEnd(i, r), t.removeAllRanges(), t.addRange(a), this.savedRange = a.cloneRange();
|
|
3024
3131
|
return;
|
|
3025
3132
|
}
|
|
3026
3133
|
}
|
|
@@ -3045,7 +3152,7 @@ const I = class I {
|
|
|
3045
3152
|
this.saveSel(), this.refreshState(), this.onChange();
|
|
3046
3153
|
}
|
|
3047
3154
|
stepFontSize(t) {
|
|
3048
|
-
const e = parseInt(this.currentSize(), 10) || 14, i = Math.min(
|
|
3155
|
+
const e = parseInt(this.currentSize(), 10) || 14, i = Math.min(mt, Math.max(pt, e + t));
|
|
3049
3156
|
i !== e && this.applyFontSize(i + "px");
|
|
3050
3157
|
}
|
|
3051
3158
|
/* ------------------------------------------------ case / spacing / link */
|
|
@@ -3054,21 +3161,21 @@ const I = class I {
|
|
|
3054
3161
|
const e = window.getSelection();
|
|
3055
3162
|
if (!e || !e.rangeCount || e.isCollapsed) return;
|
|
3056
3163
|
const i = e.getRangeAt(0), s = document.createTreeWalker(this.ed, NodeFilter.SHOW_TEXT), l = [];
|
|
3057
|
-
let
|
|
3058
|
-
for (;
|
|
3059
|
-
l.forEach((
|
|
3060
|
-
const r =
|
|
3061
|
-
if (
|
|
3062
|
-
const h =
|
|
3063
|
-
let
|
|
3064
|
-
t === "lower" ?
|
|
3164
|
+
let n;
|
|
3165
|
+
for (; n = s.nextNode(); ) i.intersectsNode(n) && l.push(n);
|
|
3166
|
+
l.forEach((o) => {
|
|
3167
|
+
const r = o === i.startContainer ? i.startOffset : 0, a = o === i.endContainer ? i.endOffset : o.data.length;
|
|
3168
|
+
if (a <= r) return;
|
|
3169
|
+
const h = o.data.slice(r, a);
|
|
3170
|
+
let p = h;
|
|
3171
|
+
t === "lower" ? p = h.toLowerCase() : t === "upper" ? p = h.toUpperCase() : p = h.replace(/(^|\s)(\S)/g, (m, g, u) => g + u.toUpperCase()), o.replaceData(r, a - r, p);
|
|
3065
3172
|
}), this.saveSel(), this.refreshState(), this.onChange();
|
|
3066
3173
|
}
|
|
3067
3174
|
caseItems() {
|
|
3068
3175
|
return [
|
|
3069
|
-
{ label: this.t("lowercase"), icon:
|
|
3070
|
-
{ label: this.t("uppercase"), icon:
|
|
3071
|
-
{ label: this.t("capitalize"), icon:
|
|
3176
|
+
{ label: this.t("lowercase"), icon: c.lowercaseic, action: () => this.transformCase("lower") },
|
|
3177
|
+
{ label: this.t("uppercase"), icon: c.uppercaseic, action: () => this.transformCase("upper") },
|
|
3178
|
+
{ label: this.t("capitalize"), icon: c.capitalizeic, action: () => this.transformCase("capitalize") }
|
|
3072
3179
|
];
|
|
3073
3180
|
}
|
|
3074
3181
|
caseMenu(t) {
|
|
@@ -3097,13 +3204,13 @@ const I = class I {
|
|
|
3097
3204
|
];
|
|
3098
3205
|
}
|
|
3099
3206
|
lineHeightMenu(t) {
|
|
3100
|
-
this.popup(t, (e) => this.menuItems(e, this.blockStyleItems("lineHeight",
|
|
3207
|
+
this.popup(t, (e) => this.menuItems(e, this.blockStyleItems("lineHeight", U)));
|
|
3101
3208
|
}
|
|
3102
3209
|
wordSpacingMenu(t) {
|
|
3103
|
-
this.popup(t, (e) => this.menuItems(e, this.blockStyleItems("wordSpacing",
|
|
3210
|
+
this.popup(t, (e) => this.menuItems(e, this.blockStyleItems("wordSpacing", W)));
|
|
3104
3211
|
}
|
|
3105
3212
|
letterSpacingMenu(t) {
|
|
3106
|
-
this.popup(t, (e) => this.menuItems(e, this.blockStyleItems("letterSpacing",
|
|
3213
|
+
this.popup(t, (e) => this.menuItems(e, this.blockStyleItems("letterSpacing", j)));
|
|
3107
3214
|
}
|
|
3108
3215
|
closestAnchor() {
|
|
3109
3216
|
const t = window.getSelection();
|
|
@@ -3149,14 +3256,14 @@ const I = class I {
|
|
|
3149
3256
|
(s) => {
|
|
3150
3257
|
const l = document.createElement("div");
|
|
3151
3258
|
l.style.cssText = "display:flex;align-items:center;gap:10px;margin:10px 0;min-width:360px";
|
|
3152
|
-
const
|
|
3153
|
-
|
|
3259
|
+
const n = document.createElement("span");
|
|
3260
|
+
n.style.cssText = "width:60px;color:#556;flex:none", n.textContent = this.t("linkurl"), e = document.createElement("input"), e.type = "url", e.placeholder = "https://", e.style.cssText = "flex:1;border:1px solid #cfd6df;border-radius:6px;padding:7px 9px;font:14px inherit", e.value = (t == null ? void 0 : t.getAttribute("href")) || "", l.append(n, e), s.appendChild(l), setTimeout(() => e.focus(), 0);
|
|
3154
3261
|
},
|
|
3155
3262
|
i
|
|
3156
3263
|
);
|
|
3157
3264
|
}
|
|
3158
3265
|
blockItems() {
|
|
3159
|
-
return
|
|
3266
|
+
return X.map(([t]) => ({
|
|
3160
3267
|
label: this.blockLabel(t),
|
|
3161
3268
|
previewStyle: t.startsWith("h") ? `font-weight:700;font-size:${22 - 2 * +t[1]}px` : t === "pre" ? "font-family:monospace" : "",
|
|
3162
3269
|
on: this.currentBlock() === t,
|
|
@@ -3168,10 +3275,10 @@ const I = class I {
|
|
|
3168
3275
|
}
|
|
3169
3276
|
alignItems() {
|
|
3170
3277
|
return [
|
|
3171
|
-
["justifyLeft", "alignleft",
|
|
3172
|
-
["justifyCenter", "aligncenter",
|
|
3173
|
-
["justifyRight", "alignright",
|
|
3174
|
-
["justifyFull", "alignjustify",
|
|
3278
|
+
["justifyLeft", "alignleft", c.alignleft],
|
|
3279
|
+
["justifyCenter", "aligncenter", c.aligncenter],
|
|
3280
|
+
["justifyRight", "alignright", c.alignright],
|
|
3281
|
+
["justifyFull", "alignjustify", c.alignjustify]
|
|
3175
3282
|
].map(([e, i, s]) => ({
|
|
3176
3283
|
label: this.t(i),
|
|
3177
3284
|
icon: s,
|
|
@@ -3193,15 +3300,15 @@ const I = class I {
|
|
|
3193
3300
|
s.className = "tgrid";
|
|
3194
3301
|
const l = document.createElement("div");
|
|
3195
3302
|
l.className = "tgridlbl", l.textContent = "1 × 1";
|
|
3196
|
-
const
|
|
3197
|
-
for (let
|
|
3303
|
+
const n = [];
|
|
3304
|
+
for (let o = 0; o < 8; o++)
|
|
3198
3305
|
for (let r = 0; r < 10; r++) {
|
|
3199
|
-
const
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
}),
|
|
3203
|
-
this.closePop(), this.insertTable(
|
|
3204
|
-
}),
|
|
3306
|
+
const a = document.createElement("span");
|
|
3307
|
+
a.dataset.r = String(o), a.dataset.c = String(r), a.addEventListener("mouseenter", () => {
|
|
3308
|
+
n.forEach((h) => h.classList.toggle("hot", +h.dataset.r <= o && +h.dataset.c <= r)), l.textContent = r + 1 + " × " + (o + 1);
|
|
3309
|
+
}), a.addEventListener("click", () => {
|
|
3310
|
+
this.closePop(), this.insertTable(o + 1, r + 1), e == null || e();
|
|
3311
|
+
}), n.push(a), s.appendChild(a);
|
|
3205
3312
|
}
|
|
3206
3313
|
i.append(s, l), t.appendChild(i);
|
|
3207
3314
|
}
|
|
@@ -3232,73 +3339,73 @@ const I = class I {
|
|
|
3232
3339
|
* behavior changes, just named lookup. Only `forecolor` yields multiple elements
|
|
3233
3340
|
* (the quick color chips); everything else yields one. */
|
|
3234
3341
|
buildToolbarRegistry() {
|
|
3235
|
-
const t = this.tbtn(
|
|
3236
|
-
undo: () => this.tbtn(
|
|
3237
|
-
redo: () => this.tbtn(
|
|
3238
|
-
preview: () => this.tbtn(
|
|
3239
|
-
print: () => this.tbtn(
|
|
3240
|
-
importword: () => this.tbtn(
|
|
3241
|
-
revhistory: () => this.tbtn(
|
|
3342
|
+
const t = this.tbtn(c.tableic, this.t("quicktable"), () => this.tableGrid(t)), e = {
|
|
3343
|
+
undo: () => this.tbtn(c.undo, this.t("undo"), () => this.exec("undo"), "undo"),
|
|
3344
|
+
redo: () => this.tbtn(c.redo, this.t("redo"), () => this.exec("redo"), "redo"),
|
|
3345
|
+
preview: () => this.tbtn(c.prevw, this.t("preview"), () => this.previewDlg()),
|
|
3346
|
+
print: () => this.tbtn(c.printic, this.t("print"), () => this.printDoc()),
|
|
3347
|
+
importword: () => this.tbtn(c.wordic, this.t("importword"), () => this.pickWordDoc()),
|
|
3348
|
+
revhistory: () => this.tbtn(c.historyic, this.t("revhistory"), () => this.revisionDlg()),
|
|
3242
3349
|
fontfamily: () => this.tsel("w-font", "fontsel", "", (i) => this.fontMenu(i)),
|
|
3243
3350
|
fontsize: () => this.tsel("w-size", "sizesel", "", (i) => this.sizeMenu(i)),
|
|
3244
3351
|
fontsizeincrease: () => this.stepBtn(1),
|
|
3245
3352
|
fontsizedecrease: () => this.stepBtn(-1),
|
|
3246
|
-
bold: () => this.tbtn(
|
|
3247
|
-
italic: () => this.tbtn(
|
|
3248
|
-
underline: () => this.tbtn(
|
|
3249
|
-
strikethrough: () => this.tbtn(
|
|
3353
|
+
bold: () => this.tbtn(c.bold, this.t("bold"), () => this.exec("bold"), "bold"),
|
|
3354
|
+
italic: () => this.tbtn(c.italic, this.t("italic"), () => this.exec("italic"), "italic"),
|
|
3355
|
+
underline: () => this.tbtn(c.underline, this.t("underline"), () => this.exec("underline"), "underline"),
|
|
3356
|
+
strikethrough: () => this.tbtn(c.strikethrough, this.t("strikethrough"), () => this.exec("strikeThrough"), "strikeThrough"),
|
|
3250
3357
|
forecolor: () => this.colorChips(),
|
|
3251
3358
|
backcolor: () => this.menuTbtn(
|
|
3252
|
-
|
|
3359
|
+
c.backcolor + '<span class="colorbar" data-cb="back"></span>',
|
|
3253
3360
|
this.t("backcolor"),
|
|
3254
3361
|
(i) => this.colorMenu(i, "back")
|
|
3255
3362
|
),
|
|
3256
|
-
alignleft: () => this.tbtn(
|
|
3257
|
-
aligncenter: () => this.tbtn(
|
|
3258
|
-
alignright: () => this.tbtn(
|
|
3259
|
-
alignjustify: () => this.tbtn(
|
|
3260
|
-
bullist: () => this.menuTbtn(
|
|
3261
|
-
numlist: () => this.menuTbtn(
|
|
3262
|
-
outdent: () => this.tbtn(
|
|
3263
|
-
indent: () => this.tbtn(
|
|
3264
|
-
link: () => this.tbtn(
|
|
3265
|
-
blockquote: () => this.tbtn(
|
|
3266
|
-
code: () => this.tbtn(
|
|
3267
|
-
codesample: () => this.tbtn(
|
|
3268
|
-
changecase: () => this.menuTbtn(
|
|
3269
|
-
lineheight: () => this.menuTbtn(
|
|
3270
|
-
wordspacing: () => this.menuTbtn(
|
|
3271
|
-
letterspacing: () => this.menuTbtn(
|
|
3272
|
-
removeformat: () => this.tbtn(
|
|
3363
|
+
alignleft: () => this.tbtn(c.alignleft, this.t("alignleft"), () => this.exec("justifyLeft"), "justifyLeft"),
|
|
3364
|
+
aligncenter: () => this.tbtn(c.aligncenter, this.t("aligncenter"), () => this.exec("justifyCenter"), "justifyCenter"),
|
|
3365
|
+
alignright: () => this.tbtn(c.alignright, this.t("alignright"), () => this.exec("justifyRight"), "justifyRight"),
|
|
3366
|
+
alignjustify: () => this.tbtn(c.alignjustify, this.t("alignjustify"), () => this.exec("justifyFull"), "justifyFull"),
|
|
3367
|
+
bullist: () => this.menuTbtn(c.bullist, this.t("bullist"), (i) => this.listMenu(i, "ul"), "insertUnorderedList"),
|
|
3368
|
+
numlist: () => this.menuTbtn(c.numlist, this.t("numlist"), (i) => this.listMenu(i, "ol"), "insertOrderedList"),
|
|
3369
|
+
outdent: () => this.tbtn(c.outdent, this.t("outdent"), () => this.exec("outdent")),
|
|
3370
|
+
indent: () => this.tbtn(c.indent, this.t("indent"), () => this.exec("indent")),
|
|
3371
|
+
link: () => this.tbtn(c.link, this.t("linkttl"), () => this.linkDlg()),
|
|
3372
|
+
blockquote: () => this.tbtn(c.quote, this.t("quote"), () => this.toggleBlock("blockquote"), "blockquote"),
|
|
3373
|
+
code: () => this.tbtn(c.inlinecodeic, this.t("code"), () => this.toggleInlineCode(), "code"),
|
|
3374
|
+
codesample: () => this.tbtn(c.codesampleic, this.t("codesample"), () => this.codeDlg()),
|
|
3375
|
+
changecase: () => this.menuTbtn(c.caseic, this.t("changecase"), (i) => this.caseMenu(i)),
|
|
3376
|
+
lineheight: () => this.menuTbtn(c.lineheight, this.t("lineheight"), (i) => this.lineHeightMenu(i)),
|
|
3377
|
+
wordspacing: () => this.menuTbtn(c.wordspacing, this.t("wordspacing"), (i) => this.wordSpacingMenu(i)),
|
|
3378
|
+
letterspacing: () => this.menuTbtn(c.letterspacing, this.t("letterspacing"), (i) => this.letterSpacingMenu(i)),
|
|
3379
|
+
removeformat: () => this.tbtn(c.clearformatic, this.t("removeformat"), () => this.exec("removeFormat")),
|
|
3273
3380
|
blocks: () => this.tsel("w-block", "blocksel", this.t("para"), (i) => this.blocksMenu(i)),
|
|
3274
|
-
ltr: () => this.tbtn(
|
|
3275
|
-
rtl: () => this.tbtn(
|
|
3276
|
-
quickimage: () => this.tbtn(
|
|
3277
|
-
quickvideo: () => this.tbtn(
|
|
3381
|
+
ltr: () => this.tbtn(c.ltr, this.t("ltr"), () => this.setDir("ltr"), "ltr"),
|
|
3382
|
+
rtl: () => this.tbtn(c.rtl, this.t("rtl"), () => this.setDir("rtl"), "rtl"),
|
|
3383
|
+
quickimage: () => this.tbtn(c.image, this.t("quickimage"), () => this.insertImagePlaceholder()),
|
|
3384
|
+
quickvideo: () => this.tbtn(c.video, this.t("quickvideo"), () => this.videoDlg()),
|
|
3278
3385
|
quicktable: () => t,
|
|
3279
|
-
template: () => this.menuTbtn(
|
|
3280
|
-
charmap: () => this.tbtn(
|
|
3281
|
-
emoji: () => this.tbtn(
|
|
3282
|
-
fullscreen: () => this.tbtn(
|
|
3283
|
-
sourcecode: () => this.tbtn(
|
|
3386
|
+
template: () => this.menuTbtn(c.templateic, this.t("template"), (i) => this.templateMenu(i)),
|
|
3387
|
+
charmap: () => this.tbtn(c.charic, this.t("charmap"), () => this.charMap()),
|
|
3388
|
+
emoji: () => this.tbtn(c.emojiic, this.t("emoji"), () => this.emojiMap()),
|
|
3389
|
+
fullscreen: () => this.tbtn(c.fullscreen, this.t("fullscreen"), () => this.toggleFullscreen(), "fullscreen"),
|
|
3390
|
+
sourcecode: () => this.tbtn(c.srcic, this.t("sourcecode"), () => this.sourceDlg())
|
|
3284
3391
|
};
|
|
3285
3392
|
return e.styles = e.blocks, e.image = e.quickimage, e.media = e.quickvideo, e.table = e.quicktable, e;
|
|
3286
3393
|
}
|
|
3287
3394
|
buildToolbar() {
|
|
3288
3395
|
this.toolbar.innerHTML = "";
|
|
3289
|
-
const t = this.options.toolbar === !0 ?
|
|
3396
|
+
const t = this.options.toolbar === !0 ? at : this.options.toolbar, e = this.buildToolbarRegistry();
|
|
3290
3397
|
this.parseToolbarString(t).forEach((i) => {
|
|
3291
3398
|
const s = [];
|
|
3292
3399
|
i.forEach((l) => {
|
|
3293
|
-
const
|
|
3294
|
-
if (!
|
|
3400
|
+
const n = e[l];
|
|
3401
|
+
if (!n) {
|
|
3295
3402
|
console.warn(`FableEditor: unknown toolbar item "${l}"`);
|
|
3296
3403
|
return;
|
|
3297
3404
|
}
|
|
3298
|
-
const
|
|
3299
|
-
Array.isArray(
|
|
3405
|
+
const o = n();
|
|
3406
|
+
Array.isArray(o) ? s.push(...o) : s.push(o);
|
|
3300
3407
|
}), s.length && this.toolbar.appendChild(this.group(...s));
|
|
3301
|
-
}), this.tbrMore = this.tbtn(
|
|
3408
|
+
}), this.tbrMore = this.tbtn(c.more, this.t("more"), () => {
|
|
3302
3409
|
this.tbrExpanded = !this.tbrExpanded, this.updateToolbarOverflow();
|
|
3303
3410
|
}), this.tbrMore.classList.add("tbr-more"), this.toolbar.appendChild(this.tbrMore), this.syncColorSwatches(this.toolbar), this.updateToolbarOverflow();
|
|
3304
3411
|
}
|
|
@@ -3328,134 +3435,134 @@ const I = class I {
|
|
|
3328
3435
|
this.menubar.innerHTML = "";
|
|
3329
3436
|
const t = {
|
|
3330
3437
|
file: [
|
|
3331
|
-
this.mItem("newdoc",
|
|
3438
|
+
this.mItem("newdoc", c.newic, () => {
|
|
3332
3439
|
this.recordRevision(), this.ed.innerHTML = "<p><br></p>", this.onChange();
|
|
3333
3440
|
}),
|
|
3334
3441
|
"|",
|
|
3335
|
-
this.mItem("importword",
|
|
3336
|
-
this.mItem("restoredraft",
|
|
3442
|
+
this.mItem("importword", c.wordic, () => this.pickWordDoc()),
|
|
3443
|
+
this.mItem("restoredraft", c.draftic, () => {
|
|
3337
3444
|
this.restoreDraft() || alert(this.t("draftempty"));
|
|
3338
3445
|
}),
|
|
3339
|
-
this.mItem("revhistory",
|
|
3446
|
+
this.mItem("revhistory", c.historyic, () => this.revisionDlg()),
|
|
3340
3447
|
"|",
|
|
3341
|
-
this.mItem("preview",
|
|
3342
|
-
this.mItem("print",
|
|
3448
|
+
this.mItem("preview", c.prevw, () => this.previewDlg()),
|
|
3449
|
+
this.mItem("print", c.printic, () => this.printDoc(), "Ctrl+P")
|
|
3343
3450
|
],
|
|
3344
3451
|
edit: [
|
|
3345
|
-
this.mItem("undo",
|
|
3346
|
-
this.mItem("redo",
|
|
3452
|
+
this.mItem("undo", c.undo, () => this.exec("undo"), "Ctrl+Z"),
|
|
3453
|
+
this.mItem("redo", c.redo, () => this.exec("redo"), "Ctrl+Y"),
|
|
3347
3454
|
"|",
|
|
3348
|
-
this.mItem("cut",
|
|
3349
|
-
this.mItem("copy",
|
|
3350
|
-
this.mItem("paste",
|
|
3455
|
+
this.mItem("cut", c.cutic, () => this.exec("cut"), "Ctrl+X"),
|
|
3456
|
+
this.mItem("copy", c.copyic, () => this.exec("copy"), "Ctrl+C"),
|
|
3457
|
+
this.mItem("paste", c.pasteic, () => alert(this.t("pastehint")), "Ctrl+V"),
|
|
3351
3458
|
"|",
|
|
3352
|
-
this.mItem("selectall",
|
|
3459
|
+
this.mItem("selectall", c.selall, () => this.exec("selectAll"), "Ctrl+A")
|
|
3353
3460
|
],
|
|
3354
3461
|
view: [
|
|
3355
|
-
this.mItem("fullscreen",
|
|
3356
|
-
this.mItem("preview",
|
|
3357
|
-
this.mItem("sourcecode",
|
|
3462
|
+
this.mItem("fullscreen", c.fullscreen, () => this.toggleFullscreen()),
|
|
3463
|
+
this.mItem("preview", c.prevw, () => this.previewDlg()),
|
|
3464
|
+
this.mItem("sourcecode", c.srcic, () => this.sourceDlg())
|
|
3358
3465
|
],
|
|
3359
3466
|
insert: [
|
|
3360
|
-
this.mItem("link",
|
|
3361
|
-
this.mItem("image",
|
|
3362
|
-
this.mItem("video",
|
|
3363
|
-
{ label: this.t("inserttable"), icon:
|
|
3364
|
-
this.mItem("codesample",
|
|
3365
|
-
{ label: this.t("template"), icon:
|
|
3366
|
-
this.mItem("hr",
|
|
3467
|
+
this.mItem("link", c.link, () => this.linkDlg()),
|
|
3468
|
+
this.mItem("image", c.image, () => this.insertImagePlaceholder()),
|
|
3469
|
+
this.mItem("video", c.video, () => this.videoDlg()),
|
|
3470
|
+
{ label: this.t("inserttable"), icon: c.tableic, action: () => this.tableGrid(this.menubar.querySelector('[data-menu-key="table"]') || this.menubar) },
|
|
3471
|
+
this.mItem("codesample", c.codesampleic, () => this.codeDlg()),
|
|
3472
|
+
{ label: this.t("template"), icon: c.templateic, subBuild: (s) => this.buildTemplatePickInto(s) },
|
|
3473
|
+
this.mItem("hr", c.hric, () => this.exec("insertHorizontalRule")),
|
|
3367
3474
|
"|",
|
|
3368
|
-
this.mItem("charmap",
|
|
3369
|
-
this.mItem("emoji",
|
|
3475
|
+
this.mItem("charmap", c.charic, () => this.charMap()),
|
|
3476
|
+
this.mItem("emoji", c.emojiic, () => this.emojiMap()),
|
|
3370
3477
|
this.mItem(
|
|
3371
3478
|
"datetime",
|
|
3372
|
-
|
|
3479
|
+
c.dateic,
|
|
3373
3480
|
() => this.exec("insertText", (/* @__PURE__ */ new Date()).toLocaleString(this.lang === "ar" ? "ar-AE" : "en-GB"))
|
|
3374
3481
|
),
|
|
3375
3482
|
"|",
|
|
3376
3483
|
{
|
|
3377
3484
|
label: this.t("pagebreak"),
|
|
3378
|
-
icon:
|
|
3485
|
+
icon: c.pbic,
|
|
3379
3486
|
action: () => {
|
|
3380
3487
|
this.restoreSel(), document.execCommand("insertHTML", !1, '<hr class="pagebreak"><p><br></p>'), this.onChange();
|
|
3381
3488
|
}
|
|
3382
3489
|
},
|
|
3383
|
-
this.mItem("nbsp",
|
|
3490
|
+
this.mItem("nbsp", c.nbspic, () => this.exec("insertText", " "))
|
|
3384
3491
|
],
|
|
3385
3492
|
format: [
|
|
3386
|
-
this.mItem("bold",
|
|
3387
|
-
this.mItem("italic",
|
|
3388
|
-
this.mItem("underline",
|
|
3389
|
-
this.mItem("strikethrough",
|
|
3390
|
-
this.mItem("superscript",
|
|
3391
|
-
this.mItem("subscript",
|
|
3392
|
-
this.mItem("code",
|
|
3393
|
-
this.mItem("quote",
|
|
3493
|
+
this.mItem("bold", c.bold, () => this.exec("bold"), "Ctrl+B"),
|
|
3494
|
+
this.mItem("italic", c.italic, () => this.exec("italic"), "Ctrl+I"),
|
|
3495
|
+
this.mItem("underline", c.underline, () => this.exec("underline"), "Ctrl+U"),
|
|
3496
|
+
this.mItem("strikethrough", c.strikethrough, () => this.exec("strikeThrough")),
|
|
3497
|
+
this.mItem("superscript", c.superscriptic, () => this.exec("superscript")),
|
|
3498
|
+
this.mItem("subscript", c.subscriptic, () => this.exec("subscript")),
|
|
3499
|
+
this.mItem("code", c.inlinecodeic, () => this.toggleInlineCode()),
|
|
3500
|
+
this.mItem("quote", c.quote, () => this.toggleBlock("blockquote")),
|
|
3394
3501
|
"|",
|
|
3395
3502
|
{ label: this.t("fontfamily"), subBuild: (s) => this.menuItems(s, this.fontItems()) },
|
|
3396
3503
|
{ label: this.t("fontsize"), subBuild: (s) => this.menuItems(s, this.sizeItems()) },
|
|
3397
3504
|
{ label: this.t("blocks"), subBuild: (s) => this.menuItems(s, this.blockItems()) },
|
|
3398
3505
|
{ label: this.t("align"), subBuild: (s) => this.menuItems(s, this.alignItems()) },
|
|
3399
|
-
{ label: this.t("lineheight"), icon:
|
|
3400
|
-
{ label: this.t("wordspacing"), icon:
|
|
3401
|
-
{ label: this.t("letterspacing"), icon:
|
|
3506
|
+
{ label: this.t("lineheight"), icon: c.lineheight, subBuild: (s) => this.menuItems(s, this.blockStyleItems("lineHeight", U)) },
|
|
3507
|
+
{ label: this.t("wordspacing"), icon: c.wordspacing, subBuild: (s) => this.menuItems(s, this.blockStyleItems("wordSpacing", W)) },
|
|
3508
|
+
{ label: this.t("letterspacing"), icon: c.letterspacing, subBuild: (s) => this.menuItems(s, this.blockStyleItems("letterSpacing", j)) },
|
|
3402
3509
|
"|",
|
|
3403
|
-
{ label: this.t("forecolor"), icon:
|
|
3404
|
-
{ label: this.t("backcolor"), icon:
|
|
3510
|
+
{ label: this.t("forecolor"), icon: c.palette, subBuild: (s) => this.buildPaletteInto(s, this.foreColor, (l) => this.applyColor("fore", l)) },
|
|
3511
|
+
{ label: this.t("backcolor"), icon: c.backcolor, subBuild: (s) => this.buildPaletteInto(s, this.backColor, (l) => this.applyColor("back", l)) },
|
|
3405
3512
|
"|",
|
|
3406
|
-
this.mItem("bullist",
|
|
3407
|
-
this.mItem("numlist",
|
|
3408
|
-
this.mItem("outdent",
|
|
3409
|
-
this.mItem("indent",
|
|
3513
|
+
this.mItem("bullist", c.bullist, () => this.exec("insertUnorderedList")),
|
|
3514
|
+
this.mItem("numlist", c.numlist, () => this.exec("insertOrderedList")),
|
|
3515
|
+
this.mItem("outdent", c.outdent, () => this.exec("outdent")),
|
|
3516
|
+
this.mItem("indent", c.indent, () => this.exec("indent")),
|
|
3410
3517
|
"|",
|
|
3411
|
-
this.mItem("ltr",
|
|
3412
|
-
this.mItem("rtl",
|
|
3518
|
+
this.mItem("ltr", c.ltr, () => this.setDir("ltr")),
|
|
3519
|
+
this.mItem("rtl", c.rtl, () => this.setDir("rtl")),
|
|
3413
3520
|
"|",
|
|
3414
|
-
{ label: this.t("changecase"), icon:
|
|
3521
|
+
{ label: this.t("changecase"), icon: c.caseic, sub: this.caseItems() },
|
|
3415
3522
|
"|",
|
|
3416
|
-
this.mItem("clearformat",
|
|
3523
|
+
this.mItem("clearformat", c.clearformatic, () => this.exec("removeFormat"))
|
|
3417
3524
|
],
|
|
3418
|
-
tools: [this.mItem("sourcecode",
|
|
3525
|
+
tools: [this.mItem("sourcecode", c.srcic, () => this.sourceDlg()), this.mItem("wordcount", c.wcic, () => this.wordCountDlg())],
|
|
3419
3526
|
table: [
|
|
3420
|
-
{ label: this.t("inserttable"), icon:
|
|
3527
|
+
{ label: this.t("inserttable"), icon: c.tableic, subBuild: (s) => this.buildTableGridInto(s) },
|
|
3421
3528
|
"|",
|
|
3422
3529
|
{
|
|
3423
3530
|
label: this.t("cell"),
|
|
3424
3531
|
sub: [
|
|
3425
|
-
{ label: this.t("cellprops"), icon:
|
|
3426
|
-
{ label: this.t("cellbg"), icon:
|
|
3532
|
+
{ label: this.t("cellprops"), icon: c.tableic, action: () => this.cellPropsDlg() },
|
|
3533
|
+
{ label: this.t("cellbg"), icon: c.palette, subBuild: (s) => this.buildCellFillInto(s) }
|
|
3427
3534
|
]
|
|
3428
3535
|
},
|
|
3429
3536
|
{
|
|
3430
3537
|
label: this.t("row"),
|
|
3431
3538
|
sub: [
|
|
3432
|
-
{ label: this.t("rowabove"), icon:
|
|
3433
|
-
{ label: this.t("rowbelow"), icon:
|
|
3434
|
-
{ label: this.t("delrow"), icon:
|
|
3539
|
+
{ label: this.t("rowabove"), icon: c.rowbefore, action: () => this.tableOp("rowabove"), hover: (s) => this.setOpTarget(s ? "row" : null) },
|
|
3540
|
+
{ label: this.t("rowbelow"), icon: c.rowafter, action: () => this.tableOp("rowbelow"), hover: (s) => this.setOpTarget(s ? "row" : null) },
|
|
3541
|
+
{ label: this.t("delrow"), icon: c.rowdelete, action: () => this.tableOp("delrow"), hover: (s) => this.setOpTarget(s ? "row" : null) },
|
|
3435
3542
|
"|",
|
|
3436
|
-
{ label: this.t("moverowup"), icon:
|
|
3437
|
-
{ label: this.t("moverowdown"), icon:
|
|
3543
|
+
{ label: this.t("moverowup"), icon: c.moverowup, action: () => this.tableMove("rowup"), hover: (s) => this.setOpTarget(s ? "row" : null) },
|
|
3544
|
+
{ label: this.t("moverowdown"), icon: c.moverowdown, action: () => this.tableMove("rowdown"), hover: (s) => this.setOpTarget(s ? "row" : null) },
|
|
3438
3545
|
"|",
|
|
3439
|
-
{ label: this.t("rowprops"), icon:
|
|
3546
|
+
{ label: this.t("rowprops"), icon: c.tableic, action: () => this.rowPropsDlg(), hover: (s) => this.setOpTarget(s ? "row" : null) }
|
|
3440
3547
|
]
|
|
3441
3548
|
},
|
|
3442
3549
|
{
|
|
3443
3550
|
label: this.t("column"),
|
|
3444
3551
|
sub: [
|
|
3445
|
-
{ label: this.t("colbefore"), icon:
|
|
3446
|
-
{ label: this.t("colafter"), icon:
|
|
3447
|
-
{ label: this.t("delcol"), icon:
|
|
3552
|
+
{ label: this.t("colbefore"), icon: c.colbefore, action: () => this.tableOp("colbefore"), hover: (s) => this.setOpTarget(s ? "col" : null) },
|
|
3553
|
+
{ label: this.t("colafter"), icon: c.colafter, action: () => this.tableOp("colafter"), hover: (s) => this.setOpTarget(s ? "col" : null) },
|
|
3554
|
+
{ label: this.t("delcol"), icon: c.coldelete, action: () => this.tableOp("delcol"), hover: (s) => this.setOpTarget(s ? "col" : null) },
|
|
3448
3555
|
"|",
|
|
3449
|
-
{ label: this.t("movecolleft"), icon:
|
|
3450
|
-
{ label: this.t("movecolright"), icon:
|
|
3556
|
+
{ label: this.t("movecolleft"), icon: c.movecolleft, action: () => this.tableMove("colleft"), hover: (s) => this.setOpTarget(s ? "col" : null) },
|
|
3557
|
+
{ label: this.t("movecolright"), icon: c.movecolright, action: () => this.tableMove("colright"), hover: (s) => this.setOpTarget(s ? "col" : null) },
|
|
3451
3558
|
"|",
|
|
3452
|
-
{ label: this.t("colprops"), icon:
|
|
3559
|
+
{ label: this.t("colprops"), icon: c.tableic, action: () => this.colPropsDlg(), hover: (s) => this.setOpTarget(s ? "col" : null) }
|
|
3453
3560
|
]
|
|
3454
3561
|
},
|
|
3455
3562
|
"|",
|
|
3456
3563
|
{
|
|
3457
3564
|
label: this.t("tablepropsttl"),
|
|
3458
|
-
icon:
|
|
3565
|
+
icon: c.tableic,
|
|
3459
3566
|
action: () => {
|
|
3460
3567
|
const s = this.currentCell();
|
|
3461
3568
|
if (!s) {
|
|
@@ -3465,10 +3572,10 @@ const I = class I {
|
|
|
3465
3572
|
this.tblActive = s.closest("table"), this.tablePropsDlg();
|
|
3466
3573
|
}
|
|
3467
3574
|
},
|
|
3468
|
-
{ label: this.t("deltable"), icon:
|
|
3575
|
+
{ label: this.t("deltable"), icon: c.trash, action: () => this.tableOp("deltable") }
|
|
3469
3576
|
],
|
|
3470
|
-
help: [this.mItem("helpttl",
|
|
3471
|
-
}, e = this.options.menubar === !0 ?
|
|
3577
|
+
help: [this.mItem("helpttl", c.helpic, () => this.helpDlg(), "Alt+0")]
|
|
3578
|
+
}, e = this.options.menubar === !0 ? ct : this.options.menubar, i = /* @__PURE__ */ new Set();
|
|
3472
3579
|
e.split(/\s+/).filter(Boolean).forEach((s) => {
|
|
3473
3580
|
if (i.has(s)) return;
|
|
3474
3581
|
if (i.add(s), !t[s]) {
|
|
@@ -3476,36 +3583,36 @@ const I = class I {
|
|
|
3476
3583
|
return;
|
|
3477
3584
|
}
|
|
3478
3585
|
const l = document.createElement("button");
|
|
3479
|
-
l.type = "button", l.textContent = this.t(s), l.dataset.menuKey = s, l.addEventListener("mousedown", (
|
|
3480
|
-
|
|
3481
|
-
}), l.addEventListener("click", () => this.popup(l, (
|
|
3586
|
+
l.type = "button", l.textContent = this.t(s), l.dataset.menuKey = s, l.addEventListener("mousedown", (n) => {
|
|
3587
|
+
n.preventDefault(), this.saveSel();
|
|
3588
|
+
}), l.addEventListener("click", () => this.popup(l, (n) => this.menuItems(n, t[s]))), this.menubar.appendChild(l);
|
|
3482
3589
|
});
|
|
3483
3590
|
}
|
|
3484
3591
|
/* ---------------------------------------------------------- table ops */
|
|
3485
3592
|
tableOp(t) {
|
|
3486
|
-
var r,
|
|
3593
|
+
var r, a, h;
|
|
3487
3594
|
this.restoreSel();
|
|
3488
3595
|
const e = window.getSelection();
|
|
3489
3596
|
if (!e) return;
|
|
3490
|
-
const i = ((r = this.closestBlock(e.anchorNode)) == null ? void 0 : r.closest("td,th")) || (e.anchorNode && e.anchorNode.nodeType === 1 ? (h = (
|
|
3597
|
+
const i = ((r = this.closestBlock(e.anchorNode)) == null ? void 0 : r.closest("td,th")) || (e.anchorNode && e.anchorNode.nodeType === 1 ? (h = (a = e.anchorNode).closest) == null ? void 0 : h.call(a, "td,th") : null);
|
|
3491
3598
|
if (!i) return;
|
|
3492
|
-
const s = i.parentElement, l = i.closest("table"),
|
|
3493
|
-
const
|
|
3599
|
+
const s = i.parentElement, l = i.closest("table"), n = Array.from(s.children).indexOf(i), o = () => {
|
|
3600
|
+
const p = s.cloneNode(!1);
|
|
3494
3601
|
return Array.from(s.children).forEach((m) => {
|
|
3495
3602
|
const g = document.createElement("td"), u = m.getAttribute("style");
|
|
3496
|
-
u && g.setAttribute("style", u), g.style.removeProperty("background-color"), g.innerHTML = "<br>",
|
|
3497
|
-
}),
|
|
3603
|
+
u && g.setAttribute("style", u), g.style.removeProperty("background-color"), g.innerHTML = "<br>", p.appendChild(g);
|
|
3604
|
+
}), p;
|
|
3498
3605
|
};
|
|
3499
|
-
if (t === "rowabove" && s.before(
|
|
3500
|
-
const
|
|
3501
|
-
s.remove(),
|
|
3606
|
+
if (t === "rowabove" && s.before(o()), t === "rowbelow" && s.after(o()), t === "delrow") {
|
|
3607
|
+
const p = s.parentElement;
|
|
3608
|
+
s.remove(), p.querySelector("tr") || l.remove();
|
|
3502
3609
|
}
|
|
3503
|
-
(t === "colbefore" || t === "colafter") && l.querySelectorAll("tr").forEach((
|
|
3504
|
-
const m =
|
|
3610
|
+
(t === "colbefore" || t === "colafter") && l.querySelectorAll("tr").forEach((p) => {
|
|
3611
|
+
const m = p.children[Math.min(n, p.children.length - 1)], g = document.createElement("td"), u = m.getAttribute("style");
|
|
3505
3612
|
u && g.setAttribute("style", u), g.style.removeProperty("width"), g.style.removeProperty("background-color"), g.innerHTML = "<br>", t === "colbefore" ? m.before(g) : m.after(g);
|
|
3506
|
-
}), t === "delcol" && (l.querySelectorAll("tr").forEach((
|
|
3613
|
+
}), t === "delcol" && (l.querySelectorAll("tr").forEach((p) => {
|
|
3507
3614
|
var m;
|
|
3508
|
-
return (m =
|
|
3615
|
+
return (m = p.children[n]) == null ? void 0 : m.remove();
|
|
3509
3616
|
}), l.querySelector("td,th") || l.remove()), t === "deltable" && l.remove(), this.onChange(), this.positionTableHandles();
|
|
3510
3617
|
}
|
|
3511
3618
|
/** Reorders the current row/column: 'rowup'/'rowdown' swap the caret's row with
|
|
@@ -3525,16 +3632,16 @@ const I = class I {
|
|
|
3525
3632
|
r && r.after(i);
|
|
3526
3633
|
}
|
|
3527
3634
|
t === "colleft" && l > 0 && s.querySelectorAll("tr").forEach((r) => {
|
|
3528
|
-
const
|
|
3529
|
-
|
|
3635
|
+
const a = r.children[l], h = r.children[l - 1];
|
|
3636
|
+
a && h && h.before(a);
|
|
3530
3637
|
}), t === "colright" && s.querySelectorAll("tr").forEach((r) => {
|
|
3531
|
-
const
|
|
3532
|
-
|
|
3638
|
+
const a = r.children[l], h = r.children[l + 1];
|
|
3639
|
+
a && h && h.after(a);
|
|
3533
3640
|
});
|
|
3534
|
-
const
|
|
3535
|
-
|
|
3536
|
-
const
|
|
3537
|
-
|
|
3641
|
+
const n = document.createRange();
|
|
3642
|
+
n.selectNodeContents(e), n.collapse(!0);
|
|
3643
|
+
const o = window.getSelection();
|
|
3644
|
+
o && (o.removeAllRanges(), o.addRange(n)), this.saveSel(), this.onChange(), this.positionTableHandles(), this.positionCellMarker();
|
|
3538
3645
|
}
|
|
3539
3646
|
/** Align the whole table via auto margins — same semantics as the align
|
|
3540
3647
|
* field in the table-properties dialog. */
|
|
@@ -3571,26 +3678,26 @@ const I = class I {
|
|
|
3571
3678
|
tablePropsDlg() {
|
|
3572
3679
|
const t = this.tblActive;
|
|
3573
3680
|
if (!t) return;
|
|
3574
|
-
let e, i, s, l,
|
|
3575
|
-
const
|
|
3681
|
+
let e, i, s, l, n;
|
|
3682
|
+
const o = "display:flex;align-items:center;gap:10px;margin:10px 0", r = "width:120px;color:#556;flex:none", a = "flex:1;border:1px solid #cfd6df;border-radius:6px;padding:7px 9px;font:14px inherit", h = t.querySelector("td,th"), p = t.style.width || "", m = h && h.style.padding ? parseFloat(h.style.padding) : "", g = t.style.borderSpacing ? parseFloat(t.style.borderSpacing) : "", u = t.style.borderWidth ? parseFloat(t.style.borderWidth) : "", v = t.style.marginLeft, b = t.style.marginRight, x = v === "auto" && b === "auto" ? "center" : v === "auto" ? "right" : b === "auto" && v === "0" ? "left" : "";
|
|
3576
3683
|
this.dialog(
|
|
3577
3684
|
this.t("tablepropsttl"),
|
|
3578
3685
|
(C) => {
|
|
3579
|
-
const
|
|
3686
|
+
const S = (w, k) => {
|
|
3580
3687
|
const L = document.createElement("div");
|
|
3581
|
-
L.style.cssText =
|
|
3582
|
-
const
|
|
3583
|
-
|
|
3688
|
+
L.style.cssText = o;
|
|
3689
|
+
const H = document.createElement("span");
|
|
3690
|
+
H.style.cssText = r, H.textContent = this.t(w), L.append(H, k), C.appendChild(L);
|
|
3584
3691
|
};
|
|
3585
|
-
e = document.createElement("input"), e.type = "text", e.style.cssText =
|
|
3692
|
+
e = document.createElement("input"), e.type = "text", e.style.cssText = a, e.placeholder = "e.g. 600px or 100%", e.value = p, S("tblwidth", e), i = document.createElement("input"), i.type = "number", i.min = "0", i.style.cssText = a, i.value = String(m), S("tblcellpadding", i), s = document.createElement("input"), s.type = "number", s.min = "0", s.style.cssText = a, s.value = String(g), S("tblcellspacing", s), l = document.createElement("input"), l.type = "number", l.min = "0", l.style.cssText = a, l.value = String(u), S("tblborder", l), n = document.createElement("select"), n.style.cssText = a, [
|
|
3586
3693
|
["", "alignnone"],
|
|
3587
3694
|
["left", "alignleft"],
|
|
3588
3695
|
["center", "aligncenter"],
|
|
3589
3696
|
["right", "alignright"]
|
|
3590
|
-
].forEach(([w,
|
|
3697
|
+
].forEach(([w, k]) => {
|
|
3591
3698
|
const L = document.createElement("option");
|
|
3592
|
-
L.value = w, L.textContent = this.t(
|
|
3593
|
-
}),
|
|
3699
|
+
L.value = w, L.textContent = this.t(k), w === x && (L.selected = !0), n.appendChild(L);
|
|
3700
|
+
}), S("tblalign", n);
|
|
3594
3701
|
},
|
|
3595
3702
|
[
|
|
3596
3703
|
{ label: this.t("cancel"), action: () => this.closeDlg() },
|
|
@@ -3603,7 +3710,7 @@ const I = class I {
|
|
|
3603
3710
|
cellpadding: i.value.trim(),
|
|
3604
3711
|
cellspacing: s.value.trim(),
|
|
3605
3712
|
border: l.value.trim(),
|
|
3606
|
-
align:
|
|
3713
|
+
align: n.value
|
|
3607
3714
|
}), this.closeDlg(), this.onChange(), this.positionTableHandles();
|
|
3608
3715
|
}
|
|
3609
3716
|
}
|
|
@@ -3642,8 +3749,8 @@ const I = class I {
|
|
|
3642
3749
|
formSelect(t, e) {
|
|
3643
3750
|
const i = document.createElement("select");
|
|
3644
3751
|
return i.style.cssText = "flex:1;border:1px solid #cfd6df;border-radius:6px;padding:7px 9px;font:14px inherit;background:#fff", t.forEach(([s, l]) => {
|
|
3645
|
-
const
|
|
3646
|
-
|
|
3752
|
+
const n = document.createElement("option");
|
|
3753
|
+
n.value = s, n.textContent = l, s === e && (n.selected = !0), i.appendChild(n);
|
|
3647
3754
|
}), i;
|
|
3648
3755
|
}
|
|
3649
3756
|
formBg(t) {
|
|
@@ -3653,8 +3760,8 @@ const I = class I {
|
|
|
3653
3760
|
s.type = "color", s.value = i || "#ffffff", s.style.cssText = "width:36px;height:29px;border:1px solid #cfd6df;border-radius:4px;padding:1px;background:none;cursor:pointer";
|
|
3654
3761
|
const l = document.createElement("label");
|
|
3655
3762
|
l.style.cssText = "display:flex;align-items:center;gap:6px;cursor:pointer;color:#556";
|
|
3656
|
-
const
|
|
3657
|
-
return
|
|
3763
|
+
const n = document.createElement("input");
|
|
3764
|
+
return n.type = "checkbox", n.checked = !!i, l.append(n, document.createTextNode(this.t("fill"))), s.addEventListener("input", () => n.checked = !0), e.append(s, l), { wrap: e, color: s, fill: n };
|
|
3658
3765
|
}
|
|
3659
3766
|
setOrClear(t, e, i) {
|
|
3660
3767
|
i ? t.style.setProperty(e, /^(width|height)$/.test(e) && /^\d+$/.test(i) ? i + "px" : i) : t.style.removeProperty(e);
|
|
@@ -3665,11 +3772,11 @@ const I = class I {
|
|
|
3665
3772
|
alert(this.t("nocell"));
|
|
3666
3773
|
return;
|
|
3667
3774
|
}
|
|
3668
|
-
let e, i, s, l,
|
|
3775
|
+
let e, i, s, l, n;
|
|
3669
3776
|
this.dialog(
|
|
3670
3777
|
this.t("cellprops").replace("…", ""),
|
|
3671
|
-
(
|
|
3672
|
-
e = this.formInput(t.style.width, "e.g. 120px / 25%"), this.formRow(
|
|
3778
|
+
(o) => {
|
|
3779
|
+
e = this.formInput(t.style.width, "e.g. 120px / 25%"), this.formRow(o, this.t("tblwidth"), e), i = this.formInput(t.style.height, "e.g. 40px"), this.formRow(o, this.t("tblheight"), i), s = this.formSelect(
|
|
3673
3780
|
[
|
|
3674
3781
|
["", this.t("alignnone")],
|
|
3675
3782
|
["left", this.t("alignleft")],
|
|
@@ -3677,7 +3784,7 @@ const I = class I {
|
|
|
3677
3784
|
["right", this.t("alignright")]
|
|
3678
3785
|
],
|
|
3679
3786
|
t.style.textAlign || ""
|
|
3680
|
-
), this.formRow(
|
|
3787
|
+
), this.formRow(o, this.t("tblalign"), s), l = this.formSelect(
|
|
3681
3788
|
[
|
|
3682
3789
|
["", this.t("alignnone")],
|
|
3683
3790
|
["top", this.t("valigntop")],
|
|
@@ -3685,7 +3792,7 @@ const I = class I {
|
|
|
3685
3792
|
["bottom", this.t("valignbottom")]
|
|
3686
3793
|
],
|
|
3687
3794
|
t.style.verticalAlign || ""
|
|
3688
|
-
), this.formRow(
|
|
3795
|
+
), this.formRow(o, this.t("valign"), l), n = this.formBg(t.style.backgroundColor || ""), this.formRow(o, this.t("backcolor"), n.wrap);
|
|
3689
3796
|
},
|
|
3690
3797
|
[
|
|
3691
3798
|
{ label: this.t("cancel"), action: () => this.closeDlg() },
|
|
@@ -3693,7 +3800,7 @@ const I = class I {
|
|
|
3693
3800
|
label: this.t("save"),
|
|
3694
3801
|
primary: !0,
|
|
3695
3802
|
action: () => {
|
|
3696
|
-
this.setOrClear(t, "width", e.value.trim()), this.setOrClear(t, "height", i.value.trim()), this.setOrClear(t, "text-align", s.value), this.setOrClear(t, "vertical-align", l.value), this.setOrClear(t, "background-color",
|
|
3803
|
+
this.setOrClear(t, "width", e.value.trim()), this.setOrClear(t, "height", i.value.trim()), this.setOrClear(t, "text-align", s.value), this.setOrClear(t, "vertical-align", l.value), this.setOrClear(t, "background-color", n.fill.checked ? n.color.value : ""), this.closeDlg(), this.onChange(), this.positionTableHandles();
|
|
3697
3804
|
}
|
|
3698
3805
|
}
|
|
3699
3806
|
]
|
|
@@ -3731,11 +3838,11 @@ const I = class I {
|
|
|
3731
3838
|
return;
|
|
3732
3839
|
}
|
|
3733
3840
|
const e = t.parentElement, i = t.closest("table"), s = Array.from(e.children).indexOf(t), l = Array.from(i.rows).map((r) => r.cells[s]).filter(Boolean);
|
|
3734
|
-
let
|
|
3841
|
+
let n, o;
|
|
3735
3842
|
this.dialog(
|
|
3736
3843
|
this.t("colprops").replace("…", ""),
|
|
3737
3844
|
(r) => {
|
|
3738
|
-
|
|
3845
|
+
n = this.formInput(t.style.width, "e.g. 120px / 25%"), this.formRow(r, this.t("tblwidth"), n), o = this.formBg(t.style.backgroundColor || ""), this.formRow(r, this.t("backcolor"), o.wrap);
|
|
3739
3846
|
},
|
|
3740
3847
|
[
|
|
3741
3848
|
{ label: this.t("cancel"), action: () => this.closeDlg() },
|
|
@@ -3744,7 +3851,7 @@ const I = class I {
|
|
|
3744
3851
|
primary: !0,
|
|
3745
3852
|
action: () => {
|
|
3746
3853
|
l.forEach((r) => {
|
|
3747
|
-
this.setOrClear(r, "width",
|
|
3854
|
+
this.setOrClear(r, "width", n.value.trim()), this.setOrClear(r, "background-color", o.fill.checked ? o.color.value : "");
|
|
3748
3855
|
}), this.closeDlg(), this.onChange(), this.positionTableHandles();
|
|
3749
3856
|
}
|
|
3750
3857
|
}
|
|
@@ -3760,8 +3867,8 @@ const I = class I {
|
|
|
3760
3867
|
const s = document.createElement("div");
|
|
3761
3868
|
s.className = "dlg", s.dir = this.dir(), s.innerHTML = `<header><span>${t}</span><button type="button">×</button></header>
|
|
3762
3869
|
<div class="body"></div><footer></footer>`, s.querySelector("header button").onclick = () => this.closeDlg(), e(s.querySelector(".body")), (i || [{ label: this.t("close"), primary: !0, action: () => this.closeDlg() }]).forEach((l) => {
|
|
3763
|
-
const
|
|
3764
|
-
|
|
3870
|
+
const n = document.createElement("button");
|
|
3871
|
+
n.type = "button", n.textContent = l.label, l.primary && (n.className = "pri"), n.onclick = l.action, s.querySelector("footer").appendChild(n);
|
|
3765
3872
|
}), this.dlgOvl.appendChild(s), this.dlgOvl.addEventListener("mousedown", (l) => {
|
|
3766
3873
|
l.target === this.dlgOvl && this.closeDlg();
|
|
3767
3874
|
}), document.body.appendChild(this.dlgOvl);
|
|
@@ -3811,8 +3918,12 @@ const I = class I {
|
|
|
3811
3918
|
}
|
|
3812
3919
|
previewDlg() {
|
|
3813
3920
|
this.dialog(this.t("previewttl"), (t) => {
|
|
3921
|
+
var s;
|
|
3922
|
+
(s = t.closest(".dlg")) == null || s.classList.add("dlg-preview");
|
|
3814
3923
|
const e = document.createElement("div");
|
|
3815
|
-
e.
|
|
3924
|
+
e.className = "pv-box";
|
|
3925
|
+
const i = this.contentWidth();
|
|
3926
|
+
e.style.cssText = `width:${i > 0 ? Math.round(i) : 640}px;max-width:100%;max-height:52vh;overflow:auto;border:1px solid #e3e3e3;border-radius:6px;padding:14px;font-family:Helvetica,Arial,sans-serif;font-size:14px`, e.innerHTML = this.ed.innerHTML, t.appendChild(e);
|
|
3816
3927
|
});
|
|
3817
3928
|
}
|
|
3818
3929
|
/** Two-pane picker shared by the special-character map and the emoji map:
|
|
@@ -3821,31 +3932,31 @@ const I = class I {
|
|
|
3821
3932
|
this.saveSel(), this.dialog(t, (s) => {
|
|
3822
3933
|
const l = document.createElement("div");
|
|
3823
3934
|
l.className = "chmap";
|
|
3824
|
-
const o = document.createElement("div");
|
|
3825
|
-
o.className = "chtabs";
|
|
3826
3935
|
const n = document.createElement("div");
|
|
3827
|
-
n.className = "
|
|
3936
|
+
n.className = "chtabs";
|
|
3937
|
+
const o = document.createElement("div");
|
|
3938
|
+
o.className = "chpanel";
|
|
3828
3939
|
const r = document.createElement("div");
|
|
3829
|
-
r.className = "chgrid" + (i ? " emgrid" : ""),
|
|
3830
|
-
const
|
|
3831
|
-
|
|
3940
|
+
r.className = "chgrid" + (i ? " emgrid" : ""), o.appendChild(r);
|
|
3941
|
+
const a = (h) => {
|
|
3942
|
+
n.querySelectorAll("button").forEach((p, m) => p.classList.toggle("on", m === h)), r.innerHTML = "", e[h].chars.forEach((p) => {
|
|
3832
3943
|
const m = document.createElement("button");
|
|
3833
|
-
m.type = "button", m.textContent =
|
|
3834
|
-
this.closeDlg(), this.exec("insertText",
|
|
3944
|
+
m.type = "button", m.textContent = p, m.onclick = () => {
|
|
3945
|
+
this.closeDlg(), this.exec("insertText", p);
|
|
3835
3946
|
}, r.appendChild(m);
|
|
3836
|
-
}),
|
|
3947
|
+
}), o.scrollTop = 0;
|
|
3837
3948
|
};
|
|
3838
|
-
e.forEach((h,
|
|
3949
|
+
e.forEach((h, p) => {
|
|
3839
3950
|
const m = document.createElement("button");
|
|
3840
|
-
m.type = "button", m.textContent = this.t(h.key), m.addEventListener("click", () =>
|
|
3841
|
-
}), l.append(
|
|
3951
|
+
m.type = "button", m.textContent = this.t(h.key), m.addEventListener("click", () => a(p)), n.appendChild(m);
|
|
3952
|
+
}), l.append(n, o), s.appendChild(l), a(0);
|
|
3842
3953
|
});
|
|
3843
3954
|
}
|
|
3844
3955
|
charMap() {
|
|
3845
|
-
this.glyphPickerDlg(this.t("charmap").replace("…", ""),
|
|
3956
|
+
this.glyphPickerDlg(this.t("charmap").replace("…", ""), ft, !1);
|
|
3846
3957
|
}
|
|
3847
3958
|
emojiMap() {
|
|
3848
|
-
this.glyphPickerDlg(this.t("emoji").replace("…", ""),
|
|
3959
|
+
this.glyphPickerDlg(this.t("emoji").replace("…", ""), vt, !0);
|
|
3849
3960
|
}
|
|
3850
3961
|
printDoc() {
|
|
3851
3962
|
const t = window.open("", "_blank");
|
|
@@ -3858,7 +3969,7 @@ const I = class I {
|
|
|
3858
3969
|
}
|
|
3859
3970
|
/* ---------------------------------------------- image upload placeholder */
|
|
3860
3971
|
imgPhHTML(t) {
|
|
3861
|
-
return `<div class="img-ph"${t ? ` id="${t}"` : ""} contenteditable="false">${
|
|
3972
|
+
return `<div class="img-ph"${t ? ` id="${t}"` : ""} contenteditable="false">${c.image}<span>${this.t("dropimage")}</span></div>`;
|
|
3862
3973
|
}
|
|
3863
3974
|
insertImagePlaceholder() {
|
|
3864
3975
|
this.restoreSel();
|
|
@@ -3882,11 +3993,11 @@ const I = class I {
|
|
|
3882
3993
|
var e;
|
|
3883
3994
|
const t = this.phCtx;
|
|
3884
3995
|
t && (t.innerHTML = "", t.append(
|
|
3885
|
-
this.ctxBtn(
|
|
3996
|
+
this.ctxBtn(c.uploadic, this.t("uploadimg"), () => {
|
|
3886
3997
|
this.phUploadTarget = this.phActive, this.pickImage();
|
|
3887
3998
|
}),
|
|
3888
|
-
this.ctxBtn(
|
|
3889
|
-
), (e = this.phActive) != null && e.closest(".tpl-media") && t.append(this.ctxBtn(
|
|
3999
|
+
this.ctxBtn(c.link, this.t("imagelink"), () => this.renderPhCtxUrlInput())
|
|
4000
|
+
), (e = this.phActive) != null && e.closest(".tpl-media") && t.append(this.ctxBtn(c.video, this.t("quickvideo"), () => this.swapPlaceholderKind("video"))), t.append(this.ctxSep(), this.ctxBtn(c.trash, this.t("deleteimg"), () => this.removeImgPlaceholder())), this.positionImgPhCtx());
|
|
3890
4001
|
}
|
|
3891
4002
|
/** Swaps a template slot's placeholder between image and video kinds, so the
|
|
3892
4003
|
* same media slot can be filled with either. */
|
|
@@ -3907,17 +4018,17 @@ const I = class I {
|
|
|
3907
4018
|
const i = document.createElement("button");
|
|
3908
4019
|
i.type = "button", i.className = "txtbtn", i.textContent = this.t("insertimg");
|
|
3909
4020
|
const s = () => {
|
|
3910
|
-
const l = e.value.trim(),
|
|
3911
|
-
if (!
|
|
4021
|
+
const l = e.value.trim(), n = this.phActive;
|
|
4022
|
+
if (!n) return;
|
|
3912
4023
|
if (!/^(https?:|data:image\/|blob:)/i.test(l)) {
|
|
3913
4024
|
e.classList.add("err"), e.focus();
|
|
3914
4025
|
return;
|
|
3915
4026
|
}
|
|
3916
4027
|
i.disabled = !0, e.disabled = !0;
|
|
3917
|
-
const
|
|
3918
|
-
|
|
4028
|
+
const o = new Image();
|
|
4029
|
+
o.onload = () => this.replacePlaceholderWithImage(n, l, ""), o.onerror = () => {
|
|
3919
4030
|
i.disabled = !1, e.disabled = !1, e.classList.add("err"), e.focus();
|
|
3920
|
-
},
|
|
4031
|
+
}, o.src = l;
|
|
3921
4032
|
};
|
|
3922
4033
|
i.addEventListener("click", s), e.addEventListener("input", () => e.classList.remove("err")), e.addEventListener("keydown", (l) => {
|
|
3923
4034
|
l.key === "Enter" ? (l.preventDefault(), s()) : l.key === "Escape" && (l.stopPropagation(), this.renderPhCtxButtons());
|
|
@@ -3943,13 +4054,64 @@ const I = class I {
|
|
|
3943
4054
|
s && (s.textContent = this.t("uploading")), this.imageUploadHandler(t).then((l) => {
|
|
3944
4055
|
this.ed.contains(e) && this.replacePlaceholderWithImage(e, l, i);
|
|
3945
4056
|
}).catch((l) => {
|
|
3946
|
-
var
|
|
3947
|
-
this.ed.contains(e) && (e.classList.remove("uploading"), e.classList.add("upload-error"), s && (s.textContent = this.t("uploadfailed")), (
|
|
4057
|
+
var n;
|
|
4058
|
+
this.ed.contains(e) && (e.classList.remove("uploading"), e.classList.add("upload-error"), s && (s.textContent = this.t("uploadfailed")), (n = this.onImageUploadError) == null || n.call(this, l, t));
|
|
3948
4059
|
});
|
|
3949
4060
|
}
|
|
3950
4061
|
replacePlaceholderWithImage(t, e, i) {
|
|
3951
4062
|
const s = document.createElement("img");
|
|
3952
|
-
s.src = e, s.alt = "", i && (s.title = i), t.replaceWith(s), this.phActive === t && this.clearImgPlaceholderSel(), this.refreshState(), this.onChange();
|
|
4063
|
+
s.src = e, s.alt = "", i && (s.title = i), t.replaceWith(s), this.stampImageSize(s), this.phActive === t && this.clearImgPlaceholderSel(), this.refreshState(), this.onChange();
|
|
4064
|
+
}
|
|
4065
|
+
/** Width of the editor's text column — the width `.earea img { max-width:100% }`
|
|
4066
|
+
* clamps an oversized image to. */
|
|
4067
|
+
contentWidth() {
|
|
4068
|
+
const t = getComputedStyle(this.ed), e = (parseFloat(t.paddingLeft) || 0) + (parseFloat(t.paddingRight) || 0);
|
|
4069
|
+
return Math.max(0, this.ed.clientWidth - e);
|
|
4070
|
+
}
|
|
4071
|
+
/** Inserts an <img> through execCommand and stamps its size once it has decoded.
|
|
4072
|
+
* A throwaway id is the only way to get a handle on what insertHTML created. */
|
|
4073
|
+
insertImageHTML(t, e) {
|
|
4074
|
+
const i = "fable-img-" + Date.now().toString(36) + Math.random().toString(36).slice(2, 6);
|
|
4075
|
+
document.execCommand(
|
|
4076
|
+
"insertHTML",
|
|
4077
|
+
!1,
|
|
4078
|
+
`<img id="${i}" src="${t}"${e ? ` title="${e}"` : ""} alt="">`
|
|
4079
|
+
);
|
|
4080
|
+
const s = this.ed.querySelector("#" + i);
|
|
4081
|
+
s && (s.removeAttribute("id"), this.stampImageSize(s));
|
|
4082
|
+
}
|
|
4083
|
+
/** Gives a newly inserted image an explicit size so it renders the same in the
|
|
4084
|
+
* editor, in Preview and in a sent email. Without it the image only looks right
|
|
4085
|
+
* inside `.earea`, whose `max-width:100%` rule exists nowhere else — which is why
|
|
4086
|
+
* the same picture came out at a different size once the mail was sent.
|
|
4087
|
+
* Leaves alone: images inside a template media slot (deliberately fluid) and any
|
|
4088
|
+
* image that already carries a size from its source. */
|
|
4089
|
+
stampImageSize(t, e) {
|
|
4090
|
+
const i = (l) => {
|
|
4091
|
+
e ? e(l) : l && this.onChange();
|
|
4092
|
+
}, s = () => {
|
|
4093
|
+
if (!this.ed.contains(t) || t.closest(".tpl-media") || t.getAttribute("width") || t.getAttribute("height") || t.style.width || t.style.height) return i(!1);
|
|
4094
|
+
const l = t.naturalWidth;
|
|
4095
|
+
if (!l) return i(!1);
|
|
4096
|
+
const n = this.contentWidth(), o = Math.round(n > 0 ? Math.min(l, n) : l);
|
|
4097
|
+
t.setAttribute("width", String(o)), t.style.width = o + "px", t.style.height = "auto", i(!0);
|
|
4098
|
+
};
|
|
4099
|
+
t.complete && t.naturalWidth ? s() : (t.addEventListener("load", s, { once: !0 }), t.addEventListener("error", () => i(!1), { once: !0 }));
|
|
4100
|
+
}
|
|
4101
|
+
/** Sizes images in content that arrived from outside the editor — a document saved
|
|
4102
|
+
* before the editor started recording image sizes. Without this such a document
|
|
4103
|
+
* keeps rendering at one size here and another in a sent mail. Images that already
|
|
4104
|
+
* carry a size, and template slots, are left alone, so content written by a
|
|
4105
|
+
* current version passes through untouched. Emits one change after the images have
|
|
4106
|
+
* settled rather than one per image, and none at all if nothing needed stamping. */
|
|
4107
|
+
stampExistingImages() {
|
|
4108
|
+
const t = Array.from(this.ed.querySelectorAll("img"));
|
|
4109
|
+
if (!t.length) return;
|
|
4110
|
+
let e = t.length, i = !1;
|
|
4111
|
+
const s = (l) => {
|
|
4112
|
+
l && (i = !0), --e === 0 && i && this.onChange();
|
|
4113
|
+
};
|
|
4114
|
+
t.forEach((l) => this.stampImageSize(l, s));
|
|
3953
4115
|
}
|
|
3954
4116
|
positionImgPhCtx() {
|
|
3955
4117
|
if (this.phActive && !document.body.contains(this.phActive)) {
|
|
@@ -3968,7 +4130,7 @@ const I = class I {
|
|
|
3968
4130
|
this.vidInput.value = "", this.vidInput.click();
|
|
3969
4131
|
}
|
|
3970
4132
|
vidPhHTML(t) {
|
|
3971
|
-
return `<div class="img-ph vid-ph"${t ? ` id="${t}"` : ""} contenteditable="false">${
|
|
4133
|
+
return `<div class="img-ph vid-ph"${t ? ` id="${t}"` : ""} contenteditable="false">${c.video}<span>${this.t("dropvideo")}</span></div>`;
|
|
3972
4134
|
}
|
|
3973
4135
|
insertVideoPlaceholder() {
|
|
3974
4136
|
this.restoreSel();
|
|
@@ -3992,11 +4154,11 @@ const I = class I {
|
|
|
3992
4154
|
var e;
|
|
3993
4155
|
const t = this.vphCtx;
|
|
3994
4156
|
t && (t.innerHTML = "", t.append(
|
|
3995
|
-
this.ctxBtn(
|
|
4157
|
+
this.ctxBtn(c.uploadic, this.t("uploadvideo"), () => {
|
|
3996
4158
|
this.vphUploadTarget = this.vphActive, this.pickVideo();
|
|
3997
4159
|
}),
|
|
3998
|
-
this.ctxBtn(
|
|
3999
|
-
), (e = this.vphActive) != null && e.closest(".tpl-media") && t.append(this.ctxBtn(
|
|
4160
|
+
this.ctxBtn(c.link, this.t("videolink"), () => this.renderVphCtxUrlInput())
|
|
4161
|
+
), (e = this.vphActive) != null && e.closest(".tpl-media") && t.append(this.ctxBtn(c.image, this.t("quickimage"), () => this.swapPlaceholderKind("image"))), t.append(this.ctxSep(), this.ctxBtn(c.trash, this.t("deletevideo"), () => this.removeVphPlaceholder())), this.positionVphCtx());
|
|
4000
4162
|
}
|
|
4001
4163
|
renderVphCtxUrlInput() {
|
|
4002
4164
|
const t = this.vphCtx;
|
|
@@ -4007,20 +4169,20 @@ const I = class I {
|
|
|
4007
4169
|
const i = document.createElement("button");
|
|
4008
4170
|
i.type = "button", i.className = "txtbtn", i.textContent = this.t("insertvideo");
|
|
4009
4171
|
const s = () => {
|
|
4010
|
-
const l = e.value.trim(),
|
|
4011
|
-
if (!
|
|
4172
|
+
const l = e.value.trim(), n = this.vphActive;
|
|
4173
|
+
if (!n) return;
|
|
4012
4174
|
if (!/^(https?:|data:video\/|blob:)/i.test(l)) {
|
|
4013
4175
|
e.classList.add("err"), e.focus();
|
|
4014
4176
|
return;
|
|
4015
4177
|
}
|
|
4016
|
-
const
|
|
4017
|
-
if (
|
|
4018
|
-
this.replacePlaceholderWithEmbed(
|
|
4178
|
+
const o = this.videoEmbedUrl(l);
|
|
4179
|
+
if (o) {
|
|
4180
|
+
this.replacePlaceholderWithEmbed(n, o);
|
|
4019
4181
|
return;
|
|
4020
4182
|
}
|
|
4021
4183
|
i.disabled = !0, e.disabled = !0;
|
|
4022
4184
|
const r = document.createElement("video");
|
|
4023
|
-
r.preload = "metadata", r.onloadedmetadata = () => this.replacePlaceholderWithVideo(
|
|
4185
|
+
r.preload = "metadata", r.onloadedmetadata = () => this.replacePlaceholderWithVideo(n, l, ""), r.onerror = () => {
|
|
4024
4186
|
i.disabled = !1, e.disabled = !1, e.classList.add("err"), e.focus();
|
|
4025
4187
|
}, r.src = l;
|
|
4026
4188
|
};
|
|
@@ -4048,8 +4210,8 @@ const I = class I {
|
|
|
4048
4210
|
s && (s.textContent = this.t("uploading")), this.videoUploadHandler(t).then((l) => {
|
|
4049
4211
|
this.ed.contains(e) && this.replacePlaceholderWithVideo(e, l, i);
|
|
4050
4212
|
}).catch((l) => {
|
|
4051
|
-
var
|
|
4052
|
-
this.ed.contains(e) && (e.classList.remove("uploading"), e.classList.add("upload-error"), s && (s.textContent = this.t("uploadfailed")), (
|
|
4213
|
+
var n;
|
|
4214
|
+
this.ed.contains(e) && (e.classList.remove("uploading"), e.classList.add("upload-error"), s && (s.textContent = this.t("uploadfailed")), (n = this.onVideoUploadError) == null || n.call(this, l, t));
|
|
4053
4215
|
});
|
|
4054
4216
|
}
|
|
4055
4217
|
replacePlaceholderWithVideo(t, e, i) {
|
|
@@ -4089,23 +4251,23 @@ const I = class I {
|
|
|
4089
4251
|
e.className = "imgctx", e.dir = this.dir();
|
|
4090
4252
|
const i = () => {
|
|
4091
4253
|
var h;
|
|
4092
|
-
const
|
|
4093
|
-
(h = this.vidCtx) == null || h.replaceWith(
|
|
4094
|
-
}, s = (
|
|
4095
|
-
this.setVideoAlign(t,
|
|
4096
|
-
}, l = t.style.float === "left",
|
|
4097
|
-
const g = this.ctxBtn(
|
|
4098
|
-
return g.classList.toggle("on",
|
|
4254
|
+
const a = this.buildVideoCtxToolbar(t);
|
|
4255
|
+
(h = this.vidCtx) == null || h.replaceWith(a), this.vidCtx = a, this.positionVidCtx();
|
|
4256
|
+
}, s = (a) => {
|
|
4257
|
+
this.setVideoAlign(t, a), i();
|
|
4258
|
+
}, l = t.style.float === "left", n = t.style.float === "right", o = !l && !n && t.style.marginLeft === "auto" && t.style.marginRight === "auto", r = (a, h, p, m) => {
|
|
4259
|
+
const g = this.ctxBtn(a, h, m);
|
|
4260
|
+
return g.classList.toggle("on", p), g;
|
|
4099
4261
|
};
|
|
4100
4262
|
return e.append(
|
|
4101
|
-
r(
|
|
4102
|
-
r(
|
|
4103
|
-
r(
|
|
4263
|
+
r(c.alignleft, this.t("alignleft"), l, () => s("left")),
|
|
4264
|
+
r(c.aligncenter, this.t("aligncenter"), o, () => s("center")),
|
|
4265
|
+
r(c.alignright, this.t("alignright"), n, () => s("right")),
|
|
4104
4266
|
this.ctxSep(),
|
|
4105
|
-
r(
|
|
4267
|
+
r(c.trash, this.t("deletevideo"), !1, () => {
|
|
4106
4268
|
t.remove(), this.clearVidHandles(), this.onChange();
|
|
4107
4269
|
})
|
|
4108
|
-
), e.addEventListener("mousedown", (
|
|
4270
|
+
), e.addEventListener("mousedown", (a) => a.preventDefault()), e.addEventListener("mouseenter", () => this.cancelVidHide()), e.addEventListener("mouseleave", () => {
|
|
4109
4271
|
this.cancelVidHide(), this.vidHideTimer = window.setTimeout(() => this.clearVidHandles(), 250);
|
|
4110
4272
|
}), document.body.appendChild(e), e;
|
|
4111
4273
|
}
|
|
@@ -4142,30 +4304,30 @@ const I = class I {
|
|
|
4142
4304
|
* (videoUploadHandler when configured, else inline base64). */
|
|
4143
4305
|
videoDlg() {
|
|
4144
4306
|
this.saveSel();
|
|
4145
|
-
let t, e, i, s, l,
|
|
4146
|
-
const
|
|
4147
|
-
const
|
|
4148
|
-
|
|
4307
|
+
let t, e, i, s, l, n;
|
|
4308
|
+
const o = (a, h) => {
|
|
4309
|
+
const p = document.createElement("div");
|
|
4310
|
+
p.className = "dfield";
|
|
4149
4311
|
const m = document.createElement("label");
|
|
4150
|
-
return m.textContent = this.t(
|
|
4312
|
+
return m.textContent = this.t(a), p.append(m, h), p;
|
|
4151
4313
|
}, r = () => {
|
|
4152
|
-
const
|
|
4153
|
-
return
|
|
4314
|
+
const a = document.createElement("input");
|
|
4315
|
+
return a.type = "url", a;
|
|
4154
4316
|
};
|
|
4155
4317
|
this.dialog(
|
|
4156
4318
|
this.t("videodlgttl"),
|
|
4157
|
-
(
|
|
4319
|
+
(a) => {
|
|
4158
4320
|
const h = document.createElement("div");
|
|
4159
4321
|
h.className = "dtabs";
|
|
4160
|
-
const
|
|
4322
|
+
const p = [], m = (v, b) => {
|
|
4161
4323
|
const x = document.createElement("button");
|
|
4162
4324
|
x.type = "button", x.textContent = this.t(v);
|
|
4163
4325
|
const C = document.createElement("div");
|
|
4164
4326
|
C.className = "dtabpanel", b(C);
|
|
4165
|
-
const
|
|
4166
|
-
|
|
4327
|
+
const S = p.length;
|
|
4328
|
+
p.push(C), x.addEventListener("click", () => g(S)), h.appendChild(x);
|
|
4167
4329
|
}, g = (v) => {
|
|
4168
|
-
h.querySelectorAll("button").forEach((b, x) => b.classList.toggle("on", x === v)),
|
|
4330
|
+
h.querySelectorAll("button").forEach((b, x) => b.classList.toggle("on", x === v)), p.forEach((b, x) => b.style.display = x === v ? "" : "none");
|
|
4169
4331
|
};
|
|
4170
4332
|
m("vidgeneral", (v) => {
|
|
4171
4333
|
t = r(), t.placeholder = this.t("videourlph");
|
|
@@ -4181,29 +4343,29 @@ const I = class I {
|
|
|
4181
4343
|
const w = (L = C.files) == null ? void 0 : L[0];
|
|
4182
4344
|
if (!w) return;
|
|
4183
4345
|
x.disabled = !0, x.textContent = this.t("uploading");
|
|
4184
|
-
const
|
|
4185
|
-
t.value =
|
|
4346
|
+
const k = (H) => {
|
|
4347
|
+
t.value = H, x.disabled = !1, x.textContent = this.t("uploadvideo");
|
|
4186
4348
|
};
|
|
4187
4349
|
if (this.videoUploadHandler)
|
|
4188
|
-
this.videoUploadHandler(w).then(
|
|
4189
|
-
var
|
|
4190
|
-
x.disabled = !1, x.textContent = this.t("uploadfailed"), (
|
|
4350
|
+
this.videoUploadHandler(w).then(k).catch((H) => {
|
|
4351
|
+
var z;
|
|
4352
|
+
x.disabled = !1, x.textContent = this.t("uploadfailed"), (z = this.onVideoUploadError) == null || z.call(this, H, w);
|
|
4191
4353
|
});
|
|
4192
4354
|
else {
|
|
4193
|
-
const
|
|
4194
|
-
|
|
4355
|
+
const H = new FileReader();
|
|
4356
|
+
H.onload = () => k(H.result), H.readAsDataURL(w);
|
|
4195
4357
|
}
|
|
4196
|
-
}), b.append(t, x, C), t.style.flex = "1", v.appendChild(
|
|
4197
|
-
const
|
|
4198
|
-
|
|
4358
|
+
}), b.append(t, x, C), t.style.flex = "1", v.appendChild(o("vidsource", b));
|
|
4359
|
+
const S = document.createElement("div");
|
|
4360
|
+
S.className = "drow", e = document.createElement("input"), e.type = "number", e.value = "560", i = document.createElement("input"), i.type = "number", i.value = "314", S.append(o("tblwidth", e), o("tblheight", i)), v.appendChild(S);
|
|
4199
4361
|
}), m("vidembed", (v) => {
|
|
4200
4362
|
const b = document.createElement("p");
|
|
4201
4363
|
b.textContent = this.t("vidembedhint"), b.style.cssText = "margin:0 0 8px;color:#556;font-size:13.5px", s = document.createElement("textarea"), s.style.cssText = "width:100%;box-sizing:border-box;height:160px", v.append(b, s);
|
|
4202
4364
|
}), m("vidadvanced", (v) => {
|
|
4203
|
-
l = r(),
|
|
4365
|
+
l = r(), n = r(), v.append(o("vidaltsource", l), o("vidposter", n));
|
|
4204
4366
|
});
|
|
4205
4367
|
const u = document.createElement("div");
|
|
4206
|
-
u.className = "dtabbody",
|
|
4368
|
+
u.className = "dtabbody", p.forEach((v) => u.appendChild(v)), a.append(h, u), g(0), setTimeout(() => t.focus(), 0);
|
|
4207
4369
|
},
|
|
4208
4370
|
[
|
|
4209
4371
|
{ label: this.t("cancel"), action: () => this.closeDlg() },
|
|
@@ -4211,21 +4373,21 @@ const I = class I {
|
|
|
4211
4373
|
label: this.t("save"),
|
|
4212
4374
|
primary: !0,
|
|
4213
4375
|
action: () => {
|
|
4214
|
-
const
|
|
4215
|
-
if (this.closeDlg(), !
|
|
4216
|
-
if (this.restoreSel(),
|
|
4217
|
-
document.execCommand("insertHTML", !1, `<span class="video-embed" contenteditable="false">${
|
|
4376
|
+
const a = s.value.trim(), h = t.value.trim(), p = parseInt(e.value, 10) || 560, m = parseInt(i.value, 10) || 314;
|
|
4377
|
+
if (this.closeDlg(), !a && !h) return;
|
|
4378
|
+
if (this.restoreSel(), a) {
|
|
4379
|
+
document.execCommand("insertHTML", !1, `<span class="video-embed" contenteditable="false">${a}</span>`), this.onChange();
|
|
4218
4380
|
return;
|
|
4219
4381
|
}
|
|
4220
4382
|
const g = this.videoEmbedUrl(h);
|
|
4221
4383
|
if (g)
|
|
4222
|
-
document.execCommand("insertHTML", !1, this.videoEmbedHTML(g,
|
|
4384
|
+
document.execCommand("insertHTML", !1, this.videoEmbedHTML(g, p, m));
|
|
4223
4385
|
else {
|
|
4224
|
-
const u = l.value.trim(), v =
|
|
4386
|
+
const u = l.value.trim(), v = n.value.trim();
|
|
4225
4387
|
document.execCommand(
|
|
4226
4388
|
"insertHTML",
|
|
4227
4389
|
!1,
|
|
4228
|
-
`<video controls width="${
|
|
4390
|
+
`<video controls width="${p}" height="${m}"${v ? ` poster="${this.escapeAttr(v)}"` : ""}><source src="${this.escapeAttr(h)}">${u ? `<source src="${this.escapeAttr(u)}">` : ""}</video>`
|
|
4229
4391
|
);
|
|
4230
4392
|
}
|
|
4231
4393
|
this.onChange();
|
|
@@ -4283,15 +4445,15 @@ const I = class I {
|
|
|
4283
4445
|
if (i.nodeType !== Node.TEXT_NODE || !this.ed.contains(i) || (h = i.parentElement) != null && h.closest("code, pre")) return;
|
|
4284
4446
|
const l = (i.textContent || "").slice(0, e.anchorOffset).match(/(?:^|[^`])`([^`]+)$/);
|
|
4285
4447
|
if (!l) return;
|
|
4286
|
-
const
|
|
4287
|
-
if (/^\s|\s$/.test(
|
|
4448
|
+
const n = l[1];
|
|
4449
|
+
if (/^\s|\s$/.test(n)) return;
|
|
4288
4450
|
t.preventDefault();
|
|
4289
|
-
const
|
|
4290
|
-
|
|
4451
|
+
const o = document.createRange();
|
|
4452
|
+
o.setStart(i, e.anchorOffset - n.length - 1), o.setEnd(i, e.anchorOffset), o.deleteContents();
|
|
4291
4453
|
const r = document.createElement("code");
|
|
4292
|
-
r.textContent =
|
|
4293
|
-
const
|
|
4294
|
-
|
|
4454
|
+
r.textContent = n, o.insertNode(r);
|
|
4455
|
+
const a = document.createRange();
|
|
4456
|
+
a.setStartAfter(r), a.collapse(!0), e.removeAllRanges(), e.addRange(a), this.saveSel(), this.onChange();
|
|
4295
4457
|
}
|
|
4296
4458
|
/** Custom dropdown for dialog fields (a native <select> popup can't be styled):
|
|
4297
4459
|
* a field-styled button showing the current choice that opens a floating,
|
|
@@ -4303,22 +4465,22 @@ const I = class I {
|
|
|
4303
4465
|
s.className = "dsel";
|
|
4304
4466
|
const l = document.createElement("button");
|
|
4305
4467
|
l.type = "button", l.className = "dsel-btn";
|
|
4306
|
-
const
|
|
4307
|
-
|
|
4308
|
-
const
|
|
4309
|
-
return
|
|
4310
|
-
const
|
|
4311
|
-
|
|
4312
|
-
i =
|
|
4313
|
-
}),
|
|
4468
|
+
const n = document.createElement("span");
|
|
4469
|
+
n.className = "lbl", n.textContent = ((r = t.find(([a]) => a === e)) == null ? void 0 : r[1]) || "", l.append(n), l.insertAdjacentHTML("beforeend", c.chev);
|
|
4470
|
+
const o = document.createElement("div");
|
|
4471
|
+
return o.className = "dsel-list", t.forEach(([a, h]) => {
|
|
4472
|
+
const p = document.createElement("button");
|
|
4473
|
+
p.type = "button", p.textContent = h, p.classList.toggle("on", a === i), p.addEventListener("click", () => {
|
|
4474
|
+
i = a, n.textContent = h, o.querySelectorAll("button").forEach((m) => m.classList.toggle("on", m === p)), s.classList.remove("open"), l.focus();
|
|
4475
|
+
}), o.appendChild(p);
|
|
4314
4476
|
}), l.addEventListener("click", () => {
|
|
4315
|
-
var
|
|
4316
|
-
s.classList.toggle("open"), s.classList.contains("open") && ((
|
|
4317
|
-
}), s.addEventListener("focusout", (
|
|
4318
|
-
s.contains(
|
|
4319
|
-
}), s.addEventListener("keydown", (
|
|
4320
|
-
|
|
4321
|
-
}), s.append(l,
|
|
4477
|
+
var a;
|
|
4478
|
+
s.classList.toggle("open"), s.classList.contains("open") && ((a = o.querySelector(".on")) == null || a.scrollIntoView({ block: "nearest" }));
|
|
4479
|
+
}), s.addEventListener("focusout", (a) => {
|
|
4480
|
+
s.contains(a.relatedTarget) || s.classList.remove("open");
|
|
4481
|
+
}), s.addEventListener("keydown", (a) => {
|
|
4482
|
+
a.key === "Escape" && s.classList.contains("open") && (a.stopPropagation(), s.classList.remove("open"), l.focus());
|
|
4483
|
+
}), s.append(l, o), { el: s, value: () => i };
|
|
4322
4484
|
}
|
|
4323
4485
|
/** Insert/edit-code-sample dialog: language dropdown + monospace textarea to
|
|
4324
4486
|
* paste or type code into. Inserts a non-editable <pre class="code-block">
|
|
@@ -4329,11 +4491,11 @@ const I = class I {
|
|
|
4329
4491
|
this.dialog(
|
|
4330
4492
|
this.t("codedlgttl"),
|
|
4331
4493
|
(s) => {
|
|
4332
|
-
var
|
|
4494
|
+
var o;
|
|
4333
4495
|
const l = document.createElement("div");
|
|
4334
4496
|
l.className = "dfield";
|
|
4335
|
-
const
|
|
4336
|
-
|
|
4497
|
+
const n = document.createElement("label");
|
|
4498
|
+
n.textContent = this.t("codelang"), e = this.dlgSelect(V, (t == null ? void 0 : t.dataset.lang) || "plain"), l.append(n, e.el), i = document.createElement("textarea"), i.className = "code-input", i.spellcheck = !1, i.value = ((o = t == null ? void 0 : t.querySelector("code")) == null ? void 0 : o.textContent) || "", i.placeholder = "const answer = 42;", s.append(l, i), setTimeout(() => i.focus(), 0);
|
|
4337
4499
|
},
|
|
4338
4500
|
[
|
|
4339
4501
|
{ label: this.t("cancel"), action: () => this.closeDlg() },
|
|
@@ -4341,11 +4503,11 @@ const I = class I {
|
|
|
4341
4503
|
label: this.t("save"),
|
|
4342
4504
|
primary: !0,
|
|
4343
4505
|
action: () => {
|
|
4344
|
-
var
|
|
4345
|
-
const s = i.value.replace(/\s+$/, ""), l = e.value(),
|
|
4506
|
+
var o;
|
|
4507
|
+
const s = i.value.replace(/\s+$/, ""), l = e.value(), n = ((o = V.find(([r]) => r === l)) == null ? void 0 : o[1]) || l;
|
|
4346
4508
|
if (this.closeDlg(), !!s.trim()) {
|
|
4347
4509
|
if (t) {
|
|
4348
|
-
t.dataset.lang = l, t.setAttribute("data-lang-label",
|
|
4510
|
+
t.dataset.lang = l, t.setAttribute("data-lang-label", n);
|
|
4349
4511
|
const r = t.querySelector("code") || t;
|
|
4350
4512
|
r.textContent = s, this.clearCodeSel(), this.onChange();
|
|
4351
4513
|
return;
|
|
@@ -4353,7 +4515,7 @@ const I = class I {
|
|
|
4353
4515
|
this.restoreSel(), document.execCommand(
|
|
4354
4516
|
"insertHTML",
|
|
4355
4517
|
!1,
|
|
4356
|
-
`<pre class="code-block" contenteditable="false" data-lang="${l}" data-lang-label="${this.escapeAttr(
|
|
4518
|
+
`<pre class="code-block" contenteditable="false" data-lang="${l}" data-lang-label="${this.escapeAttr(n)}"><code>${this.escHtml(s)}</code></pre><p><br></p>`
|
|
4357
4519
|
), this.onChange();
|
|
4358
4520
|
}
|
|
4359
4521
|
}
|
|
@@ -4371,10 +4533,10 @@ const I = class I {
|
|
|
4371
4533
|
buildCodeCtxToolbar(t) {
|
|
4372
4534
|
const e = document.createElement("div");
|
|
4373
4535
|
return e.className = "imgctx", e.dir = this.dir(), e.append(
|
|
4374
|
-
this.ctxBtn(
|
|
4375
|
-
this.ctxBtn(
|
|
4536
|
+
this.ctxBtn(c.editic, this.t("editcode"), () => this.codeDlg(t)),
|
|
4537
|
+
this.ctxBtn(c.copyic, this.t("copycode"), () => this.copyCodeBlock(t)),
|
|
4376
4538
|
this.ctxSep(),
|
|
4377
|
-
this.ctxBtn(
|
|
4539
|
+
this.ctxBtn(c.trash, this.t("deletecode"), () => {
|
|
4378
4540
|
t.remove(), this.clearCodeSel(), this.onChange();
|
|
4379
4541
|
})
|
|
4380
4542
|
), e.addEventListener("mousedown", (i) => i.preventDefault()), document.body.appendChild(e), e;
|
|
@@ -4410,14 +4572,14 @@ const I = class I {
|
|
|
4410
4572
|
/** Miniature div-based mockup of a layout, mirroring what the block looks
|
|
4411
4573
|
like in the editor: grey box = image slot, bars = heading/paragraph. */
|
|
4412
4574
|
tplPreviewHTML(t) {
|
|
4413
|
-
const e = '<span class="pv-img"></span>', i = '<span class="pv-h"></span>', s = (r) => `<span class="pv-l" style="width:${r}%"></span>`, l = (r) => `<span class="pv-col">${r}</span>`,
|
|
4414
|
-
return t === "img-left" ? `<span class="pv">${
|
|
4575
|
+
const e = '<span class="pv-img"></span>', i = '<span class="pv-h"></span>', s = (r) => `<span class="pv-l" style="width:${r}%"></span>`, l = (r) => `<span class="pv-col">${r}</span>`, n = (r) => `<span class="pv-row">${r}</span>`, o = l(i + s(100) + s(88));
|
|
4576
|
+
return t === "img-left" ? `<span class="pv">${n(e + o)}${s(100)}${s(72)}</span>` : t === "img-right" ? `<span class="pv">${n(o + e)}${s(100)}${s(72)}</span>` : t === "img-top" ? `<span class="pv pv-c">${e}${i}${s(100)}${s(72)}</span>` : `<span class="pv pv-c">${i}${s(100)}${s(72)}${e}</span>`;
|
|
4415
4577
|
}
|
|
4416
4578
|
buildTemplatePickInto(t, e) {
|
|
4417
4579
|
const i = document.createElement("div");
|
|
4418
|
-
i.className = "tplpick",
|
|
4580
|
+
i.className = "tplpick", O.forEach((s) => {
|
|
4419
4581
|
const l = document.createElement("button");
|
|
4420
|
-
l.type = "button", l.className = "tpltile", l.title = this.t(
|
|
4582
|
+
l.type = "button", l.className = "tpltile", l.title = this.t($[s]), l.innerHTML = this.tplPreviewHTML(s) + `<span class="tpllbl">${this.t($[s])}</span>`, l.addEventListener("click", () => {
|
|
4421
4583
|
this.closePop(), this.insertTemplate(s), e == null || e();
|
|
4422
4584
|
}), i.appendChild(l);
|
|
4423
4585
|
}), t.appendChild(i);
|
|
@@ -4436,15 +4598,15 @@ const I = class I {
|
|
|
4436
4598
|
}
|
|
4437
4599
|
renderTplCtxButtons() {
|
|
4438
4600
|
const t = this.tplCtx, e = this.tplActive;
|
|
4439
|
-
!t || !e || (t.innerHTML = "",
|
|
4440
|
-
const s = this.ctxBtn(
|
|
4601
|
+
!t || !e || (t.innerHTML = "", O.forEach((i) => {
|
|
4602
|
+
const s = this.ctxBtn(Wt[i], this.t($[i]), () => this.setTplLayout(i));
|
|
4441
4603
|
s.classList.toggle("on", e.classList.contains("tpl-" + i)), t.appendChild(s);
|
|
4442
|
-
}), t.append(this.ctxSep(), this.ctxBtn(
|
|
4604
|
+
}), t.append(this.ctxSep(), this.ctxBtn(c.trash, this.t("deltemplate"), () => this.removeTemplate())), this.positionTplCtx());
|
|
4443
4605
|
}
|
|
4444
4606
|
setTplLayout(t) {
|
|
4445
4607
|
const e = this.tplActive;
|
|
4446
4608
|
if (!e) return;
|
|
4447
|
-
|
|
4609
|
+
O.forEach((l) => e.classList.remove("tpl-" + l)), e.classList.add("tpl-" + t);
|
|
4448
4610
|
const i = e.querySelector(":scope > .tpl-media"), s = e.querySelector(":scope > .tpl-text");
|
|
4449
4611
|
i && s && (t === "img-center" ? e.appendChild(i) : e.insertBefore(i, s)), this.renderTplCtxButtons(), this.positionImgPhCtx(), this.positionImageHandles(), this.onChange();
|
|
4450
4612
|
}
|
|
@@ -4476,7 +4638,7 @@ const I = class I {
|
|
|
4476
4638
|
/* ---------------------------------------------------------- table resize */
|
|
4477
4639
|
clearTableHandles() {
|
|
4478
4640
|
var t, e, i, s, l;
|
|
4479
|
-
(t = this.tblCorner) == null || t.remove(), this.tblCorner = null, this.tblColBars.forEach((
|
|
4641
|
+
(t = this.tblCorner) == null || t.remove(), this.tblCorner = null, this.tblColBars.forEach((n) => n.remove()), this.tblColBars = [], (e = this.tblCtx) == null || e.remove(), this.tblCtx = null, (i = this.tblCellMark) == null || i.remove(), this.tblCellMark = null, (s = this.tblOpMark) == null || s.remove(), this.tblOpMark = null, this.tblOpMarkKind = null, (l = this.tblActive) == null || l.classList.remove("tbl-selected"), this.tblActive = null;
|
|
4480
4642
|
}
|
|
4481
4643
|
/** Blue outline around the cell that holds the caret, so it is clear
|
|
4482
4644
|
which cell / row / column the table operations will target. */
|
|
@@ -4503,8 +4665,8 @@ const I = class I {
|
|
|
4503
4665
|
return;
|
|
4504
4666
|
}
|
|
4505
4667
|
this.tblOpMark || (this.tblOpMark = document.createElement("div"), this.tblOpMark.className = "tbl-opmark", document.body.appendChild(this.tblOpMark));
|
|
4506
|
-
const i = this.tblActive.getBoundingClientRect(), s = e.getBoundingClientRect(), l = e.parentElement.getBoundingClientRect(),
|
|
4507
|
-
this.tblOpMark.style.left =
|
|
4668
|
+
const i = this.tblActive.getBoundingClientRect(), s = e.getBoundingClientRect(), l = e.parentElement.getBoundingClientRect(), n = t === "row" ? l.left : s.left, o = t === "row" ? l.top : i.top, r = t === "row" ? l.width : s.width, a = t === "row" ? l.height : i.height;
|
|
4669
|
+
this.tblOpMark.style.left = n + scrollX + "px", this.tblOpMark.style.top = o + scrollY + "px", this.tblOpMark.style.width = r + "px", this.tblOpMark.style.height = a + "px";
|
|
4508
4670
|
}
|
|
4509
4671
|
/** Lowest allowed top for floating context toolbars — keeps them from
|
|
4510
4672
|
covering the editor menubar/toolbar when the target sits on the first line. */
|
|
@@ -4513,7 +4675,7 @@ const I = class I {
|
|
|
4513
4675
|
}
|
|
4514
4676
|
ctxBtn(t, e, i, s) {
|
|
4515
4677
|
const l = document.createElement("button");
|
|
4516
|
-
return l.type = "button", l.title = e, l.innerHTML = t, s && (l.dataset.id = s), l.addEventListener("mousedown", (
|
|
4678
|
+
return l.type = "button", l.title = e, l.innerHTML = t, s && (l.dataset.id = s), l.addEventListener("mousedown", (n) => n.preventDefault()), l.addEventListener("click", i), l;
|
|
4517
4679
|
}
|
|
4518
4680
|
ctxSep() {
|
|
4519
4681
|
const t = document.createElement("div");
|
|
@@ -4522,27 +4684,27 @@ const I = class I {
|
|
|
4522
4684
|
buildTableCtxToolbar() {
|
|
4523
4685
|
const t = document.createElement("div");
|
|
4524
4686
|
t.className = "tblctx", t.dir = this.dir();
|
|
4525
|
-
const e = (s, l) => (s.addEventListener("mouseenter", () => this.setOpTarget(l)), s.addEventListener("mouseleave", () => this.setOpTarget(null)), s), i = this.ctxBtn(
|
|
4687
|
+
const e = (s, l) => (s.addEventListener("mouseenter", () => this.setOpTarget(l)), s.addEventListener("mouseleave", () => this.setOpTarget(null)), s), i = this.ctxBtn(c.palette, this.t("cellbg"), () => this.cellFillMenu(i));
|
|
4526
4688
|
return t.append(
|
|
4527
|
-
e(this.ctxBtn(
|
|
4528
|
-
e(this.ctxBtn(
|
|
4529
|
-
e(this.ctxBtn(
|
|
4530
|
-
e(this.ctxBtn(
|
|
4531
|
-
e(this.ctxBtn(
|
|
4689
|
+
e(this.ctxBtn(c.rowbefore, this.t("rowabove"), () => this.tableOp("rowabove")), "row"),
|
|
4690
|
+
e(this.ctxBtn(c.rowafter, this.t("rowbelow"), () => this.tableOp("rowbelow")), "row"),
|
|
4691
|
+
e(this.ctxBtn(c.moverowup, this.t("moverowup"), () => this.tableMove("rowup")), "row"),
|
|
4692
|
+
e(this.ctxBtn(c.moverowdown, this.t("moverowdown"), () => this.tableMove("rowdown")), "row"),
|
|
4693
|
+
e(this.ctxBtn(c.rowdelete, this.t("delrow"), () => this.tableOp("delrow")), "row"),
|
|
4532
4694
|
this.ctxSep(),
|
|
4533
|
-
e(this.ctxBtn(
|
|
4534
|
-
e(this.ctxBtn(
|
|
4535
|
-
e(this.ctxBtn(
|
|
4536
|
-
e(this.ctxBtn(
|
|
4537
|
-
e(this.ctxBtn(
|
|
4695
|
+
e(this.ctxBtn(c.colbefore, this.t("colbefore"), () => this.tableOp("colbefore")), "col"),
|
|
4696
|
+
e(this.ctxBtn(c.colafter, this.t("colafter"), () => this.tableOp("colafter")), "col"),
|
|
4697
|
+
e(this.ctxBtn(c.movecolleft, this.t("movecolleft"), () => this.tableMove("colleft")), "col"),
|
|
4698
|
+
e(this.ctxBtn(c.movecolright, this.t("movecolright"), () => this.tableMove("colright")), "col"),
|
|
4699
|
+
e(this.ctxBtn(c.coldelete, this.t("delcol"), () => this.tableOp("delcol")), "col"),
|
|
4538
4700
|
this.ctxSep(),
|
|
4539
|
-
this.ctxBtn(
|
|
4540
|
-
this.ctxBtn(
|
|
4541
|
-
this.ctxBtn(
|
|
4701
|
+
this.ctxBtn(c.alignleft, this.t("tblalignleft"), () => this.alignTable("left")),
|
|
4702
|
+
this.ctxBtn(c.aligncenter, this.t("tblaligncenter"), () => this.alignTable("center")),
|
|
4703
|
+
this.ctxBtn(c.alignright, this.t("tblalignright"), () => this.alignTable("right")),
|
|
4542
4704
|
this.ctxSep(),
|
|
4543
4705
|
i,
|
|
4544
|
-
this.ctxBtn(
|
|
4545
|
-
this.ctxBtn(
|
|
4706
|
+
this.ctxBtn(c.trash, this.t("deltable"), () => this.tableOp("deltable")),
|
|
4707
|
+
this.ctxBtn(c.tableic, this.t("tablepropsttl"), () => this.tablePropsDlg())
|
|
4546
4708
|
), document.body.appendChild(t), t;
|
|
4547
4709
|
}
|
|
4548
4710
|
positionTableHandles() {
|
|
@@ -4550,20 +4712,20 @@ const I = class I {
|
|
|
4550
4712
|
this.clearTableHandles();
|
|
4551
4713
|
return;
|
|
4552
4714
|
}
|
|
4553
|
-
const t = this.ed.getAttribute("dir") === "rtl", e = this.tblActive.getBoundingClientRect(), i = e.top + scrollY, s = e.left + scrollX, l = e.right + scrollX,
|
|
4554
|
-
if (this.tblCorner && (this.tblCorner.style.top =
|
|
4555
|
-
const r = this.tblCtx.offsetWidth,
|
|
4715
|
+
const t = this.ed.getAttribute("dir") === "rtl", e = this.tblActive.getBoundingClientRect(), i = e.top + scrollY, s = e.left + scrollX, l = e.right + scrollX, n = e.bottom + scrollY;
|
|
4716
|
+
if (this.tblCorner && (this.tblCorner.style.top = n - 5 + "px", this.tblCorner.style.left = (t ? s - 5 : l - 5) + "px", this.tblCorner.style.cursor = t ? "nesw-resize" : "nwse-resize"), this.tblCtx) {
|
|
4717
|
+
const r = this.tblCtx.offsetWidth, a = this.tblCtx.offsetHeight;
|
|
4556
4718
|
let h = s + (l - s) / 2 - r / 2;
|
|
4557
4719
|
h = Math.max(8 + scrollX, Math.min(h, scrollX + innerWidth - r - 8));
|
|
4558
|
-
let
|
|
4559
|
-
|
|
4720
|
+
let p = i - a - 8;
|
|
4721
|
+
p < this.ctxMinTop() && (p = n + 8), this.tblCtx.style.left = h + "px", this.tblCtx.style.top = p + "px";
|
|
4560
4722
|
}
|
|
4561
4723
|
this.tblColBars.forEach((r) => r.remove()), this.tblColBars = [];
|
|
4562
|
-
const
|
|
4563
|
-
if (
|
|
4564
|
-
for (let r = 0; r <
|
|
4565
|
-
const
|
|
4566
|
-
|
|
4724
|
+
const o = this.tblActive.rows[0];
|
|
4725
|
+
if (o)
|
|
4726
|
+
for (let r = 0; r < o.cells.length - 1; r++) {
|
|
4727
|
+
const a = o.cells[r].getBoundingClientRect(), h = (t ? a.left : a.right) + scrollX, p = document.createElement("div");
|
|
4728
|
+
p.className = "tbl-colbar", p.style.top = i + "px", p.style.left = h + "px", p.style.height = n - i + "px", document.body.appendChild(p), p.addEventListener("mousedown", (m) => this.startColBarDrag(m, r)), this.tblColBars.push(p);
|
|
4567
4729
|
}
|
|
4568
4730
|
this.positionCellMarker(), this.positionOpMark();
|
|
4569
4731
|
}
|
|
@@ -4581,29 +4743,29 @@ const I = class I {
|
|
|
4581
4743
|
const e = this.tblActive;
|
|
4582
4744
|
if (!e) return;
|
|
4583
4745
|
const i = this.ed.getAttribute("dir") === "rtl", s = t.clientX, l = e.getBoundingClientRect().width;
|
|
4584
|
-
e.style.tableLayout = e.style.tableLayout || "fixed", this.withNoTextSelect((
|
|
4585
|
-
const
|
|
4586
|
-
const h = i ? -(
|
|
4746
|
+
e.style.tableLayout = e.style.tableLayout || "fixed", this.withNoTextSelect((n) => {
|
|
4747
|
+
const o = (a) => {
|
|
4748
|
+
const h = i ? -(a.clientX - s) : a.clientX - s;
|
|
4587
4749
|
e.style.width = Math.max(60, Math.round(l + h)) + "px", this.positionTableHandles();
|
|
4588
4750
|
}, r = () => {
|
|
4589
|
-
window.removeEventListener("mousemove",
|
|
4751
|
+
window.removeEventListener("mousemove", o), window.removeEventListener("mouseup", r), n(), this.onChange();
|
|
4590
4752
|
};
|
|
4591
|
-
window.addEventListener("mousemove",
|
|
4753
|
+
window.addEventListener("mousemove", o), window.addEventListener("mouseup", r);
|
|
4592
4754
|
});
|
|
4593
4755
|
}
|
|
4594
4756
|
startColBarDrag(t, e) {
|
|
4595
4757
|
t.preventDefault(), t.stopPropagation();
|
|
4596
4758
|
const i = this.tblActive;
|
|
4597
4759
|
if (!i) return;
|
|
4598
|
-
const s = this.ed.getAttribute("dir") === "rtl", l = Array.from(i.rows),
|
|
4599
|
-
if (!
|
|
4600
|
-
const r = t.clientX,
|
|
4601
|
-
i.style.tableLayout = "fixed", this.withNoTextSelect((
|
|
4760
|
+
const s = this.ed.getAttribute("dir") === "rtl", l = Array.from(i.rows), n = l.map((p) => p.cells[e]).filter(Boolean), o = l.map((p) => p.cells[e + 1]).filter(Boolean);
|
|
4761
|
+
if (!n.length || !o.length) return;
|
|
4762
|
+
const r = t.clientX, a = n[0].getBoundingClientRect().width, h = o[0].getBoundingClientRect().width;
|
|
4763
|
+
i.style.tableLayout = "fixed", this.withNoTextSelect((p) => {
|
|
4602
4764
|
const m = (u) => {
|
|
4603
4765
|
const v = (s ? -1 : 1) * (u.clientX - r);
|
|
4604
|
-
|
|
4766
|
+
n.forEach((b) => b.style.width = Math.max(24, Math.round(a + v)) + "px"), o.forEach((b) => b.style.width = Math.max(24, Math.round(h - v)) + "px"), this.positionTableHandles();
|
|
4605
4767
|
}, g = () => {
|
|
4606
|
-
window.removeEventListener("mousemove", m), window.removeEventListener("mouseup", g),
|
|
4768
|
+
window.removeEventListener("mousemove", m), window.removeEventListener("mouseup", g), p(), this.onChange();
|
|
4607
4769
|
};
|
|
4608
4770
|
window.addEventListener("mousemove", m), window.addEventListener("mouseup", g);
|
|
4609
4771
|
});
|
|
@@ -4620,7 +4782,7 @@ const I = class I {
|
|
|
4620
4782
|
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;
|
|
4621
4783
|
}
|
|
4622
4784
|
selectImage(t) {
|
|
4623
|
-
this.imgActive !== t && (this.clearImageHandles(), this.imgActive = t, t.classList.add("img-selected"), this.imgHandles =
|
|
4785
|
+
this.imgActive !== t && (this.clearImageHandles(), this.imgActive = t, t.classList.add("img-selected"), this.imgHandles = Ut.map((e) => {
|
|
4624
4786
|
const i = document.createElement("div");
|
|
4625
4787
|
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;
|
|
4626
4788
|
}), this.imgCtx = this.buildImageCtxToolbar(t), this.positionImageHandles());
|
|
@@ -4630,38 +4792,38 @@ const I = class I {
|
|
|
4630
4792
|
e.className = "imgctx", e.dir = this.dir();
|
|
4631
4793
|
const i = () => {
|
|
4632
4794
|
var h;
|
|
4633
|
-
const
|
|
4634
|
-
(h = this.imgCtx) == null || h.replaceWith(
|
|
4635
|
-
}, s = (
|
|
4636
|
-
this.setImageAlign(t,
|
|
4637
|
-
}, l = t.style.float === "left",
|
|
4638
|
-
const g = this.ctxBtn(
|
|
4639
|
-
return g.classList.toggle("on",
|
|
4795
|
+
const a = this.buildImageCtxToolbar(t);
|
|
4796
|
+
(h = this.imgCtx) == null || h.replaceWith(a), this.imgCtx = a, this.positionImageHandles();
|
|
4797
|
+
}, s = (a) => {
|
|
4798
|
+
this.setImageAlign(t, a), i();
|
|
4799
|
+
}, l = t.style.float === "left", n = t.style.float === "right", o = !l && !n && t.style.marginLeft === "auto" && t.style.marginRight === "auto", r = (a, h, p, m) => {
|
|
4800
|
+
const g = this.ctxBtn(a, h, m);
|
|
4801
|
+
return g.classList.toggle("on", p), g;
|
|
4640
4802
|
};
|
|
4641
4803
|
return e.append(
|
|
4642
|
-
r(
|
|
4643
|
-
r(
|
|
4644
|
-
r(
|
|
4804
|
+
r(c.alignleft, this.t("alignleft"), l, () => s("left")),
|
|
4805
|
+
r(c.aligncenter, this.t("aligncenter"), o, () => s("center")),
|
|
4806
|
+
r(c.alignright, this.t("alignright"), n, () => s("right")),
|
|
4645
4807
|
this.ctxSep(),
|
|
4646
|
-
r(
|
|
4808
|
+
r(c.rotateleft, this.t("rotateleft"), !1, () => {
|
|
4647
4809
|
this.rotateImage(t, -90), i();
|
|
4648
4810
|
}),
|
|
4649
|
-
r(
|
|
4811
|
+
r(c.rotateright, this.t("rotateright"), !1, () => {
|
|
4650
4812
|
this.rotateImage(t, 90), i();
|
|
4651
4813
|
}),
|
|
4652
4814
|
this.ctxSep(),
|
|
4653
|
-
r(
|
|
4815
|
+
r(c.fliphorizontal, this.t("fliphorizontal"), t.dataset.flipx === "1", () => {
|
|
4654
4816
|
this.flipImage(t, "x"), i();
|
|
4655
4817
|
}),
|
|
4656
|
-
r(
|
|
4818
|
+
r(c.flipvertical, this.t("flipvertical"), t.dataset.flipy === "1", () => {
|
|
4657
4819
|
this.flipImage(t, "y"), i();
|
|
4658
4820
|
}),
|
|
4659
4821
|
this.ctxSep(),
|
|
4660
|
-
r(
|
|
4661
|
-
const
|
|
4662
|
-
|
|
4822
|
+
r(c.trash, this.t("deleteimg"), !1, () => {
|
|
4823
|
+
const a = t.closest(".tpl-media");
|
|
4824
|
+
a && this.ed.contains(a) ? t.outerHTML = this.imgPhHTML() : t.remove(), this.clearImageHandles(), this.onChange();
|
|
4663
4825
|
})
|
|
4664
|
-
), e.addEventListener("mousedown", (
|
|
4826
|
+
), e.addEventListener("mousedown", (a) => a.preventDefault()), e.addEventListener("mouseenter", () => this.cancelImgHide()), e.addEventListener("mouseleave", () => this.scheduleImgHide()), document.body.appendChild(e), e;
|
|
4665
4827
|
}
|
|
4666
4828
|
setImageAlign(t, e) {
|
|
4667
4829
|
t.style.float = "", t.style.display = "", t.style.marginLeft = "", t.style.marginRight = "", t.style.marginBottom = "", e === "left" ? (t.style.float = "left", t.style.marginInlineEnd = "1em", t.style.marginBottom = "0.5em") : e === "right" ? (t.style.float = "right", t.style.marginInlineStart = "1em", t.style.marginBottom = "0.5em") : (t.style.display = "block", t.style.marginLeft = "auto", t.style.marginRight = "auto"), this.onChange();
|
|
@@ -4683,21 +4845,21 @@ const I = class I {
|
|
|
4683
4845
|
this.clearImageHandles();
|
|
4684
4846
|
return;
|
|
4685
4847
|
}
|
|
4686
|
-
const t = this.imgActive.getBoundingClientRect(), e = t.top + scrollY, i = t.left + scrollX, s = t.right + scrollX, l = t.bottom + scrollY,
|
|
4848
|
+
const t = this.imgActive.getBoundingClientRect(), e = t.top + scrollY, i = t.left + scrollX, s = t.right + scrollX, l = t.bottom + scrollY, n = {
|
|
4687
4849
|
nw: [i, e],
|
|
4688
4850
|
ne: [s, e],
|
|
4689
4851
|
sw: [i, l],
|
|
4690
4852
|
se: [s, l]
|
|
4691
4853
|
};
|
|
4692
|
-
if (this.imgHandles.forEach((
|
|
4693
|
-
const [r,
|
|
4694
|
-
|
|
4854
|
+
if (this.imgHandles.forEach((o) => {
|
|
4855
|
+
const [r, a] = n[o.dataset.corner];
|
|
4856
|
+
o.style.left = r - 5 + "px", o.style.top = a - 5 + "px";
|
|
4695
4857
|
}), this.imgCtx) {
|
|
4696
|
-
const
|
|
4697
|
-
let
|
|
4698
|
-
|
|
4858
|
+
const o = this.imgCtx.offsetWidth, r = this.imgCtx.offsetHeight;
|
|
4859
|
+
let a = i + (s - i) / 2 - o / 2;
|
|
4860
|
+
a = Math.max(8 + scrollX, Math.min(a, scrollX + innerWidth - o - 8));
|
|
4699
4861
|
let h = e - r - 8;
|
|
4700
|
-
h < this.ctxMinTop() && (h = l + 8), this.imgCtx.style.left =
|
|
4862
|
+
h < this.ctxMinTop() && (h = l + 8), this.imgCtx.style.left = a + "px", this.imgCtx.style.top = h + "px";
|
|
4701
4863
|
}
|
|
4702
4864
|
}
|
|
4703
4865
|
startImageResizeDrag(t, e) {
|
|
@@ -4705,14 +4867,16 @@ const I = class I {
|
|
|
4705
4867
|
const i = this.imgActive;
|
|
4706
4868
|
if (!i) return;
|
|
4707
4869
|
this.cancelImgHide();
|
|
4708
|
-
const s = t.clientX, l = i.getBoundingClientRect().width,
|
|
4709
|
-
this.withNoTextSelect((
|
|
4870
|
+
const s = t.clientX, l = i.getBoundingClientRect().width, n = e === "nw" || e === "sw" ? -1 : 1;
|
|
4871
|
+
this.withNoTextSelect((o) => {
|
|
4710
4872
|
const r = (h) => {
|
|
4711
|
-
i.style.width = Math.max(24, Math.round(l +
|
|
4712
|
-
},
|
|
4713
|
-
window.removeEventListener("mousemove", r), window.removeEventListener("mouseup",
|
|
4873
|
+
i.style.width = Math.max(24, Math.round(l + n * (h.clientX - s))) + "px", i.style.height = "auto", this.positionImageHandles();
|
|
4874
|
+
}, a = () => {
|
|
4875
|
+
window.removeEventListener("mousemove", r), window.removeEventListener("mouseup", a), o();
|
|
4876
|
+
const h = parseInt(i.style.width, 10);
|
|
4877
|
+
h > 0 && !i.closest(".tpl-media") && (i.setAttribute("width", String(h)), i.removeAttribute("height")), this.onChange();
|
|
4714
4878
|
};
|
|
4715
|
-
window.addEventListener("mousemove", r), window.addEventListener("mouseup",
|
|
4879
|
+
window.addEventListener("mousemove", r), window.addEventListener("mouseup", a);
|
|
4716
4880
|
});
|
|
4717
4881
|
}
|
|
4718
4882
|
/* ---------------------------------------------------------- selection bubble toolbar */
|
|
@@ -4751,40 +4915,40 @@ const I = class I {
|
|
|
4751
4915
|
this.selCtx || (this.selCtx = this.buildSelToolbar()), this.positionSelToolbar(e);
|
|
4752
4916
|
}
|
|
4753
4917
|
buildSelToolbar() {
|
|
4754
|
-
var
|
|
4918
|
+
var o;
|
|
4755
4919
|
const t = document.createElement("div");
|
|
4756
4920
|
t.className = "selctx", t.dir = this.dir();
|
|
4757
4921
|
const e = this.ctxBtn(
|
|
4758
4922
|
'<b style="font:600 15px/1 Georgia,serif">A</b><span class="colorbar" data-cb="fore"></span>',
|
|
4759
4923
|
this.t("forecolor"),
|
|
4760
4924
|
() => this.colorMenu(e, "fore")
|
|
4761
|
-
), i = this.ctxBtn(
|
|
4762
|
-
(
|
|
4763
|
-
const s = this.ctxBtn(
|
|
4925
|
+
), i = this.ctxBtn(c.backcolor, this.t("backcolor"), () => this.colorMenu(i, "back"));
|
|
4926
|
+
(o = i.querySelector("svg")) == null || o.insertAdjacentHTML("afterend", '<span class="colorbar" data-cb="back"></span>');
|
|
4927
|
+
const s = this.ctxBtn(c.caseic, this.t("changecase"), () => this.caseMenu(s)), l = this.ctxBtn(c.lineheight, this.t("lineheight"), () => this.lineHeightMenu(l)), n = this.ctxBtn(c.wordspacing, this.t("wordspacing"), () => this.wordSpacingMenu(n));
|
|
4764
4928
|
return t.append(
|
|
4765
|
-
this.ctxBtn(
|
|
4766
|
-
this.ctxBtn(
|
|
4929
|
+
this.ctxBtn(c.bold, this.t("bold"), () => this.exec("bold"), "bold"),
|
|
4930
|
+
this.ctxBtn(c.italic, this.t("italic"), () => this.exec("italic"), "italic"),
|
|
4767
4931
|
e,
|
|
4768
4932
|
i,
|
|
4769
4933
|
this.ctxSep(),
|
|
4770
|
-
this.ctxBtn(
|
|
4771
|
-
this.ctxBtn(
|
|
4934
|
+
this.ctxBtn(c.quote, this.t("quote"), () => this.toggleBlock("blockquote"), "blockquote"),
|
|
4935
|
+
this.ctxBtn(c.inlinecodeic, this.t("code"), () => this.toggleInlineCode(), "code"),
|
|
4772
4936
|
this.ctxBtn('<b style="font:700 12px/1 Arial,sans-serif">H2</b>', this.blockLabel("h2"), () => this.toggleBlock("h2"), "h2"),
|
|
4773
4937
|
this.ctxBtn('<b style="font:700 12px/1 Arial,sans-serif">H3</b>', this.blockLabel("h3"), () => this.toggleBlock("h3"), "h3"),
|
|
4774
4938
|
this.ctxSep(),
|
|
4775
|
-
this.ctxBtn(
|
|
4939
|
+
this.ctxBtn(c.link, this.t("linkttl"), () => this.linkDlg()),
|
|
4776
4940
|
s,
|
|
4777
4941
|
l,
|
|
4778
|
-
|
|
4942
|
+
n
|
|
4779
4943
|
), t.addEventListener("mousedown", (r) => r.preventDefault()), document.body.appendChild(t), this.syncColorSwatches(t), t;
|
|
4780
4944
|
}
|
|
4781
4945
|
positionSelToolbar(t) {
|
|
4782
4946
|
if (!this.selCtx) return;
|
|
4783
|
-
const e = t.getBoundingClientRect(), i = e.top + scrollY, s = e.left + scrollX, l = e.right + scrollX,
|
|
4784
|
-
let
|
|
4785
|
-
|
|
4947
|
+
const e = t.getBoundingClientRect(), i = e.top + scrollY, s = e.left + scrollX, l = e.right + scrollX, n = e.bottom + scrollY, o = this.selCtx.offsetWidth, r = this.selCtx.offsetHeight;
|
|
4948
|
+
let a = s + (l - s) / 2 - o / 2;
|
|
4949
|
+
a = Math.max(8 + scrollX, Math.min(a, scrollX + innerWidth - o - 8));
|
|
4786
4950
|
let h = i - r - 8;
|
|
4787
|
-
h < this.ctxMinTop() && (h =
|
|
4951
|
+
h < this.ctxMinTop() && (h = n + 8), this.selCtx.style.left = a + "px", this.selCtx.style.top = h + "px";
|
|
4788
4952
|
}
|
|
4789
4953
|
repositionSelToolbar() {
|
|
4790
4954
|
if (!this.selCtx) return;
|
|
@@ -4817,9 +4981,9 @@ const I = class I {
|
|
|
4817
4981
|
return t > 0 ? t + "px" : "";
|
|
4818
4982
|
}
|
|
4819
4983
|
refreshState() {
|
|
4820
|
-
var r,
|
|
4984
|
+
var r, a, h;
|
|
4821
4985
|
const t = window.getSelection(), e = t ? this.ed.contains(t.anchorNode) : !1, i = this.currentBlock();
|
|
4822
|
-
[this.toolbar, this.selCtx].filter(Boolean).forEach((
|
|
4986
|
+
[this.toolbar, this.selCtx].filter(Boolean).forEach((p) => {
|
|
4823
4987
|
[
|
|
4824
4988
|
"bold",
|
|
4825
4989
|
"italic",
|
|
@@ -4832,22 +4996,22 @@ const I = class I {
|
|
|
4832
4996
|
"insertOrderedList",
|
|
4833
4997
|
"insertUnorderedList"
|
|
4834
4998
|
].forEach((g) => {
|
|
4835
|
-
const u =
|
|
4999
|
+
const u = p.querySelector(`[data-id=${g}]`);
|
|
4836
5000
|
u && u.classList.toggle("on", e && document.queryCommandState(g));
|
|
4837
5001
|
}), ["h2", "h3", "blockquote"].forEach((g) => {
|
|
4838
|
-
const u =
|
|
5002
|
+
const u = p.querySelector(`[data-id=${g}]`);
|
|
4839
5003
|
u && u.classList.toggle("on", e && i === g);
|
|
4840
5004
|
});
|
|
4841
|
-
const m =
|
|
5005
|
+
const m = p.querySelector("[data-id=code]");
|
|
4842
5006
|
m && m.classList.toggle("on", e && !!this.closestInlineCode());
|
|
4843
5007
|
});
|
|
4844
|
-
const l = t ? this.closestBlock(t.anchorNode) : null,
|
|
4845
|
-
(
|
|
4846
|
-
const
|
|
4847
|
-
const u = this.toolbar.querySelector(`[data-id=${
|
|
5008
|
+
const l = t ? this.closestBlock(t.anchorNode) : null, n = ((r = l == null ? void 0 : l.closest("[dir]")) == null ? void 0 : r.getAttribute("dir")) || this.ed.getAttribute("dir") || this.dir();
|
|
5009
|
+
(a = this.toolbar.querySelector("[data-id=ltr]")) == null || a.classList.toggle("on", e && n === "ltr"), (h = this.toolbar.querySelector("[data-id=rtl]")) == null || h.classList.toggle("on", e && n === "rtl");
|
|
5010
|
+
const o = (p, m, g) => {
|
|
5011
|
+
const u = this.toolbar.querySelector(`[data-id=${p}] .lbl`);
|
|
4848
5012
|
u && (u.textContent = m || g || "", u.classList.toggle("empty", !m));
|
|
4849
5013
|
};
|
|
4850
|
-
|
|
5014
|
+
o("fontsel", this.currentFont()), o("sizesel", this.currentSize().replace("px", "")), e && o("blocksel", X.some((p) => p[0] === i) ? this.blockLabel(i) : this.t("para")), this.sbWords.textContent = this.countWords() + " " + this.t("words");
|
|
4851
5015
|
}
|
|
4852
5016
|
countWords() {
|
|
4853
5017
|
const t = (this.ed.textContent || "").trim();
|
|
@@ -4862,18 +5026,75 @@ const I = class I {
|
|
|
4862
5026
|
if (s && !i) {
|
|
4863
5027
|
const l = new FileReader();
|
|
4864
5028
|
l.onload = () => {
|
|
4865
|
-
|
|
5029
|
+
this.insertImageHTML(l.result), this.onChange();
|
|
4866
5030
|
}, l.readAsDataURL(s.getAsFile());
|
|
4867
5031
|
return;
|
|
4868
5032
|
}
|
|
4869
5033
|
if (!i) {
|
|
4870
|
-
const l = e.getData("text/plain"),
|
|
4871
|
-
if (
|
|
4872
|
-
document.execCommand("insertHTML", !1, this.videoEmbedHTML(
|
|
5034
|
+
const l = e.getData("text/plain"), n = /^\S+$/.test(l.trim()) ? this.videoEmbedUrl(l.trim()) : null;
|
|
5035
|
+
if (n) {
|
|
5036
|
+
document.execCommand("insertHTML", !1, this.videoEmbedHTML(n)), this.onChange();
|
|
4873
5037
|
return;
|
|
4874
5038
|
}
|
|
4875
5039
|
}
|
|
4876
|
-
i ?
|
|
5040
|
+
i ? this.pasteRichHTML(i, e, s) : (document.execCommand("insertHTML", !1, kt(e.getData("text/plain"))), this.onChange());
|
|
5041
|
+
}
|
|
5042
|
+
/** Rich-HTML paste. Before the (untouched) paste engine runs, pictures Word left
|
|
5043
|
+
* behind as unreadable file:// refs are pulled out of the clipboard's RTF flavor
|
|
5044
|
+
* and inlined — the same pairing TinyMCE PowerPaste does for
|
|
5045
|
+
* powerpaste_allow_local_images. Everything the engine already handled is
|
|
5046
|
+
* unaffected: with no RTF, or no recoverable picture, the HTML reaches it
|
|
5047
|
+
* byte-identical to before. */
|
|
5048
|
+
pasteRichHTML(t, e, i) {
|
|
5049
|
+
let s = [];
|
|
5050
|
+
const l = e.getData("text/rtf");
|
|
5051
|
+
if (l) {
|
|
5052
|
+
const n = Pt(t, l);
|
|
5053
|
+
t = n.html, s = n.injected;
|
|
5054
|
+
}
|
|
5055
|
+
if (i && Rt(t) === 1) {
|
|
5056
|
+
const n = i.getAsFile();
|
|
5057
|
+
if (n) {
|
|
5058
|
+
const o = t;
|
|
5059
|
+
this.saveSel();
|
|
5060
|
+
const r = new FileReader();
|
|
5061
|
+
r.onload = () => {
|
|
5062
|
+
const a = nt(o, [r.result]);
|
|
5063
|
+
this.finishRichPaste(a.html, s.concat(a.injected), !0);
|
|
5064
|
+
}, r.onerror = () => this.finishRichPaste(o, s, !0), r.readAsDataURL(n);
|
|
5065
|
+
return;
|
|
5066
|
+
}
|
|
5067
|
+
}
|
|
5068
|
+
this.finishRichPaste(t, s);
|
|
5069
|
+
}
|
|
5070
|
+
/** Hands recovered pictures to the host's imageUploadHandler when one is
|
|
5071
|
+
* configured (PowerPaste's automatic_uploads equivalent), then inserts. Without a
|
|
5072
|
+
* handler they stay inline base64, which is what PowerPaste does by default. */
|
|
5073
|
+
finishRichPaste(t, e, i = !1) {
|
|
5074
|
+
if (!this.imageUploadHandler || !e.length) {
|
|
5075
|
+
this.insertPastedHTML(t, i);
|
|
5076
|
+
return;
|
|
5077
|
+
}
|
|
5078
|
+
const s = this.imageUploadHandler, l = e.filter((n, o) => e.indexOf(n) === o);
|
|
5079
|
+
i || this.saveSel(), Promise.all(
|
|
5080
|
+
l.map((n, o) => {
|
|
5081
|
+
const r = Dt(n, "pasted-image-" + (o + 1));
|
|
5082
|
+
return r ? s(r).catch((a) => {
|
|
5083
|
+
var h;
|
|
5084
|
+
return (h = this.onImageUploadError) == null || h.call(this, a, r), n;
|
|
5085
|
+
}) : Promise.resolve(n);
|
|
5086
|
+
})
|
|
5087
|
+
).then((n) => {
|
|
5088
|
+
let o = t;
|
|
5089
|
+
l.forEach((r, a) => {
|
|
5090
|
+
n[a] !== r && (o = o.split(r).join(n[a]));
|
|
5091
|
+
}), this.insertPastedHTML(o, !0);
|
|
5092
|
+
});
|
|
5093
|
+
}
|
|
5094
|
+
/** `deferred` means the insert is happening after an async hop, so the caret the
|
|
5095
|
+
* paste started from has to be put back first. */
|
|
5096
|
+
insertPastedHTML(t, e = !1) {
|
|
5097
|
+
e && this.restoreSel(), document.execCommand("insertHTML", !1, Ht(t, this.dir())), e && this.saveSel(), this.onChange();
|
|
4877
5098
|
}
|
|
4878
5099
|
/* ---------------------------------------------------------- init */
|
|
4879
5100
|
initUI() {
|
|
@@ -4881,18 +5102,18 @@ const I = class I {
|
|
|
4881
5102
|
}
|
|
4882
5103
|
};
|
|
4883
5104
|
I.instanceCounter = 0, I.TBR_COLLAPSE_MAX = 992;
|
|
4884
|
-
let
|
|
5105
|
+
let it = I;
|
|
4885
5106
|
export {
|
|
4886
|
-
|
|
4887
|
-
|
|
4888
|
-
|
|
4889
|
-
|
|
4890
|
-
|
|
4891
|
-
|
|
4892
|
-
|
|
4893
|
-
|
|
4894
|
-
|
|
4895
|
-
|
|
4896
|
-
|
|
4897
|
-
|
|
5107
|
+
X as BLOCKS,
|
|
5108
|
+
Jt as CHARS,
|
|
5109
|
+
gt as COLORS,
|
|
5110
|
+
ht as FONTS,
|
|
5111
|
+
it as FableEditor,
|
|
5112
|
+
rt as I18N,
|
|
5113
|
+
c as IC,
|
|
5114
|
+
dt as SIZES,
|
|
5115
|
+
te as TXT,
|
|
5116
|
+
Ht as cleanPastedHTML,
|
|
5117
|
+
D as getStrings,
|
|
5118
|
+
kt as normalizeTextPaste
|
|
4898
5119
|
};
|