@preprio/toolkit 0.2.0 → 0.3.4
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 +87 -10
- package/dist/astro/index.cjs +1 -1
- package/dist/astro/index.js +1 -1
- package/dist/{chunk-4PJK6IQ4.js → chunk-HXQ6JUZM.js} +97 -23
- package/dist/index.cjs +98 -24
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +2 -2
- package/dist/nextjs/components.cjs +97 -23
- package/dist/nextjs/components.d.cts +1 -1
- package/dist/nextjs/components.d.ts +1 -1
- package/dist/nextjs/components.js +1 -1
- package/dist/nextjs/index.cjs +1 -1
- package/dist/nextjs/index.d.cts +14 -0
- package/dist/nextjs/index.d.ts +14 -0
- package/dist/nextjs/index.js +1 -1
- package/dist/nuxt/index.cjs +1 -1
- package/dist/nuxt/index.js +1 -1
- package/dist/{pixel-Dd72wuJp.d.cts → pixel-B6FtY-11.d.cts} +14 -0
- package/dist/{pixel-Dd72wuJp.d.ts → pixel-B6FtY-11.d.ts} +14 -0
- package/dist/react/components.cjs +97 -23
- package/dist/react/components.d.cts +14 -0
- package/dist/react/components.d.ts +14 -0
- package/dist/react/components.js +97 -23
- package/dist/sveltekit/index.cjs +1 -1
- package/dist/sveltekit/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# @preprio/toolkit
|
|
2
2
|
|
|
3
|
+
> **Beta — pre-1.0.** The package is published to `latest` and is safe to use, but the
|
|
4
|
+
> public API can still change between minor versions (`0.2.x` → `0.3.0`). Every change
|
|
5
|
+
> is documented in [Breaking changes](https://github.com/preprio/prepr-toolkit/blob/main/RELEASING.md#breaking-changes). Pin an exact
|
|
6
|
+
> version in production, or use a tilde range (`~0.2.0`) so you only pick up patches.
|
|
7
|
+
|
|
3
8
|
A framework-agnostic TypeScript library that provides preview functionality, visual editing, and A/B testing for [Prepr CMS](https://prepr.io). Ships thin wrappers for Next.js, Nuxt, Astro, and SvelteKit on top of a vanilla core that runs anywhere.
|
|
4
9
|
|
|
5
10
|
Every integration is the same three steps:
|
|
@@ -10,6 +15,8 @@ Every integration is the same three steps:
|
|
|
10
15
|
|
|
11
16
|
Jump to your framework: [Next.js](#nextjs) · [Astro](#astro) · [SvelteKit](#sveltekit) · [Nuxt](#nuxt) · [React without a framework](#react-no-framework) · [anything else](#any-other-framework).
|
|
12
17
|
|
|
18
|
+
Coming from `@preprio/prepr-nextjs`? See the [migration guide](https://github.com/preprio/prepr-toolkit/blob/main/MIGRATION.md).
|
|
19
|
+
|
|
13
20
|
## Quick Start (Next.js)
|
|
14
21
|
|
|
15
22
|
```bash
|
|
@@ -624,14 +631,14 @@ controller.destroy();
|
|
|
624
631
|
| Option | Type | Description |
|
|
625
632
|
| ------------ | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
626
633
|
| `props` | `PreprToolbarProps` | From `getToolbarProps`. Optional — a headless preview has no segment list to pass. |
|
|
627
|
-
| `options` | `PreprPreviewOptions` | `{ debug?, locale?, features?, ui?, allowedEditorOrigins? }`. See [Preview options](#preview-options).
|
|
634
|
+
| `options` | `PreprPreviewOptions` | `{ debug?, locale?, features?, ui?, allowedEditorOrigins?, autoClean? }`. See [Preview options](#preview-options). |
|
|
628
635
|
| `navigation` | `PreprNavigationAdapter` | How segment/variant switches navigate. Optional — omitted, the toolbar uses `window.location.assign` (a full page load). `reload` is optional too, runs after a preview-mode toggle, and defaults to `window.location.reload()`. The Next.js and SvelteKit wrappers wire all of this up for you. |
|
|
629
636
|
|
|
630
637
|
`createPreprPreview` is a no-op outside a browser (no `window`/`document`) and returns a controller whose `destroy()` does nothing, so it is safe to call during SSR. Call it **once per page** — two calls start two bridges and announce the preview twice.
|
|
631
638
|
|
|
632
639
|
#### Tracking
|
|
633
640
|
|
|
634
|
-
- **`loadTrackingPixel(id, config?)`** — installs the CDN tracking pixel. Idempotent, and a no-op outside a browser. A typed facade over Prepr's existing CDN pixel (`https://cdn.tracking.prepr.io/js/prepr
|
|
641
|
+
- **`loadTrackingPixel(id, config?)`** — installs the CDN tracking pixel. Idempotent, and a no-op outside a browser. A typed facade over Prepr's existing CDN pixel (`https://cdn.tracking.prepr.io/js/prepr.min.js`), reproducing the legacy `<script>` snippet's queue-stub semantics: calls made before the CDN script loads are queued and flushed once it is ready.
|
|
635
642
|
- **`trackEvent(name, data?)`** — sends a custom tracking event: `trackEvent('add_to_cart', { productId: 'abc123' })`.
|
|
636
643
|
- **`setTrackingParam(key, value)`** — sets a persistent tracking parameter: `setTrackingParam('user_type', 'returning')`.
|
|
637
644
|
|
|
@@ -682,13 +689,14 @@ createPreprMiddleware(request, response, { preview });
|
|
|
682
689
|
createPreprPreview({ props, options: { debug: true, locale: 'nl' } });
|
|
683
690
|
```
|
|
684
691
|
|
|
685
|
-
| Option | Type | Default | Description
|
|
686
|
-
| ---------------------- | --------------- | ------------- |
|
|
687
|
-
| `debug` | `boolean` | `false` | Enable debug logging.
|
|
688
|
-
| `locale` | `'en' \| 'nl'` | auto-detected | UI language. Falls back to the first supported browser language, then `en`.
|
|
689
|
-
| `features` | `PreprFeatures` | all enabled | Which features run. See [Feature flags](#feature-flags).
|
|
690
|
-
| `ui` | `boolean` | `true` | Mount the visible toolbar. See [Headless preview](#headless-preview-no-toolbar-ui).
|
|
691
|
-
| `allowedEditorOrigins` | `string[]` | `*.prepr.io` | Exact editor origins allowed to drive this preview, for self-hosted editors. Replaces the wildcard.
|
|
692
|
+
| Option | Type | Default | Description |
|
|
693
|
+
| ---------------------- | --------------- | ------------- | -------------------------------------------------------------------------------------------------------- |
|
|
694
|
+
| `debug` | `boolean` | `false` | Enable debug logging. |
|
|
695
|
+
| `locale` | `'en' \| 'nl'` | auto-detected | UI language. Falls back to the first supported browser language, then `en`. |
|
|
696
|
+
| `features` | `PreprFeatures` | all enabled | Which features run. See [Feature flags](#feature-flags). |
|
|
697
|
+
| `ui` | `boolean` | `true` | Mount the visible toolbar. See [Headless preview](#headless-preview-no-toolbar-ui). |
|
|
698
|
+
| `allowedEditorOrigins` | `string[]` | `*.prepr.io` | Exact editor origins allowed to drive this preview, for self-hosted editors. Replaces the wildcard. |
|
|
699
|
+
| `autoClean` | `boolean` | `true` | Strip the invisible stega characters from visible text. See [Stega auto-cleaning](#stega-auto-cleaning). |
|
|
692
700
|
|
|
693
701
|
`features` and `ui` are independent: `features` decides _what runs_, `ui` decides _whether the toolbar is visible_.
|
|
694
702
|
|
|
@@ -812,6 +820,12 @@ createPreprPreview({ props, options: { locale: 'nl' } });
|
|
|
812
820
|
- **Confirm the middleware matcher**: if `config.matcher` excludes the current path, no Prepr headers were set for it. `getPreprUUID()` returning `null` confirms this.
|
|
813
821
|
- **Check for `prepr_hide_bar=true`** in the URL, which suppresses the bar by design.
|
|
814
822
|
|
|
823
|
+
### Click-to-edit not working on some elements
|
|
824
|
+
|
|
825
|
+
- **Check the token permissions**: "Enable edit mode" must be checked on the token in Prepr.
|
|
826
|
+
- **Check whether the encoded text sits in a hidden element.** The parent of the encoded text node is what becomes editable, and a parent that renders no box (`display: none`, `visibility: hidden`, the `hidden` attribute) is skipped — it cannot be hovered or clicked. Put `data-prepr-edit-target` on the visible ancestor that should be editable instead. See [Choosing the element that becomes editable](#choosing-the-element-that-becomes-editable).
|
|
827
|
+
- **Inspect the tagged elements**: `document.querySelectorAll('[data-prepr-encoded]')` in the console lists everything edit mode found. An element you expected to be in that list points at one of the two cases above.
|
|
828
|
+
|
|
815
829
|
### Headers not working
|
|
816
830
|
|
|
817
831
|
- **Middleware setup**: confirm `middleware.ts` sits in the project root (or `src/`) and its matcher covers the route.
|
|
@@ -883,7 +897,62 @@ The toolbar renders with Preact into a shadow-DOM custom element (`<prepr-toolba
|
|
|
883
897
|
|
|
884
898
|
With edit mode enabled, the toolkit scans for stega-encoded content, strips the invisible Unicode characters after load so they cannot cause layout shifts, highlights editable elements by cursor proximity, and talks to the Prepr editor over a `postMessage` bridge when running inside the live-preview iframe.
|
|
885
899
|
|
|
886
|
-
Stega cleaning is automatic. There is no need to call `vercelStegaSplit` or
|
|
900
|
+
Stega cleaning is automatic. There is no need to call `vercelStegaSplit` or to strip the payload yourself before rendering — the data attributes the toolkit relies on survive the clean, so edit mode still activates instantly.
|
|
901
|
+
|
|
902
|
+
#### Stega auto-cleaning
|
|
903
|
+
|
|
904
|
+
Preview content carries its edit payload inside the text itself, as a run of invisible Unicode characters. The toolkit strips them from the DOM after load and keeps stripping them as your framework re-renders.
|
|
905
|
+
|
|
906
|
+
Leaving them in place is not cosmetic. The characters are real string content: they inflate `String.length`, break text measurement and truncation, and are announced by screen readers.
|
|
907
|
+
|
|
908
|
+
Turn the stripping off with `autoClean: false`:
|
|
909
|
+
|
|
910
|
+
```typescript
|
|
911
|
+
createPreprPreview({ props, options: { autoClean: false } });
|
|
912
|
+
```
|
|
913
|
+
|
|
914
|
+
Only do this when your app already strips the payload itself — for example by passing every field through `stegaClean` as it renders:
|
|
915
|
+
|
|
916
|
+
```typescript
|
|
917
|
+
import { stegaClean } from '@preprio/toolkit';
|
|
918
|
+
|
|
919
|
+
<h1>{stegaClean(page.title)}</h1>;
|
|
920
|
+
```
|
|
921
|
+
|
|
922
|
+
Click-to-edit is unaffected by this option. Elements are still tagged from the payload, so the overlay, tooltip and edit bridge keep working either way.
|
|
923
|
+
|
|
924
|
+
#### Choosing the element that becomes editable
|
|
925
|
+
|
|
926
|
+
The element that gets the outline, the tooltip and the click handler is the **parent of the encoded text node**. Rendering `{title}` inside an `<h2>` makes the `<h2>` editable, which is what you want almost every time.
|
|
927
|
+
|
|
928
|
+
Two rules govern the choice:
|
|
929
|
+
|
|
930
|
+
- A parent that renders no box is skipped. An element hidden with `display: none`, `visibility: hidden`, or the `hidden` attribute cannot be hovered or outlined, so tagging it would produce an element that looks editable to the code and is unreachable to the visitor. Nothing is tagged for it.
|
|
931
|
+
- `data-prepr-edit-target` overrides the parent. The closest ancestor carrying it becomes the editable element instead.
|
|
932
|
+
|
|
933
|
+
That attribute is the supported way to separate _where the payload lives_ from _what the visitor clicks_. It is what makes the hidden-payload pattern work:
|
|
934
|
+
|
|
935
|
+
```html
|
|
936
|
+
<!-- The payload rides in a visually hidden span; the <article> is what
|
|
937
|
+
gets outlined and clicked. -->
|
|
938
|
+
<article data-prepr-edit-target>
|
|
939
|
+
<h2>Product title</h2>
|
|
940
|
+
<span hidden>{encodedPayload}</span>
|
|
941
|
+
</article>
|
|
942
|
+
```
|
|
943
|
+
|
|
944
|
+
Without the attribute that span is skipped entirely — it renders no box, so there is nothing to click.
|
|
945
|
+
|
|
946
|
+
It is equally useful when the encoded text sits deep inside markup you do not control, and the natural click target is an ancestor:
|
|
947
|
+
|
|
948
|
+
```html
|
|
949
|
+
<figure data-prepr-edit-target>
|
|
950
|
+
<img src="..." alt="..." />
|
|
951
|
+
<figcaption><em>{encodedCaption}</em></figcaption>
|
|
952
|
+
</figure>
|
|
953
|
+
```
|
|
954
|
+
|
|
955
|
+
Without it the `<em>` would be the editable element; with it the whole figure is.
|
|
887
956
|
|
|
888
957
|
## Examples
|
|
889
958
|
|
|
@@ -897,6 +966,14 @@ Runnable examples live in the repository root:
|
|
|
897
966
|
| `examples/nuxt` | `server/middleware`, `useAsyncData`, `.vue` components |
|
|
898
967
|
| `examples/express` | Vanilla core — a hand-written adapter for an unsupported framework |
|
|
899
968
|
|
|
969
|
+
## Migrating from `@preprio/prepr-nextjs`
|
|
970
|
+
|
|
971
|
+
`@preprio/toolkit` replaces the Next.js-only `@preprio/prepr-nextjs` package. Most of
|
|
972
|
+
the change is import paths — the middleware signature is unchanged and the server
|
|
973
|
+
helpers keep their names — but the toolbar's provider and the stylesheet are gone.
|
|
974
|
+
|
|
975
|
+
The [migration guide](https://github.com/preprio/prepr-toolkit/blob/main/MIGRATION.md) has the diffs.
|
|
976
|
+
|
|
900
977
|
## Support
|
|
901
978
|
|
|
902
979
|
- **Documentation**: [Prepr Documentation](https://docs.prepr.io)
|
package/dist/astro/index.cjs
CHANGED
package/dist/astro/index.js
CHANGED
|
@@ -169,6 +169,20 @@ function walkTextNodes(root, visit) {
|
|
|
169
169
|
visit(node);
|
|
170
170
|
}
|
|
171
171
|
}
|
|
172
|
+
function resolveEditTarget(node) {
|
|
173
|
+
const parent = node.parentElement;
|
|
174
|
+
if (!parent) return null;
|
|
175
|
+
const editTarget = parent.closest("[data-prepr-edit-target]");
|
|
176
|
+
if (editTarget) return editTarget;
|
|
177
|
+
return isRenderedElement(parent) ? parent : null;
|
|
178
|
+
}
|
|
179
|
+
function isRenderedElement(element) {
|
|
180
|
+
if (element.hidden) return false;
|
|
181
|
+
if (element.getClientRects().length === 0) return false;
|
|
182
|
+
const style = element.ownerDocument.defaultView?.getComputedStyle(element);
|
|
183
|
+
if (!style) return true;
|
|
184
|
+
return style.visibility !== "hidden" && style.display !== "none";
|
|
185
|
+
}
|
|
172
186
|
function tagEncodedElement(element, decoded) {
|
|
173
187
|
element.setAttribute("data-prepr-encoded", "");
|
|
174
188
|
element.setAttribute("data-prepr-href", decoded.href);
|
|
@@ -192,7 +206,7 @@ var StegaElements = class {
|
|
|
192
206
|
tagFromTextNode(node) {
|
|
193
207
|
const decoded = this.decode(node.textContent);
|
|
194
208
|
if (!decoded?.href) return false;
|
|
195
|
-
const target = node
|
|
209
|
+
const target = resolveEditTarget(node);
|
|
196
210
|
if (!target || target.hasAttribute("data-prepr-encoded")) return false;
|
|
197
211
|
tagEncodedElement(target, decoded);
|
|
198
212
|
return true;
|
|
@@ -238,8 +252,13 @@ var StegaElements = class {
|
|
|
238
252
|
if (mutation.type === "characterData") {
|
|
239
253
|
addedNodes.add(mutation.target);
|
|
240
254
|
}
|
|
255
|
+
if (mutation.type === "attributes") {
|
|
256
|
+
addedNodes.add(mutation.target);
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
addedNodes.forEach((node) => {
|
|
260
|
+
if (node.isConnected) this.scanNode(node);
|
|
241
261
|
});
|
|
242
|
-
addedNodes.forEach((node) => this.scanNode(node));
|
|
243
262
|
pending = [];
|
|
244
263
|
this.elements = document.querySelectorAll("[data-prepr-encoded]");
|
|
245
264
|
onUpdate?.();
|
|
@@ -252,7 +271,11 @@ var StegaElements = class {
|
|
|
252
271
|
this.observer.observe(document.body, {
|
|
253
272
|
childList: true,
|
|
254
273
|
subtree: true,
|
|
255
|
-
characterData: true
|
|
274
|
+
characterData: true,
|
|
275
|
+
// Reveal-on-class/style (dropdowns, accordions) changes no text and adds
|
|
276
|
+
// no nodes, but does change what is hoverable and needs a rescan.
|
|
277
|
+
attributes: true,
|
|
278
|
+
attributeFilter: ["class", "style", "hidden", "open", "aria-expanded"]
|
|
256
279
|
});
|
|
257
280
|
}
|
|
258
281
|
/** Drops the active class but keeps the data attributes, unlike cleanup(). */
|
|
@@ -341,11 +364,13 @@ var StegaOverlay = class {
|
|
|
341
364
|
const maxTop = window.scrollY + window.innerHeight - tooltip.clientHeight - 4;
|
|
342
365
|
const minLeft = window.scrollX + 4;
|
|
343
366
|
const maxLeft = window.scrollX + window.innerWidth - tooltip.clientWidth - 4;
|
|
344
|
-
|
|
367
|
+
const below = top < minTop;
|
|
368
|
+
if (below) {
|
|
345
369
|
top = rect.bottom + window.scrollY + 2;
|
|
346
370
|
}
|
|
347
371
|
top = Math.max(minTop, Math.min(top, maxTop));
|
|
348
372
|
left = Math.max(minLeft, Math.min(left, maxLeft));
|
|
373
|
+
tooltip.dataset.preprPlacement = below ? "below" : "above";
|
|
349
374
|
tooltip.style.top = `${top}px`;
|
|
350
375
|
tooltip.style.left = `${left}px`;
|
|
351
376
|
});
|
|
@@ -477,7 +502,7 @@ var StegaProximity = class {
|
|
|
477
502
|
};
|
|
478
503
|
|
|
479
504
|
// src/core/stega/stega.generated.ts
|
|
480
|
-
var STEGA_STYLES = '[data-prepr-encoded]{position:relative}.prepr-overlay{pointer-events:none;z-index:10000;border:2px solid #4f46e5;border-radius:4px 0 4px 4px;transition:all .2s ease-in-out;position:absolute}.prepr-tooltip{color:#fff;white-space:nowrap;z-index:10001;text-align:center;pointer-events:auto;cursor:pointer;background-color:#4f46e5;border-radius:4px 4px 0 0;min-width:80px;padding:4px 8px;font-size:12px;line-height:1;transition:opacity .2s ease-in-out;position:absolute}.prepr-tooltip:hover{background-color:#4338ca}.prepr-proximity-highlight{z-index:1;position:relative}.prepr-proximity-highlight,.prepr-proximity-highlight *{overflow:visible!important}.prepr-proximity-highlight:before{content:"";pointer-events:none;background:radial-gradient(circle var(--gradient-size) at var(--cursor-x) var(--cursor-y), #4f46e526 0%, #2563eb00 70%);z-index:9999;border:2px solid #4f46e526;border-radius:4px;transition:all .2s;position:absolute;top:-2px;bottom:-2px;left:-4px;right:-4px;overflow:visible}';
|
|
505
|
+
var STEGA_STYLES = '[data-prepr-encoded]{position:relative}.prepr-overlay{pointer-events:none;z-index:10000;border:2px solid #4f46e5;border-radius:4px 0 4px 4px;transition:all .2s ease-in-out;position:absolute}.prepr-tooltip{color:#fff;white-space:nowrap;z-index:10001;text-align:center;pointer-events:auto;cursor:pointer;background-color:#4f46e5;border-radius:4px 4px 0 0;min-width:80px;padding:4px 8px;font-size:12px;line-height:1;transition:opacity .2s ease-in-out;position:absolute}.prepr-tooltip[data-prepr-placement=below]{border-radius:0 0 4px 4px}.prepr-tooltip:hover{background-color:#4338ca}.prepr-proximity-highlight{z-index:1;position:relative}.prepr-proximity-highlight,.prepr-proximity-highlight *{overflow:visible!important}.prepr-proximity-highlight:before{content:"";pointer-events:none;background:radial-gradient(circle var(--gradient-size) at var(--cursor-x) var(--cursor-y), #4f46e526 0%, #2563eb00 70%);z-index:9999;border:2px solid #4f46e526;border-radius:4px;transition:all .2s;position:absolute;top:-2px;bottom:-2px;left:-4px;right:-4px;overflow:visible}';
|
|
481
506
|
|
|
482
507
|
// src/core/stega/styles.ts
|
|
483
508
|
var STEGA_STYLE_MARKER = "data-prepr-stega";
|
|
@@ -613,32 +638,45 @@ function createStegaController(opts) {
|
|
|
613
638
|
// src/core/stega/auto-clean.ts
|
|
614
639
|
import { vercelStegaSplit } from "@vercel/stega";
|
|
615
640
|
var debug6 = createScopedLogger("stega:auto-clean");
|
|
616
|
-
function createStegaAutoClean() {
|
|
641
|
+
function createStegaAutoClean(options) {
|
|
642
|
+
const stripText = options?.enabled ?? true;
|
|
617
643
|
let observer = null;
|
|
618
644
|
let processing = false;
|
|
619
645
|
let cleaned = /* @__PURE__ */ new WeakMap();
|
|
646
|
+
let pendingHidden = /* @__PURE__ */ new Set();
|
|
647
|
+
let pendingDirty = /* @__PURE__ */ new Set();
|
|
620
648
|
let debounceTimeout = null;
|
|
621
649
|
function cleanTextNode(textNode) {
|
|
622
650
|
if (isIgnoredTextNode(textNode)) return false;
|
|
623
651
|
const textContent = textNode.textContent;
|
|
624
652
|
const info = cleaned.get(textNode);
|
|
625
|
-
|
|
653
|
+
const settled = stripText ? info?.cleaned : info?.original;
|
|
654
|
+
if (info && textContent === settled) {
|
|
655
|
+
const shown = resolveEditTarget(textNode);
|
|
656
|
+
if (!shown) return false;
|
|
657
|
+
pendingHidden.delete(textNode);
|
|
658
|
+
if (shown.hasAttribute("data-prepr-encoded")) return false;
|
|
659
|
+
tagEncodedElement(shown, info.decoded);
|
|
660
|
+
return true;
|
|
661
|
+
}
|
|
626
662
|
try {
|
|
627
663
|
const { cleaned: stripped, encoded } = vercelStegaSplit(textContent);
|
|
628
664
|
if (!encoded || stripped === textContent) return false;
|
|
629
665
|
const decoded = decodeStega(textContent);
|
|
630
666
|
if (!decoded?.href) return false;
|
|
631
|
-
cleaned.set(textNode, {
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
);
|
|
637
|
-
|
|
667
|
+
cleaned.set(textNode, {
|
|
668
|
+
original: textContent,
|
|
669
|
+
cleaned: stripped,
|
|
670
|
+
decoded
|
|
671
|
+
});
|
|
672
|
+
if (stripText) textNode.textContent = stripped;
|
|
673
|
+
const target = resolveEditTarget(textNode);
|
|
638
674
|
if (target) {
|
|
675
|
+
pendingHidden.delete(textNode);
|
|
639
676
|
tagEncodedElement(target, decoded);
|
|
640
677
|
return true;
|
|
641
678
|
}
|
|
679
|
+
pendingHidden.add(textNode);
|
|
642
680
|
} catch (error) {
|
|
643
681
|
debug6.log("error cleaning text node", error);
|
|
644
682
|
}
|
|
@@ -647,8 +685,10 @@ function createStegaAutoClean() {
|
|
|
647
685
|
function scanAndClean() {
|
|
648
686
|
processing = true;
|
|
649
687
|
walkTextNodes(document.body, cleanTextNode);
|
|
650
|
-
|
|
651
|
-
|
|
688
|
+
if (stripText) {
|
|
689
|
+
const title = vercelStegaSplit(document.title);
|
|
690
|
+
if (title.encoded) document.title = title.cleaned;
|
|
691
|
+
}
|
|
652
692
|
processing = false;
|
|
653
693
|
}
|
|
654
694
|
function collectAffected(mutations) {
|
|
@@ -673,15 +713,37 @@ function createStegaAutoClean() {
|
|
|
673
713
|
});
|
|
674
714
|
return affected;
|
|
675
715
|
}
|
|
716
|
+
function retryPendingHidden() {
|
|
717
|
+
if (pendingHidden.size === 0) return;
|
|
718
|
+
processing = true;
|
|
719
|
+
[...pendingHidden].forEach((textNode) => {
|
|
720
|
+
if (!textNode.isConnected) {
|
|
721
|
+
pendingHidden.delete(textNode);
|
|
722
|
+
return;
|
|
723
|
+
}
|
|
724
|
+
cleanTextNode(textNode);
|
|
725
|
+
});
|
|
726
|
+
processing = false;
|
|
727
|
+
}
|
|
676
728
|
function handleMutations(mutations) {
|
|
677
729
|
if (processing) return;
|
|
678
730
|
const affected = collectAffected(mutations);
|
|
679
|
-
if (affected.size === 0)
|
|
731
|
+
if (affected.size === 0) {
|
|
732
|
+
retryPendingHidden();
|
|
733
|
+
return;
|
|
734
|
+
}
|
|
735
|
+
affected.forEach((textNode) => pendingDirty.add(textNode));
|
|
680
736
|
if (debounceTimeout) clearTimeout(debounceTimeout);
|
|
681
737
|
debounceTimeout = setTimeout(() => {
|
|
738
|
+
debounceTimeout = null;
|
|
682
739
|
processing = true;
|
|
683
|
-
|
|
740
|
+
const batch = [...pendingDirty];
|
|
741
|
+
pendingDirty.clear();
|
|
742
|
+
batch.forEach((textNode) => {
|
|
743
|
+
if (textNode.isConnected) cleanTextNode(textNode);
|
|
744
|
+
});
|
|
684
745
|
processing = false;
|
|
746
|
+
retryPendingHidden();
|
|
685
747
|
}, 50);
|
|
686
748
|
}
|
|
687
749
|
function setupObserver() {
|
|
@@ -689,7 +751,11 @@ function createStegaAutoClean() {
|
|
|
689
751
|
observer.observe(document.body, {
|
|
690
752
|
childList: true,
|
|
691
753
|
subtree: true,
|
|
692
|
-
characterData: true
|
|
754
|
+
characterData: true,
|
|
755
|
+
// A dropdown opening only toggles a class or inline style; without these
|
|
756
|
+
// the nodes it reveals are never revisited and stay untagged.
|
|
757
|
+
attributes: true,
|
|
758
|
+
attributeFilter: ["class", "style", "hidden", "open", "aria-expanded"]
|
|
693
759
|
});
|
|
694
760
|
}
|
|
695
761
|
function start() {
|
|
@@ -708,6 +774,8 @@ function createStegaAutoClean() {
|
|
|
708
774
|
observer = null;
|
|
709
775
|
}
|
|
710
776
|
cleaned = /* @__PURE__ */ new WeakMap();
|
|
777
|
+
pendingHidden = /* @__PURE__ */ new Set();
|
|
778
|
+
pendingDirty = /* @__PURE__ */ new Set();
|
|
711
779
|
debug6.log("stega auto-clean stopped");
|
|
712
780
|
}
|
|
713
781
|
return { start, stop };
|
|
@@ -1031,7 +1099,7 @@ var CLOSE_ICON_SVG = `<svg width="10" height="10" viewBox="0 0 10 10" fill="none
|
|
|
1031
1099
|
</svg>`;
|
|
1032
1100
|
|
|
1033
1101
|
// src/core/ui/toolbar.generated.ts
|
|
1034
|
-
var TOOLBAR_CSS = ":host{--prepr-primary:#4338ca;--prepr-bg:#eef2ff;--prepr-text:#1f2937;--prepr-radius:8px;--prepr-shadow:0px 0px 40px 0px #1f29373d;--prepr-z-index:10000;--prepr-primary-50:#eef2ff;--prepr-primary-100:#e0e7ff;--prepr-primary-800:#3730a3;--prepr-indigo-600:#4f46e5;--prepr-indigo-50:#eef2ff;--prepr-indigo-700:#4338ca;--prepr-secondary-400:#fb923c;--prepr-secondary-500:#f97316;--prepr-gray-100:#f3f4f6;--prepr-gray-200:#e5e7eb;--prepr-gray-300:#d1d5db;--prepr-gray-400:#9ca3af;--prepr-gray-500:#6b7280;--prepr-gray-700:#374151;--prepr-gray-800:#1f2937;--prepr-gray-900:#111827;--prepr-shadow-sm:0px 0px 12px 0px #c3c3c3cc;color:var(--prepr-text);box-sizing:border-box;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif;font-size:14px;line-height:1.5}:host *,:host :before,:host :after,*,:before,:after{box-sizing:border-box}button{font-family:inherit;font-size:inherit;margin:0}.prepr-regular-text{font-size:.875rem;font-weight:500;line-height:1.5}.prepr-backdrop{z-index:calc(var(--prepr-z-index) - 1);opacity:0;pointer-events:none;background:#0000001a;transition:opacity .2s ease-in-out;position:fixed;top:0;bottom:0;left:0;right:0}.prepr-backdrop[data-open=true]{opacity:1;pointer-events:auto;animation:.2s ease-in-out prepr-fade-in}.prepr-container{z-index:var(--prepr-z-index);justify-content:flex-end;align-items:center;display:flex;position:fixed;top:calc(50% - 64px);right:0}.prepr-toggle-holder{padding:.5rem}.prepr-toggle{cursor:pointer;background:var(--prepr-primary);color:#fff;border:none;border-radius:9999px;justify-content:center;align-items:center;width:2.25rem;height:2.25rem;display:flex}.prepr-toggle>span{display:flex}.prepr-toggle svg{color:#fff}.prepr-panel{z-index:var(--prepr-z-index);opacity:0;pointer-events:none;justify-content:flex-end;padding:.75rem;transition:opacity .2s ease-in-out;display:flex;position:fixed;top:50%;right:0;transform:translateY(-50%)}.prepr-panel[data-open=true]{opacity:1;pointer-events:auto;animation:.2s ease-in-out prepr-fade-in}.prepr-content{box-shadow:var(--prepr-shadow);border-radius:var(--prepr-radius);background:var(--prepr-bg);flex-direction:column;gap:2.5rem;width:100%;padding:1.5rem;display:flex}@media (min-width:640px){.prepr-panel{margin-right:4rem;padding:0}.prepr-content{width:502px;padding:2.5rem}}.prepr-header{justify-content:space-between;align-items:center;gap:.5rem;display:flex}.prepr-header-left{align-items:flex-start;gap:.75rem;display:flex}.prepr-badge{background:var(--prepr-primary-100);height:1.5rem;color:var(--prepr-primary);border-radius:4px;align-items:center;padding:.25rem .75rem;font-size:.875rem;display:flex}.prepr-header-close{cursor:pointer;background:var(--prepr-primary-100);width:2rem;height:2rem;color:var(--prepr-gray-700);border:none;border-radius:6px;justify-content:center;align-items:center;display:flex}.prepr-section{flex-direction:column;gap:.5rem;display:flex}.prepr-section-label{color:var(--prepr-gray-400);font-size:.875rem}.prepr-row{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:.5rem 1.5rem;display:flex}.prepr-row-title{color:var(--prepr-gray-800);margin:0;font-size:1rem;font-weight:600}.prepr-radiogroup{border-radius:var(--prepr-radius);border:1px solid var(--prepr-gray-300);background:#fff;align-items:center;gap:.25rem;height:2.5rem;padding:.25rem;display:flex}.prepr-radiogroup[data-disabled=true]{cursor:not-allowed;opacity:.5}.prepr-radiogroup[data-disabled=true] .prepr-radio{pointer-events:none}.prepr-radio{cursor:pointer;white-space:nowrap;text-align:center;height:2rem;color:var(--prepr-gray-900);background:0 0;border:none;border-radius:6px;justify-content:center;align-items:center;padding:.5rem 1.125rem;font-size:.875rem;font-weight:500;transition:all .2s ease-in-out;display:flex}.prepr-radio[data-checked=true]{background:var(--prepr-indigo-600);color:#fff;box-shadow:var(--prepr-shadow-sm)}.prepr-radio[data-checked=true][data-off=true]{background:var(--prepr-gray-800);color:#fff}.prepr-radio-variant{width:82px}.prepr-listbox{position:relative}.prepr-segment-button{border-radius:var(--prepr-radius);border:1px solid var(--prepr-gray-300);width:240px;height:2.5rem;color:var(--prepr-gray-500);cursor:pointer;background:#fff;flex-shrink:0;align-items:center;gap:.5rem;padding:0 .5rem;font-size:.875rem;font-weight:500;display:flex;overflow:hidden}@media (min-width:768px){.prepr-segment-button{padding:0 1rem}}.prepr-segment-button:disabled{cursor:not-allowed;background:var(--prepr-gray-200);color:var(--prepr-gray-400)}.prepr-segment-button[aria-expanded=true]{border-bottom-color:#fff;border-bottom-right-radius:0;border-bottom-left-radius:0}.prepr-segment-label{white-space:nowrap;text-overflow:ellipsis;text-align:left;width:100%;margin-right:auto;overflow:hidden}.prepr-segment-caret{color:var(--prepr-gray-800);display:flex}.prepr-options{z-index:calc(var(--prepr-z-index) + 1);border-left:1px solid var(--prepr-gray-300);border-right:1px solid var(--prepr-gray-300);border-bottom:1px solid var(--prepr-gray-300);-ms-overflow-style:none;scrollbar-width:none;background:#fff;border-radius:0 0 6px 6px;width:240px;max-height:300px;margin:0;padding:0;list-style:none;position:absolute;top:100%;left:0;overflow-y:auto;box-shadow:0 20px 25px -5px #0000001a,0 8px 10px -6px #0000001a}.prepr-options::-webkit-scrollbar{display:none}.prepr-options[hidden]{display:none}.prepr-option-search{background:#fff;padding:.5rem;position:-webkit-sticky;position:sticky;top:0}.prepr-segment-search{border:1px solid var(--prepr-gray-300);border-radius:var(--prepr-radius);width:100%;height:2rem;font:inherit;color:var(--prepr-gray-900);box-sizing:border-box;background:#fff;padding:0 .5rem;font-size:.875rem}.prepr-segment-search::placeholder{color:var(--prepr-gray-400)}.prepr-segment-search:focus{border-color:var(--prepr-gray-400);outline:none}.prepr-option{cursor:pointer;width:100%;color:var(--prepr-gray-900);background:#fff;align-items:center;padding:.5rem 1rem;font-size:.875rem;font-weight:500;display:flex}.prepr-option:hover{background:var(--prepr-gray-100)}.prepr-option[aria-selected=true]{background:var(--prepr-indigo-50);color:var(--prepr-indigo-700)}.prepr-option-label{white-space:nowrap;text-overflow:ellipsis;text-align:left;width:100%;margin-right:auto;overflow:hidden}.prepr-reset{background:var(--prepr-secondary-400);color:#fff;cursor:pointer;border:none;border-radius:6px;justify-content:center;align-items:center;gap:.5rem;width:100%;height:2.5rem;padding:.5rem .75rem;font-size:.875rem;font-weight:500;display:flex}.prepr-reset:hover:not(:disabled){background:var(--prepr-secondary-500)}.prepr-reset:disabled{background:var(--prepr-gray-400);color:var(--prepr-gray-500);cursor:not-allowed}@media (min-width:768px){.prepr-reset{width:108px}}.prepr-indicators{z-index:var(--prepr-z-index);gap:.75rem;display:flex;position:fixed;bottom:1.5rem;right:1.5rem}.prepr-status-pill{background:var(--prepr-primary);color:#fff;cursor:pointer;border:none;border-radius:9999px;align-items:center;gap:.5rem;padding:.5rem 1rem;font-size:.75rem;font-weight:500;transition:background-color .15s;display:flex;box-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a}.prepr-status-pill:hover{background:var(--prepr-primary-800)}.prepr-status-pill[hidden]{display:none}.prepr-status-viewing{color:#fff9;font-size:10px}.prepr-status-segment{text-overflow:ellipsis;white-space:nowrap;max-width:120px;display:inline-block;overflow:hidden}.prepr-status-variant{text-overflow:ellipsis;white-space:nowrap;background:#fff3;border-radius:4px;max-width:80px;padding:0 .5rem;display:inline-block;overflow:hidden}.prepr-status-x{color:#fff;width:.75rem;height:.75rem}.prepr-close-edit-pill{background:var(--prepr-primary-50);color:var(--prepr-gray-800);cursor:pointer;border:none;border-radius:9999px;align-items:center;gap:.5rem;padding:.5rem 1rem;font-size:.75rem;font-weight:500;transition:background-color .15s;display:flex;box-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a}.prepr-close-edit-pill:hover{background:var(--prepr-primary-100)}.prepr-close-edit-pill[hidden]{display:none}.prepr-close-edit-x{width:1rem;height:1rem;color:var(--prepr-gray-500);transition:color .15s}.prepr-close-edit-pill:hover .prepr-close-edit-x{color:var(--prepr-gray-700)}.prepr-tip{z-index:calc(var(--prepr-z-index) + 2);overflow-wrap:break-word;background:var(--prepr-gray-900);color:#fff;pointer-events:none;border-radius:6px;width:auto;max-width:min(420px,100vw - 16px);padding:.5rem .75rem;font-size:.75rem;font-weight:500;position:fixed;box-shadow:0 20px 25px -5px #0000001a,0 8px 10px -6px #0000001a}.prepr-tip-arrow{border-left:6px solid #0000;border-right:6px solid #0000;border-top:6px solid var(--prepr-gray-900);width:0;height:0;position:absolute;top:100%;transform:translate(-50%)}[hidden]{display:none!important}@keyframes prepr-fade-in{0%{opacity:0}to{opacity:1}}";
|
|
1102
|
+
var TOOLBAR_CSS = ":host{--prepr-primary:#4338ca;--prepr-bg:#eef2ff;--prepr-text:#1f2937;--prepr-radius:8px;--prepr-shadow:0px 0px 40px 0px #1f29373d;--prepr-z-index:10000;--prepr-primary-50:#eef2ff;--prepr-primary-100:#e0e7ff;--prepr-primary-800:#3730a3;--prepr-indigo-600:#4f46e5;--prepr-indigo-50:#eef2ff;--prepr-indigo-700:#4338ca;--prepr-secondary-400:#fb923c;--prepr-secondary-500:#f97316;--prepr-gray-100:#f3f4f6;--prepr-gray-200:#e5e7eb;--prepr-gray-300:#d1d5db;--prepr-gray-400:#9ca3af;--prepr-gray-500:#6b7280;--prepr-gray-700:#374151;--prepr-gray-800:#1f2937;--prepr-gray-900:#111827;--prepr-shadow-sm:0px 0px 12px 0px #c3c3c3cc;color:var(--prepr-text);box-sizing:border-box;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif;font-size:14px;line-height:1.5}:host *,:host :before,:host :after,*,:before,:after{box-sizing:border-box}button{font-family:inherit;font-size:inherit;margin:0}.prepr-regular-text{font-size:.875rem;font-weight:500;line-height:1.5}.prepr-backdrop{z-index:calc(var(--prepr-z-index) - 1);opacity:0;pointer-events:none;background:#0000001a;transition:opacity .2s ease-in-out;position:fixed;top:0;bottom:0;left:0;right:0}.prepr-backdrop[data-open=true]{opacity:1;pointer-events:auto;animation:.2s ease-in-out prepr-fade-in}.prepr-container{z-index:var(--prepr-z-index);justify-content:flex-end;align-items:center;display:flex;position:fixed;top:calc(50% - 64px);right:0}.prepr-toggle-holder{padding:.5rem}.prepr-toggle{cursor:pointer;background:var(--prepr-primary);color:#fff;border:none;border-radius:9999px;justify-content:center;align-items:center;width:2.25rem;height:2.25rem;display:flex}.prepr-toggle>span{display:flex}.prepr-toggle svg{color:#fff}.prepr-panel{z-index:var(--prepr-z-index);opacity:0;pointer-events:none;justify-content:flex-end;padding:.75rem;transition:opacity .2s ease-in-out;display:flex;position:fixed;top:50%;right:0;transform:translateY(-50%)}.prepr-panel[data-open=true]{opacity:1;pointer-events:auto;animation:.2s ease-in-out prepr-fade-in}.prepr-content{box-shadow:var(--prepr-shadow);border-radius:var(--prepr-radius);background:var(--prepr-bg);flex-direction:column;gap:2.5rem;width:100%;padding:1.5rem;display:flex}@media (min-width:640px){.prepr-panel{margin-right:4rem;padding:0}.prepr-content{width:502px;padding:2.5rem}}.prepr-header{justify-content:space-between;align-items:center;gap:.5rem;display:flex}.prepr-header-left{align-items:flex-start;gap:.75rem;display:flex}.prepr-badge{background:var(--prepr-primary-100);height:1.5rem;color:var(--prepr-primary);border-radius:4px;align-items:center;padding:.25rem .75rem;font-size:.875rem;display:flex}.prepr-header-close{cursor:pointer;background:var(--prepr-primary-100);width:2rem;height:2rem;color:var(--prepr-gray-700);border:none;border-radius:6px;justify-content:center;align-items:center;display:flex}.prepr-section{flex-direction:column;gap:.5rem;display:flex}.prepr-section-label{color:var(--prepr-gray-400);font-size:.875rem}.prepr-row{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:.5rem 1.5rem;display:flex}.prepr-row-title{color:var(--prepr-gray-800);margin:0;font-size:1rem;font-weight:600}.prepr-radiogroup{border-radius:var(--prepr-radius);border:1px solid var(--prepr-gray-300);background:#fff;align-items:center;gap:.25rem;height:2.5rem;padding:.25rem;display:flex}.prepr-radiogroup[data-disabled=true]{cursor:not-allowed;opacity:.5}.prepr-radiogroup[data-disabled=true] .prepr-radio{pointer-events:none}.prepr-radio{cursor:pointer;white-space:nowrap;text-align:center;height:2rem;color:var(--prepr-gray-900);background:0 0;border:none;border-radius:6px;justify-content:center;align-items:center;padding:.5rem 1.125rem;font-size:.875rem;font-weight:500;transition:all .2s ease-in-out;display:flex}.prepr-radio[data-checked=true]{background:var(--prepr-indigo-600);color:#fff;box-shadow:var(--prepr-shadow-sm)}.prepr-radio[data-checked=true][data-off=true]{background:var(--prepr-gray-800);color:#fff}.prepr-radio-variant{width:82px}.prepr-listbox{position:relative}.prepr-segment-button{border-radius:var(--prepr-radius);border:1px solid var(--prepr-gray-300);width:240px;height:2.5rem;color:var(--prepr-gray-500);cursor:pointer;background:#fff;flex-shrink:0;align-items:center;gap:.5rem;padding:0 .5rem;font-size:.875rem;font-weight:500;display:flex;overflow:hidden}@media (min-width:768px){.prepr-segment-button{padding:0 1rem}}.prepr-segment-button:disabled{cursor:not-allowed;background:var(--prepr-gray-200);color:var(--prepr-gray-400)}.prepr-segment-button[aria-expanded=true]{border-bottom-color:#fff;border-bottom-right-radius:0;border-bottom-left-radius:0}.prepr-segment-label{white-space:nowrap;text-overflow:ellipsis;text-align:left;width:100%;margin-right:auto;overflow:hidden}.prepr-segment-caret{color:var(--prepr-gray-800);display:flex}.prepr-options{z-index:calc(var(--prepr-z-index) + 1);border-left:1px solid var(--prepr-gray-300);border-right:1px solid var(--prepr-gray-300);border-bottom:1px solid var(--prepr-gray-300);-ms-overflow-style:none;scrollbar-width:none;background:#fff;border-radius:0 0 6px 6px;width:240px;max-height:300px;margin:0;padding:0;list-style:none;position:absolute;top:100%;left:0;overflow-y:auto;box-shadow:0 20px 25px -5px #0000001a,0 8px 10px -6px #0000001a}.prepr-options::-webkit-scrollbar{display:none}.prepr-options[hidden]{display:none}.prepr-option-search{background:#fff;padding:.5rem;position:-webkit-sticky;position:sticky;top:0}.prepr-segment-search{border:1px solid var(--prepr-gray-300);border-radius:var(--prepr-radius);width:100%;height:2rem;font:inherit;color:var(--prepr-gray-900);box-sizing:border-box;background:#fff;padding:0 .5rem;font-size:.875rem}.prepr-segment-search::placeholder{color:var(--prepr-gray-400)}.prepr-segment-search:focus{border-color:var(--prepr-gray-400);outline:none}.prepr-option{cursor:pointer;width:100%;color:var(--prepr-gray-900);background:#fff;align-items:center;padding:.5rem 1rem;font-size:.875rem;font-weight:500;display:flex}.prepr-option:hover{background:var(--prepr-gray-100)}.prepr-option[aria-selected=true]{background:var(--prepr-indigo-50);color:var(--prepr-indigo-700)}.prepr-option-label{white-space:nowrap;text-overflow:ellipsis;text-align:left;width:100%;margin-right:auto;overflow:hidden}.prepr-reset{background:var(--prepr-secondary-400);color:#fff;cursor:pointer;border:none;border-radius:6px;justify-content:center;align-items:center;gap:.5rem;width:100%;height:2.5rem;padding:.5rem .75rem;font-size:.875rem;font-weight:500;display:flex}.prepr-reset:hover:not(:disabled){background:var(--prepr-secondary-500)}.prepr-reset:disabled{background:var(--prepr-gray-400);color:var(--prepr-gray-500);cursor:not-allowed}@media (min-width:768px){.prepr-reset{width:108px}}.prepr-indicators{z-index:var(--prepr-z-index);gap:.75rem;display:flex;position:fixed;bottom:1.5rem;right:1.5rem}.prepr-status-pill{background:var(--prepr-primary);color:#fff;cursor:pointer;border:none;border-radius:9999px;align-items:center;gap:.5rem;padding:.5rem 1rem;font-size:.75rem;font-weight:500;transition:background-color .15s;display:flex;box-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a}.prepr-status-pill[data-interactive=false]{cursor:default;opacity:1;color:#fff}.prepr-status-pill[data-interactive=true]:hover{background:var(--prepr-primary-800)}.prepr-status-pill[hidden]{display:none}.prepr-status-viewing{color:#fff9;font-size:10px}.prepr-status-segment{text-overflow:ellipsis;white-space:nowrap;max-width:120px;display:inline-block;overflow:hidden}.prepr-status-variant{text-overflow:ellipsis;white-space:nowrap;background:#fff3;border-radius:4px;max-width:80px;padding:0 .5rem;display:inline-block;overflow:hidden}.prepr-status-x{color:#fff;width:.75rem;height:.75rem}.prepr-close-edit-pill{background:var(--prepr-primary-50);color:var(--prepr-gray-800);cursor:pointer;border:none;border-radius:9999px;align-items:center;gap:.5rem;padding:.5rem 1rem;font-size:.75rem;font-weight:500;transition:background-color .15s;display:flex;box-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a}.prepr-close-edit-pill:hover{background:var(--prepr-primary-100)}.prepr-close-edit-pill[hidden]{display:none}.prepr-close-edit-x{width:1rem;height:1rem;color:var(--prepr-gray-500);transition:color .15s}.prepr-close-edit-pill:hover .prepr-close-edit-x{color:var(--prepr-gray-700)}.prepr-tip{z-index:calc(var(--prepr-z-index) + 2);overflow-wrap:break-word;background:var(--prepr-gray-900);color:#fff;pointer-events:none;border-radius:6px;width:auto;max-width:min(420px,100vw - 16px);padding:.5rem .75rem;font-size:.75rem;font-weight:500;position:fixed;box-shadow:0 20px 25px -5px #0000001a,0 8px 10px -6px #0000001a}.prepr-tip-arrow{border-left:6px solid #0000;border-right:6px solid #0000;border-top:6px solid var(--prepr-gray-900);width:0;height:0;position:absolute;top:100%;transform:translate(-50%)}[hidden]{display:none!important}@keyframes prepr-fade-in{0%{opacity:0}to{opacity:1}}";
|
|
1035
1103
|
|
|
1036
1104
|
// ../../node_modules/.pnpm/preact@10.29.7/node_modules/preact/jsx-runtime/dist/jsxRuntime.mjs
|
|
1037
1105
|
var f2 = 0;
|
|
@@ -1290,13 +1358,17 @@ function StatusPill({
|
|
|
1290
1358
|
} else {
|
|
1291
1359
|
segmentLabel = defaultSegmentName;
|
|
1292
1360
|
}
|
|
1361
|
+
const dirty = features.segments && state.selectedSegment !== null || features.abTesting && state.selectedVariant === "B";
|
|
1362
|
+
const interactive = !state.previewMode || dirty;
|
|
1293
1363
|
return /* @__PURE__ */ u2(
|
|
1294
1364
|
"button",
|
|
1295
1365
|
{
|
|
1296
1366
|
type: "button",
|
|
1297
1367
|
class: "prepr-status-pill",
|
|
1298
1368
|
"data-prepr": "status-pill",
|
|
1369
|
+
"data-interactive": String(interactive),
|
|
1299
1370
|
hidden: state.isIframe,
|
|
1371
|
+
disabled: !interactive,
|
|
1300
1372
|
onClick: () => handlers.onStatusPill(),
|
|
1301
1373
|
children: [
|
|
1302
1374
|
/* @__PURE__ */ u2("span", { class: "prepr-status-viewing", "data-prepr": "status-viewing", children: t3("common.viewingAs") }),
|
|
@@ -1315,7 +1387,7 @@ function StatusPill({
|
|
|
1315
1387
|
{
|
|
1316
1388
|
class: "prepr-status-x",
|
|
1317
1389
|
"data-prepr": "status-x",
|
|
1318
|
-
hidden: !state.previewMode || !
|
|
1390
|
+
hidden: !state.previewMode || !dirty,
|
|
1319
1391
|
children: /* @__PURE__ */ u2(RawSvg, { svg: XMARK_ICON_SVG })
|
|
1320
1392
|
}
|
|
1321
1393
|
)
|
|
@@ -2119,7 +2191,9 @@ function createPreprPreview(opts = {}) {
|
|
|
2119
2191
|
}
|
|
2120
2192
|
}
|
|
2121
2193
|
});
|
|
2122
|
-
const autoClean = createStegaAutoClean(
|
|
2194
|
+
const autoClean = createStegaAutoClean({
|
|
2195
|
+
enabled: options?.autoClean
|
|
2196
|
+
});
|
|
2123
2197
|
autoClean.start();
|
|
2124
2198
|
const handleChange = createChangeHandler({
|
|
2125
2199
|
store,
|
|
@@ -2165,7 +2239,7 @@ function createPreprPreview(opts = {}) {
|
|
|
2165
2239
|
}
|
|
2166
2240
|
|
|
2167
2241
|
// src/core/pixel.ts
|
|
2168
|
-
var PIXEL_SCRIPT_URL = "https://cdn.tracking.prepr.io/js/prepr
|
|
2242
|
+
var PIXEL_SCRIPT_URL = "https://cdn.tracking.prepr.io/js/prepr.min.js";
|
|
2169
2243
|
var CACHE_BUST_INTERVAL_MS = 24 * 60 * 60 * 1e3;
|
|
2170
2244
|
var warnedNoPixel = false;
|
|
2171
2245
|
function warnNoPixelOnce() {
|