frontend-auto-cms 1.0.8 → 1.0.10
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/runtime/dashboard.js +153 -140
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
const
|
|
1
|
+
const ye = "cms-export.patch.json", he = "frontend-auto-cms::content", te = "frontend-auto-cms::locales";
|
|
2
2
|
function ae(e) {
|
|
3
|
-
localStorage.setItem(
|
|
3
|
+
localStorage.setItem(he, JSON.stringify(e));
|
|
4
4
|
}
|
|
5
5
|
function ne() {
|
|
6
6
|
try {
|
|
@@ -10,10 +10,10 @@ function ne() {
|
|
|
10
10
|
return {};
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
|
-
function
|
|
13
|
+
function I(e) {
|
|
14
14
|
localStorage.setItem(te, JSON.stringify(e));
|
|
15
15
|
}
|
|
16
|
-
async function
|
|
16
|
+
async function xe() {
|
|
17
17
|
try {
|
|
18
18
|
const e = await fetch("/cms-content.json", { cache: "no-store" });
|
|
19
19
|
if (!e.ok)
|
|
@@ -24,7 +24,7 @@ async function he() {
|
|
|
24
24
|
return null;
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
|
-
async function
|
|
27
|
+
async function oe() {
|
|
28
28
|
try {
|
|
29
29
|
const e = await fetch("/cms-locales.json", { cache: "no-store" });
|
|
30
30
|
if (!e.ok)
|
|
@@ -37,7 +37,7 @@ async function xe() {
|
|
|
37
37
|
}
|
|
38
38
|
function ve(e) {
|
|
39
39
|
const t = new Blob([JSON.stringify(e, null, 2)], { type: "application/json" }), a = URL.createObjectURL(t), o = document.createElement("a");
|
|
40
|
-
o.href = a, o.download =
|
|
40
|
+
o.href = a, o.download = ye, o.click(), URL.revokeObjectURL(a);
|
|
41
41
|
}
|
|
42
42
|
function _(e) {
|
|
43
43
|
return e.replace(/[^\w]+/g, "_").replace(/^_+|_+$/g, "").toLowerCase();
|
|
@@ -49,7 +49,7 @@ function v(e) {
|
|
|
49
49
|
const a = (e.getAttribute("class") ?? "").split(/\s+/).filter(Boolean)[0];
|
|
50
50
|
return a ? `${e.tagName.toLowerCase()}.${a}` : e.tagName.toLowerCase();
|
|
51
51
|
}
|
|
52
|
-
function
|
|
52
|
+
function re(e) {
|
|
53
53
|
return ["SCRIPT", "STYLE", "NOSCRIPT", "IFRAME"].includes(e.tagName);
|
|
54
54
|
}
|
|
55
55
|
function N(e) {
|
|
@@ -57,7 +57,7 @@ function N(e) {
|
|
|
57
57
|
}
|
|
58
58
|
function ke(e, t, a) {
|
|
59
59
|
const o = t.parentElement;
|
|
60
|
-
if (!o ||
|
|
60
|
+
if (!o || re(o))
|
|
61
61
|
return null;
|
|
62
62
|
if (Array.from(o.childNodes).filter(
|
|
63
63
|
(s) => s.nodeType === Node.TEXT_NODE && N(s.nodeValue).length > 0
|
|
@@ -69,7 +69,7 @@ function ke(e, t, a) {
|
|
|
69
69
|
function $(e = document, t) {
|
|
70
70
|
const a = [];
|
|
71
71
|
let o = 0, n = 0, r = 0, s = 0;
|
|
72
|
-
const
|
|
72
|
+
const i = t ?? e.location?.pathname ?? location.pathname, c = e.body;
|
|
73
73
|
if (!c)
|
|
74
74
|
return {
|
|
75
75
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -84,74 +84,74 @@ function $(e = document, t) {
|
|
|
84
84
|
if (m.length < 2)
|
|
85
85
|
continue;
|
|
86
86
|
o += 1;
|
|
87
|
-
const K = `${_(
|
|
88
|
-
if (!
|
|
87
|
+
const K = `${_(i || "index")}.text.${o}`, O = ke(e, b, K);
|
|
88
|
+
if (!O)
|
|
89
89
|
continue;
|
|
90
90
|
a.push({
|
|
91
91
|
id: `dom_txt_${o}`,
|
|
92
92
|
key: K,
|
|
93
93
|
type: "text",
|
|
94
|
-
label: v(
|
|
94
|
+
label: v(O),
|
|
95
95
|
value: m,
|
|
96
|
-
selector: v(
|
|
97
|
-
sourceRefs: [{ file:
|
|
96
|
+
selector: v(O),
|
|
97
|
+
sourceRefs: [{ file: i, original: m }]
|
|
98
98
|
});
|
|
99
99
|
continue;
|
|
100
100
|
}
|
|
101
|
-
const
|
|
102
|
-
if (
|
|
101
|
+
const l = d;
|
|
102
|
+
if (re(l))
|
|
103
103
|
continue;
|
|
104
|
-
const p =
|
|
104
|
+
const p = l.tagName.toLowerCase();
|
|
105
105
|
if (p === "img" || p === "video") {
|
|
106
|
-
const b =
|
|
106
|
+
const b = l.getAttribute("src") ?? "";
|
|
107
107
|
if (b) {
|
|
108
108
|
n += 1;
|
|
109
|
-
const m = `${_(
|
|
110
|
-
|
|
109
|
+
const m = `${_(i || "index")}.${p}.${n}`;
|
|
110
|
+
l.setAttribute("data-cms-key", m), a.push({
|
|
111
111
|
id: `dom_media_${n}`,
|
|
112
112
|
key: m,
|
|
113
113
|
type: p === "img" ? "image" : "video",
|
|
114
|
-
label: v(
|
|
114
|
+
label: v(l),
|
|
115
115
|
value: b,
|
|
116
|
-
selector: v(
|
|
117
|
-
attrs: { src: b, alt:
|
|
118
|
-
sourceRefs: [{ file:
|
|
116
|
+
selector: v(l),
|
|
117
|
+
attrs: { src: b, alt: l.getAttribute("alt") ?? "" },
|
|
118
|
+
sourceRefs: [{ file: i, original: b }]
|
|
119
119
|
});
|
|
120
120
|
}
|
|
121
121
|
}
|
|
122
|
-
if (["section", "ul", "ol"].includes(p) ||
|
|
123
|
-
const b = Array.from(
|
|
122
|
+
if (["section", "ul", "ol"].includes(p) || l.hasAttribute("data-repeatable")) {
|
|
123
|
+
const b = Array.from(l.children).map((m) => N(m.textContent)).filter(Boolean);
|
|
124
124
|
if (b.length >= 2) {
|
|
125
125
|
r += 1;
|
|
126
|
-
const m = `${_(
|
|
127
|
-
|
|
126
|
+
const m = `${_(i || "index")}.section.${r}`;
|
|
127
|
+
l.setAttribute("data-cms-key", m), a.push({
|
|
128
128
|
id: `dom_sec_${r}`,
|
|
129
129
|
key: m,
|
|
130
130
|
type: "section",
|
|
131
|
-
label: v(
|
|
131
|
+
label: v(l),
|
|
132
132
|
value: b.join(" | "),
|
|
133
|
-
selector: v(
|
|
133
|
+
selector: v(l),
|
|
134
134
|
sectionItems: b,
|
|
135
|
-
sourceRefs: [{ file:
|
|
135
|
+
sourceRefs: [{ file: i, original: l.innerHTML }]
|
|
136
136
|
});
|
|
137
137
|
}
|
|
138
138
|
}
|
|
139
139
|
const g = {};
|
|
140
140
|
if (["alt", "href", "src", "aria-label", "title"].forEach((b) => {
|
|
141
|
-
const m =
|
|
141
|
+
const m = l.getAttribute(b);
|
|
142
142
|
m != null && m.trim() && (g[b] = m);
|
|
143
143
|
}), Object.keys(g).length > 0 && !(p === "img" || p === "video")) {
|
|
144
144
|
s += 1;
|
|
145
|
-
const b = `${_(
|
|
145
|
+
const b = `${_(i || "index")}.property.${s}`;
|
|
146
146
|
a.push({
|
|
147
147
|
id: `dom_prop_${s}`,
|
|
148
148
|
key: b,
|
|
149
149
|
type: "property",
|
|
150
|
-
label: v(
|
|
150
|
+
label: v(l),
|
|
151
151
|
value: JSON.stringify(g),
|
|
152
|
-
selector: v(
|
|
152
|
+
selector: v(l),
|
|
153
153
|
attrs: g,
|
|
154
|
-
sourceRefs: [{ file:
|
|
154
|
+
sourceRefs: [{ file: i, original: JSON.stringify(g) }]
|
|
155
155
|
});
|
|
156
156
|
}
|
|
157
157
|
}
|
|
@@ -272,27 +272,27 @@ async function Le(e, t, a) {
|
|
|
272
272
|
return typeof s == "string" && s.trim() ? s : e;
|
|
273
273
|
}
|
|
274
274
|
async function $e(e, t, a = "en", o) {
|
|
275
|
-
const n = F(a), r = F(t), s = /* @__PURE__ */ new Map(),
|
|
275
|
+
const n = F(a), r = F(t), s = /* @__PURE__ */ new Map(), i = {}, c = Object.entries(e), f = c.length;
|
|
276
276
|
let d = 0;
|
|
277
|
-
for (const [
|
|
277
|
+
for (const [l, p] of c) {
|
|
278
278
|
if (s.has(p)) {
|
|
279
|
-
l
|
|
279
|
+
i[l] = s.get(p), d += 1, o?.(d, f);
|
|
280
280
|
continue;
|
|
281
281
|
}
|
|
282
282
|
try {
|
|
283
283
|
const g = await Le(p, n, r);
|
|
284
|
-
s.set(p, g), l
|
|
284
|
+
s.set(p, g), i[l] = g;
|
|
285
285
|
} catch {
|
|
286
|
-
l
|
|
286
|
+
i[l] = p;
|
|
287
287
|
}
|
|
288
288
|
d += 1, o?.(d, f);
|
|
289
289
|
}
|
|
290
|
-
return
|
|
290
|
+
return i;
|
|
291
291
|
}
|
|
292
|
-
function
|
|
292
|
+
function se(e) {
|
|
293
293
|
return /^[^/\s]+\/[^/\s]+$/.test(e);
|
|
294
294
|
}
|
|
295
|
-
function
|
|
295
|
+
function ie(e) {
|
|
296
296
|
return /^([^/\s]+\/)+[^/\s]+$/.test(e);
|
|
297
297
|
}
|
|
298
298
|
async function Se(e, t, a) {
|
|
@@ -313,18 +313,18 @@ async function Ee() {
|
|
|
313
313
|
if (!t || !t.provider || t.provider === "none" || t.provider !== "github" && t.provider !== "gitlab" || typeof t.repository != "string" || !t.repository.trim())
|
|
314
314
|
return null;
|
|
315
315
|
const a = t.repository.trim();
|
|
316
|
-
return t.provider === "github" && !
|
|
316
|
+
return t.provider === "github" && !se(a) || t.provider === "gitlab" && !ie(a) || typeof t.branch != "string" || !t.branch.trim() ? null : { ...t, repository: a, branch: t.branch.trim() };
|
|
317
317
|
} catch {
|
|
318
318
|
return null;
|
|
319
319
|
}
|
|
320
320
|
}
|
|
321
|
-
async function
|
|
321
|
+
async function A(e, t, a, o, n) {
|
|
322
322
|
const r = `https://api.github.com/repos/${e.repository}/contents/${encodeURIComponent(a).replace(/%2F/g, "/")}`;
|
|
323
323
|
let s;
|
|
324
|
-
const
|
|
324
|
+
const i = await fetch(`${r}?ref=${encodeURIComponent(e.branch)}`, {
|
|
325
325
|
headers: { Authorization: `Bearer ${t}` }
|
|
326
326
|
});
|
|
327
|
-
|
|
327
|
+
i.ok && (s = (await i.json()).sha);
|
|
328
328
|
const c = {
|
|
329
329
|
message: n,
|
|
330
330
|
content: btoa(unescape(encodeURIComponent(o))),
|
|
@@ -343,24 +343,34 @@ async function O(e, t, a, o, n) {
|
|
|
343
343
|
}
|
|
344
344
|
async function _e(e, t, a) {
|
|
345
345
|
const o = `chore(cms): publish content updates ${(/* @__PURE__ */ new Date()).toISOString()}`;
|
|
346
|
-
if (await
|
|
346
|
+
if (await A(e, t, "cms-content.json", JSON.stringify(a.content, null, 2), o), a.locales) {
|
|
347
347
|
for (const [n, r] of Object.entries(a.locales))
|
|
348
|
-
await
|
|
349
|
-
|
|
348
|
+
await A(e, t, `locales/${n}.json`, JSON.stringify(r, null, 2), o);
|
|
349
|
+
await A(
|
|
350
|
+
e,
|
|
351
|
+
t,
|
|
352
|
+
"cms-locales.json",
|
|
353
|
+
JSON.stringify({ version: 1, locales: a.locales }, null, 2),
|
|
354
|
+
o
|
|
355
|
+
);
|
|
356
|
+
}
|
|
357
|
+
await A(e, t, "cms-export.patch.json", JSON.stringify(a, null, 2), o);
|
|
350
358
|
}
|
|
351
359
|
async function Ae(e, t, a) {
|
|
352
360
|
const o = [
|
|
353
361
|
{ filePath: "cms-content.json", content: JSON.stringify(a.content, null, 2) },
|
|
354
362
|
{ filePath: "cms-export.patch.json", content: JSON.stringify(a, null, 2) }
|
|
355
363
|
];
|
|
356
|
-
if (a.locales)
|
|
357
|
-
for (const [s,
|
|
358
|
-
o.push({ filePath: `locales/${s}.json`, content: JSON.stringify(
|
|
364
|
+
if (a.locales) {
|
|
365
|
+
for (const [s, i] of Object.entries(a.locales))
|
|
366
|
+
o.push({ filePath: `locales/${s}.json`, content: JSON.stringify(i, null, 2) });
|
|
367
|
+
o.push({ filePath: "cms-locales.json", content: JSON.stringify({ version: 1, locales: a.locales }, null, 2) });
|
|
368
|
+
}
|
|
359
369
|
const n = [];
|
|
360
370
|
for (const s of o) {
|
|
361
|
-
const
|
|
371
|
+
const i = await Se(e, t, s.filePath);
|
|
362
372
|
n.push({
|
|
363
|
-
action:
|
|
373
|
+
action: i ? "update" : "create",
|
|
364
374
|
file_path: s.filePath,
|
|
365
375
|
content: s.content
|
|
366
376
|
});
|
|
@@ -382,15 +392,15 @@ async function Ae(e, t, a) {
|
|
|
382
392
|
async function Te(e, t, a) {
|
|
383
393
|
if (!a || !t.trim())
|
|
384
394
|
return !1;
|
|
385
|
-
if (a.provider === "github" && !
|
|
395
|
+
if (a.provider === "github" && !se(a.repository))
|
|
386
396
|
throw new Error('Invalid GitHub repository format. Use "owner/repo".');
|
|
387
|
-
if (a.provider === "gitlab" && !
|
|
397
|
+
if (a.provider === "gitlab" && !ie(a.repository))
|
|
388
398
|
throw new Error('Invalid GitLab repository format. Use "group/project".');
|
|
389
399
|
return a.provider === "github" ? (await _e(a, t.trim(), e), !0) : a.provider === "gitlab" ? (await Ae(a, t.trim(), e), !0) : !1;
|
|
390
400
|
}
|
|
391
|
-
const Y = "facms-auth-modal", M = "facms-auth-missing", V = "facms-token-modal", W = "facms-language-modal", Ie = "frontend-auto-cms::theme",
|
|
401
|
+
const Y = "facms-auth-modal", M = "facms-auth-missing", V = "facms-token-modal", W = "facms-language-modal", Ie = "frontend-auto-cms::theme", le = "frontend-auto-cms::main-language", ce = "frontend-auto-cms::language-labels";
|
|
392
402
|
let D = !1, k = null, X = !1, x = null, u = "dark";
|
|
393
|
-
function
|
|
403
|
+
function de() {
|
|
394
404
|
if (document.getElementById("facms-dashboard-css"))
|
|
395
405
|
return;
|
|
396
406
|
const e = document.createElement("style");
|
|
@@ -629,15 +639,15 @@ function ce() {
|
|
|
629
639
|
}
|
|
630
640
|
`, document.head.appendChild(e);
|
|
631
641
|
}
|
|
632
|
-
function
|
|
642
|
+
function ue(e) {
|
|
633
643
|
u = e;
|
|
634
644
|
const t = e === "dark";
|
|
635
645
|
document.documentElement.classList.toggle("dark", t), document.body.classList.toggle("dark", t), document.documentElement.style.background = t ? "#020617" : "#f1f5f9", document.body.style.background = t ? "#020617" : "#f1f5f9", document.documentElement.setAttribute("data-facms-theme", e), document.getElementById("facms-app")?.classList.toggle("dark", t), localStorage.setItem(Ie, e);
|
|
636
646
|
const o = document.getElementById("facms-theme-toggle");
|
|
637
647
|
o && (o.textContent = e === "dark" ? "Switch to light" : "Switch to dark");
|
|
638
648
|
}
|
|
639
|
-
function
|
|
640
|
-
u = "dark",
|
|
649
|
+
function fe() {
|
|
650
|
+
u = "dark", ue("dark");
|
|
641
651
|
}
|
|
642
652
|
function Ce(e) {
|
|
643
653
|
return Array.from(new Uint8Array(e)).map((t) => t.toString(16).padStart(2, "0")).join("");
|
|
@@ -646,7 +656,7 @@ async function je(e) {
|
|
|
646
656
|
const t = new TextEncoder().encode(e), a = await crypto.subtle.digest("SHA-256", t);
|
|
647
657
|
return Ce(a);
|
|
648
658
|
}
|
|
649
|
-
async function
|
|
659
|
+
async function pe() {
|
|
650
660
|
if (x)
|
|
651
661
|
return x;
|
|
652
662
|
try {
|
|
@@ -694,10 +704,10 @@ function ze() {
|
|
|
694
704
|
function Ne() {
|
|
695
705
|
document.getElementById(M)?.remove();
|
|
696
706
|
}
|
|
697
|
-
async function
|
|
707
|
+
async function ge() {
|
|
698
708
|
return await G(), k ? (Ne(), !0) : (ze(), !1);
|
|
699
709
|
}
|
|
700
|
-
function
|
|
710
|
+
function be(e) {
|
|
701
711
|
const t = document.getElementById(Y);
|
|
702
712
|
if (t) {
|
|
703
713
|
t.style.display = "grid";
|
|
@@ -727,7 +737,7 @@ function ge(e) {
|
|
|
727
737
|
}
|
|
728
738
|
n && (n.style.display = "none"), D = !0, r(), e();
|
|
729
739
|
};
|
|
730
|
-
a.querySelector("#facms-passcode-cancel")?.addEventListener("click", r), a.querySelector("#facms-passcode-submit")?.addEventListener("click", s), o?.addEventListener("keydown", (
|
|
740
|
+
a.querySelector("#facms-passcode-cancel")?.addEventListener("click", r), a.querySelector("#facms-passcode-submit")?.addEventListener("click", s), o?.addEventListener("keydown", (i) => i.key === "Enter" && void s()), document.body.appendChild(a), o?.focus();
|
|
731
741
|
}
|
|
732
742
|
function Me(e, t) {
|
|
733
743
|
const a = document.getElementById(V);
|
|
@@ -745,7 +755,7 @@ function Me(e, t) {
|
|
|
745
755
|
</div>
|
|
746
756
|
</div>
|
|
747
757
|
`;
|
|
748
|
-
const n = o.querySelector("#facms-token-input"), r = o.querySelector("#facms-token-error"), s = () => o.style.display = "none",
|
|
758
|
+
const n = o.querySelector("#facms-token-input"), r = o.querySelector("#facms-token-error"), s = () => o.style.display = "none", i = () => {
|
|
749
759
|
const c = (n?.value ?? "").trim();
|
|
750
760
|
if (!c) {
|
|
751
761
|
r && (r.style.display = "block");
|
|
@@ -753,7 +763,7 @@ function Me(e, t) {
|
|
|
753
763
|
}
|
|
754
764
|
r && (r.style.display = "none"), s(), t(c);
|
|
755
765
|
};
|
|
756
|
-
o.querySelector("#facms-token-cancel")?.addEventListener("click", s), o.querySelector("#facms-token-submit")?.addEventListener("click",
|
|
766
|
+
o.querySelector("#facms-token-cancel")?.addEventListener("click", s), o.querySelector("#facms-token-submit")?.addEventListener("click", i), n?.addEventListener("keydown", (c) => c.key === "Enter" && i()), document.body.appendChild(o), n?.focus();
|
|
757
767
|
}
|
|
758
768
|
function Pe(e, t, a) {
|
|
759
769
|
const o = document.getElementById(W);
|
|
@@ -780,25 +790,25 @@ function Pe(e, t, a) {
|
|
|
780
790
|
`;
|
|
781
791
|
const r = () => n.style.display = "none";
|
|
782
792
|
n.querySelector("#facms-language-cancel")?.addEventListener("click", r);
|
|
783
|
-
const s = n.querySelector("#facms-language-select"),
|
|
793
|
+
const s = n.querySelector("#facms-language-select"), i = n.querySelector("#facms-language-input"), c = n.querySelector("#facms-language-name");
|
|
784
794
|
s?.addEventListener("change", () => {
|
|
785
795
|
const d = s.value === "__custom__";
|
|
786
|
-
|
|
796
|
+
i && (i.style.display = d ? "block" : "none"), c && (c.style.display = d ? "block" : "none");
|
|
787
797
|
});
|
|
788
798
|
const f = (d) => {
|
|
789
|
-
const
|
|
799
|
+
const l = n.querySelector("#facms-language-error");
|
|
790
800
|
let p = "";
|
|
791
801
|
const g = s?.value ?? "";
|
|
792
802
|
let h = "";
|
|
793
|
-
if (g && g !== "__custom__" ? (p =
|
|
794
|
-
|
|
803
|
+
if (g && g !== "__custom__" ? (p = C(g), h = S(p)) : (p = C(i?.value ?? ""), h = (c?.value ?? "").trim()), !p || !/^[a-z]{2,3}([_-][a-z0-9]{2,8})?$|^[a-z]{3}_[A-Za-z]+$/i.test(p)) {
|
|
804
|
+
l && (l.textContent = "Enter a valid language code.", l.style.display = "block");
|
|
795
805
|
return;
|
|
796
806
|
}
|
|
797
807
|
if (h || (h = S(p)), e.includes(p)) {
|
|
798
|
-
|
|
808
|
+
l && (l.textContent = `Language "${p}" already exists.`, l.style.display = "block");
|
|
799
809
|
return;
|
|
800
810
|
}
|
|
801
|
-
|
|
811
|
+
l && (l.style.display = "none"), r(), a(`${p}::${h}`, d);
|
|
802
812
|
};
|
|
803
813
|
n.querySelector("#facms-language-manual")?.addEventListener("click", () => f("manual")), t && n.querySelector("#facms-language-autofill")?.addEventListener("click", () => f("auto")), document.body.appendChild(n);
|
|
804
814
|
}
|
|
@@ -809,7 +819,7 @@ function z(e, t) {
|
|
|
809
819
|
}
|
|
810
820
|
console.info(`[frontend-auto-cms:dashboard] ${e}`, t);
|
|
811
821
|
}
|
|
812
|
-
function
|
|
822
|
+
function C(e) {
|
|
813
823
|
return e.trim().toLowerCase();
|
|
814
824
|
}
|
|
815
825
|
function Re(e) {
|
|
@@ -817,12 +827,12 @@ function Re(e) {
|
|
|
817
827
|
return t === "/" ? "/" : (t.startsWith("/") ? t : `/${t}`).toLowerCase();
|
|
818
828
|
}
|
|
819
829
|
function S(e) {
|
|
820
|
-
const t =
|
|
830
|
+
const t = C(e), a = B.find((o) => o.code === t);
|
|
821
831
|
return a ? a.label : t.toUpperCase();
|
|
822
832
|
}
|
|
823
833
|
function Be() {
|
|
824
834
|
try {
|
|
825
|
-
const e = localStorage.getItem(
|
|
835
|
+
const e = localStorage.getItem(ce);
|
|
826
836
|
if (!e)
|
|
827
837
|
return {};
|
|
828
838
|
const t = JSON.parse(e);
|
|
@@ -832,24 +842,24 @@ function Be() {
|
|
|
832
842
|
}
|
|
833
843
|
}
|
|
834
844
|
function H(e) {
|
|
835
|
-
localStorage.setItem(
|
|
845
|
+
localStorage.setItem(ce, JSON.stringify(e));
|
|
836
846
|
}
|
|
837
|
-
function
|
|
838
|
-
const t = localStorage.getItem(
|
|
847
|
+
function j(e) {
|
|
848
|
+
const t = localStorage.getItem(le);
|
|
839
849
|
return t && e[t] ? t : e.en ? "en" : Object.keys(e)[0] ?? "en";
|
|
840
850
|
}
|
|
841
851
|
function Z(e) {
|
|
842
|
-
localStorage.setItem(
|
|
852
|
+
localStorage.setItem(le, e);
|
|
843
853
|
}
|
|
844
854
|
function y(e) {
|
|
845
855
|
return e.replace(/[&<>'"]/g, (t) => ({ "&": "&", "<": "<", ">": ">", "'": "'", '"': """ })[t]);
|
|
846
856
|
}
|
|
847
|
-
function
|
|
857
|
+
function T(e, t = 72) {
|
|
848
858
|
const a = e.replace(/\s+/g, " ").trim();
|
|
849
859
|
return a.length <= t ? a : `${a.slice(0, t)}...`;
|
|
850
860
|
}
|
|
851
861
|
function De(e) {
|
|
852
|
-
return e.type === "section" ?
|
|
862
|
+
return e.type === "section" ? T((e.sectionItems ?? []).join(" | ")) : e.type === "property" ? T(JSON.stringify(e.attrs ?? {})) : T(e.value);
|
|
853
863
|
}
|
|
854
864
|
function Ge(e) {
|
|
855
865
|
const t = [];
|
|
@@ -884,11 +894,11 @@ async function Ue(e) {
|
|
|
884
894
|
}
|
|
885
895
|
async function qe(e, t, a) {
|
|
886
896
|
const o = e.nodes.flatMap(
|
|
887
|
-
(s) => s.sourceRefs.map((
|
|
888
|
-
file:
|
|
889
|
-
find:
|
|
897
|
+
(s) => s.sourceRefs.map((i) => ({
|
|
898
|
+
file: i.file,
|
|
899
|
+
find: i.original,
|
|
890
900
|
replace: s.type === "property" ? JSON.stringify(s.attrs ?? {}) : s.type === "section" ? (s.sectionItems ?? []).join(" ") : s.type === "text" ? a[s.key] ?? s.value : s.value,
|
|
891
|
-
occurrence:
|
|
901
|
+
occurrence: i.occurrence ?? 1
|
|
892
902
|
}))
|
|
893
903
|
), n = {
|
|
894
904
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -933,9 +943,9 @@ function Fe(e, t) {
|
|
|
933
943
|
return;
|
|
934
944
|
const o = Object.keys(t.locales);
|
|
935
945
|
a.innerHTML = o.map((n) => {
|
|
936
|
-
const r = n === t.activeLanguage, s = n === t.mainLanguage,
|
|
946
|
+
const r = n === t.activeLanguage, s = n === t.mainLanguage, i = t.languageLabels[n] ?? S(n);
|
|
937
947
|
return `<div class="inline-flex items-center rounded-lg overflow-hidden border ${r ? "border-indigo-500" : "border-slate-200 dark:border-slate-700"}">
|
|
938
|
-
<button data-lang="${n}" class="px-2.5 py-1.5 text-xs ${r ? "bg-indigo-600 text-white" : "bg-slate-100 dark:bg-slate-800 text-slate-700 dark:text-slate-200"}">${y(
|
|
948
|
+
<button data-lang="${n}" class="px-2.5 py-1.5 text-xs ${r ? "bg-indigo-600 text-white" : "bg-slate-100 dark:bg-slate-800 text-slate-700 dark:text-slate-200"}">${y(i)}</button>
|
|
939
949
|
${s ? `<span class="px-2 py-1.5 text-[10px] font-semibold ${r ? "bg-indigo-700 text-indigo-100" : "bg-emerald-600 text-white"}">MAIN</span>` : `<button data-main-lang="${n}" title="Set as main language" class="px-2 py-1.5 text-xs ${r ? "bg-indigo-700 text-indigo-100 hover:bg-indigo-800" : "bg-emerald-600 text-white hover:bg-emerald-500"}">★</button>`}
|
|
940
950
|
<button data-remove-lang="${n}" title="Remove language" class="px-2 py-1.5 text-xs ${r ? "bg-indigo-700 text-indigo-100 hover:bg-indigo-800" : "bg-slate-200 dark:bg-slate-700 text-slate-700 dark:text-slate-200 hover:bg-slate-300 dark:hover:bg-slate-600"}">×</button>
|
|
941
951
|
</div>`;
|
|
@@ -959,7 +969,7 @@ function Fe(e, t) {
|
|
|
959
969
|
alert("You must keep at least one language.");
|
|
960
970
|
return;
|
|
961
971
|
}
|
|
962
|
-
delete t.locales[s], delete t.languageLabels[s], H(t.languageLabels),
|
|
972
|
+
delete t.locales[s], delete t.languageLabels[s], H(t.languageLabels), I(t.locales), t.mainLanguage === s && (t.mainLanguage = j(t.locales), Z(t.mainLanguage), t.baseTextByKey = { ...t.locales[t.mainLanguage] ?? {} }), t.activeLanguage === s && (t.activeLanguage = U(t.locales, t.mainLanguage)), me(t), L(e, t);
|
|
963
973
|
}
|
|
964
974
|
});
|
|
965
975
|
});
|
|
@@ -974,7 +984,7 @@ function Ye(e, t) {
|
|
|
974
984
|
r.value = a.value, r.type === "text" && (t.activeLanguage === t.mainLanguage ? (t.baseTextByKey[r.key] = a.value, t.locales[t.mainLanguage] = { ...t.locales[t.mainLanguage] ?? {}, [r.key]: a.value }) : t.locales[t.activeLanguage] = {
|
|
975
985
|
...t.locales[t.activeLanguage] ?? {},
|
|
976
986
|
[r.key]: a.value
|
|
977
|
-
},
|
|
987
|
+
}, I(t.locales));
|
|
978
988
|
else if (n === "alt") r.attrs = { ...r.attrs ?? {}, alt: a.value };
|
|
979
989
|
else if (n === "sectionItems") r.sectionItems = a.value.split(`
|
|
980
990
|
`).map((s) => s.trim()).filter(Boolean);
|
|
@@ -999,13 +1009,13 @@ function P(e, t) {
|
|
|
999
1009
|
}
|
|
1000
1010
|
function L(e, t) {
|
|
1001
1011
|
const a = Ge(t.content.nodes), o = a.length ? a.map((n) => {
|
|
1002
|
-
const r = n.items[0], s = n.items[n.items.length - 1],
|
|
1012
|
+
const r = n.items[0], s = n.items[n.items.length - 1], i = r.index === s.index ? `#${r.index + 1}` : `#${r.index + 1} - #${s.index + 1}`, c = n.items.map((l) => De(l.node)).filter(Boolean).join(" • "), f = n.items.length > 1 ? `${i} ${y(n.selector || "Grouped fields")} (${n.items.length} fields)` : `${i} ${y(r.node.type.toUpperCase())} • ${y(r.node.label || r.node.selector || "")}`, d = n.items.map((l) => Ke(l.node, l.index)).join("");
|
|
1003
1013
|
return `
|
|
1004
1014
|
<details class="rounded-xl p-2 border border-slate-200 dark:border-transparent bg-white dark:bg-slate-900/60 shadow-sm">
|
|
1005
1015
|
<summary class="list-none cursor-pointer flex items-center justify-between gap-2 p-3 rounded-lg bg-slate-50 dark:bg-slate-800/70 border border-slate-200 dark:border-slate-800">
|
|
1006
1016
|
<div class="min-w-0">
|
|
1007
1017
|
<div class="text-xs text-slate-500 dark:text-slate-400">${f}</div>
|
|
1008
|
-
<div class="text-sm text-slate-700 dark:text-slate-300 truncate">${y(
|
|
1018
|
+
<div class="text-sm text-slate-700 dark:text-slate-300 truncate">${y(T(c || "No preview"))}</div>
|
|
1009
1019
|
</div>
|
|
1010
1020
|
<span class="text-xs text-indigo-600 dark:text-indigo-400">Expand</span>
|
|
1011
1021
|
</summary>
|
|
@@ -1038,13 +1048,13 @@ function L(e, t) {
|
|
|
1038
1048
|
return;
|
|
1039
1049
|
}
|
|
1040
1050
|
const s = r.provider;
|
|
1041
|
-
Me(s, async (
|
|
1051
|
+
Me(s, async (i) => {
|
|
1042
1052
|
let c = !1, f = "Publishing failed. Please verify token permissions and repository settings.";
|
|
1043
1053
|
try {
|
|
1044
|
-
c = await Te(n,
|
|
1054
|
+
c = await Te(n, i, r);
|
|
1045
1055
|
} catch (d) {
|
|
1046
|
-
const
|
|
1047
|
-
|
|
1056
|
+
const l = d instanceof Error ? d.message : String(d);
|
|
1057
|
+
l && (f = `Publishing failed: ${l}`), c = !1;
|
|
1048
1058
|
}
|
|
1049
1059
|
if (!c) {
|
|
1050
1060
|
alert(f);
|
|
@@ -1054,27 +1064,27 @@ function L(e, t) {
|
|
|
1054
1064
|
});
|
|
1055
1065
|
}), e.querySelector("#facms-add-language")?.addEventListener("click", () => {
|
|
1056
1066
|
Pe(Object.keys(t.locales), x?.autoTranslateEnabled ?? !0, async (n, r) => {
|
|
1057
|
-
const [s,
|
|
1067
|
+
const [s, i] = n.split("::"), c = C(s ?? ""), f = (i ?? "").trim() || S(c);
|
|
1058
1068
|
if (!c)
|
|
1059
1069
|
return;
|
|
1060
|
-
const d = performance.now(),
|
|
1070
|
+
const d = performance.now(), l = t.locales[t.mainLanguage] ?? t.baseTextByKey, p = { ...l };
|
|
1061
1071
|
if (z("Add language requested", {
|
|
1062
1072
|
lang: c,
|
|
1063
1073
|
mode: r,
|
|
1064
|
-
sourceKeys: Object.keys(
|
|
1074
|
+
sourceKeys: Object.keys(l).length,
|
|
1065
1075
|
browserLanguage: navigator.language,
|
|
1066
1076
|
browserLanguages: navigator.languages
|
|
1067
|
-
}), t.locales[c] = p, t.languageLabels[c] = f, H(t.languageLabels), t.activeLanguage = c,
|
|
1077
|
+
}), t.locales[c] = p, t.languageLabels[c] = f, H(t.languageLabels), t.activeLanguage = c, I(t.locales), E(t.content, t.locales[c], t.workingDocument, t.baseTextByKey), L(e, t), z("Manual language tab created", { lang: c }), w(e, `Added ${f} tab prefilled with source text for manual translation.`, !1), r !== "auto" || !(x?.autoTranslateEnabled ?? !0)) {
|
|
1068
1078
|
r === "auto" && !(x?.autoTranslateEnabled ?? !0) && w(e, `Privacy mode is on. Added ${f} tab for manual translation only.`, !1);
|
|
1069
1079
|
return;
|
|
1070
1080
|
}
|
|
1071
1081
|
try {
|
|
1072
|
-
const g = Object.keys(
|
|
1082
|
+
const g = Object.keys(l).length;
|
|
1073
1083
|
w(e, `Auto-filling ${f} translation... (0/${g})`, !0);
|
|
1074
|
-
const h = await $e(
|
|
1084
|
+
const h = await $e(l, c, t.mainLanguage, (q, b) => {
|
|
1075
1085
|
w(e, `Auto-filling ${f} translation... (${q}/${b})`, !0);
|
|
1076
1086
|
});
|
|
1077
|
-
t.locales[c] = h,
|
|
1087
|
+
t.locales[c] = h, I(t.locales), t.activeLanguage = c, E(t.content, h, t.workingDocument, t.baseTextByKey), L(e, t), z("Automatic translation succeeded", {
|
|
1078
1088
|
lang: c,
|
|
1079
1089
|
translatedKeys: Object.keys(h).length,
|
|
1080
1090
|
ms: Math.round(performance.now() - d)
|
|
@@ -1091,13 +1101,13 @@ function L(e, t) {
|
|
|
1091
1101
|
}), Ye(e, t);
|
|
1092
1102
|
}
|
|
1093
1103
|
function U(e, t) {
|
|
1094
|
-
const a = Object.keys(e), o = t && e[t] ? t :
|
|
1104
|
+
const a = Object.keys(e), o = t && e[t] ? t : j(e), n = [...navigator.languages ?? [], navigator.language].map((r) => r.toLowerCase().split("-")[0]);
|
|
1095
1105
|
for (const r of n)
|
|
1096
1106
|
if (a.includes(r))
|
|
1097
1107
|
return r;
|
|
1098
1108
|
return a.includes(o) ? o : a[0] ?? "en";
|
|
1099
1109
|
}
|
|
1100
|
-
function
|
|
1110
|
+
function me(e) {
|
|
1101
1111
|
const t = e.locales[e.activeLanguage] ?? e.locales.en ?? e.baseTextByKey;
|
|
1102
1112
|
E(e.content, t, e.workingDocument, e.baseTextByKey);
|
|
1103
1113
|
}
|
|
@@ -1118,26 +1128,26 @@ function We(e, t, a) {
|
|
|
1118
1128
|
const o = ne(), n = {
|
|
1119
1129
|
...a,
|
|
1120
1130
|
...o
|
|
1121
|
-
}, r = Be(), s = Object.fromEntries(e.nodes.filter((
|
|
1131
|
+
}, r = Be(), s = Object.fromEntries(e.nodes.filter((l) => l.type === "text").map((l) => [l.key, l.value])), i = j(n), c = {
|
|
1122
1132
|
...n,
|
|
1123
|
-
[
|
|
1133
|
+
[i]: { ...n[i] ?? {}, ...s }
|
|
1124
1134
|
};
|
|
1125
|
-
!c.en &&
|
|
1126
|
-
const f = U(c,
|
|
1127
|
-
return Object.keys(c).forEach((
|
|
1128
|
-
d[
|
|
1135
|
+
!c.en && i === "en" && (c.en = Object.assign({}, c.en ?? {}, s));
|
|
1136
|
+
const f = U(c, i), d = { ...r };
|
|
1137
|
+
return Object.keys(c).forEach((l) => {
|
|
1138
|
+
d[l] || (d[l] = S(l));
|
|
1129
1139
|
}), H(d), {
|
|
1130
1140
|
content: e,
|
|
1131
1141
|
locales: c,
|
|
1132
1142
|
workingDocument: t,
|
|
1133
|
-
baseTextByKey: c[
|
|
1143
|
+
baseTextByKey: c[i] ?? s,
|
|
1134
1144
|
activeLanguage: f,
|
|
1135
|
-
mainLanguage:
|
|
1145
|
+
mainLanguage: i,
|
|
1136
1146
|
languageLabels: d
|
|
1137
1147
|
};
|
|
1138
1148
|
}
|
|
1139
1149
|
async function Xe() {
|
|
1140
|
-
const e = await
|
|
1150
|
+
const e = await xe();
|
|
1141
1151
|
if (!e?.nodes?.length)
|
|
1142
1152
|
return;
|
|
1143
1153
|
const t = $(document, location.pathname);
|
|
@@ -1151,17 +1161,20 @@ async function Xe() {
|
|
|
1151
1161
|
}
|
|
1152
1162
|
async function Ze() {
|
|
1153
1163
|
await Xe();
|
|
1154
|
-
const
|
|
1155
|
-
|
|
1164
|
+
const t = {
|
|
1165
|
+
...await oe(),
|
|
1166
|
+
...ne()
|
|
1167
|
+
};
|
|
1168
|
+
if (!Object.keys(t).length)
|
|
1156
1169
|
return;
|
|
1157
|
-
const t = U(
|
|
1158
|
-
if (!
|
|
1170
|
+
const a = j(t), o = U(t, a);
|
|
1171
|
+
if (!o || o === a)
|
|
1159
1172
|
return;
|
|
1160
|
-
const
|
|
1161
|
-
if (!
|
|
1173
|
+
const n = $(document, location.pathname), r = t[o];
|
|
1174
|
+
if (!r)
|
|
1162
1175
|
return;
|
|
1163
|
-
const
|
|
1164
|
-
E(
|
|
1176
|
+
const s = Object.fromEntries(n.nodes.filter((i) => i.type === "text").map((i) => [i.key, i.value]));
|
|
1177
|
+
E(n, r, document, s);
|
|
1165
1178
|
}
|
|
1166
1179
|
function Qe(e) {
|
|
1167
1180
|
const t = e.pages.length ? e.pages : ["/"];
|
|
@@ -1194,7 +1207,7 @@ function Qe(e) {
|
|
|
1194
1207
|
</div>
|
|
1195
1208
|
`;
|
|
1196
1209
|
const a = document.getElementById("facms-route-preview"), o = document.getElementById("facms-route-editor"), n = document.getElementById("facms-page-tabs"), r = /* @__PURE__ */ new Map();
|
|
1197
|
-
let s = t[0],
|
|
1210
|
+
let s = t[0], i = {};
|
|
1198
1211
|
const c = () => {
|
|
1199
1212
|
n.innerHTML = t.map(
|
|
1200
1213
|
(f) => `<button data-page="${f}" class="w-full text-left px-3 py-2 rounded-lg text-sm border ${f === s ? "bg-indigo-600 border-indigo-500 text-white" : "bg-slate-100 border-slate-200 dark:bg-slate-800 dark:border-slate-700 text-slate-700 dark:text-slate-200 hover:bg-slate-200 dark:hover:bg-slate-700"}">${y(f)}</button>`
|
|
@@ -1204,7 +1217,7 @@ function Qe(e) {
|
|
|
1204
1217
|
});
|
|
1205
1218
|
});
|
|
1206
1219
|
};
|
|
1207
|
-
|
|
1220
|
+
ue(u), a.addEventListener("load", async () => {
|
|
1208
1221
|
const f = a.contentDocument;
|
|
1209
1222
|
if (f) {
|
|
1210
1223
|
P(!0, `Scanning page content for ${s}...`);
|
|
@@ -1212,40 +1225,40 @@ function Qe(e) {
|
|
|
1212
1225
|
let d = r.get(s);
|
|
1213
1226
|
if (d) {
|
|
1214
1227
|
d.workingDocument = f;
|
|
1215
|
-
const
|
|
1216
|
-
|
|
1228
|
+
const l = d.content.nodes.length ? $(f, s) : await Q(f, s);
|
|
1229
|
+
l.nodes.length && !d.content.nodes.length && (d.content = l);
|
|
1217
1230
|
} else {
|
|
1218
|
-
const
|
|
1219
|
-
d = We(
|
|
1231
|
+
const l = await Q(f, s);
|
|
1232
|
+
d = We(l, f, i), r.set(s, d);
|
|
1220
1233
|
}
|
|
1221
|
-
|
|
1234
|
+
me(d), ae(d.content), L(o, d);
|
|
1222
1235
|
} finally {
|
|
1223
1236
|
P(!1, "Loading");
|
|
1224
1237
|
}
|
|
1225
1238
|
}
|
|
1226
|
-
}), c(),
|
|
1227
|
-
|
|
1239
|
+
}), c(), oe().then((f) => {
|
|
1240
|
+
i = f, a.src = s;
|
|
1228
1241
|
});
|
|
1229
1242
|
}
|
|
1230
1243
|
async function ee() {
|
|
1231
|
-
if (
|
|
1244
|
+
if (de(), fe(), !await ge())
|
|
1232
1245
|
return;
|
|
1233
|
-
const e = await
|
|
1246
|
+
const e = await pe(), t = () => Qe(e);
|
|
1234
1247
|
if (!D) {
|
|
1235
|
-
|
|
1248
|
+
be(t);
|
|
1236
1249
|
return;
|
|
1237
1250
|
}
|
|
1238
1251
|
t();
|
|
1239
1252
|
}
|
|
1240
1253
|
async function et() {
|
|
1241
|
-
const e = await
|
|
1254
|
+
const e = await pe(), a = new URLSearchParams(location.search).get("__facms") === "1";
|
|
1242
1255
|
if (location.pathname !== e.dashboardPath && !a) {
|
|
1243
1256
|
Ze();
|
|
1244
1257
|
return;
|
|
1245
1258
|
}
|
|
1246
|
-
if (
|
|
1259
|
+
if (de(), fe(), !!await ge()) {
|
|
1247
1260
|
if (!D) {
|
|
1248
|
-
|
|
1261
|
+
be(() => {
|
|
1249
1262
|
ee();
|
|
1250
1263
|
});
|
|
1251
1264
|
return;
|