@preprio/toolkit 0.4.3 → 0.5.0-rc.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/astro/index.cjs +1 -1
- package/dist/astro/index.js +1 -1
- package/dist/{chunk-H7VA7NGY.js → chunk-4JNKYIEV.js} +90 -12
- package/dist/index.cjs +110 -32
- package/dist/index.d.cts +12 -1
- package/dist/index.d.ts +12 -1
- package/dist/index.js +1 -1
- package/dist/nextjs/components.cjs +110 -32
- package/dist/nextjs/components.js +1 -1
- package/dist/nextjs/index.cjs +1 -1
- package/dist/nextjs/index.js +1 -1
- package/dist/nuxt/index.cjs +1 -1
- package/dist/nuxt/index.js +1 -1
- package/dist/react/components.cjs +110 -32
- package/dist/react/components.js +110 -32
- package/dist/sveltekit/index.cjs +1 -1
- package/dist/sveltekit/index.js +1 -1
- package/package.json +1 -1
|
@@ -292,6 +292,7 @@ function createElementCache(query, ttl = 1e3) {
|
|
|
292
292
|
}
|
|
293
293
|
|
|
294
294
|
// src/core/iframe-bridge.ts
|
|
295
|
+
var debug = createScopedLogger("iframe-bridge");
|
|
295
296
|
var EDITOR_BASE_DOMAIN = "prepr.io";
|
|
296
297
|
function isAllowedEditorOrigin(origin, allowed) {
|
|
297
298
|
if (allowed) return allowed.includes(origin);
|
|
@@ -309,6 +310,7 @@ function isAllowedEditorOrigin(origin, allowed) {
|
|
|
309
310
|
}
|
|
310
311
|
function createIframeBridge(store, options = {}) {
|
|
311
312
|
const allowedOrigins = options.allowedEditorOrigins;
|
|
313
|
+
const onScrollToField = options.onScrollToField;
|
|
312
314
|
let parentOrigin = null;
|
|
313
315
|
const onKeyDown = (event) => {
|
|
314
316
|
const key = event.key.toLowerCase();
|
|
@@ -332,6 +334,15 @@ function createIframeBridge(store, options = {}) {
|
|
|
332
334
|
const currentScrollY = window.scrollY || document.documentElement.scrollTop;
|
|
333
335
|
sendPreprEvent("getScrollPosition", { value: currentScrollY });
|
|
334
336
|
}
|
|
337
|
+
if (data?.event === "prepr:scrollToField") {
|
|
338
|
+
if (typeof data.field !== "string" || !data.field) return;
|
|
339
|
+
if (data.id !== void 0 && typeof data.id !== "string") return;
|
|
340
|
+
try {
|
|
341
|
+
onScrollToField?.({ field: data.field, id: data.id });
|
|
342
|
+
} catch (error) {
|
|
343
|
+
debug.warn("scrollToField handler failed", error);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
335
346
|
};
|
|
336
347
|
return {
|
|
337
348
|
start() {
|
|
@@ -356,7 +367,7 @@ var import_stega2 = require("@vercel/stega");
|
|
|
356
367
|
|
|
357
368
|
// src/core/stega/clean.ts
|
|
358
369
|
var import_stega = require("@vercel/stega");
|
|
359
|
-
var
|
|
370
|
+
var debug2 = createScopedLogger("stega:clean");
|
|
360
371
|
function decodeStega(str) {
|
|
361
372
|
if (!str) return null;
|
|
362
373
|
try {
|
|
@@ -365,7 +376,7 @@ function decodeStega(str) {
|
|
|
365
376
|
return decoded;
|
|
366
377
|
}
|
|
367
378
|
} catch (error) {
|
|
368
|
-
|
|
379
|
+
debug2.log("error decoding stega data", error);
|
|
369
380
|
const match = str.match(/{"origin.*?}/);
|
|
370
381
|
if (match) {
|
|
371
382
|
try {
|
|
@@ -374,7 +385,7 @@ function decodeStega(str) {
|
|
|
374
385
|
return decodedMatch;
|
|
375
386
|
}
|
|
376
387
|
} catch (innerError) {
|
|
377
|
-
|
|
388
|
+
debug2.log("error decoding stega regex match", innerError);
|
|
378
389
|
}
|
|
379
390
|
}
|
|
380
391
|
}
|
|
@@ -410,14 +421,37 @@ function isRenderedElement(element) {
|
|
|
410
421
|
if (!style) return true;
|
|
411
422
|
return style.visibility !== "hidden" && style.display !== "none";
|
|
412
423
|
}
|
|
424
|
+
function parseEditHref(href) {
|
|
425
|
+
try {
|
|
426
|
+
const url = new URL(href, window.location.origin);
|
|
427
|
+
return {
|
|
428
|
+
id: url.pathname.split("/").pop() || void 0,
|
|
429
|
+
field: url.searchParams.get("field") || void 0,
|
|
430
|
+
locale: url.searchParams.get("locale") || void 0
|
|
431
|
+
};
|
|
432
|
+
} catch {
|
|
433
|
+
return {};
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
function setOrRemove(element, name, value) {
|
|
437
|
+
if (value) {
|
|
438
|
+
element.setAttribute(name, value);
|
|
439
|
+
} else {
|
|
440
|
+
element.removeAttribute(name);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
413
443
|
function tagEncodedElement(element, decoded) {
|
|
414
444
|
element.setAttribute("data-prepr-encoded", "");
|
|
415
445
|
element.setAttribute("data-prepr-href", decoded.href);
|
|
416
446
|
element.setAttribute("data-prepr-origin", decoded.origin);
|
|
447
|
+
const { id, field, locale } = parseEditHref(decoded.href);
|
|
448
|
+
setOrRemove(element, "data-prepr-id", id);
|
|
449
|
+
setOrRemove(element, "data-prepr-field", field);
|
|
450
|
+
setOrRemove(element, "data-prepr-locale", locale);
|
|
417
451
|
}
|
|
418
452
|
|
|
419
453
|
// src/core/stega/auto-clean.ts
|
|
420
|
-
var
|
|
454
|
+
var debug3 = createScopedLogger("stega:auto-clean");
|
|
421
455
|
function createStegaAutoClean(options) {
|
|
422
456
|
const stripText = options?.enabled ?? true;
|
|
423
457
|
let observer = null;
|
|
@@ -460,7 +494,7 @@ function createStegaAutoClean(options) {
|
|
|
460
494
|
}
|
|
461
495
|
pendingHidden.add(textNode);
|
|
462
496
|
} catch (error) {
|
|
463
|
-
|
|
497
|
+
debug3.log("error cleaning text node", error);
|
|
464
498
|
}
|
|
465
499
|
return false;
|
|
466
500
|
}
|
|
@@ -546,7 +580,7 @@ function createStegaAutoClean(options) {
|
|
|
546
580
|
if (observer || typeof window === "undefined") return;
|
|
547
581
|
scanAndClean();
|
|
548
582
|
setupObserver();
|
|
549
|
-
|
|
583
|
+
debug3.log("stega auto-clean started");
|
|
550
584
|
}
|
|
551
585
|
function stop() {
|
|
552
586
|
if (debounceTimeout) {
|
|
@@ -560,13 +594,13 @@ function createStegaAutoClean(options) {
|
|
|
560
594
|
cleaned = /* @__PURE__ */ new WeakMap();
|
|
561
595
|
pendingHidden = /* @__PURE__ */ new Set();
|
|
562
596
|
pendingDirty = /* @__PURE__ */ new Set();
|
|
563
|
-
|
|
597
|
+
debug3.log("stega auto-clean stopped");
|
|
564
598
|
}
|
|
565
599
|
return { start, stop };
|
|
566
600
|
}
|
|
567
601
|
|
|
568
602
|
// src/core/stega/elements.ts
|
|
569
|
-
var
|
|
603
|
+
var debug4 = createScopedLogger("stega:elements");
|
|
570
604
|
var StegaElements = class {
|
|
571
605
|
constructor(decode = decodeStega) {
|
|
572
606
|
this.observer = null;
|
|
@@ -611,7 +645,7 @@ var StegaElements = class {
|
|
|
611
645
|
walkTextNodes(document.body, (textNode) => {
|
|
612
646
|
if (this.tagFromTextNode(textNode)) encodedCount++;
|
|
613
647
|
});
|
|
614
|
-
|
|
648
|
+
debug4.log("document scan complete, encoded", encodedCount, "elements");
|
|
615
649
|
this.elements = document.querySelectorAll("[data-prepr-encoded]");
|
|
616
650
|
}
|
|
617
651
|
/** `onUpdate` fires after each debounced batch, for refreshing derived state. */
|
|
@@ -667,6 +701,9 @@ var StegaElements = class {
|
|
|
667
701
|
element.removeAttribute("data-prepr-encoded");
|
|
668
702
|
element.removeAttribute("data-prepr-href");
|
|
669
703
|
element.removeAttribute("data-prepr-origin");
|
|
704
|
+
element.removeAttribute("data-prepr-id");
|
|
705
|
+
element.removeAttribute("data-prepr-field");
|
|
706
|
+
element.removeAttribute("data-prepr-locale");
|
|
670
707
|
element.classList.remove("prepr-overlay-active");
|
|
671
708
|
});
|
|
672
709
|
this.elements = void 0;
|
|
@@ -674,7 +711,7 @@ var StegaElements = class {
|
|
|
674
711
|
};
|
|
675
712
|
|
|
676
713
|
// src/core/stega/overlay.ts
|
|
677
|
-
var
|
|
714
|
+
var debug5 = createScopedLogger("stega:overlay");
|
|
678
715
|
var StegaOverlay = class {
|
|
679
716
|
constructor(onEdit) {
|
|
680
717
|
this.overlay = null;
|
|
@@ -719,7 +756,8 @@ var StegaOverlay = class {
|
|
|
719
756
|
const origin = element.getAttribute("data-prepr-origin");
|
|
720
757
|
const id = element.getAttribute("data-prepr-id") ?? void 0;
|
|
721
758
|
const field = element.getAttribute("data-prepr-field") ?? void 0;
|
|
722
|
-
|
|
759
|
+
const locale = element.getAttribute("data-prepr-locale") ?? void 0;
|
|
760
|
+
debug5.log("showing overlay", { href, origin });
|
|
723
761
|
const overlay = this.overlay;
|
|
724
762
|
overlay.style.display = "block";
|
|
725
763
|
overlay.style.top = `${rect.top + window.scrollY - 2}px`;
|
|
@@ -751,7 +789,7 @@ var StegaOverlay = class {
|
|
|
751
789
|
tooltip.style.left = `${left}px`;
|
|
752
790
|
});
|
|
753
791
|
tooltip.onclick = () => {
|
|
754
|
-
this.onEdit({ href, origin, id, field });
|
|
792
|
+
this.onEdit({ href, origin, id, field, locale });
|
|
755
793
|
};
|
|
756
794
|
}
|
|
757
795
|
this.currentElement = element;
|
|
@@ -791,7 +829,7 @@ var StegaOverlay = class {
|
|
|
791
829
|
};
|
|
792
830
|
|
|
793
831
|
// src/core/stega/proximity.ts
|
|
794
|
-
var
|
|
832
|
+
var debug6 = createScopedLogger("stega:proximity");
|
|
795
833
|
var StegaProximity = class {
|
|
796
834
|
constructor() {
|
|
797
835
|
this.highlighted = /* @__PURE__ */ new Set();
|
|
@@ -826,9 +864,9 @@ var StegaProximity = class {
|
|
|
826
864
|
);
|
|
827
865
|
const nodes = this.getEncodedElements();
|
|
828
866
|
nodes.forEach((el) => this.observer.observe(el));
|
|
829
|
-
|
|
867
|
+
debug6.log("observing", nodes.length, "encoded elements");
|
|
830
868
|
} catch (error) {
|
|
831
|
-
|
|
869
|
+
debug6.log("error setting up IntersectionObserver", error);
|
|
832
870
|
}
|
|
833
871
|
}
|
|
834
872
|
stopObserving() {
|
|
@@ -898,7 +936,7 @@ function removeStegaStyles() {
|
|
|
898
936
|
}
|
|
899
937
|
|
|
900
938
|
// src/core/stega/scan.ts
|
|
901
|
-
var
|
|
939
|
+
var debug7 = createScopedLogger("stega:scan");
|
|
902
940
|
var EDITOR_MODE_STYLES = "[data-prepr-encoded]{cursor:pointer}";
|
|
903
941
|
function createStegaController(opts) {
|
|
904
942
|
const tooltipEnabled = opts.tooltip ?? true;
|
|
@@ -931,12 +969,13 @@ function createStegaController(opts) {
|
|
|
931
969
|
href: encoded.getAttribute("data-prepr-href") ?? "",
|
|
932
970
|
origin: encoded.getAttribute("data-prepr-origin") ?? "",
|
|
933
971
|
id: encoded.getAttribute("data-prepr-id") ?? void 0,
|
|
934
|
-
field: encoded.getAttribute("data-prepr-field") ?? void 0
|
|
972
|
+
field: encoded.getAttribute("data-prepr-field") ?? void 0,
|
|
973
|
+
locale: encoded.getAttribute("data-prepr-locale") ?? void 0
|
|
935
974
|
});
|
|
936
975
|
};
|
|
937
976
|
const start = () => {
|
|
938
977
|
if (initialized) {
|
|
939
|
-
|
|
978
|
+
debug7.log("already initialized, skipping setup");
|
|
940
979
|
return;
|
|
941
980
|
}
|
|
942
981
|
if (!tooltipEnabled) {
|
|
@@ -946,7 +985,7 @@ function createStegaController(opts) {
|
|
|
946
985
|
});
|
|
947
986
|
document.addEventListener("click", handleClick, { capture: true });
|
|
948
987
|
initialized = true;
|
|
949
|
-
|
|
988
|
+
debug7.log("stega controller started (editor mode)");
|
|
950
989
|
return;
|
|
951
990
|
}
|
|
952
991
|
injectStegaStyles();
|
|
@@ -977,7 +1016,7 @@ function createStegaController(opts) {
|
|
|
977
1016
|
passive: true
|
|
978
1017
|
});
|
|
979
1018
|
initialized = true;
|
|
980
|
-
|
|
1019
|
+
debug7.log("stega controller started");
|
|
981
1020
|
};
|
|
982
1021
|
const stop = () => {
|
|
983
1022
|
if (!initialized) return;
|
|
@@ -986,7 +1025,7 @@ function createStegaController(opts) {
|
|
|
986
1025
|
elements.cleanup();
|
|
987
1026
|
removeStegaStyles();
|
|
988
1027
|
initialized = false;
|
|
989
|
-
|
|
1028
|
+
debug7.log("stega controller stopped (editor mode)");
|
|
990
1029
|
return;
|
|
991
1030
|
}
|
|
992
1031
|
if (throttledMouseMove) {
|
|
@@ -1006,11 +1045,43 @@ function createStegaController(opts) {
|
|
|
1006
1045
|
elements.cleanup();
|
|
1007
1046
|
removeStegaStyles();
|
|
1008
1047
|
initialized = false;
|
|
1009
|
-
|
|
1048
|
+
debug7.log("stega controller stopped");
|
|
1010
1049
|
};
|
|
1011
1050
|
return { start, stop };
|
|
1012
1051
|
}
|
|
1013
1052
|
|
|
1053
|
+
// src/core/stega/scroll-to-field.ts
|
|
1054
|
+
var debug8 = createScopedLogger("stega:scroll");
|
|
1055
|
+
var FLASH_DURATION_MS = 1200;
|
|
1056
|
+
var flashTimeout = null;
|
|
1057
|
+
function scrollToField(request) {
|
|
1058
|
+
const { field, id } = request;
|
|
1059
|
+
if (!field) return false;
|
|
1060
|
+
const candidates = document.querySelectorAll(
|
|
1061
|
+
"[data-prepr-encoded]"
|
|
1062
|
+
);
|
|
1063
|
+
let target = null;
|
|
1064
|
+
for (const candidate of candidates) {
|
|
1065
|
+
if (candidate.getAttribute("data-prepr-field") !== field) continue;
|
|
1066
|
+
if (id && candidate.getAttribute("data-prepr-id") !== id) continue;
|
|
1067
|
+
target = candidate;
|
|
1068
|
+
break;
|
|
1069
|
+
}
|
|
1070
|
+
if (!target) {
|
|
1071
|
+
debug8.log("no element found for field", field);
|
|
1072
|
+
return false;
|
|
1073
|
+
}
|
|
1074
|
+
target.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
1075
|
+
if (flashTimeout) clearTimeout(flashTimeout);
|
|
1076
|
+
document.querySelectorAll(".prepr-overlay-active").forEach((el) => el.classList.remove("prepr-overlay-active"));
|
|
1077
|
+
target.classList.add("prepr-overlay-active");
|
|
1078
|
+
flashTimeout = setTimeout(() => {
|
|
1079
|
+
target.classList.remove("prepr-overlay-active");
|
|
1080
|
+
flashTimeout = null;
|
|
1081
|
+
}, FLASH_DURATION_MS);
|
|
1082
|
+
return true;
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1014
1085
|
// src/core/store.ts
|
|
1015
1086
|
var DEFAULT_STATE = {
|
|
1016
1087
|
locale: "en",
|
|
@@ -2123,7 +2194,7 @@ function definePreprToolbar() {
|
|
|
2123
2194
|
}
|
|
2124
2195
|
|
|
2125
2196
|
// src/core/create-preview.ts
|
|
2126
|
-
var
|
|
2197
|
+
var debug9 = createScopedLogger("create-preview");
|
|
2127
2198
|
var controllerStores = /* @__PURE__ */ new WeakMap();
|
|
2128
2199
|
function defaultNavigation() {
|
|
2129
2200
|
return {
|
|
@@ -2165,7 +2236,7 @@ function createPreprPreview(opts = {}) {
|
|
|
2165
2236
|
const search = new URLSearchParams(window.location.search);
|
|
2166
2237
|
const hideBar = search.get(PARAM_HIDE_BAR) === "true";
|
|
2167
2238
|
if (hideBar) {
|
|
2168
|
-
|
|
2239
|
+
debug9.log(`${PARAM_HIDE_BAR}=true \u2014 no visible toolbar`);
|
|
2169
2240
|
}
|
|
2170
2241
|
const mountUi = (options?.ui ?? true) && !isIframe && !hideBar;
|
|
2171
2242
|
const locale = resolveLocale(options);
|
|
@@ -2201,18 +2272,17 @@ function createPreprPreview(opts = {}) {
|
|
|
2201
2272
|
tooltip: mountUi,
|
|
2202
2273
|
// In the editor, ask the parent to focus the field instead of opening a new
|
|
2203
2274
|
// tab. Standalone previews keep the window.open behaviour.
|
|
2204
|
-
onEdit: ({ href,
|
|
2275
|
+
onEdit: ({ href, id, field, locale: contentLocale }) => {
|
|
2205
2276
|
const safeHref = href ? safeEditUrl(href) : null;
|
|
2206
2277
|
if (href && !safeHref) {
|
|
2207
|
-
|
|
2278
|
+
debug9.warn("ignored edit request with unsupported href scheme");
|
|
2208
2279
|
return;
|
|
2209
2280
|
}
|
|
2210
2281
|
if (isIframe) {
|
|
2211
2282
|
sendPreprEvent("field_edit_requested", {
|
|
2212
|
-
href: safeHref ?? void 0,
|
|
2213
|
-
origin,
|
|
2214
2283
|
id,
|
|
2215
|
-
field
|
|
2284
|
+
field,
|
|
2285
|
+
locale: contentLocale
|
|
2216
2286
|
});
|
|
2217
2287
|
} else if (safeHref) {
|
|
2218
2288
|
window.open(safeHref, "_blank", "noopener,noreferrer");
|
|
@@ -2239,7 +2309,15 @@ function createPreprPreview(opts = {}) {
|
|
|
2239
2309
|
handleChange(before, state);
|
|
2240
2310
|
});
|
|
2241
2311
|
const bridge = createIframeBridge(store, {
|
|
2242
|
-
allowedEditorOrigins: options?.allowedEditorOrigins
|
|
2312
|
+
allowedEditorOrigins: options?.allowedEditorOrigins,
|
|
2313
|
+
// The editor selecting a field scrolls the matching element into view. The
|
|
2314
|
+
// lookup relies on the attributes the stega scan writes, so it finds
|
|
2315
|
+
// nothing until encoded content has been tagged.
|
|
2316
|
+
onScrollToField: ({ field, id }) => {
|
|
2317
|
+
if (!scrollToField({ field, id })) {
|
|
2318
|
+
debug9.log("no element on this page renders field", field);
|
|
2319
|
+
}
|
|
2320
|
+
}
|
|
2243
2321
|
});
|
|
2244
2322
|
sendPreprEvent(
|
|
2245
2323
|
"getScrollPosition",
|
|
@@ -2259,7 +2337,7 @@ function createPreprPreview(opts = {}) {
|
|
|
2259
2337
|
bridge.stop();
|
|
2260
2338
|
}
|
|
2261
2339
|
el?.remove();
|
|
2262
|
-
|
|
2340
|
+
debug9.log("preview destroyed");
|
|
2263
2341
|
}
|
|
2264
2342
|
const controller = { destroy };
|
|
2265
2343
|
controllerStores.set(controller, store);
|
|
@@ -2270,7 +2348,7 @@ function createPreprPreview(opts = {}) {
|
|
|
2270
2348
|
var import_react = require("react");
|
|
2271
2349
|
|
|
2272
2350
|
// src/version.ts
|
|
2273
|
-
var VERSION = "0.
|
|
2351
|
+
var VERSION = "0.5.0-rc.1";
|
|
2274
2352
|
|
|
2275
2353
|
// src/core/pixel.ts
|
|
2276
2354
|
var PIXEL_SCRIPT_URL = "https://cdn.tracking.prepr.io/js/prepr.min.js";
|
package/dist/nextjs/index.cjs
CHANGED
package/dist/nextjs/index.js
CHANGED
package/dist/nuxt/index.cjs
CHANGED
package/dist/nuxt/index.js
CHANGED