@preprio/toolkit 0.5.0-rc.10 → 0.5.0-rc.12
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/README.md +21 -0
- package/dist/astro/index.cjs +31 -2
- package/dist/astro/index.js +31 -2
- package/dist/{chunk-KD3GK6TO.js → chunk-CABGJW5X.js} +30 -1
- package/dist/{chunk-URXSDJOU.js → chunk-H3AFUPYD.js} +9 -0
- package/dist/{chunk-F46GJS6Y.js → chunk-HVTNUCF7.js} +1 -1
- package/dist/{chunk-IPMB32AZ.js → chunk-LWUSRWFE.js} +2 -2
- package/dist/{chunk-IDEC77LZ.js → chunk-M7FT7XXV.js} +93 -20
- package/dist/{chunk-TBBU3LDD.js → chunk-TJ7VALNA.js} +1 -1
- package/dist/index.cjs +131 -20
- package/dist/index.d.cts +6 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.js +6 -6
- package/dist/{live-preview-DLXGXRE5.js → live-preview-SFBGATWC.js} +3 -3
- package/dist/nextjs/components.cjs +101 -19
- package/dist/nextjs/components.js +3 -3
- package/dist/nextjs/index.cjs +31 -2
- package/dist/nextjs/index.js +31 -2
- package/dist/nextjs/live-action.js +3 -3
- package/dist/nextjs/live.cjs +30 -1
- package/dist/nextjs/live.js +1 -1
- package/dist/nuxt/index.cjs +1 -1
- package/dist/nuxt/index.js +1 -1
- package/dist/nuxt/{live-preview-2RCU35W5.js → live-preview-XMQQZHMZ.js} +30 -1
- package/dist/nuxt/live.cjs +30 -1
- package/dist/nuxt/live.js +1 -1
- package/dist/react/components.cjs +101 -19
- package/dist/react/components.js +101 -19
- package/dist/sveltekit/index.cjs +1 -1
- package/dist/sveltekit/index.js +1 -1
- package/dist/sveltekit/{live-preview-2RCU35W5.js → live-preview-XMQQZHMZ.js} +30 -1
- package/dist/sveltekit/live.cjs +30 -1
- package/dist/sveltekit/live.js +1 -1
- package/package.json +1 -1
|
@@ -395,6 +395,7 @@ function createIframeBridge(store, options = {}) {
|
|
|
395
395
|
const onReferences = options.onReferences;
|
|
396
396
|
const onAssets = options.onAssets;
|
|
397
397
|
const onAllowNavigation = options.onAllowNavigation;
|
|
398
|
+
const onItemChanged = options.onItemChanged;
|
|
398
399
|
let parentOrigin = null;
|
|
399
400
|
const onKeyDown = (event) => {
|
|
400
401
|
const key = event.key.toLowerCase();
|
|
@@ -485,6 +486,14 @@ function createIframeBridge(store, options = {}) {
|
|
|
485
486
|
debug.warn("allowNavigation handler failed", error);
|
|
486
487
|
}
|
|
487
488
|
}
|
|
489
|
+
if (data?.event === "prepr:itemChanged") {
|
|
490
|
+
if (typeof data.itemId !== "string" || !data.itemId) return;
|
|
491
|
+
try {
|
|
492
|
+
onItemChanged?.(data.itemId);
|
|
493
|
+
} catch (error) {
|
|
494
|
+
debug.warn("itemChanged handler failed", error);
|
|
495
|
+
}
|
|
496
|
+
}
|
|
488
497
|
};
|
|
489
498
|
return {
|
|
490
499
|
start() {
|
|
@@ -2628,6 +2637,7 @@ var ABSOLUTE_HTTP = /^https?:\/\//i;
|
|
|
2628
2637
|
var SOURCE_URL_ATTRIBUTES = ["src", "data-src"];
|
|
2629
2638
|
var SOURCE_SET_ATTRIBUTES = ["srcset", "data-srcset"];
|
|
2630
2639
|
var ASSET_ATTR = "data-prepr-asset";
|
|
2640
|
+
var REMOVED_ATTR = "data-prepr-removed";
|
|
2631
2641
|
var ASSET_SOURCE_ATTRIBUTES = [
|
|
2632
2642
|
...SOURCE_URL_ATTRIBUTES,
|
|
2633
2643
|
...SOURCE_SET_ATTRIBUTES
|
|
@@ -2637,7 +2647,8 @@ var TAG_ATTRIBUTES = [
|
|
|
2637
2647
|
"data-prepr-id",
|
|
2638
2648
|
"data-prepr-field",
|
|
2639
2649
|
"data-prepr-entry-id",
|
|
2640
|
-
ASSET_ATTR
|
|
2650
|
+
ASSET_ATTR,
|
|
2651
|
+
REMOVED_ATTR
|
|
2641
2652
|
];
|
|
2642
2653
|
function decodeSegment(segment) {
|
|
2643
2654
|
try {
|
|
@@ -2756,11 +2767,22 @@ function besideOtherItem(img, isCurrentItem) {
|
|
|
2756
2767
|
return false;
|
|
2757
2768
|
}
|
|
2758
2769
|
function tagAssetImages(index, itemId, keys, options = {}) {
|
|
2759
|
-
const { isCurrentItem } = options;
|
|
2770
|
+
const { isCurrentItem, removed } = options;
|
|
2771
|
+
let showsRemoved = false;
|
|
2760
2772
|
for (const img of document.getElementsByTagName("img")) {
|
|
2761
2773
|
const ours = img.hasAttribute(ASSET_ATTR);
|
|
2762
|
-
|
|
2763
|
-
|
|
2774
|
+
let match = index.size ? matchAsset(img, index, keys) : void 0;
|
|
2775
|
+
let isRemoved = false;
|
|
2776
|
+
if (!match && removed?.size) {
|
|
2777
|
+
match = matchAsset(img, removed, keys);
|
|
2778
|
+
isRemoved = match !== void 0;
|
|
2779
|
+
}
|
|
2780
|
+
if (!ours && img.hasAttribute("data-prepr-encoded")) {
|
|
2781
|
+
const mark = isRemoved && (!isCurrentItem || isCurrentItem(img));
|
|
2782
|
+
setIfChanged(img, REMOVED_ATTR, mark ? "" : null);
|
|
2783
|
+
showsRemoved || (showsRemoved = mark);
|
|
2784
|
+
continue;
|
|
2785
|
+
}
|
|
2764
2786
|
const asset = match && isCurrentItem && besideOtherItem(img, isCurrentItem) ? void 0 : match;
|
|
2765
2787
|
if (!asset) {
|
|
2766
2788
|
if (ours) untagAssetImage(img);
|
|
@@ -2771,10 +2793,14 @@ function tagAssetImages(index, itemId, keys, options = {}) {
|
|
|
2771
2793
|
setIfChanged(img, "data-prepr-id", itemId);
|
|
2772
2794
|
setIfChanged(img, "data-prepr-field", asset.field);
|
|
2773
2795
|
setIfChanged(img, "data-prepr-entry-id", asset.entryId ?? null);
|
|
2796
|
+
setIfChanged(img, REMOVED_ATTR, isRemoved ? "" : null);
|
|
2797
|
+
showsRemoved || (showsRemoved = isRemoved);
|
|
2774
2798
|
}
|
|
2799
|
+
return showsRemoved;
|
|
2775
2800
|
}
|
|
2776
2801
|
function untagAssetImages() {
|
|
2777
2802
|
document.querySelectorAll(`img[${ASSET_ATTR}]`).forEach(untagAssetImage);
|
|
2803
|
+
document.querySelectorAll(`img[${REMOVED_ATTR}]`).forEach((img) => img.removeAttribute(REMOVED_ATTR));
|
|
2778
2804
|
}
|
|
2779
2805
|
|
|
2780
2806
|
// src/core/visual-editor/navigation-guard.ts
|
|
@@ -2944,12 +2970,19 @@ var debug8 = createScopedLogger("visual-editor");
|
|
|
2944
2970
|
var ENCODED_SELECTOR2 = "[data-prepr-encoded]";
|
|
2945
2971
|
var REFERENCE_ATTR = "data-prepr-reference";
|
|
2946
2972
|
var REFERENCE_SELECTOR = `[${REFERENCE_ATTR}]`;
|
|
2973
|
+
var OTHER_ITEM_ATTR = "data-prepr-other-item";
|
|
2974
|
+
var OTHER_ITEM_SELECTOR = `[${OTHER_ITEM_ATTR}="on"],[${OTHER_ITEM_ATTR}="off"]`;
|
|
2975
|
+
var CHROME_SELECTOR = "header, footer, nav, [role=banner], [role=contentinfo], [role=navigation]";
|
|
2976
|
+
var SECTIONING_SELECTOR = "article, aside, main, nav, section";
|
|
2977
|
+
var PLAIN_HEADER_FOOTER = "header:not([role]), footer:not([role])";
|
|
2947
2978
|
var CURSOR_STYLE_MARKER = "data-prepr-visual-editor";
|
|
2948
|
-
var
|
|
2979
|
+
var REMOVED_STYLES = `img[${REMOVED_ATTR}]{opacity:.2!important;transition:opacity .2s ease}@media (prefers-reduced-motion:reduce){img[${REMOVED_ATTR}]{transition:none}}`;
|
|
2980
|
+
var CURSOR_STYLES = `${ENCODED_SELECTOR2}{cursor:pointer}html[data-prepr-ve-suspended] ${ENCODED_SELECTOR2}{cursor:auto}${REMOVED_STYLES}`;
|
|
2949
2981
|
var SUSPENDED_ATTR = "data-prepr-ve-suspended";
|
|
2950
2982
|
var FIND_RETRY_MS = 150;
|
|
2951
2983
|
var FIND_RETRIES = 6;
|
|
2952
2984
|
var MAX_CACHED_KEYS = 2e3;
|
|
2985
|
+
var SAVED_FADE_MS = 1e4;
|
|
2953
2986
|
var LAYOUT_MUTATIONS = {
|
|
2954
2987
|
childList: true,
|
|
2955
2988
|
subtree: true,
|
|
@@ -2992,6 +3025,9 @@ function createVisualEditor(opts) {
|
|
|
2992
3025
|
let guardEnabled = false;
|
|
2993
3026
|
let assetIndex = /* @__PURE__ */ new Map();
|
|
2994
3027
|
const assetKeys = /* @__PURE__ */ new Map();
|
|
3028
|
+
const removedAssets = /* @__PURE__ */ new Map();
|
|
3029
|
+
let saved = false;
|
|
3030
|
+
let savedTimeout = null;
|
|
2995
3031
|
const guard = createNavigationGuard({
|
|
2996
3032
|
onBlocked: (href) => opts.onNavigationBlocked?.(href),
|
|
2997
3033
|
showsEditedContent: () => showsEditedContent()
|
|
@@ -3023,10 +3059,26 @@ function createVisualEditor(opts) {
|
|
|
3023
3059
|
}
|
|
3024
3060
|
return null;
|
|
3025
3061
|
};
|
|
3062
|
+
const inSiteChrome = (el) => {
|
|
3063
|
+
let chrome = el.closest(CHROME_SELECTOR);
|
|
3064
|
+
while (chrome) {
|
|
3065
|
+
if (!chrome.matches(PLAIN_HEADER_FOOTER) || !chrome.parentElement?.closest(SECTIONING_SELECTOR)) {
|
|
3066
|
+
return true;
|
|
3067
|
+
}
|
|
3068
|
+
chrome = chrome.parentElement?.closest(CHROME_SELECTOR) ?? null;
|
|
3069
|
+
}
|
|
3070
|
+
return false;
|
|
3071
|
+
};
|
|
3072
|
+
const showsOtherItem = (el) => {
|
|
3073
|
+
const choice = el.closest(OTHER_ITEM_SELECTOR);
|
|
3074
|
+
if (choice) return choice.getAttribute(OTHER_ITEM_ATTR) === "on";
|
|
3075
|
+
return !inSiteChrome(el);
|
|
3076
|
+
};
|
|
3026
3077
|
const itemKind = (el) => {
|
|
3027
3078
|
if (isCurrentItem(el)) return "current";
|
|
3028
3079
|
if (!references) return "other";
|
|
3029
|
-
|
|
3080
|
+
if (linkedIdOf(el)) return "referenced";
|
|
3081
|
+
return showsOtherItem(el) ? "other" : null;
|
|
3030
3082
|
};
|
|
3031
3083
|
const referenceFieldOf = (el) => {
|
|
3032
3084
|
const linked = linkedIdOf(el);
|
|
@@ -3099,6 +3151,7 @@ function createVisualEditor(opts) {
|
|
|
3099
3151
|
}
|
|
3100
3152
|
return;
|
|
3101
3153
|
}
|
|
3154
|
+
if (kind === "other" && (e2.ctrlKey || e2.metaKey || e2.shiftKey)) return;
|
|
3102
3155
|
e2.preventDefault();
|
|
3103
3156
|
e2.stopPropagation();
|
|
3104
3157
|
const item = listItemIn(encoded, e2.target);
|
|
@@ -3106,11 +3159,13 @@ function createVisualEditor(opts) {
|
|
|
3106
3159
|
select(item?.element ?? encoded, encoded, item?.index);
|
|
3107
3160
|
const referenceField = kind === "referenced" ? referenceFieldOf(encoded) : void 0;
|
|
3108
3161
|
const linkedId = kind === "referenced" ? linkedIdOf(encoded) : null;
|
|
3162
|
+
const linkHref = kind === "other" ? leavingLinkHref(e2.target) : null;
|
|
3109
3163
|
opts.onEdit({
|
|
3110
3164
|
...readEditPayload(encoded),
|
|
3111
3165
|
...linkedId && { id: linkedId },
|
|
3112
3166
|
...item && { block: item.index },
|
|
3113
|
-
...referenceField && { referenceField }
|
|
3167
|
+
...referenceField && { referenceField },
|
|
3168
|
+
...linkHref && { linkHref }
|
|
3114
3169
|
});
|
|
3115
3170
|
};
|
|
3116
3171
|
const handleKey = (e2) => {
|
|
@@ -3171,15 +3226,32 @@ function createVisualEditor(opts) {
|
|
|
3171
3226
|
const el = block !== void 0 ? nthListItem(found, block) ?? found : found;
|
|
3172
3227
|
select(el, found, block);
|
|
3173
3228
|
}
|
|
3229
|
+
const hasAssets = () => assetIndex.size > 0 || removedAssets.size > 0;
|
|
3174
3230
|
function tagAssets() {
|
|
3175
3231
|
if (assetKeys.size > MAX_CACHED_KEYS) assetKeys.clear();
|
|
3176
|
-
tagAssetImages(assetIndex, currentItemId, assetKeys, {
|
|
3177
|
-
isCurrentItem: (el) => isCurrentItem(el)
|
|
3232
|
+
const showsRemoved = tagAssetImages(assetIndex, currentItemId, assetKeys, {
|
|
3233
|
+
isCurrentItem: (el) => isCurrentItem(el),
|
|
3234
|
+
removed: removedAssets
|
|
3178
3235
|
});
|
|
3236
|
+
if (saved && !showsRemoved) forgetRemoved();
|
|
3237
|
+
}
|
|
3238
|
+
function forgetRemoved() {
|
|
3239
|
+
saved = false;
|
|
3240
|
+
if (savedTimeout) clearTimeout(savedTimeout);
|
|
3241
|
+
savedTimeout = null;
|
|
3242
|
+
if (!removedAssets.size) return;
|
|
3243
|
+
removedAssets.clear();
|
|
3244
|
+
if (running) tagAssets();
|
|
3245
|
+
}
|
|
3246
|
+
function itemSaved() {
|
|
3247
|
+
if (!removedAssets.size) return;
|
|
3248
|
+
saved = true;
|
|
3249
|
+
if (savedTimeout) clearTimeout(savedTimeout);
|
|
3250
|
+
savedTimeout = setTimeout(forgetRemoved, SAVED_FADE_MS);
|
|
3179
3251
|
}
|
|
3180
3252
|
const handleLayoutFrame = () => {
|
|
3181
3253
|
mutationFrame = null;
|
|
3182
|
-
if (
|
|
3254
|
+
if (hasAssets()) tagAssets();
|
|
3183
3255
|
reselect();
|
|
3184
3256
|
const hovered = overlay.getHoverTarget();
|
|
3185
3257
|
if (hovered && !hovered.isConnected) {
|
|
@@ -3191,7 +3263,7 @@ function createVisualEditor(opts) {
|
|
|
3191
3263
|
};
|
|
3192
3264
|
const handleMutations = () => {
|
|
3193
3265
|
if (mutationFrame !== null) return;
|
|
3194
|
-
if (!selection && !overlay.getHoverTarget() && !
|
|
3266
|
+
if (!selection && !overlay.getHoverTarget() && !hasAssets()) return;
|
|
3195
3267
|
mutationFrame = requestAnimationFrame(handleLayoutFrame);
|
|
3196
3268
|
};
|
|
3197
3269
|
function injectCursorStyles() {
|
|
@@ -3232,7 +3304,7 @@ function createVisualEditor(opts) {
|
|
|
3232
3304
|
});
|
|
3233
3305
|
mutationObserver = new MutationObserver(handleMutations);
|
|
3234
3306
|
mutationObserver.observe(document.body, LAYOUT_MUTATIONS);
|
|
3235
|
-
if (
|
|
3307
|
+
if (hasAssets()) tagAssets();
|
|
3236
3308
|
syncGuard();
|
|
3237
3309
|
debug8.log("visual editor started");
|
|
3238
3310
|
}
|
|
@@ -3308,18 +3380,24 @@ function createVisualEditor(opts) {
|
|
|
3308
3380
|
});
|
|
3309
3381
|
}
|
|
3310
3382
|
function setCurrentItem(itemId, referenceList, componentIds) {
|
|
3383
|
+
if (itemId !== currentItemId) forgetRemoved();
|
|
3311
3384
|
currentItemId = itemId;
|
|
3312
3385
|
if (referenceList) setReferences(referenceList, componentIds);
|
|
3313
3386
|
else if (componentIds) ownComponents = new Set(componentIds);
|
|
3314
|
-
if (running &&
|
|
3387
|
+
if (running && hasAssets()) tagAssets();
|
|
3315
3388
|
const selected = overlay.getSelectedTarget();
|
|
3316
3389
|
const owner = selected ? encodedFrom(selected) : null;
|
|
3317
3390
|
if (owner && !isCurrentItem(owner)) clearSelection();
|
|
3318
3391
|
}
|
|
3319
3392
|
function setAssets(assets) {
|
|
3320
|
-
const hadAssets =
|
|
3321
|
-
|
|
3322
|
-
|
|
3393
|
+
const hadAssets = hasAssets();
|
|
3394
|
+
const next = createAssetIndex(assets);
|
|
3395
|
+
for (const [key, asset] of assetIndex) {
|
|
3396
|
+
if (!next.has(key)) removedAssets.set(key, asset);
|
|
3397
|
+
}
|
|
3398
|
+
for (const key of next.keys()) removedAssets.delete(key);
|
|
3399
|
+
assetIndex = next;
|
|
3400
|
+
if (running && (hadAssets || hasAssets())) tagAssets();
|
|
3323
3401
|
}
|
|
3324
3402
|
function setReferences(referenceList, componentIds) {
|
|
3325
3403
|
if (componentIds) ownComponents = new Set(componentIds);
|
|
@@ -3345,6 +3423,7 @@ function createVisualEditor(opts) {
|
|
|
3345
3423
|
setCurrentItem,
|
|
3346
3424
|
setReferences,
|
|
3347
3425
|
setAssets,
|
|
3426
|
+
itemSaved,
|
|
3348
3427
|
setLocale,
|
|
3349
3428
|
focusField,
|
|
3350
3429
|
setNavigationGuard,
|
|
@@ -3431,7 +3510,8 @@ function createPreprPreview(opts = {}) {
|
|
|
3431
3510
|
locale: contentLocale,
|
|
3432
3511
|
block,
|
|
3433
3512
|
entryId,
|
|
3434
|
-
referenceField
|
|
3513
|
+
referenceField,
|
|
3514
|
+
linkHref
|
|
3435
3515
|
}) => {
|
|
3436
3516
|
const safeHref = href ? safeEditUrl(href) : null;
|
|
3437
3517
|
if (href && !safeHref) {
|
|
@@ -3445,7 +3525,8 @@ function createPreprPreview(opts = {}) {
|
|
|
3445
3525
|
locale: contentLocale,
|
|
3446
3526
|
...block !== void 0 && { block },
|
|
3447
3527
|
...entryId && { entryId },
|
|
3448
|
-
...referenceField && { referenceField }
|
|
3528
|
+
...referenceField && { referenceField },
|
|
3529
|
+
...linkHref && { linkHref }
|
|
3449
3530
|
});
|
|
3450
3531
|
} else if (safeHref) {
|
|
3451
3532
|
window.open(safeHref, "_blank", "noopener,noreferrer");
|
|
@@ -3500,6 +3581,7 @@ function createPreprPreview(opts = {}) {
|
|
|
3500
3581
|
},
|
|
3501
3582
|
onAssets: (assets) => visualEditor?.setAssets(assets),
|
|
3502
3583
|
onAllowNavigation: (href) => visualEditor?.allowNavigation(href),
|
|
3584
|
+
onItemChanged: () => visualEditor?.itemSaved(),
|
|
3503
3585
|
onReferences: (referencedIds, componentIds) => visualEditor?.setReferences(referencedIds, componentIds),
|
|
3504
3586
|
// The editor selecting a field scrolls the matching element into view. The
|
|
3505
3587
|
// lookup relies on the attributes the stega scan writes, so it finds
|
|
@@ -3540,7 +3622,7 @@ function createPreprPreview(opts = {}) {
|
|
|
3540
3622
|
}
|
|
3541
3623
|
|
|
3542
3624
|
// src/version.ts
|
|
3543
|
-
var VERSION = "0.5.0-rc.
|
|
3625
|
+
var VERSION = "0.5.0-rc.12";
|
|
3544
3626
|
|
|
3545
3627
|
// src/core/pixel.ts
|
|
3546
3628
|
var PIXEL_SCRIPT_URL = "https://cdn.tracking.prepr.io/js/prepr.min.js";
|
package/dist/react/components.js
CHANGED
|
@@ -371,6 +371,7 @@ function createIframeBridge(store, options = {}) {
|
|
|
371
371
|
const onReferences = options.onReferences;
|
|
372
372
|
const onAssets = options.onAssets;
|
|
373
373
|
const onAllowNavigation = options.onAllowNavigation;
|
|
374
|
+
const onItemChanged = options.onItemChanged;
|
|
374
375
|
let parentOrigin = null;
|
|
375
376
|
const onKeyDown = (event) => {
|
|
376
377
|
const key = event.key.toLowerCase();
|
|
@@ -461,6 +462,14 @@ function createIframeBridge(store, options = {}) {
|
|
|
461
462
|
debug.warn("allowNavigation handler failed", error);
|
|
462
463
|
}
|
|
463
464
|
}
|
|
465
|
+
if (data?.event === "prepr:itemChanged") {
|
|
466
|
+
if (typeof data.itemId !== "string" || !data.itemId) return;
|
|
467
|
+
try {
|
|
468
|
+
onItemChanged?.(data.itemId);
|
|
469
|
+
} catch (error) {
|
|
470
|
+
debug.warn("itemChanged handler failed", error);
|
|
471
|
+
}
|
|
472
|
+
}
|
|
464
473
|
};
|
|
465
474
|
return {
|
|
466
475
|
start() {
|
|
@@ -2604,6 +2613,7 @@ var ABSOLUTE_HTTP = /^https?:\/\//i;
|
|
|
2604
2613
|
var SOURCE_URL_ATTRIBUTES = ["src", "data-src"];
|
|
2605
2614
|
var SOURCE_SET_ATTRIBUTES = ["srcset", "data-srcset"];
|
|
2606
2615
|
var ASSET_ATTR = "data-prepr-asset";
|
|
2616
|
+
var REMOVED_ATTR = "data-prepr-removed";
|
|
2607
2617
|
var ASSET_SOURCE_ATTRIBUTES = [
|
|
2608
2618
|
...SOURCE_URL_ATTRIBUTES,
|
|
2609
2619
|
...SOURCE_SET_ATTRIBUTES
|
|
@@ -2613,7 +2623,8 @@ var TAG_ATTRIBUTES = [
|
|
|
2613
2623
|
"data-prepr-id",
|
|
2614
2624
|
"data-prepr-field",
|
|
2615
2625
|
"data-prepr-entry-id",
|
|
2616
|
-
ASSET_ATTR
|
|
2626
|
+
ASSET_ATTR,
|
|
2627
|
+
REMOVED_ATTR
|
|
2617
2628
|
];
|
|
2618
2629
|
function decodeSegment(segment) {
|
|
2619
2630
|
try {
|
|
@@ -2732,11 +2743,22 @@ function besideOtherItem(img, isCurrentItem) {
|
|
|
2732
2743
|
return false;
|
|
2733
2744
|
}
|
|
2734
2745
|
function tagAssetImages(index, itemId, keys, options = {}) {
|
|
2735
|
-
const { isCurrentItem } = options;
|
|
2746
|
+
const { isCurrentItem, removed } = options;
|
|
2747
|
+
let showsRemoved = false;
|
|
2736
2748
|
for (const img of document.getElementsByTagName("img")) {
|
|
2737
2749
|
const ours = img.hasAttribute(ASSET_ATTR);
|
|
2738
|
-
|
|
2739
|
-
|
|
2750
|
+
let match = index.size ? matchAsset(img, index, keys) : void 0;
|
|
2751
|
+
let isRemoved = false;
|
|
2752
|
+
if (!match && removed?.size) {
|
|
2753
|
+
match = matchAsset(img, removed, keys);
|
|
2754
|
+
isRemoved = match !== void 0;
|
|
2755
|
+
}
|
|
2756
|
+
if (!ours && img.hasAttribute("data-prepr-encoded")) {
|
|
2757
|
+
const mark = isRemoved && (!isCurrentItem || isCurrentItem(img));
|
|
2758
|
+
setIfChanged(img, REMOVED_ATTR, mark ? "" : null);
|
|
2759
|
+
showsRemoved || (showsRemoved = mark);
|
|
2760
|
+
continue;
|
|
2761
|
+
}
|
|
2740
2762
|
const asset = match && isCurrentItem && besideOtherItem(img, isCurrentItem) ? void 0 : match;
|
|
2741
2763
|
if (!asset) {
|
|
2742
2764
|
if (ours) untagAssetImage(img);
|
|
@@ -2747,10 +2769,14 @@ function tagAssetImages(index, itemId, keys, options = {}) {
|
|
|
2747
2769
|
setIfChanged(img, "data-prepr-id", itemId);
|
|
2748
2770
|
setIfChanged(img, "data-prepr-field", asset.field);
|
|
2749
2771
|
setIfChanged(img, "data-prepr-entry-id", asset.entryId ?? null);
|
|
2772
|
+
setIfChanged(img, REMOVED_ATTR, isRemoved ? "" : null);
|
|
2773
|
+
showsRemoved || (showsRemoved = isRemoved);
|
|
2750
2774
|
}
|
|
2775
|
+
return showsRemoved;
|
|
2751
2776
|
}
|
|
2752
2777
|
function untagAssetImages() {
|
|
2753
2778
|
document.querySelectorAll(`img[${ASSET_ATTR}]`).forEach(untagAssetImage);
|
|
2779
|
+
document.querySelectorAll(`img[${REMOVED_ATTR}]`).forEach((img) => img.removeAttribute(REMOVED_ATTR));
|
|
2754
2780
|
}
|
|
2755
2781
|
|
|
2756
2782
|
// src/core/visual-editor/navigation-guard.ts
|
|
@@ -2920,12 +2946,19 @@ var debug8 = createScopedLogger("visual-editor");
|
|
|
2920
2946
|
var ENCODED_SELECTOR2 = "[data-prepr-encoded]";
|
|
2921
2947
|
var REFERENCE_ATTR = "data-prepr-reference";
|
|
2922
2948
|
var REFERENCE_SELECTOR = `[${REFERENCE_ATTR}]`;
|
|
2949
|
+
var OTHER_ITEM_ATTR = "data-prepr-other-item";
|
|
2950
|
+
var OTHER_ITEM_SELECTOR = `[${OTHER_ITEM_ATTR}="on"],[${OTHER_ITEM_ATTR}="off"]`;
|
|
2951
|
+
var CHROME_SELECTOR = "header, footer, nav, [role=banner], [role=contentinfo], [role=navigation]";
|
|
2952
|
+
var SECTIONING_SELECTOR = "article, aside, main, nav, section";
|
|
2953
|
+
var PLAIN_HEADER_FOOTER = "header:not([role]), footer:not([role])";
|
|
2923
2954
|
var CURSOR_STYLE_MARKER = "data-prepr-visual-editor";
|
|
2924
|
-
var
|
|
2955
|
+
var REMOVED_STYLES = `img[${REMOVED_ATTR}]{opacity:.2!important;transition:opacity .2s ease}@media (prefers-reduced-motion:reduce){img[${REMOVED_ATTR}]{transition:none}}`;
|
|
2956
|
+
var CURSOR_STYLES = `${ENCODED_SELECTOR2}{cursor:pointer}html[data-prepr-ve-suspended] ${ENCODED_SELECTOR2}{cursor:auto}${REMOVED_STYLES}`;
|
|
2925
2957
|
var SUSPENDED_ATTR = "data-prepr-ve-suspended";
|
|
2926
2958
|
var FIND_RETRY_MS = 150;
|
|
2927
2959
|
var FIND_RETRIES = 6;
|
|
2928
2960
|
var MAX_CACHED_KEYS = 2e3;
|
|
2961
|
+
var SAVED_FADE_MS = 1e4;
|
|
2929
2962
|
var LAYOUT_MUTATIONS = {
|
|
2930
2963
|
childList: true,
|
|
2931
2964
|
subtree: true,
|
|
@@ -2968,6 +3001,9 @@ function createVisualEditor(opts) {
|
|
|
2968
3001
|
let guardEnabled = false;
|
|
2969
3002
|
let assetIndex = /* @__PURE__ */ new Map();
|
|
2970
3003
|
const assetKeys = /* @__PURE__ */ new Map();
|
|
3004
|
+
const removedAssets = /* @__PURE__ */ new Map();
|
|
3005
|
+
let saved = false;
|
|
3006
|
+
let savedTimeout = null;
|
|
2971
3007
|
const guard = createNavigationGuard({
|
|
2972
3008
|
onBlocked: (href) => opts.onNavigationBlocked?.(href),
|
|
2973
3009
|
showsEditedContent: () => showsEditedContent()
|
|
@@ -2999,10 +3035,26 @@ function createVisualEditor(opts) {
|
|
|
2999
3035
|
}
|
|
3000
3036
|
return null;
|
|
3001
3037
|
};
|
|
3038
|
+
const inSiteChrome = (el) => {
|
|
3039
|
+
let chrome = el.closest(CHROME_SELECTOR);
|
|
3040
|
+
while (chrome) {
|
|
3041
|
+
if (!chrome.matches(PLAIN_HEADER_FOOTER) || !chrome.parentElement?.closest(SECTIONING_SELECTOR)) {
|
|
3042
|
+
return true;
|
|
3043
|
+
}
|
|
3044
|
+
chrome = chrome.parentElement?.closest(CHROME_SELECTOR) ?? null;
|
|
3045
|
+
}
|
|
3046
|
+
return false;
|
|
3047
|
+
};
|
|
3048
|
+
const showsOtherItem = (el) => {
|
|
3049
|
+
const choice = el.closest(OTHER_ITEM_SELECTOR);
|
|
3050
|
+
if (choice) return choice.getAttribute(OTHER_ITEM_ATTR) === "on";
|
|
3051
|
+
return !inSiteChrome(el);
|
|
3052
|
+
};
|
|
3002
3053
|
const itemKind = (el) => {
|
|
3003
3054
|
if (isCurrentItem(el)) return "current";
|
|
3004
3055
|
if (!references) return "other";
|
|
3005
|
-
|
|
3056
|
+
if (linkedIdOf(el)) return "referenced";
|
|
3057
|
+
return showsOtherItem(el) ? "other" : null;
|
|
3006
3058
|
};
|
|
3007
3059
|
const referenceFieldOf = (el) => {
|
|
3008
3060
|
const linked = linkedIdOf(el);
|
|
@@ -3075,6 +3127,7 @@ function createVisualEditor(opts) {
|
|
|
3075
3127
|
}
|
|
3076
3128
|
return;
|
|
3077
3129
|
}
|
|
3130
|
+
if (kind === "other" && (e2.ctrlKey || e2.metaKey || e2.shiftKey)) return;
|
|
3078
3131
|
e2.preventDefault();
|
|
3079
3132
|
e2.stopPropagation();
|
|
3080
3133
|
const item = listItemIn(encoded, e2.target);
|
|
@@ -3082,11 +3135,13 @@ function createVisualEditor(opts) {
|
|
|
3082
3135
|
select(item?.element ?? encoded, encoded, item?.index);
|
|
3083
3136
|
const referenceField = kind === "referenced" ? referenceFieldOf(encoded) : void 0;
|
|
3084
3137
|
const linkedId = kind === "referenced" ? linkedIdOf(encoded) : null;
|
|
3138
|
+
const linkHref = kind === "other" ? leavingLinkHref(e2.target) : null;
|
|
3085
3139
|
opts.onEdit({
|
|
3086
3140
|
...readEditPayload(encoded),
|
|
3087
3141
|
...linkedId && { id: linkedId },
|
|
3088
3142
|
...item && { block: item.index },
|
|
3089
|
-
...referenceField && { referenceField }
|
|
3143
|
+
...referenceField && { referenceField },
|
|
3144
|
+
...linkHref && { linkHref }
|
|
3090
3145
|
});
|
|
3091
3146
|
};
|
|
3092
3147
|
const handleKey = (e2) => {
|
|
@@ -3147,15 +3202,32 @@ function createVisualEditor(opts) {
|
|
|
3147
3202
|
const el = block !== void 0 ? nthListItem(found, block) ?? found : found;
|
|
3148
3203
|
select(el, found, block);
|
|
3149
3204
|
}
|
|
3205
|
+
const hasAssets = () => assetIndex.size > 0 || removedAssets.size > 0;
|
|
3150
3206
|
function tagAssets() {
|
|
3151
3207
|
if (assetKeys.size > MAX_CACHED_KEYS) assetKeys.clear();
|
|
3152
|
-
tagAssetImages(assetIndex, currentItemId, assetKeys, {
|
|
3153
|
-
isCurrentItem: (el) => isCurrentItem(el)
|
|
3208
|
+
const showsRemoved = tagAssetImages(assetIndex, currentItemId, assetKeys, {
|
|
3209
|
+
isCurrentItem: (el) => isCurrentItem(el),
|
|
3210
|
+
removed: removedAssets
|
|
3154
3211
|
});
|
|
3212
|
+
if (saved && !showsRemoved) forgetRemoved();
|
|
3213
|
+
}
|
|
3214
|
+
function forgetRemoved() {
|
|
3215
|
+
saved = false;
|
|
3216
|
+
if (savedTimeout) clearTimeout(savedTimeout);
|
|
3217
|
+
savedTimeout = null;
|
|
3218
|
+
if (!removedAssets.size) return;
|
|
3219
|
+
removedAssets.clear();
|
|
3220
|
+
if (running) tagAssets();
|
|
3221
|
+
}
|
|
3222
|
+
function itemSaved() {
|
|
3223
|
+
if (!removedAssets.size) return;
|
|
3224
|
+
saved = true;
|
|
3225
|
+
if (savedTimeout) clearTimeout(savedTimeout);
|
|
3226
|
+
savedTimeout = setTimeout(forgetRemoved, SAVED_FADE_MS);
|
|
3155
3227
|
}
|
|
3156
3228
|
const handleLayoutFrame = () => {
|
|
3157
3229
|
mutationFrame = null;
|
|
3158
|
-
if (
|
|
3230
|
+
if (hasAssets()) tagAssets();
|
|
3159
3231
|
reselect();
|
|
3160
3232
|
const hovered = overlay.getHoverTarget();
|
|
3161
3233
|
if (hovered && !hovered.isConnected) {
|
|
@@ -3167,7 +3239,7 @@ function createVisualEditor(opts) {
|
|
|
3167
3239
|
};
|
|
3168
3240
|
const handleMutations = () => {
|
|
3169
3241
|
if (mutationFrame !== null) return;
|
|
3170
|
-
if (!selection && !overlay.getHoverTarget() && !
|
|
3242
|
+
if (!selection && !overlay.getHoverTarget() && !hasAssets()) return;
|
|
3171
3243
|
mutationFrame = requestAnimationFrame(handleLayoutFrame);
|
|
3172
3244
|
};
|
|
3173
3245
|
function injectCursorStyles() {
|
|
@@ -3208,7 +3280,7 @@ function createVisualEditor(opts) {
|
|
|
3208
3280
|
});
|
|
3209
3281
|
mutationObserver = new MutationObserver(handleMutations);
|
|
3210
3282
|
mutationObserver.observe(document.body, LAYOUT_MUTATIONS);
|
|
3211
|
-
if (
|
|
3283
|
+
if (hasAssets()) tagAssets();
|
|
3212
3284
|
syncGuard();
|
|
3213
3285
|
debug8.log("visual editor started");
|
|
3214
3286
|
}
|
|
@@ -3284,18 +3356,24 @@ function createVisualEditor(opts) {
|
|
|
3284
3356
|
});
|
|
3285
3357
|
}
|
|
3286
3358
|
function setCurrentItem(itemId, referenceList, componentIds) {
|
|
3359
|
+
if (itemId !== currentItemId) forgetRemoved();
|
|
3287
3360
|
currentItemId = itemId;
|
|
3288
3361
|
if (referenceList) setReferences(referenceList, componentIds);
|
|
3289
3362
|
else if (componentIds) ownComponents = new Set(componentIds);
|
|
3290
|
-
if (running &&
|
|
3363
|
+
if (running && hasAssets()) tagAssets();
|
|
3291
3364
|
const selected = overlay.getSelectedTarget();
|
|
3292
3365
|
const owner = selected ? encodedFrom(selected) : null;
|
|
3293
3366
|
if (owner && !isCurrentItem(owner)) clearSelection();
|
|
3294
3367
|
}
|
|
3295
3368
|
function setAssets(assets) {
|
|
3296
|
-
const hadAssets =
|
|
3297
|
-
|
|
3298
|
-
|
|
3369
|
+
const hadAssets = hasAssets();
|
|
3370
|
+
const next = createAssetIndex(assets);
|
|
3371
|
+
for (const [key, asset] of assetIndex) {
|
|
3372
|
+
if (!next.has(key)) removedAssets.set(key, asset);
|
|
3373
|
+
}
|
|
3374
|
+
for (const key of next.keys()) removedAssets.delete(key);
|
|
3375
|
+
assetIndex = next;
|
|
3376
|
+
if (running && (hadAssets || hasAssets())) tagAssets();
|
|
3299
3377
|
}
|
|
3300
3378
|
function setReferences(referenceList, componentIds) {
|
|
3301
3379
|
if (componentIds) ownComponents = new Set(componentIds);
|
|
@@ -3321,6 +3399,7 @@ function createVisualEditor(opts) {
|
|
|
3321
3399
|
setCurrentItem,
|
|
3322
3400
|
setReferences,
|
|
3323
3401
|
setAssets,
|
|
3402
|
+
itemSaved,
|
|
3324
3403
|
setLocale,
|
|
3325
3404
|
focusField,
|
|
3326
3405
|
setNavigationGuard,
|
|
@@ -3407,7 +3486,8 @@ function createPreprPreview(opts = {}) {
|
|
|
3407
3486
|
locale: contentLocale,
|
|
3408
3487
|
block,
|
|
3409
3488
|
entryId,
|
|
3410
|
-
referenceField
|
|
3489
|
+
referenceField,
|
|
3490
|
+
linkHref
|
|
3411
3491
|
}) => {
|
|
3412
3492
|
const safeHref = href ? safeEditUrl(href) : null;
|
|
3413
3493
|
if (href && !safeHref) {
|
|
@@ -3421,7 +3501,8 @@ function createPreprPreview(opts = {}) {
|
|
|
3421
3501
|
locale: contentLocale,
|
|
3422
3502
|
...block !== void 0 && { block },
|
|
3423
3503
|
...entryId && { entryId },
|
|
3424
|
-
...referenceField && { referenceField }
|
|
3504
|
+
...referenceField && { referenceField },
|
|
3505
|
+
...linkHref && { linkHref }
|
|
3425
3506
|
});
|
|
3426
3507
|
} else if (safeHref) {
|
|
3427
3508
|
window.open(safeHref, "_blank", "noopener,noreferrer");
|
|
@@ -3476,6 +3557,7 @@ function createPreprPreview(opts = {}) {
|
|
|
3476
3557
|
},
|
|
3477
3558
|
onAssets: (assets) => visualEditor?.setAssets(assets),
|
|
3478
3559
|
onAllowNavigation: (href) => visualEditor?.allowNavigation(href),
|
|
3560
|
+
onItemChanged: () => visualEditor?.itemSaved(),
|
|
3479
3561
|
onReferences: (referencedIds, componentIds) => visualEditor?.setReferences(referencedIds, componentIds),
|
|
3480
3562
|
// The editor selecting a field scrolls the matching element into view. The
|
|
3481
3563
|
// lookup relies on the attributes the stega scan writes, so it finds
|
|
@@ -3516,7 +3598,7 @@ function createPreprPreview(opts = {}) {
|
|
|
3516
3598
|
}
|
|
3517
3599
|
|
|
3518
3600
|
// src/version.ts
|
|
3519
|
-
var VERSION = "0.5.0-rc.
|
|
3601
|
+
var VERSION = "0.5.0-rc.12";
|
|
3520
3602
|
|
|
3521
3603
|
// src/core/pixel.ts
|
|
3522
3604
|
var PIXEL_SCRIPT_URL = "https://cdn.tracking.prepr.io/js/prepr.min.js";
|
package/dist/sveltekit/index.cjs
CHANGED
package/dist/sveltekit/index.js
CHANGED
|
@@ -160,8 +160,32 @@ function shapeLike(template, incoming) {
|
|
|
160
160
|
}
|
|
161
161
|
return out;
|
|
162
162
|
}
|
|
163
|
+
function isAsset(value) {
|
|
164
|
+
return isPlainObject(value) && (typeof value.url === "string" || value.__typename === "Asset");
|
|
165
|
+
}
|
|
166
|
+
function hasId(list, entry) {
|
|
167
|
+
return entry._id !== void 0 && list.some((c) => isPlainObject(c) && c._id === entry._id);
|
|
168
|
+
}
|
|
169
|
+
function isAssetValue(value) {
|
|
170
|
+
return Array.isArray(value) ? value.length > 0 && value.every(isAsset) : isAsset(value);
|
|
171
|
+
}
|
|
172
|
+
function keepRemovedAssets(current, next) {
|
|
173
|
+
const listed = /* @__PURE__ */ new Set();
|
|
174
|
+
for (const entry of next) {
|
|
175
|
+
if (isPlainObject(entry) && entry._id !== void 0) listed.add(entry._id);
|
|
176
|
+
}
|
|
177
|
+
let out = next;
|
|
178
|
+
current.forEach((entry, position) => {
|
|
179
|
+
if (!isPlainObject(entry) || entry._id === void 0) return;
|
|
180
|
+
if (listed.has(entry._id)) return;
|
|
181
|
+
if (out === next) out = [...next];
|
|
182
|
+
out.splice(Math.min(position, out.length), 0, entry);
|
|
183
|
+
});
|
|
184
|
+
return out;
|
|
185
|
+
}
|
|
163
186
|
function mergeStructured(current, incoming) {
|
|
164
187
|
if (incoming === null || Array.isArray(incoming) && !incoming.length) {
|
|
188
|
+
if (isAssetValue(current)) return current;
|
|
165
189
|
if (Array.isArray(current)) return current.length ? [] : current;
|
|
166
190
|
return null;
|
|
167
191
|
}
|
|
@@ -169,13 +193,18 @@ function mergeStructured(current, incoming) {
|
|
|
169
193
|
if (current === null || current === void 0) return incoming;
|
|
170
194
|
if (Array.isArray(current)) {
|
|
171
195
|
const template = current.find(isPlainObject);
|
|
172
|
-
|
|
196
|
+
const next = list.map((entry) => {
|
|
173
197
|
const match = current.find(
|
|
174
198
|
(c) => isPlainObject(c) && c._id !== void 0 && c._id === entry._id
|
|
175
199
|
);
|
|
176
200
|
if (isPlainObject(match)) return mergeObject(match, entry);
|
|
177
201
|
return isPlainObject(template) ? shapeLike(template, entry) : entry;
|
|
178
202
|
});
|
|
203
|
+
if (!isAssetValue(current) || list.some((entry) => !hasId(current, entry))) {
|
|
204
|
+
return next;
|
|
205
|
+
}
|
|
206
|
+
const kept = keepRemovedAssets(current, next);
|
|
207
|
+
return kept.length === current.length && kept.every((entry, i) => entry === current[i]) ? current : kept;
|
|
179
208
|
}
|
|
180
209
|
if (isPlainObject(current)) return mergeObject(current, list[0]);
|
|
181
210
|
return current;
|