@cancia/toolbar 0.12.0 → 0.12.1
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/cancia.iife.js +98 -98
- package/dist/cancia.js +23 -47
- package/dist/cancia.js.map +1 -1
- package/package.json +3 -3
package/dist/cancia.js
CHANGED
|
@@ -145,6 +145,7 @@ function inlineToShorthand(el) {
|
|
|
145
145
|
}
|
|
146
146
|
|
|
147
147
|
// src/state.ts
|
|
148
|
+
import { parseLinkValue } from "@cancia/astro/schema";
|
|
148
149
|
var state = {
|
|
149
150
|
config: null,
|
|
150
151
|
cmsData: {},
|
|
@@ -174,20 +175,6 @@ function setPending(key, lang, value) {
|
|
|
174
175
|
const full = pendingKey(key, lang);
|
|
175
176
|
state.pending.set(full, { key, lang, value });
|
|
176
177
|
}
|
|
177
|
-
function parseLinkOverlay(raw) {
|
|
178
|
-
if (!raw) return { label: "", href: "" };
|
|
179
|
-
const trimmed = raw.trim();
|
|
180
|
-
if (trimmed.startsWith("{")) {
|
|
181
|
-
try {
|
|
182
|
-
const p = JSON.parse(trimmed);
|
|
183
|
-
if (p && typeof p === "object") {
|
|
184
|
-
return { label: String(p.label ?? ""), href: String(p.href ?? "") };
|
|
185
|
-
}
|
|
186
|
-
} catch {
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
return { label: raw, href: "" };
|
|
190
|
-
}
|
|
191
178
|
function applyOverlay() {
|
|
192
179
|
document.querySelectorAll("[data-cms]").forEach((el) => {
|
|
193
180
|
if (el.dataset.cmsList !== void 0) return;
|
|
@@ -205,7 +192,7 @@ function applyOverlay() {
|
|
|
205
192
|
return;
|
|
206
193
|
}
|
|
207
194
|
if (el.dataset.cmsType === "link") {
|
|
208
|
-
const link =
|
|
195
|
+
const link = parseLinkValue(savedValue);
|
|
209
196
|
if (link.href && el.tagName === "A") el.setAttribute("href", link.href);
|
|
210
197
|
const labelEls = el.querySelectorAll("[data-cms-label]");
|
|
211
198
|
if (labelEls.length > 0) labelEls.forEach((n) => n.textContent = link.label);
|
|
@@ -383,19 +370,23 @@ async function reorderList(listName, ids) {
|
|
|
383
370
|
);
|
|
384
371
|
if (!res.ok) throw new Error(`Cancia: failed to reorder list (${res.status})`);
|
|
385
372
|
}
|
|
373
|
+
async function flushEdits(edits, save) {
|
|
374
|
+
const results = await Promise.allSettled(edits.map((edit) => save(edit)));
|
|
375
|
+
const saved = [];
|
|
376
|
+
const failed = [];
|
|
377
|
+
results.forEach((result, i) => {
|
|
378
|
+
(result.status === "fulfilled" ? saved : failed).push(edits[i]);
|
|
379
|
+
});
|
|
380
|
+
return { saved, failed };
|
|
381
|
+
}
|
|
386
382
|
async function flushPending() {
|
|
387
383
|
const entries = Array.from(state.pending.values());
|
|
388
|
-
const
|
|
389
|
-
entries
|
|
384
|
+
const { saved, failed } = await flushEdits(
|
|
385
|
+
entries,
|
|
386
|
+
({ key, lang, value }) => saveEntry(key, lang, value)
|
|
390
387
|
);
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
const { key, lang } = entries[i];
|
|
394
|
-
state.pending.delete(`${key}.${lang}`);
|
|
395
|
-
}
|
|
396
|
-
});
|
|
397
|
-
const failed = results.filter((r) => r.status === "rejected").length;
|
|
398
|
-
if (failed > 0) throw new Error(`Cancia: ${failed} save(s) failed`);
|
|
388
|
+
for (const { key, lang } of saved) state.pending.delete(`${key}.${lang}`);
|
|
389
|
+
if (failed.length > 0) throw new Error(`Cancia: ${failed.length} save(s) failed`);
|
|
399
390
|
}
|
|
400
391
|
|
|
401
392
|
// src/tokens.ts
|
|
@@ -1110,9 +1101,11 @@ function onPendingChange(cb) {
|
|
|
1110
1101
|
|
|
1111
1102
|
// src/popup.ts
|
|
1112
1103
|
import {
|
|
1104
|
+
isSafeHref,
|
|
1113
1105
|
portableTextToRows,
|
|
1114
1106
|
rowsToPortableText
|
|
1115
1107
|
} from "@cancia/astro/richtext";
|
|
1108
|
+
import { parseLinkValue as parseLinkValue2 } from "@cancia/astro/schema";
|
|
1116
1109
|
var popupEl = null;
|
|
1117
1110
|
var outsideListener = null;
|
|
1118
1111
|
var keyListener = null;
|
|
@@ -1286,29 +1279,11 @@ function buildTextPopup(key, anchorEl, onClose) {
|
|
|
1286
1279
|
return wrap;
|
|
1287
1280
|
}
|
|
1288
1281
|
function isSafeHrefValue(href) {
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
if (/^(https?:|mailto:|tel:)/i.test(trimmed)) return true;
|
|
1292
|
-
const schemeMatch = /^([a-z][a-z0-9+.-]*):/i.exec(trimmed);
|
|
1293
|
-
if (schemeMatch) {
|
|
1294
|
-
const firstSep = trimmed.search(/[/?#]/);
|
|
1295
|
-
if (firstSep === -1 || schemeMatch[1].length < firstSep) return false;
|
|
1296
|
-
}
|
|
1297
|
-
return true;
|
|
1282
|
+
if (href.trim() === "") return true;
|
|
1283
|
+
return isSafeHref(href);
|
|
1298
1284
|
}
|
|
1299
1285
|
function parseLink(raw) {
|
|
1300
|
-
|
|
1301
|
-
const trimmed = raw.trim();
|
|
1302
|
-
if (trimmed.startsWith("{")) {
|
|
1303
|
-
try {
|
|
1304
|
-
const p = JSON.parse(trimmed);
|
|
1305
|
-
if (p && typeof p === "object") {
|
|
1306
|
-
return { label: String(p.label ?? ""), href: String(p.href ?? "") };
|
|
1307
|
-
}
|
|
1308
|
-
} catch {
|
|
1309
|
-
}
|
|
1310
|
-
}
|
|
1311
|
-
return { label: raw, href: "" };
|
|
1286
|
+
return parseLinkValue2(raw);
|
|
1312
1287
|
}
|
|
1313
1288
|
function buildLinkPopup(key, anchorEl, onClose) {
|
|
1314
1289
|
const langs = state.config?.languages ?? ["en"];
|
|
@@ -1899,6 +1874,7 @@ function closePopup() {
|
|
|
1899
1874
|
}
|
|
1900
1875
|
|
|
1901
1876
|
// src/list-panel.ts
|
|
1877
|
+
import { isDraft } from "@cancia/astro/schema";
|
|
1902
1878
|
var PANEL_Z = v("z-panel");
|
|
1903
1879
|
var TOOLBAR_RESERVE = "100px";
|
|
1904
1880
|
var BACKDROP_Z = v("z-overlay");
|
|
@@ -2239,7 +2215,7 @@ function renderEntries(body, schema, activeLocale, entriesInLocale, translations
|
|
|
2239
2215
|
const titleValue = row.entry.data[schema.titleField];
|
|
2240
2216
|
const title = typeof titleValue === "string" && titleValue.trim().length > 0 ? titleValue : `(untitled ${schema.labelSingular.toLowerCase()})`;
|
|
2241
2217
|
const { subtitle, thumbnail } = derivePreview(schema, row.entry.data);
|
|
2242
|
-
const isDraftRow =
|
|
2218
|
+
const isDraftRow = isDraft(schema, row.entry.data);
|
|
2243
2219
|
const draftBadge = isDraftRow ? `<span style="
|
|
2244
2220
|
flex-shrink: 0; margin-left: ${v("space-2")}; padding: 1px 6px;
|
|
2245
2221
|
font-size: 11px; font-weight: 600; line-height: 1.5;
|