@preprio/toolkit 0.5.0-rc.1 → 0.6.0-alpha.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/README.md +300 -19
- package/dist/astro/chunk-3UVUDDNY.js +173 -0
- package/dist/astro/graphql.cjs +983 -0
- package/dist/astro/graphql.d.cts +231 -0
- package/dist/astro/graphql.d.ts +231 -0
- package/dist/astro/graphql.js +893 -0
- package/dist/astro/index-XT_z-RYT.d.cts +130 -0
- package/dist/astro/index-XT_z-RYT.d.ts +130 -0
- package/dist/astro/index.cjs +14 -1
- package/dist/astro/index.d.cts +1 -120
- package/dist/astro/index.d.ts +1 -120
- package/dist/astro/index.js +15 -153
- package/dist/{chunk-4JNKYIEV.js → chunk-BJ2LBLWO.js} +69 -268
- package/dist/chunk-DGZA7KX7.js +172 -0
- package/dist/chunk-YR7P4IWE.js +187 -0
- package/dist/graphql.cjs +894 -0
- package/dist/graphql.d.cts +231 -0
- package/dist/graphql.d.ts +231 -0
- package/dist/graphql.js +787 -0
- package/dist/index.cjs +74 -111
- package/dist/index.d.cts +11 -62
- package/dist/index.d.ts +11 -62
- package/dist/index.js +23 -167
- package/dist/nextjs/chunk-U4HXENF7.js +231 -0
- package/dist/nextjs/components.cjs +188 -114
- package/dist/nextjs/components.d.cts +33 -2
- package/dist/nextjs/components.d.ts +33 -2
- package/dist/nextjs/components.js +132 -4
- package/dist/nextjs/graphql.cjs +1315 -0
- package/dist/nextjs/graphql.d.cts +361 -0
- package/dist/nextjs/graphql.d.ts +361 -0
- package/dist/nextjs/graphql.js +1218 -0
- package/dist/nextjs/index.cjs +126 -6
- package/dist/nextjs/index.d.cts +53 -141
- package/dist/nextjs/index.d.ts +53 -141
- package/dist/nextjs/index.js +113 -203
- package/dist/nextjs/server-CjpELYvq.d.cts +156 -0
- package/dist/nextjs/server-CjpELYvq.d.ts +156 -0
- package/dist/nuxt/chunk-P6ENNAEE.js +417 -0
- package/dist/nuxt/graphql.cjs +990 -0
- package/dist/nuxt/graphql.d.cts +228 -0
- package/dist/nuxt/graphql.d.ts +228 -0
- package/dist/nuxt/graphql.js +894 -0
- package/dist/nuxt/index.cjs +14 -1
- package/dist/nuxt/index.d.cts +3 -148
- package/dist/nuxt/index.d.ts +3 -148
- package/dist/nuxt/index.js +15 -391
- package/dist/nuxt/server-8v6OHbsw.d.cts +158 -0
- package/dist/nuxt/server-8v6OHbsw.d.ts +158 -0
- package/dist/pixel-DwW7cXJm.d.cts +49 -0
- package/dist/pixel-DwW7cXJm.d.ts +49 -0
- package/dist/react/components.cjs +86 -112
- package/dist/react/components.js +86 -112
- package/dist/server-Brr1UgtW.d.ts +59 -0
- package/dist/server-DJuS3YU0.d.cts +59 -0
- package/dist/sveltekit/chunk-FSARVMG5.js +413 -0
- package/dist/sveltekit/graphql.cjs +996 -0
- package/dist/sveltekit/graphql.d.cts +233 -0
- package/dist/sveltekit/graphql.d.ts +233 -0
- package/dist/sveltekit/graphql.js +900 -0
- package/dist/sveltekit/index.cjs +14 -1
- package/dist/sveltekit/index.d.cts +3 -88
- package/dist/sveltekit/index.d.ts +3 -88
- package/dist/sveltekit/index.js +15 -387
- package/dist/sveltekit/server-CO847mEV.d.cts +98 -0
- package/dist/sveltekit/server-CO847mEV.d.ts +98 -0
- package/dist/{pixel-e1fUWl2Y.d.cts → types-BYH9XqmN.d.cts} +2 -50
- package/dist/{pixel-e1fUWl2Y.d.ts → types-BYH9XqmN.d.ts} +2 -50
- package/package.json +31 -1
|
@@ -21,8 +21,10 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
// src/nextjs/components.ts
|
|
22
22
|
var components_exports = {};
|
|
23
23
|
__export(components_exports, {
|
|
24
|
+
PreprAbSwitch: () => PreprAbSwitch,
|
|
24
25
|
PreprToolbar: () => PreprToolbar,
|
|
25
|
-
PreprTrackingPixel: () => PreprTrackingPixel
|
|
26
|
+
PreprTrackingPixel: () => PreprTrackingPixel,
|
|
27
|
+
PreprVariantTracking: () => PreprVariantTracking
|
|
26
28
|
});
|
|
27
29
|
module.exports = __toCommonJS(components_exports);
|
|
28
30
|
var import_navigation = require("next/navigation");
|
|
@@ -292,7 +294,6 @@ function createElementCache(query, ttl = 1e3) {
|
|
|
292
294
|
}
|
|
293
295
|
|
|
294
296
|
// src/core/iframe-bridge.ts
|
|
295
|
-
var debug = createScopedLogger("iframe-bridge");
|
|
296
297
|
var EDITOR_BASE_DOMAIN = "prepr.io";
|
|
297
298
|
function isAllowedEditorOrigin(origin, allowed) {
|
|
298
299
|
if (allowed) return allowed.includes(origin);
|
|
@@ -310,7 +311,6 @@ function isAllowedEditorOrigin(origin, allowed) {
|
|
|
310
311
|
}
|
|
311
312
|
function createIframeBridge(store, options = {}) {
|
|
312
313
|
const allowedOrigins = options.allowedEditorOrigins;
|
|
313
|
-
const onScrollToField = options.onScrollToField;
|
|
314
314
|
let parentOrigin = null;
|
|
315
315
|
const onKeyDown = (event) => {
|
|
316
316
|
const key = event.key.toLowerCase();
|
|
@@ -334,15 +334,6 @@ function createIframeBridge(store, options = {}) {
|
|
|
334
334
|
const currentScrollY = window.scrollY || document.documentElement.scrollTop;
|
|
335
335
|
sendPreprEvent("getScrollPosition", { value: currentScrollY });
|
|
336
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
|
-
}
|
|
346
337
|
};
|
|
347
338
|
return {
|
|
348
339
|
start() {
|
|
@@ -367,7 +358,7 @@ var import_stega2 = require("@vercel/stega");
|
|
|
367
358
|
|
|
368
359
|
// src/core/stega/clean.ts
|
|
369
360
|
var import_stega = require("@vercel/stega");
|
|
370
|
-
var
|
|
361
|
+
var debug = createScopedLogger("stega:clean");
|
|
371
362
|
function decodeStega(str) {
|
|
372
363
|
if (!str) return null;
|
|
373
364
|
try {
|
|
@@ -376,7 +367,7 @@ function decodeStega(str) {
|
|
|
376
367
|
return decoded;
|
|
377
368
|
}
|
|
378
369
|
} catch (error) {
|
|
379
|
-
|
|
370
|
+
debug.log("error decoding stega data", error);
|
|
380
371
|
const match = str.match(/{"origin.*?}/);
|
|
381
372
|
if (match) {
|
|
382
373
|
try {
|
|
@@ -385,7 +376,7 @@ function decodeStega(str) {
|
|
|
385
376
|
return decodedMatch;
|
|
386
377
|
}
|
|
387
378
|
} catch (innerError) {
|
|
388
|
-
|
|
379
|
+
debug.log("error decoding stega regex match", innerError);
|
|
389
380
|
}
|
|
390
381
|
}
|
|
391
382
|
}
|
|
@@ -421,37 +412,15 @@ function isRenderedElement(element) {
|
|
|
421
412
|
if (!style) return true;
|
|
422
413
|
return style.visibility !== "hidden" && style.display !== "none";
|
|
423
414
|
}
|
|
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
|
-
}
|
|
443
415
|
function tagEncodedElement(element, decoded) {
|
|
444
416
|
element.setAttribute("data-prepr-encoded", "");
|
|
445
417
|
element.setAttribute("data-prepr-href", decoded.href);
|
|
446
418
|
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);
|
|
451
419
|
}
|
|
452
420
|
|
|
453
421
|
// src/core/stega/auto-clean.ts
|
|
454
|
-
var
|
|
422
|
+
var debug2 = createScopedLogger("stega:auto-clean");
|
|
423
|
+
var HYDRATION_RETRY_MS = 100;
|
|
455
424
|
function createStegaAutoClean(options) {
|
|
456
425
|
const stripText = options?.enabled ?? true;
|
|
457
426
|
let observer = null;
|
|
@@ -460,8 +429,29 @@ function createStegaAutoClean(options) {
|
|
|
460
429
|
let pendingHidden = /* @__PURE__ */ new Set();
|
|
461
430
|
let pendingDirty = /* @__PURE__ */ new Set();
|
|
462
431
|
let debounceTimeout = null;
|
|
432
|
+
const isHydrated = options?.isHydrated;
|
|
433
|
+
let pendingHydration = /* @__PURE__ */ new Set();
|
|
434
|
+
let hydrationTimeout = null;
|
|
435
|
+
function retryPendingHydration() {
|
|
436
|
+
hydrationTimeout = null;
|
|
437
|
+
processing = true;
|
|
438
|
+
const batch = [...pendingHydration];
|
|
439
|
+
pendingHydration.clear();
|
|
440
|
+
batch.forEach((textNode) => {
|
|
441
|
+
if (textNode.isConnected) cleanTextNode(textNode);
|
|
442
|
+
});
|
|
443
|
+
processing = false;
|
|
444
|
+
}
|
|
463
445
|
function cleanTextNode(textNode) {
|
|
464
446
|
if (isIgnoredTextNode(textNode)) return false;
|
|
447
|
+
if (isHydrated && !isHydrated(textNode)) {
|
|
448
|
+
pendingHydration.add(textNode);
|
|
449
|
+
hydrationTimeout ?? (hydrationTimeout = setTimeout(
|
|
450
|
+
retryPendingHydration,
|
|
451
|
+
HYDRATION_RETRY_MS
|
|
452
|
+
));
|
|
453
|
+
return false;
|
|
454
|
+
}
|
|
465
455
|
const textContent = textNode.textContent;
|
|
466
456
|
const info = cleaned.get(textNode);
|
|
467
457
|
const settled = stripText ? info?.cleaned : info?.original;
|
|
@@ -494,7 +484,7 @@ function createStegaAutoClean(options) {
|
|
|
494
484
|
}
|
|
495
485
|
pendingHidden.add(textNode);
|
|
496
486
|
} catch (error) {
|
|
497
|
-
|
|
487
|
+
debug2.log("error cleaning text node", error);
|
|
498
488
|
}
|
|
499
489
|
return false;
|
|
500
490
|
}
|
|
@@ -580,13 +570,17 @@ function createStegaAutoClean(options) {
|
|
|
580
570
|
if (observer || typeof window === "undefined") return;
|
|
581
571
|
scanAndClean();
|
|
582
572
|
setupObserver();
|
|
583
|
-
|
|
573
|
+
debug2.log("stega auto-clean started");
|
|
584
574
|
}
|
|
585
575
|
function stop() {
|
|
586
576
|
if (debounceTimeout) {
|
|
587
577
|
clearTimeout(debounceTimeout);
|
|
588
578
|
debounceTimeout = null;
|
|
589
579
|
}
|
|
580
|
+
if (hydrationTimeout) {
|
|
581
|
+
clearTimeout(hydrationTimeout);
|
|
582
|
+
hydrationTimeout = null;
|
|
583
|
+
}
|
|
590
584
|
if (observer) {
|
|
591
585
|
observer.disconnect();
|
|
592
586
|
observer = null;
|
|
@@ -594,13 +588,14 @@ function createStegaAutoClean(options) {
|
|
|
594
588
|
cleaned = /* @__PURE__ */ new WeakMap();
|
|
595
589
|
pendingHidden = /* @__PURE__ */ new Set();
|
|
596
590
|
pendingDirty = /* @__PURE__ */ new Set();
|
|
597
|
-
|
|
591
|
+
pendingHydration = /* @__PURE__ */ new Set();
|
|
592
|
+
debug2.log("stega auto-clean stopped");
|
|
598
593
|
}
|
|
599
594
|
return { start, stop };
|
|
600
595
|
}
|
|
601
596
|
|
|
602
597
|
// src/core/stega/elements.ts
|
|
603
|
-
var
|
|
598
|
+
var debug3 = createScopedLogger("stega:elements");
|
|
604
599
|
var StegaElements = class {
|
|
605
600
|
constructor(decode = decodeStega) {
|
|
606
601
|
this.observer = null;
|
|
@@ -645,7 +640,7 @@ var StegaElements = class {
|
|
|
645
640
|
walkTextNodes(document.body, (textNode) => {
|
|
646
641
|
if (this.tagFromTextNode(textNode)) encodedCount++;
|
|
647
642
|
});
|
|
648
|
-
|
|
643
|
+
debug3.log("document scan complete, encoded", encodedCount, "elements");
|
|
649
644
|
this.elements = document.querySelectorAll("[data-prepr-encoded]");
|
|
650
645
|
}
|
|
651
646
|
/** `onUpdate` fires after each debounced batch, for refreshing derived state. */
|
|
@@ -701,9 +696,6 @@ var StegaElements = class {
|
|
|
701
696
|
element.removeAttribute("data-prepr-encoded");
|
|
702
697
|
element.removeAttribute("data-prepr-href");
|
|
703
698
|
element.removeAttribute("data-prepr-origin");
|
|
704
|
-
element.removeAttribute("data-prepr-id");
|
|
705
|
-
element.removeAttribute("data-prepr-field");
|
|
706
|
-
element.removeAttribute("data-prepr-locale");
|
|
707
699
|
element.classList.remove("prepr-overlay-active");
|
|
708
700
|
});
|
|
709
701
|
this.elements = void 0;
|
|
@@ -711,7 +703,7 @@ var StegaElements = class {
|
|
|
711
703
|
};
|
|
712
704
|
|
|
713
705
|
// src/core/stega/overlay.ts
|
|
714
|
-
var
|
|
706
|
+
var debug4 = createScopedLogger("stega:overlay");
|
|
715
707
|
var StegaOverlay = class {
|
|
716
708
|
constructor(onEdit) {
|
|
717
709
|
this.overlay = null;
|
|
@@ -756,8 +748,7 @@ var StegaOverlay = class {
|
|
|
756
748
|
const origin = element.getAttribute("data-prepr-origin");
|
|
757
749
|
const id = element.getAttribute("data-prepr-id") ?? void 0;
|
|
758
750
|
const field = element.getAttribute("data-prepr-field") ?? void 0;
|
|
759
|
-
|
|
760
|
-
debug5.log("showing overlay", { href, origin });
|
|
751
|
+
debug4.log("showing overlay", { href, origin });
|
|
761
752
|
const overlay = this.overlay;
|
|
762
753
|
overlay.style.display = "block";
|
|
763
754
|
overlay.style.top = `${rect.top + window.scrollY - 2}px`;
|
|
@@ -789,7 +780,7 @@ var StegaOverlay = class {
|
|
|
789
780
|
tooltip.style.left = `${left}px`;
|
|
790
781
|
});
|
|
791
782
|
tooltip.onclick = () => {
|
|
792
|
-
this.onEdit({ href, origin, id, field
|
|
783
|
+
this.onEdit({ href, origin, id, field });
|
|
793
784
|
};
|
|
794
785
|
}
|
|
795
786
|
this.currentElement = element;
|
|
@@ -829,7 +820,7 @@ var StegaOverlay = class {
|
|
|
829
820
|
};
|
|
830
821
|
|
|
831
822
|
// src/core/stega/proximity.ts
|
|
832
|
-
var
|
|
823
|
+
var debug5 = createScopedLogger("stega:proximity");
|
|
833
824
|
var StegaProximity = class {
|
|
834
825
|
constructor() {
|
|
835
826
|
this.highlighted = /* @__PURE__ */ new Set();
|
|
@@ -864,9 +855,9 @@ var StegaProximity = class {
|
|
|
864
855
|
);
|
|
865
856
|
const nodes = this.getEncodedElements();
|
|
866
857
|
nodes.forEach((el) => this.observer.observe(el));
|
|
867
|
-
|
|
858
|
+
debug5.log("observing", nodes.length, "encoded elements");
|
|
868
859
|
} catch (error) {
|
|
869
|
-
|
|
860
|
+
debug5.log("error setting up IntersectionObserver", error);
|
|
870
861
|
}
|
|
871
862
|
}
|
|
872
863
|
stopObserving() {
|
|
@@ -936,7 +927,7 @@ function removeStegaStyles() {
|
|
|
936
927
|
}
|
|
937
928
|
|
|
938
929
|
// src/core/stega/scan.ts
|
|
939
|
-
var
|
|
930
|
+
var debug6 = createScopedLogger("stega:scan");
|
|
940
931
|
var EDITOR_MODE_STYLES = "[data-prepr-encoded]{cursor:pointer}";
|
|
941
932
|
function createStegaController(opts) {
|
|
942
933
|
const tooltipEnabled = opts.tooltip ?? true;
|
|
@@ -969,13 +960,12 @@ function createStegaController(opts) {
|
|
|
969
960
|
href: encoded.getAttribute("data-prepr-href") ?? "",
|
|
970
961
|
origin: encoded.getAttribute("data-prepr-origin") ?? "",
|
|
971
962
|
id: encoded.getAttribute("data-prepr-id") ?? void 0,
|
|
972
|
-
field: encoded.getAttribute("data-prepr-field") ?? void 0
|
|
973
|
-
locale: encoded.getAttribute("data-prepr-locale") ?? void 0
|
|
963
|
+
field: encoded.getAttribute("data-prepr-field") ?? void 0
|
|
974
964
|
});
|
|
975
965
|
};
|
|
976
966
|
const start = () => {
|
|
977
967
|
if (initialized) {
|
|
978
|
-
|
|
968
|
+
debug6.log("already initialized, skipping setup");
|
|
979
969
|
return;
|
|
980
970
|
}
|
|
981
971
|
if (!tooltipEnabled) {
|
|
@@ -985,7 +975,7 @@ function createStegaController(opts) {
|
|
|
985
975
|
});
|
|
986
976
|
document.addEventListener("click", handleClick, { capture: true });
|
|
987
977
|
initialized = true;
|
|
988
|
-
|
|
978
|
+
debug6.log("stega controller started (editor mode)");
|
|
989
979
|
return;
|
|
990
980
|
}
|
|
991
981
|
injectStegaStyles();
|
|
@@ -1016,7 +1006,7 @@ function createStegaController(opts) {
|
|
|
1016
1006
|
passive: true
|
|
1017
1007
|
});
|
|
1018
1008
|
initialized = true;
|
|
1019
|
-
|
|
1009
|
+
debug6.log("stega controller started");
|
|
1020
1010
|
};
|
|
1021
1011
|
const stop = () => {
|
|
1022
1012
|
if (!initialized) return;
|
|
@@ -1025,7 +1015,7 @@ function createStegaController(opts) {
|
|
|
1025
1015
|
elements.cleanup();
|
|
1026
1016
|
removeStegaStyles();
|
|
1027
1017
|
initialized = false;
|
|
1028
|
-
|
|
1018
|
+
debug6.log("stega controller stopped (editor mode)");
|
|
1029
1019
|
return;
|
|
1030
1020
|
}
|
|
1031
1021
|
if (throttledMouseMove) {
|
|
@@ -1045,43 +1035,11 @@ function createStegaController(opts) {
|
|
|
1045
1035
|
elements.cleanup();
|
|
1046
1036
|
removeStegaStyles();
|
|
1047
1037
|
initialized = false;
|
|
1048
|
-
|
|
1038
|
+
debug6.log("stega controller stopped");
|
|
1049
1039
|
};
|
|
1050
1040
|
return { start, stop };
|
|
1051
1041
|
}
|
|
1052
1042
|
|
|
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
|
-
|
|
1085
1043
|
// src/core/store.ts
|
|
1086
1044
|
var DEFAULT_STATE = {
|
|
1087
1045
|
locale: "en",
|
|
@@ -2194,7 +2152,7 @@ function definePreprToolbar() {
|
|
|
2194
2152
|
}
|
|
2195
2153
|
|
|
2196
2154
|
// src/core/create-preview.ts
|
|
2197
|
-
var
|
|
2155
|
+
var debug7 = createScopedLogger("create-preview");
|
|
2198
2156
|
var controllerStores = /* @__PURE__ */ new WeakMap();
|
|
2199
2157
|
function defaultNavigation() {
|
|
2200
2158
|
return {
|
|
@@ -2236,7 +2194,7 @@ function createPreprPreview(opts = {}) {
|
|
|
2236
2194
|
const search = new URLSearchParams(window.location.search);
|
|
2237
2195
|
const hideBar = search.get(PARAM_HIDE_BAR) === "true";
|
|
2238
2196
|
if (hideBar) {
|
|
2239
|
-
|
|
2197
|
+
debug7.log(`${PARAM_HIDE_BAR}=true \u2014 no visible toolbar`);
|
|
2240
2198
|
}
|
|
2241
2199
|
const mountUi = (options?.ui ?? true) && !isIframe && !hideBar;
|
|
2242
2200
|
const locale = resolveLocale(options);
|
|
@@ -2272,17 +2230,18 @@ function createPreprPreview(opts = {}) {
|
|
|
2272
2230
|
tooltip: mountUi,
|
|
2273
2231
|
// In the editor, ask the parent to focus the field instead of opening a new
|
|
2274
2232
|
// tab. Standalone previews keep the window.open behaviour.
|
|
2275
|
-
onEdit: ({ href, id, field
|
|
2233
|
+
onEdit: ({ href, origin, id, field }) => {
|
|
2276
2234
|
const safeHref = href ? safeEditUrl(href) : null;
|
|
2277
2235
|
if (href && !safeHref) {
|
|
2278
|
-
|
|
2236
|
+
debug7.warn("ignored edit request with unsupported href scheme");
|
|
2279
2237
|
return;
|
|
2280
2238
|
}
|
|
2281
2239
|
if (isIframe) {
|
|
2282
2240
|
sendPreprEvent("field_edit_requested", {
|
|
2241
|
+
href: safeHref ?? void 0,
|
|
2242
|
+
origin,
|
|
2283
2243
|
id,
|
|
2284
|
-
field
|
|
2285
|
-
locale: contentLocale
|
|
2244
|
+
field
|
|
2286
2245
|
});
|
|
2287
2246
|
} else if (safeHref) {
|
|
2288
2247
|
window.open(safeHref, "_blank", "noopener,noreferrer");
|
|
@@ -2290,7 +2249,8 @@ function createPreprPreview(opts = {}) {
|
|
|
2290
2249
|
}
|
|
2291
2250
|
});
|
|
2292
2251
|
const autoClean = createStegaAutoClean({
|
|
2293
|
-
enabled: options?.autoClean
|
|
2252
|
+
enabled: options?.autoClean,
|
|
2253
|
+
isHydrated: opts.isHydrated
|
|
2294
2254
|
});
|
|
2295
2255
|
autoClean.start();
|
|
2296
2256
|
const handleChange = createChangeHandler({
|
|
@@ -2309,15 +2269,7 @@ function createPreprPreview(opts = {}) {
|
|
|
2309
2269
|
handleChange(before, state);
|
|
2310
2270
|
});
|
|
2311
2271
|
const bridge = createIframeBridge(store, {
|
|
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
|
-
}
|
|
2272
|
+
allowedEditorOrigins: options?.allowedEditorOrigins
|
|
2321
2273
|
});
|
|
2322
2274
|
sendPreprEvent(
|
|
2323
2275
|
"getScrollPosition",
|
|
@@ -2337,18 +2289,101 @@ function createPreprPreview(opts = {}) {
|
|
|
2337
2289
|
bridge.stop();
|
|
2338
2290
|
}
|
|
2339
2291
|
el?.remove();
|
|
2340
|
-
|
|
2292
|
+
debug7.log("preview destroyed");
|
|
2341
2293
|
}
|
|
2342
2294
|
const controller = { destroy };
|
|
2343
2295
|
controllerStores.set(controller, store);
|
|
2344
2296
|
return controller;
|
|
2345
2297
|
}
|
|
2346
2298
|
|
|
2299
|
+
// src/react/hydration.ts
|
|
2300
|
+
var PROPS_KEY_PREFIX = "__reactProps$";
|
|
2301
|
+
function reactProps(element) {
|
|
2302
|
+
for (const key of Object.keys(element)) {
|
|
2303
|
+
if (key.startsWith(PROPS_KEY_PREFIX)) {
|
|
2304
|
+
return element[key];
|
|
2305
|
+
}
|
|
2306
|
+
}
|
|
2307
|
+
return void 0;
|
|
2308
|
+
}
|
|
2309
|
+
function isReactHydrated(text) {
|
|
2310
|
+
for (let el = text.parentElement; el; el = el.parentElement) {
|
|
2311
|
+
const props = reactProps(el);
|
|
2312
|
+
if (!props) continue;
|
|
2313
|
+
return el === text.parentElement || props.dangerouslySetInnerHTML != null;
|
|
2314
|
+
}
|
|
2315
|
+
return true;
|
|
2316
|
+
}
|
|
2317
|
+
|
|
2318
|
+
// src/nextjs/ab-switch.ts
|
|
2319
|
+
function applyPreprAbBucket() {
|
|
2320
|
+
const match = document.cookie.match(/(?:^|; )prepr_ab_bucket=([AB])(?:;|$)/);
|
|
2321
|
+
const bucket = match ? match[1] : "A";
|
|
2322
|
+
const state = window;
|
|
2323
|
+
if (state.__preprAbBucket === bucket) return;
|
|
2324
|
+
state.__preprAbBucket = bucket;
|
|
2325
|
+
const css = bucket === "A" ? "" : '[data-prepr-ab="A"]{display:none!important}[data-prepr-ab="' + bucket + '"]{display:contents!important}';
|
|
2326
|
+
try {
|
|
2327
|
+
if (!state.__preprAbSheet) {
|
|
2328
|
+
const sheet = new CSSStyleSheet();
|
|
2329
|
+
document.adoptedStyleSheets = document.adoptedStyleSheets.concat(sheet);
|
|
2330
|
+
state.__preprAbSheet = sheet;
|
|
2331
|
+
}
|
|
2332
|
+
state.__preprAbSheet.replaceSync(css);
|
|
2333
|
+
} catch {
|
|
2334
|
+
if (!state.__preprAbSheet) {
|
|
2335
|
+
state.__preprAbSheet = document.createElement("style");
|
|
2336
|
+
document.head.appendChild(state.__preprAbSheet);
|
|
2337
|
+
}
|
|
2338
|
+
state.__preprAbSheet.textContent = css;
|
|
2339
|
+
}
|
|
2340
|
+
}
|
|
2341
|
+
function applyPreprDecisions() {
|
|
2342
|
+
const match = document.cookie.match(/(?:^|; )prepr_decisions=([^;]*)/);
|
|
2343
|
+
let raw;
|
|
2344
|
+
try {
|
|
2345
|
+
raw = match ? decodeURIComponent(match[1]) : "";
|
|
2346
|
+
} catch {
|
|
2347
|
+
raw = "";
|
|
2348
|
+
}
|
|
2349
|
+
const state = window;
|
|
2350
|
+
if (state.__preprDecisions === raw) return;
|
|
2351
|
+
state.__preprDecisions = raw;
|
|
2352
|
+
const id = /^[\w-]+$/;
|
|
2353
|
+
let css = "";
|
|
2354
|
+
raw.split("~").forEach((pair) => {
|
|
2355
|
+
const at = pair.indexOf(":");
|
|
2356
|
+
const group = pair.slice(0, at);
|
|
2357
|
+
if (at < 1 || !id.test(group)) return;
|
|
2358
|
+
const selector = '[data-prepr-group="' + group + '"]';
|
|
2359
|
+
css += selector + "{display:none!important}";
|
|
2360
|
+
pair.slice(at + 1).split("|").forEach((variant) => {
|
|
2361
|
+
if (id.test(variant)) {
|
|
2362
|
+
css += selector + '[data-prepr-variant="' + variant + '"]{display:contents!important}';
|
|
2363
|
+
}
|
|
2364
|
+
});
|
|
2365
|
+
});
|
|
2366
|
+
try {
|
|
2367
|
+
if (!state.__preprDecisionSheet) {
|
|
2368
|
+
const sheet = new CSSStyleSheet();
|
|
2369
|
+
document.adoptedStyleSheets = document.adoptedStyleSheets.concat(sheet);
|
|
2370
|
+
state.__preprDecisionSheet = sheet;
|
|
2371
|
+
}
|
|
2372
|
+
state.__preprDecisionSheet.replaceSync(css);
|
|
2373
|
+
} catch {
|
|
2374
|
+
if (!state.__preprDecisionSheet) {
|
|
2375
|
+
state.__preprDecisionSheet = document.createElement("style");
|
|
2376
|
+
document.head.appendChild(state.__preprDecisionSheet);
|
|
2377
|
+
}
|
|
2378
|
+
state.__preprDecisionSheet.textContent = css;
|
|
2379
|
+
}
|
|
2380
|
+
}
|
|
2381
|
+
|
|
2347
2382
|
// src/react/components.ts
|
|
2348
2383
|
var import_react = require("react");
|
|
2349
2384
|
|
|
2350
2385
|
// src/version.ts
|
|
2351
|
-
var VERSION = "0.
|
|
2386
|
+
var VERSION = "0.6.0-alpha.0";
|
|
2352
2387
|
|
|
2353
2388
|
// src/core/pixel.ts
|
|
2354
2389
|
var PIXEL_SCRIPT_URL = "https://cdn.tracking.prepr.io/js/prepr.min.js";
|
|
@@ -2416,14 +2451,53 @@ function PreprToolbar({
|
|
|
2416
2451
|
navigation: {
|
|
2417
2452
|
navigate: (url) => router.push(url),
|
|
2418
2453
|
currentPath: () => pathnameRef.current + window.location.search
|
|
2419
|
-
}
|
|
2454
|
+
},
|
|
2455
|
+
isHydrated: isReactHydrated
|
|
2420
2456
|
});
|
|
2421
2457
|
return () => toolbar.destroy();
|
|
2422
2458
|
}, []);
|
|
2423
2459
|
return null;
|
|
2424
2460
|
}
|
|
2461
|
+
function PreprAbSwitch() {
|
|
2462
|
+
(0, import_react2.useLayoutEffect)(() => {
|
|
2463
|
+
applyPreprAbBucket();
|
|
2464
|
+
applyPreprDecisions();
|
|
2465
|
+
});
|
|
2466
|
+
return null;
|
|
2467
|
+
}
|
|
2468
|
+
var VARIANT_KEY_ATTRIBUTE = "data-prepr-variant-key";
|
|
2469
|
+
function PreprVariantTracking({
|
|
2470
|
+
variantKeys,
|
|
2471
|
+
ab,
|
|
2472
|
+
children
|
|
2473
|
+
}) {
|
|
2474
|
+
const ref = (0, import_react2.useRef)(null);
|
|
2475
|
+
const keys = variantKeys.join(" ");
|
|
2476
|
+
(0, import_react2.useLayoutEffect)(() => {
|
|
2477
|
+
const elements = [...ref.current?.children ?? []];
|
|
2478
|
+
const list = keys.split(" ");
|
|
2479
|
+
const pairs = elements.length === list.length ? elements.map((element, i2) => [element, list[i2]]) : elements.slice(0, 1).map((element) => [element, list[0]]);
|
|
2480
|
+
const tagged = pairs.filter(([element, key]) => {
|
|
2481
|
+
if (element.hasAttribute(VARIANT_KEY_ATTRIBUTE)) return false;
|
|
2482
|
+
element.setAttribute(VARIANT_KEY_ATTRIBUTE, key);
|
|
2483
|
+
return true;
|
|
2484
|
+
});
|
|
2485
|
+
return () => {
|
|
2486
|
+
for (const [element] of tagged) {
|
|
2487
|
+
element.removeAttribute(VARIANT_KEY_ATTRIBUTE);
|
|
2488
|
+
}
|
|
2489
|
+
};
|
|
2490
|
+
}, [keys]);
|
|
2491
|
+
return (0, import_react2.createElement)(
|
|
2492
|
+
"div",
|
|
2493
|
+
ab === void 0 ? { ref, style: { display: "contents" } } : { ref, "data-prepr-ab": ab },
|
|
2494
|
+
children
|
|
2495
|
+
);
|
|
2496
|
+
}
|
|
2425
2497
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2426
2498
|
0 && (module.exports = {
|
|
2499
|
+
PreprAbSwitch,
|
|
2427
2500
|
PreprToolbar,
|
|
2428
|
-
PreprTrackingPixel
|
|
2501
|
+
PreprTrackingPixel,
|
|
2502
|
+
PreprVariantTracking
|
|
2429
2503
|
});
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ReactNode, ReactElement } from 'react';
|
|
2
|
+
import { k as PreprToolbarComponentProps } from '../types-BYH9XqmN.cjs';
|
|
3
|
+
import { P as PreprPixelConfig } from '../pixel-DwW7cXJm.cjs';
|
|
2
4
|
|
|
3
5
|
interface PreprTrackingPixelProps {
|
|
4
6
|
/** Prepr tracking/access token. */
|
|
@@ -20,5 +22,34 @@ declare function PreprTrackingPixel({ id, config, }: PreprTrackingPixelProps): n
|
|
|
20
22
|
* `createPreprPreview` mounts imperatively.
|
|
21
23
|
*/
|
|
22
24
|
declare function PreprToolbar({ options, ...props }: PreprToolbarComponentProps): null;
|
|
25
|
+
/**
|
|
26
|
+
* Applies the visitor's A/B bucket, and the segment variants decided in the
|
|
27
|
+
* proxy, after client-side navigation. A full page
|
|
28
|
+
* load is covered by the inline script `PreprStack` renders, but React does
|
|
29
|
+
* not run inline scripts that arrive with a client-side navigation; a layout
|
|
30
|
+
* effect still runs before the browser paints the new page. Rendered by
|
|
31
|
+
* `PreprStack`; you do not need it yourself.
|
|
32
|
+
*/
|
|
33
|
+
declare function PreprAbSwitch(): null;
|
|
34
|
+
/**
|
|
35
|
+
* Wraps one rendered variant and, once hydrated, puts the variant keys on the
|
|
36
|
+
* elements inside, where Prepr's tracking pixel counts impressions and the
|
|
37
|
+
* clicks of any `data-prepr-variant-event` element in them. The wrapper itself
|
|
38
|
+
* takes no box (`display: contents`), and the pixel only counts an element it
|
|
39
|
+
* can see scroll into view, so the keys belong on the sections. The pixel
|
|
40
|
+
* watches for attributes added after load.
|
|
41
|
+
*
|
|
42
|
+
* A variant can hold several items, each with its own key. When the wrapper
|
|
43
|
+
* holds one element per key they are paired in order; otherwise only the
|
|
44
|
+
* first element is tagged, with the first key. An element that already
|
|
45
|
+
* carries a variant key is left alone. Rendered by `PreprStack` with
|
|
46
|
+
* `trackVariants`; you do not need it yourself.
|
|
47
|
+
*/
|
|
48
|
+
declare function PreprVariantTracking({ variantKeys, ab, children, }: {
|
|
49
|
+
variantKeys: string[];
|
|
50
|
+
/** The A/B bucket wrapper this also serves as; its CSS decides `display`. */
|
|
51
|
+
ab?: string;
|
|
52
|
+
children?: ReactNode;
|
|
53
|
+
}): ReactElement;
|
|
23
54
|
|
|
24
|
-
export { PreprToolbar, PreprTrackingPixel, type PreprTrackingPixelProps };
|
|
55
|
+
export { PreprAbSwitch, PreprToolbar, PreprTrackingPixel, type PreprTrackingPixelProps, PreprVariantTracking };
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ReactNode, ReactElement } from 'react';
|
|
2
|
+
import { k as PreprToolbarComponentProps } from '../types-BYH9XqmN.js';
|
|
3
|
+
import { P as PreprPixelConfig } from '../pixel-DwW7cXJm.js';
|
|
2
4
|
|
|
3
5
|
interface PreprTrackingPixelProps {
|
|
4
6
|
/** Prepr tracking/access token. */
|
|
@@ -20,5 +22,34 @@ declare function PreprTrackingPixel({ id, config, }: PreprTrackingPixelProps): n
|
|
|
20
22
|
* `createPreprPreview` mounts imperatively.
|
|
21
23
|
*/
|
|
22
24
|
declare function PreprToolbar({ options, ...props }: PreprToolbarComponentProps): null;
|
|
25
|
+
/**
|
|
26
|
+
* Applies the visitor's A/B bucket, and the segment variants decided in the
|
|
27
|
+
* proxy, after client-side navigation. A full page
|
|
28
|
+
* load is covered by the inline script `PreprStack` renders, but React does
|
|
29
|
+
* not run inline scripts that arrive with a client-side navigation; a layout
|
|
30
|
+
* effect still runs before the browser paints the new page. Rendered by
|
|
31
|
+
* `PreprStack`; you do not need it yourself.
|
|
32
|
+
*/
|
|
33
|
+
declare function PreprAbSwitch(): null;
|
|
34
|
+
/**
|
|
35
|
+
* Wraps one rendered variant and, once hydrated, puts the variant keys on the
|
|
36
|
+
* elements inside, where Prepr's tracking pixel counts impressions and the
|
|
37
|
+
* clicks of any `data-prepr-variant-event` element in them. The wrapper itself
|
|
38
|
+
* takes no box (`display: contents`), and the pixel only counts an element it
|
|
39
|
+
* can see scroll into view, so the keys belong on the sections. The pixel
|
|
40
|
+
* watches for attributes added after load.
|
|
41
|
+
*
|
|
42
|
+
* A variant can hold several items, each with its own key. When the wrapper
|
|
43
|
+
* holds one element per key they are paired in order; otherwise only the
|
|
44
|
+
* first element is tagged, with the first key. An element that already
|
|
45
|
+
* carries a variant key is left alone. Rendered by `PreprStack` with
|
|
46
|
+
* `trackVariants`; you do not need it yourself.
|
|
47
|
+
*/
|
|
48
|
+
declare function PreprVariantTracking({ variantKeys, ab, children, }: {
|
|
49
|
+
variantKeys: string[];
|
|
50
|
+
/** The A/B bucket wrapper this also serves as; its CSS decides `display`. */
|
|
51
|
+
ab?: string;
|
|
52
|
+
children?: ReactNode;
|
|
53
|
+
}): ReactElement;
|
|
23
54
|
|
|
24
|
-
export { PreprToolbar, PreprTrackingPixel, type PreprTrackingPixelProps };
|
|
55
|
+
export { PreprAbSwitch, PreprToolbar, PreprTrackingPixel, type PreprTrackingPixelProps, PreprVariantTracking };
|