@preprio/toolkit 0.1.0-beta.1 → 0.1.0-beta.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 +56 -3
- package/dist/astro/index.cjs +34 -10
- package/dist/astro/index.js +34 -10
- package/dist/{chunk-H7HVQSSF.js → chunk-3FOY6KL4.js} +100 -25
- package/dist/index.cjs +119 -29
- package/dist/index.d.cts +12 -1
- package/dist/index.d.ts +12 -1
- package/dist/index.js +20 -5
- package/dist/nextjs/components.cjs +100 -25
- package/dist/nextjs/components.js +1 -1
- package/dist/nextjs/index.cjs +23 -5
- package/dist/nextjs/index.js +23 -5
- package/dist/nuxt/index.cjs +399 -0
- package/dist/nuxt/index.d.cts +120 -0
- package/dist/nuxt/index.d.ts +120 -0
- package/dist/nuxt/index.js +362 -0
- package/dist/sveltekit/index.cjs +34 -10
- package/dist/sveltekit/index.js +34 -10
- package/package.json +11 -4
- package/src/nuxt/PreprToolbar.vue +38 -0
- package/src/nuxt/PreprTrackingPixel.vue +24 -0
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @preprio/toolkit
|
|
2
2
|
|
|
3
|
-
A framework-agnostic TypeScript library that provides preview functionality, visual editing capabilities, and A/B testing for [Prepr CMS](https://prepr.io). Ships thin wrappers for Next.js, Astro, and SvelteKit on top of a vanilla core that runs anywhere.
|
|
3
|
+
A framework-agnostic TypeScript library that provides preview functionality, visual editing capabilities, 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
4
|
|
|
5
5
|
## Quick Start
|
|
6
6
|
|
|
@@ -83,6 +83,7 @@ Per-framework requirements:
|
|
|
83
83
|
| `@preprio/toolkit/nextjs` | `next` >= 13, `react` >= 17, `react-dom` >= 17 |
|
|
84
84
|
| `@preprio/toolkit/astro` | none (`.astro` components compile in your own pipeline) |
|
|
85
85
|
| `@preprio/toolkit/sveltekit` | `svelte` (only for the `.svelte` components) |
|
|
86
|
+
| `@preprio/toolkit/nuxt` | `vue` (only for the `.vue` components) |
|
|
86
87
|
|
|
87
88
|
All peer dependencies are optional — installing without React or Next.js is fine as long as you only import the entry points you have dependencies for.
|
|
88
89
|
|
|
@@ -471,6 +472,57 @@ const preprHeaders = getPreprHeadersFromLocals(event.locals);
|
|
|
471
472
|
|
|
472
473
|
See the runnable example at `examples/sveltekit` for the full source of truth.
|
|
473
474
|
|
|
475
|
+
## Nuxt
|
|
476
|
+
|
|
477
|
+
`vue` is an optional peer dependency, needed only if you import the `.vue` components. Requires Nitro's Node.js preset (the Nuxt default).
|
|
478
|
+
|
|
479
|
+
**`server/middleware/prepr.ts`**
|
|
480
|
+
|
|
481
|
+
```typescript
|
|
482
|
+
import { handlePreprRequest } from '@preprio/toolkit/nuxt';
|
|
483
|
+
|
|
484
|
+
export default defineEventHandler(event => {
|
|
485
|
+
handlePreprRequest(event, { preview: import.meta.dev });
|
|
486
|
+
});
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
**`app/app.vue`** — resolve the toolbar props on the server, gated on the same flag:
|
|
490
|
+
|
|
491
|
+
```vue
|
|
492
|
+
<script setup lang="ts">
|
|
493
|
+
import { getToolbarProps } from '@preprio/toolkit/nuxt';
|
|
494
|
+
import PreprToolbar from '@preprio/toolkit/nuxt/components/PreprToolbar';
|
|
495
|
+
import PreprTrackingPixel from '@preprio/toolkit/nuxt/components/PreprTrackingPixel';
|
|
496
|
+
|
|
497
|
+
const requestHeaders = useRequestHeaders();
|
|
498
|
+
const { data: toolbarProps } = await useAsyncData('prepr-toolbar', async () => {
|
|
499
|
+
if (!import.meta.dev) return null;
|
|
500
|
+
return getToolbarProps(
|
|
501
|
+
new Headers(requestHeaders as Record<string, string>),
|
|
502
|
+
useRuntimeConfig().public.preprGraphqlUrl
|
|
503
|
+
);
|
|
504
|
+
});
|
|
505
|
+
</script>
|
|
506
|
+
|
|
507
|
+
<template>
|
|
508
|
+
<NuxtPage />
|
|
509
|
+
<PreprTrackingPixel id="YOUR_ACCESS_TOKEN" />
|
|
510
|
+
<PreprToolbar v-if="toolbarProps" v-bind="toolbarProps" />
|
|
511
|
+
</template>
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
The `.vue` components ship as source (compiled by your own Vite/Vue pipeline) and mount client-side via `onMounted`, so they never run during SSR.
|
|
515
|
+
|
|
516
|
+
The middleware folds the computed Prepr headers back onto the incoming request — read them via `useRequestHeaders()` in composables, or straight off the h3 event in server routes:
|
|
517
|
+
|
|
518
|
+
```typescript
|
|
519
|
+
import { getPreprHeadersFromEvent } from '@preprio/toolkit/nuxt';
|
|
520
|
+
|
|
521
|
+
const preprHeaders = getPreprHeadersFromEvent(event);
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
See the runnable example at `examples/nuxt` for the full source of truth.
|
|
525
|
+
|
|
474
526
|
## Any other framework
|
|
475
527
|
|
|
476
528
|
The core is runtime-neutral: it works off a WHATWG `Request` and hands back the headers to forward to Prepr plus the cookies to persist. Adapting it to Express, Hono, Fastify, or a plain server is roughly twenty lines.
|
|
@@ -522,7 +574,7 @@ Serialize the server-computed props into the page — a `<script type="applicati
|
|
|
522
574
|
|
|
523
575
|
Each wrapper exposes the same five helpers, differing only in how they reach the request headers.
|
|
524
576
|
|
|
525
|
-
| Helper | Next.js | Astro / SvelteKit |
|
|
577
|
+
| Helper | Next.js | Astro / SvelteKit / Nuxt |
|
|
526
578
|
| --- | --- | --- |
|
|
527
579
|
| `getPreprUUID` | `await getPreprUUID()` | `getPreprUUID(headers)` |
|
|
528
580
|
| `getActiveSegment` | `await getActiveSegment()` | `getActiveSegment(headers)` |
|
|
@@ -530,7 +582,7 @@ Each wrapper exposes the same five helpers, differing only in how they reach the
|
|
|
530
582
|
| `getPreprHeaders` | `await getPreprHeaders()` | `getPreprHeaders(headers)` |
|
|
531
583
|
| `getToolbarProps` | `await getToolbarProps(token)` | `await getToolbarProps(headers, token)` |
|
|
532
584
|
|
|
533
|
-
The Next.js versions read via `next/headers` and are async. The Astro and
|
|
585
|
+
The Next.js versions read via `next/headers` and are async. The Astro, SvelteKit and Nuxt versions take a standard `Headers` (`Astro.request.headers`, `event.request.headers`, or one built from `useRequestHeaders()`) and are sync, except `getToolbarProps`.
|
|
534
586
|
|
|
535
587
|
#### `getPreprUUID()`
|
|
536
588
|
|
|
@@ -895,6 +947,7 @@ Runnable examples live in the repository root:
|
|
|
895
947
|
| `examples/nextjs` | App Router, middleware, Apollo, custom image loader |
|
|
896
948
|
| `examples/astro` | Astro middleware and `.astro` components |
|
|
897
949
|
| `examples/sveltekit` | `hooks.server.ts`, `+layout.server.ts`, `.svelte` components |
|
|
950
|
+
| `examples/nuxt` | `server/middleware`, `useAsyncData`, `.vue` components |
|
|
898
951
|
| `examples/express` | Vanilla core — a hand-written adapter for an unsupported framework |
|
|
899
952
|
|
|
900
953
|
## Support
|
package/dist/astro/index.cjs
CHANGED
|
@@ -30,7 +30,7 @@ __export(astro_exports, {
|
|
|
30
30
|
module.exports = __toCommonJS(astro_exports);
|
|
31
31
|
|
|
32
32
|
// src/version.ts
|
|
33
|
-
var VERSION = "0.1.0-beta.
|
|
33
|
+
var VERSION = "0.1.0-beta.4";
|
|
34
34
|
|
|
35
35
|
// src/core/server.ts
|
|
36
36
|
var PreprError = class extends Error {
|
|
@@ -172,6 +172,20 @@ var UTM_PARAMS = [
|
|
|
172
172
|
"utm_content",
|
|
173
173
|
"utm_campaign"
|
|
174
174
|
];
|
|
175
|
+
function serializeCookie(cookie) {
|
|
176
|
+
const parts = [
|
|
177
|
+
`${cookie.name}=${encodeURIComponent(cookie.value)}`,
|
|
178
|
+
`Max-Age=${cookie.maxAge}`,
|
|
179
|
+
`Path=${cookie.path}`
|
|
180
|
+
];
|
|
181
|
+
if (cookie.sameSite) {
|
|
182
|
+
parts.push(`SameSite=${cookie.sameSite}`);
|
|
183
|
+
}
|
|
184
|
+
if (cookie.secure) {
|
|
185
|
+
parts.push("Secure");
|
|
186
|
+
}
|
|
187
|
+
return parts.join("; ");
|
|
188
|
+
}
|
|
175
189
|
function parseCookies(request) {
|
|
176
190
|
const cookies = /* @__PURE__ */ new Map();
|
|
177
191
|
const header = request.headers.get("cookie");
|
|
@@ -190,7 +204,11 @@ function processPreprRequest(request, opts) {
|
|
|
190
204
|
const requestHeaders = new Headers(request.headers);
|
|
191
205
|
const responseCookies = [];
|
|
192
206
|
const requestCookies = parseCookies(request);
|
|
193
|
-
const
|
|
207
|
+
const url = new URL(request.url);
|
|
208
|
+
const searchParams = url.searchParams;
|
|
209
|
+
const forwardedProto = request.headers.get("x-forwarded-proto")?.split(",")[0]?.trim();
|
|
210
|
+
const isSecure = forwardedProto ? forwardedProto === "https" : url.protocol === "https:";
|
|
211
|
+
const crossSite = isSecure ? { sameSite: "None", secure: true } : {};
|
|
194
212
|
for (const key of UTM_PARAMS) {
|
|
195
213
|
const value = searchParams.get(key);
|
|
196
214
|
if (value !== null) {
|
|
@@ -239,6 +257,15 @@ function processPreprRequest(request, opts) {
|
|
|
239
257
|
}
|
|
240
258
|
requestHeaders.set("Prepr-Preview-Bar", "true");
|
|
241
259
|
const isLivePreview = searchParams.get(PARAM_HIDE_BAR) === "true";
|
|
260
|
+
if (!isLivePreview && !requestCookies.has(COOKIE_PREVIEW_MODE)) {
|
|
261
|
+
responseCookies.push({
|
|
262
|
+
name: COOKIE_PREVIEW_MODE,
|
|
263
|
+
value: "true",
|
|
264
|
+
maxAge: ONE_YEAR_SECONDS,
|
|
265
|
+
path: "/",
|
|
266
|
+
...crossSite
|
|
267
|
+
});
|
|
268
|
+
}
|
|
242
269
|
if (!isLivePreview) {
|
|
243
270
|
const segmentCookie = requestCookies.get(COOKIE_SEGMENT);
|
|
244
271
|
if (segmentCookie) {
|
|
@@ -257,7 +284,8 @@ function processPreprRequest(request, opts) {
|
|
|
257
284
|
name: COOKIE_VARIANT,
|
|
258
285
|
value: previewAb,
|
|
259
286
|
maxAge: ONE_YEAR_SECONDS,
|
|
260
|
-
path: "/"
|
|
287
|
+
path: "/",
|
|
288
|
+
...crossSite
|
|
261
289
|
});
|
|
262
290
|
}
|
|
263
291
|
}
|
|
@@ -269,7 +297,8 @@ function processPreprRequest(request, opts) {
|
|
|
269
297
|
name: COOKIE_SEGMENT,
|
|
270
298
|
value: previewSegment,
|
|
271
299
|
maxAge: ONE_YEAR_SECONDS,
|
|
272
|
-
path: "/"
|
|
300
|
+
path: "/",
|
|
301
|
+
...crossSite
|
|
273
302
|
});
|
|
274
303
|
}
|
|
275
304
|
}
|
|
@@ -284,12 +313,7 @@ async function onPreprRequest(context, next, options) {
|
|
|
284
313
|
});
|
|
285
314
|
const response = await next();
|
|
286
315
|
for (const cookie of responseCookies) {
|
|
287
|
-
|
|
288
|
-
`${cookie.name}=${encodeURIComponent(cookie.value)}`,
|
|
289
|
-
`Max-Age=${cookie.maxAge}`,
|
|
290
|
-
`Path=${cookie.path}`
|
|
291
|
-
];
|
|
292
|
-
response.headers.append("Set-Cookie", parts.join("; "));
|
|
316
|
+
response.headers.append("Set-Cookie", serializeCookie(cookie));
|
|
293
317
|
}
|
|
294
318
|
return response;
|
|
295
319
|
}
|
package/dist/astro/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/version.ts
|
|
2
|
-
var VERSION = "0.1.0-beta.
|
|
2
|
+
var VERSION = "0.1.0-beta.4";
|
|
3
3
|
|
|
4
4
|
// src/core/server.ts
|
|
5
5
|
var PreprError = class extends Error {
|
|
@@ -141,6 +141,20 @@ var UTM_PARAMS = [
|
|
|
141
141
|
"utm_content",
|
|
142
142
|
"utm_campaign"
|
|
143
143
|
];
|
|
144
|
+
function serializeCookie(cookie) {
|
|
145
|
+
const parts = [
|
|
146
|
+
`${cookie.name}=${encodeURIComponent(cookie.value)}`,
|
|
147
|
+
`Max-Age=${cookie.maxAge}`,
|
|
148
|
+
`Path=${cookie.path}`
|
|
149
|
+
];
|
|
150
|
+
if (cookie.sameSite) {
|
|
151
|
+
parts.push(`SameSite=${cookie.sameSite}`);
|
|
152
|
+
}
|
|
153
|
+
if (cookie.secure) {
|
|
154
|
+
parts.push("Secure");
|
|
155
|
+
}
|
|
156
|
+
return parts.join("; ");
|
|
157
|
+
}
|
|
144
158
|
function parseCookies(request) {
|
|
145
159
|
const cookies = /* @__PURE__ */ new Map();
|
|
146
160
|
const header = request.headers.get("cookie");
|
|
@@ -159,7 +173,11 @@ function processPreprRequest(request, opts) {
|
|
|
159
173
|
const requestHeaders = new Headers(request.headers);
|
|
160
174
|
const responseCookies = [];
|
|
161
175
|
const requestCookies = parseCookies(request);
|
|
162
|
-
const
|
|
176
|
+
const url = new URL(request.url);
|
|
177
|
+
const searchParams = url.searchParams;
|
|
178
|
+
const forwardedProto = request.headers.get("x-forwarded-proto")?.split(",")[0]?.trim();
|
|
179
|
+
const isSecure = forwardedProto ? forwardedProto === "https" : url.protocol === "https:";
|
|
180
|
+
const crossSite = isSecure ? { sameSite: "None", secure: true } : {};
|
|
163
181
|
for (const key of UTM_PARAMS) {
|
|
164
182
|
const value = searchParams.get(key);
|
|
165
183
|
if (value !== null) {
|
|
@@ -208,6 +226,15 @@ function processPreprRequest(request, opts) {
|
|
|
208
226
|
}
|
|
209
227
|
requestHeaders.set("Prepr-Preview-Bar", "true");
|
|
210
228
|
const isLivePreview = searchParams.get(PARAM_HIDE_BAR) === "true";
|
|
229
|
+
if (!isLivePreview && !requestCookies.has(COOKIE_PREVIEW_MODE)) {
|
|
230
|
+
responseCookies.push({
|
|
231
|
+
name: COOKIE_PREVIEW_MODE,
|
|
232
|
+
value: "true",
|
|
233
|
+
maxAge: ONE_YEAR_SECONDS,
|
|
234
|
+
path: "/",
|
|
235
|
+
...crossSite
|
|
236
|
+
});
|
|
237
|
+
}
|
|
211
238
|
if (!isLivePreview) {
|
|
212
239
|
const segmentCookie = requestCookies.get(COOKIE_SEGMENT);
|
|
213
240
|
if (segmentCookie) {
|
|
@@ -226,7 +253,8 @@ function processPreprRequest(request, opts) {
|
|
|
226
253
|
name: COOKIE_VARIANT,
|
|
227
254
|
value: previewAb,
|
|
228
255
|
maxAge: ONE_YEAR_SECONDS,
|
|
229
|
-
path: "/"
|
|
256
|
+
path: "/",
|
|
257
|
+
...crossSite
|
|
230
258
|
});
|
|
231
259
|
}
|
|
232
260
|
}
|
|
@@ -238,7 +266,8 @@ function processPreprRequest(request, opts) {
|
|
|
238
266
|
name: COOKIE_SEGMENT,
|
|
239
267
|
value: previewSegment,
|
|
240
268
|
maxAge: ONE_YEAR_SECONDS,
|
|
241
|
-
path: "/"
|
|
269
|
+
path: "/",
|
|
270
|
+
...crossSite
|
|
242
271
|
});
|
|
243
272
|
}
|
|
244
273
|
}
|
|
@@ -253,12 +282,7 @@ async function onPreprRequest(context, next, options) {
|
|
|
253
282
|
});
|
|
254
283
|
const response = await next();
|
|
255
284
|
for (const cookie of responseCookies) {
|
|
256
|
-
|
|
257
|
-
`${cookie.name}=${encodeURIComponent(cookie.value)}`,
|
|
258
|
-
`Max-Age=${cookie.maxAge}`,
|
|
259
|
-
`Path=${cookie.path}`
|
|
260
|
-
];
|
|
261
|
-
response.headers.append("Set-Cookie", parts.join("; "));
|
|
285
|
+
response.headers.append("Set-Cookie", serializeCookie(cookie));
|
|
262
286
|
}
|
|
263
287
|
return response;
|
|
264
288
|
}
|
|
@@ -1006,7 +1006,7 @@ var CLOSE_ICON_SVG = `<svg width="10" height="10" viewBox="0 0 10 10" fill="none
|
|
|
1006
1006
|
</svg>`;
|
|
1007
1007
|
|
|
1008
1008
|
// src/core/ui/toolbar.generated.ts
|
|
1009
|
-
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 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{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}}";
|
|
1009
|
+
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 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}}";
|
|
1010
1010
|
|
|
1011
1011
|
// ../../node_modules/.pnpm/preact@10.29.7/node_modules/preact/jsx-runtime/dist/jsxRuntime.mjs
|
|
1012
1012
|
var f2 = 0;
|
|
@@ -1095,10 +1095,13 @@ function SegmentListbox({
|
|
|
1095
1095
|
state,
|
|
1096
1096
|
t: t3,
|
|
1097
1097
|
listboxOpen,
|
|
1098
|
+
segmentFilter,
|
|
1098
1099
|
handlers
|
|
1099
1100
|
}) {
|
|
1100
1101
|
const segments = state.segments;
|
|
1101
1102
|
const hasSegments = segments.length > 0;
|
|
1103
|
+
const filter = segmentFilter.trim().toLowerCase();
|
|
1104
|
+
const visibleSegments = filter ? segments.filter((s2) => s2.name.toLowerCase().includes(filter)) : segments;
|
|
1102
1105
|
let label;
|
|
1103
1106
|
if (!hasSegments) {
|
|
1104
1107
|
label = t3("adaptiveContent.none");
|
|
@@ -1135,15 +1138,30 @@ function SegmentListbox({
|
|
|
1135
1138
|
role: "listbox",
|
|
1136
1139
|
hidden: !listboxOpen,
|
|
1137
1140
|
onKeyDown: (e2) => handlers.onOptionsKeydown(e2),
|
|
1138
|
-
children:
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1141
|
+
children: [
|
|
1142
|
+
/* @__PURE__ */ u2("li", { class: "prepr-option-search", role: "none", children: /* @__PURE__ */ u2(
|
|
1143
|
+
"input",
|
|
1144
|
+
{
|
|
1145
|
+
type: "text",
|
|
1146
|
+
class: "prepr-segment-search",
|
|
1147
|
+
"data-prepr": "segment-search",
|
|
1148
|
+
placeholder: t3("adaptiveContent.searchSegments"),
|
|
1149
|
+
value: segmentFilter,
|
|
1150
|
+
onInput: (e2) => handlers.onSegmentFilterInput(
|
|
1151
|
+
e2.currentTarget.value
|
|
1152
|
+
)
|
|
1153
|
+
}
|
|
1154
|
+
) }),
|
|
1155
|
+
visibleSegments.map((seg) => /* @__PURE__ */ u2(
|
|
1156
|
+
SegmentOption,
|
|
1157
|
+
{
|
|
1158
|
+
seg,
|
|
1159
|
+
selected: seg._id === state.selectedSegment,
|
|
1160
|
+
onChoose: handlers.onChooseSegment
|
|
1161
|
+
},
|
|
1162
|
+
seg._id
|
|
1163
|
+
))
|
|
1164
|
+
]
|
|
1147
1165
|
}
|
|
1148
1166
|
)
|
|
1149
1167
|
] });
|
|
@@ -1268,7 +1286,7 @@ function StatusPill({
|
|
|
1268
1286
|
{
|
|
1269
1287
|
class: "prepr-status-x",
|
|
1270
1288
|
"data-prepr": "status-x",
|
|
1271
|
-
hidden: state.selectedSegment === null,
|
|
1289
|
+
hidden: !state.previewMode || state.selectedSegment === null,
|
|
1272
1290
|
children: /* @__PURE__ */ u2(RawSvg, { svg: XMARK_ICON_SVG })
|
|
1273
1291
|
}
|
|
1274
1292
|
)
|
|
@@ -1297,7 +1315,13 @@ function CloseEditPill({
|
|
|
1297
1315
|
}
|
|
1298
1316
|
);
|
|
1299
1317
|
}
|
|
1300
|
-
function Panel({
|
|
1318
|
+
function Panel({
|
|
1319
|
+
state,
|
|
1320
|
+
t: t3,
|
|
1321
|
+
listboxOpen,
|
|
1322
|
+
segmentFilter,
|
|
1323
|
+
handlers
|
|
1324
|
+
}) {
|
|
1301
1325
|
const hasPersonalization = state.selectedSegment !== null || state.selectedVariant !== null;
|
|
1302
1326
|
return /* @__PURE__ */ u2(S, { children: [
|
|
1303
1327
|
/* @__PURE__ */ u2(
|
|
@@ -1354,6 +1378,7 @@ function Panel({ state, t: t3, listboxOpen, handlers }) {
|
|
|
1354
1378
|
state,
|
|
1355
1379
|
t: t3,
|
|
1356
1380
|
listboxOpen,
|
|
1381
|
+
segmentFilter,
|
|
1357
1382
|
handlers
|
|
1358
1383
|
}
|
|
1359
1384
|
)
|
|
@@ -1411,6 +1436,7 @@ var PreprToolbarElement = class extends HTMLElementBase {
|
|
|
1411
1436
|
this.t = (key) => key;
|
|
1412
1437
|
this.unsubscribe = null;
|
|
1413
1438
|
this.listboxOpen = false;
|
|
1439
|
+
this.segmentFilter = "";
|
|
1414
1440
|
this.handlers = {
|
|
1415
1441
|
onToggle: () => this.set({ toolbarOpen: !this.state.toolbarOpen }),
|
|
1416
1442
|
onClose: () => this.set({ toolbarOpen: false }),
|
|
@@ -1441,6 +1467,10 @@ var PreprToolbarElement = class extends HTMLElementBase {
|
|
|
1441
1467
|
onSegmentButtonKeydown: (e2) => this.onListboxKeydown(e2),
|
|
1442
1468
|
onOptionsKeydown: (e2) => this.onListboxKeydown(e2),
|
|
1443
1469
|
onChooseSegment: (id) => this.chooseSegment(id),
|
|
1470
|
+
onSegmentFilterInput: (value) => {
|
|
1471
|
+
this.segmentFilter = value;
|
|
1472
|
+
this.renderPanel(this.state);
|
|
1473
|
+
},
|
|
1444
1474
|
onPreviewTooltipEnter: (el) => this.showTooltip(el),
|
|
1445
1475
|
onPreviewTooltipLeave: () => this.hideTooltip()
|
|
1446
1476
|
};
|
|
@@ -1489,6 +1519,7 @@ var PreprToolbarElement = class extends HTMLElementBase {
|
|
|
1489
1519
|
state,
|
|
1490
1520
|
t: this.t,
|
|
1491
1521
|
listboxOpen: this.listboxOpen,
|
|
1522
|
+
segmentFilter: this.segmentFilter,
|
|
1492
1523
|
handlers: this.handlers
|
|
1493
1524
|
}),
|
|
1494
1525
|
root
|
|
@@ -1554,6 +1585,8 @@ var PreprToolbarElement = class extends HTMLElementBase {
|
|
|
1554
1585
|
onListboxKeydown(event) {
|
|
1555
1586
|
const e2 = event;
|
|
1556
1587
|
const options = this.optionEls();
|
|
1588
|
+
const inSearch = e2.target?.getAttribute?.("data-prepr") === "segment-search";
|
|
1589
|
+
if (inSearch && e2.key === " ") return;
|
|
1557
1590
|
if (options.length === 0 && e2.key !== "Escape") return;
|
|
1558
1591
|
switch (e2.key) {
|
|
1559
1592
|
case "Enter":
|
|
@@ -1615,6 +1648,7 @@ var PreprToolbarElement = class extends HTMLElementBase {
|
|
|
1615
1648
|
const button = this.segmentButton();
|
|
1616
1649
|
if (button?.disabled) return;
|
|
1617
1650
|
this.listboxOpen = open;
|
|
1651
|
+
this.segmentFilter = "";
|
|
1618
1652
|
this.renderPanel(this.state);
|
|
1619
1653
|
if (open) {
|
|
1620
1654
|
const options = this.optionEls();
|
|
@@ -1625,11 +1659,17 @@ var PreprToolbarElement = class extends HTMLElementBase {
|
|
|
1625
1659
|
options.forEach(
|
|
1626
1660
|
(el, i2) => el.setAttribute("data-active", String(i2 === activeIndex))
|
|
1627
1661
|
);
|
|
1628
|
-
|
|
1662
|
+
this.searchInput()?.focus();
|
|
1629
1663
|
}
|
|
1630
1664
|
}
|
|
1665
|
+
searchInput() {
|
|
1666
|
+
return this.shadowRoot?.querySelector(
|
|
1667
|
+
'[data-prepr="segment-search"]'
|
|
1668
|
+
) ?? null;
|
|
1669
|
+
}
|
|
1631
1670
|
chooseSegment(id) {
|
|
1632
1671
|
this.listboxOpen = false;
|
|
1672
|
+
this.segmentFilter = "";
|
|
1633
1673
|
this.set({ selectedSegment: id });
|
|
1634
1674
|
this.renderPanel(this.state);
|
|
1635
1675
|
this.segmentButton()?.focus();
|
|
@@ -1664,16 +1704,34 @@ function getCookie(name) {
|
|
|
1664
1704
|
}
|
|
1665
1705
|
function setCookie(name, value, options = {}) {
|
|
1666
1706
|
if (typeof document === "undefined") return;
|
|
1667
|
-
const { maxAge, path = "/" } = options;
|
|
1707
|
+
const { maxAge, path = "/", sameSite, secure } = options;
|
|
1668
1708
|
let cookie = `${name}=${encodeURIComponent(value)};path=${path}`;
|
|
1669
1709
|
if (typeof maxAge === "number") {
|
|
1670
1710
|
cookie += `;max-age=${maxAge}`;
|
|
1671
1711
|
}
|
|
1712
|
+
if (sameSite) {
|
|
1713
|
+
cookie += `;samesite=${sameSite}`;
|
|
1714
|
+
}
|
|
1715
|
+
if (secure) {
|
|
1716
|
+
cookie += ";secure";
|
|
1717
|
+
}
|
|
1672
1718
|
document.cookie = cookie;
|
|
1673
1719
|
}
|
|
1674
|
-
function removeCookie(name, path = "/") {
|
|
1720
|
+
function removeCookie(name, path = "/", options = {}) {
|
|
1675
1721
|
if (typeof document === "undefined") return;
|
|
1676
|
-
|
|
1722
|
+
const { sameSite, secure } = options;
|
|
1723
|
+
let cookie = `${name}=;path=${path};expires=Thu, 01 Jan 1970 00:00:00 GMT`;
|
|
1724
|
+
if (sameSite) {
|
|
1725
|
+
cookie += `;samesite=${sameSite}`;
|
|
1726
|
+
}
|
|
1727
|
+
if (secure) {
|
|
1728
|
+
cookie += ";secure";
|
|
1729
|
+
}
|
|
1730
|
+
document.cookie = cookie;
|
|
1731
|
+
}
|
|
1732
|
+
function crossSiteCookieOptions() {
|
|
1733
|
+
if (typeof window === "undefined" || !window.isSecureContext) return {};
|
|
1734
|
+
return { sameSite: "None", secure: true };
|
|
1677
1735
|
}
|
|
1678
1736
|
|
|
1679
1737
|
// src/core/locales/en.json
|
|
@@ -1692,6 +1750,7 @@ var en_default = {
|
|
|
1692
1750
|
segment: "Segment",
|
|
1693
1751
|
ABVariant: "A/B variant",
|
|
1694
1752
|
chooseSegment: "Choose segment",
|
|
1753
|
+
searchSegments: "Search segments",
|
|
1695
1754
|
none: "No segments",
|
|
1696
1755
|
allOtherUsers: "All other users",
|
|
1697
1756
|
offDescription: "View the site as a real user (use cookies)",
|
|
@@ -1720,6 +1779,7 @@ var nl_default = {
|
|
|
1720
1779
|
segment: "Segment",
|
|
1721
1780
|
ABVariant: "A/B-variant",
|
|
1722
1781
|
chooseSegment: "Kies segment",
|
|
1782
|
+
searchSegments: "Zoek segmenten",
|
|
1723
1783
|
none: "Geen segmenten",
|
|
1724
1784
|
allOtherUsers: "Alle andere gebruikers",
|
|
1725
1785
|
offDescription: "Bekijk de site als een echte gebruiker (gebruik cookies)",
|
|
@@ -1802,7 +1862,13 @@ function createIframeBridge(store) {
|
|
|
1802
1862
|
}
|
|
1803
1863
|
|
|
1804
1864
|
// src/core/toolbar-change-handler.ts
|
|
1805
|
-
|
|
1865
|
+
function cookieOpts() {
|
|
1866
|
+
return {
|
|
1867
|
+
maxAge: ONE_YEAR_SECONDS,
|
|
1868
|
+
path: "/",
|
|
1869
|
+
...crossSiteCookieOptions()
|
|
1870
|
+
};
|
|
1871
|
+
}
|
|
1806
1872
|
function createChangeHandler(deps) {
|
|
1807
1873
|
const { store, stega, syncAutoClean } = deps;
|
|
1808
1874
|
function updateParam(name, value) {
|
|
@@ -1819,9 +1885,9 @@ function createChangeHandler(deps) {
|
|
|
1819
1885
|
return function handleChange(before, after) {
|
|
1820
1886
|
if (before.selectedSegment !== after.selectedSegment) {
|
|
1821
1887
|
if (after.selectedSegment === null) {
|
|
1822
|
-
removeCookie(COOKIE_SEGMENT);
|
|
1888
|
+
removeCookie(COOKIE_SEGMENT, "/", crossSiteCookieOptions());
|
|
1823
1889
|
} else {
|
|
1824
|
-
setCookie(COOKIE_SEGMENT, after.selectedSegment,
|
|
1890
|
+
setCookie(COOKIE_SEGMENT, after.selectedSegment, cookieOpts());
|
|
1825
1891
|
}
|
|
1826
1892
|
updateParam(PARAM_SEGMENT, after.selectedSegment);
|
|
1827
1893
|
sendPreprEvent("segment_changed", {
|
|
@@ -1830,9 +1896,9 @@ function createChangeHandler(deps) {
|
|
|
1830
1896
|
}
|
|
1831
1897
|
if (before.selectedVariant !== after.selectedVariant) {
|
|
1832
1898
|
if (after.selectedVariant === null) {
|
|
1833
|
-
removeCookie(COOKIE_VARIANT);
|
|
1899
|
+
removeCookie(COOKIE_VARIANT, "/", crossSiteCookieOptions());
|
|
1834
1900
|
} else {
|
|
1835
|
-
setCookie(COOKIE_VARIANT, after.selectedVariant,
|
|
1901
|
+
setCookie(COOKIE_VARIANT, after.selectedVariant, cookieOpts());
|
|
1836
1902
|
}
|
|
1837
1903
|
updateParam(PARAM_VARIANT, after.selectedVariant);
|
|
1838
1904
|
sendPreprEvent("variant_changed", {
|
|
@@ -1858,14 +1924,23 @@ function createChangeHandler(deps) {
|
|
|
1858
1924
|
if (Object.keys(coupled).length > 0) {
|
|
1859
1925
|
store.set(coupled);
|
|
1860
1926
|
}
|
|
1861
|
-
setCookie(COOKIE_PREVIEW_MODE, String(after.previewMode),
|
|
1862
|
-
setCookie(COOKIE_TOOLBAR_OPEN, "false",
|
|
1927
|
+
setCookie(COOKIE_PREVIEW_MODE, String(after.previewMode), cookieOpts());
|
|
1928
|
+
setCookie(COOKIE_TOOLBAR_OPEN, "false", cookieOpts());
|
|
1863
1929
|
sendPreprEvent("preview_mode_toggled", { previewMode: after.previewMode });
|
|
1864
1930
|
syncAutoClean(after.previewMode);
|
|
1865
|
-
deps.
|
|
1931
|
+
const [path, existing] = splitPath(deps.currentPath());
|
|
1932
|
+
const params = new URLSearchParams(existing);
|
|
1933
|
+
if (params.has(PARAM_SEGMENT) || params.has(PARAM_VARIANT)) {
|
|
1934
|
+
params.delete(PARAM_SEGMENT);
|
|
1935
|
+
params.delete(PARAM_VARIANT);
|
|
1936
|
+
const query = params.toString();
|
|
1937
|
+
deps.navigate(query ? `${path}?${query}` : path);
|
|
1938
|
+
} else {
|
|
1939
|
+
deps.reload();
|
|
1940
|
+
}
|
|
1866
1941
|
}
|
|
1867
1942
|
if (before.toolbarOpen !== after.toolbarOpen) {
|
|
1868
|
-
setCookie(COOKIE_TOOLBAR_OPEN, String(after.toolbarOpen),
|
|
1943
|
+
setCookie(COOKIE_TOOLBAR_OPEN, String(after.toolbarOpen), cookieOpts());
|
|
1869
1944
|
}
|
|
1870
1945
|
};
|
|
1871
1946
|
}
|