@c15t/dev-tools 2.0.0-rc.2 → 2.0.0-rc.3
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/CHANGELOG.md +12 -0
- package/dist/__tests__/core/override-storage.test.d.ts +2 -0
- package/dist/__tests__/core/override-storage.test.d.ts.map +1 -0
- package/dist/__tests__/core/store-connector.test.d.ts +2 -0
- package/dist/__tests__/core/store-connector.test.d.ts.map +1 -0
- package/dist/__tests__/panels/events.test.d.ts +2 -0
- package/dist/__tests__/panels/events.test.d.ts.map +1 -0
- package/dist/__tests__/panels/iab.test.d.ts +2 -0
- package/dist/__tests__/panels/iab.test.d.ts.map +1 -0
- package/dist/__tests__/panels/scripts.test.d.ts +2 -0
- package/dist/__tests__/panels/scripts.test.d.ts.map +1 -0
- package/dist/__tests__/utils/preference-trigger.test.d.ts +2 -0
- package/dist/__tests__/utils/preference-trigger.test.d.ts.map +1 -0
- package/dist/components/panel.d.ts +1 -0
- package/dist/components/panel.d.ts.map +1 -1
- package/dist/core/devtools.d.ts.map +1 -1
- package/dist/core/override-storage.d.ts +7 -0
- package/dist/core/override-storage.d.ts.map +1 -0
- package/dist/core/panel-renderer.d.ts.map +1 -1
- package/dist/core/state-manager.d.ts +1 -1
- package/dist/core/state-manager.d.ts.map +1 -1
- package/dist/core/store-connector.d.ts +4 -0
- package/dist/core/store-connector.d.ts.map +1 -1
- package/dist/index.cjs +1092 -244
- package/dist/index.js +1092 -244
- package/dist/panels/dom-scanner.d.ts.map +1 -1
- package/dist/panels/events.d.ts.map +1 -1
- package/dist/panels/iab.d.ts +6 -0
- package/dist/panels/iab.d.ts.map +1 -1
- package/dist/panels/location.d.ts +9 -6
- package/dist/panels/location.d.ts.map +1 -1
- package/dist/panels/scripts.d.ts +2 -0
- package/dist/panels/scripts.d.ts.map +1 -1
- package/dist/react.cjs +1015 -237
- package/dist/react.js +1015 -237
- package/dist/tanstack.cjs +810 -201
- package/dist/tanstack.js +810 -201
- package/dist/utils/preference-trigger.d.ts +2 -2
- package/dist/utils/preference-trigger.d.ts.map +1 -1
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/package.json +10 -8
package/dist/tanstack.js
CHANGED
|
@@ -344,22 +344,26 @@ var __webpack_modules__ = {
|
|
|
344
344
|
justify-content: center;
|
|
345
345
|
align-items: center;
|
|
346
346
|
gap: var(--c15t-space-xs, .25rem);
|
|
347
|
-
padding: var(--c15t-space-xs, .25rem) var(--c15t-space-sm, .5rem);
|
|
348
347
|
border: 1px solid var(--c15t-border, #e3e3e3);
|
|
349
348
|
border-radius: var(--c15t-radius-md, .5rem);
|
|
350
349
|
background-color: var(--c15t-surface, #fff);
|
|
350
|
+
min-height: 30px;
|
|
351
351
|
color: var(--c15t-text, #171717);
|
|
352
352
|
font-family: inherit;
|
|
353
|
-
font-size:
|
|
353
|
+
font-size: 12px;
|
|
354
354
|
font-weight: var(--c15t-font-weight-medium, 500);
|
|
355
355
|
cursor: pointer;
|
|
356
|
-
transition: background-color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1)), border-color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1));
|
|
356
|
+
transition: background-color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1)), border-color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1)), box-shadow var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1)), color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1));
|
|
357
|
+
padding: 5px 10px;
|
|
358
|
+
line-height: 1;
|
|
357
359
|
display: inline-flex;
|
|
360
|
+
box-shadow: 0 1px 1px #0000000a;
|
|
358
361
|
}
|
|
359
362
|
|
|
360
363
|
.btn-evRVlh:hover {
|
|
361
364
|
background-color: var(--c15t-surface-hover, #f7f7f7);
|
|
362
365
|
border-color: var(--c15t-border-hover, #c9c9c9);
|
|
366
|
+
box-shadow: 0 2px 6px #00000014;
|
|
363
367
|
}
|
|
364
368
|
|
|
365
369
|
.btn-evRVlh:focus-visible {
|
|
@@ -367,9 +371,14 @@ var __webpack_modules__ = {
|
|
|
367
371
|
outline-offset: 1px;
|
|
368
372
|
}
|
|
369
373
|
|
|
374
|
+
.btn-evRVlh:active {
|
|
375
|
+
box-shadow: 0 1px 2px #00000014;
|
|
376
|
+
}
|
|
377
|
+
|
|
370
378
|
.btn-evRVlh:disabled {
|
|
371
379
|
opacity: .5;
|
|
372
380
|
cursor: not-allowed;
|
|
381
|
+
box-shadow: none;
|
|
373
382
|
}
|
|
374
383
|
|
|
375
384
|
.btnPrimary-dA6nqY {
|
|
@@ -395,8 +404,10 @@ var __webpack_modules__ = {
|
|
|
395
404
|
}
|
|
396
405
|
|
|
397
406
|
.btnSmall-TjXoqZ {
|
|
398
|
-
|
|
399
|
-
|
|
407
|
+
border-radius: var(--c15t-radius-sm, .375rem);
|
|
408
|
+
min-height: 26px;
|
|
409
|
+
padding: 3px 8px;
|
|
410
|
+
font-size: 11px;
|
|
400
411
|
}
|
|
401
412
|
|
|
402
413
|
.btnIcon-fiYQAh {
|
|
@@ -548,6 +559,50 @@ var __webpack_modules__ = {
|
|
|
548
559
|
letter-spacing: .5px;
|
|
549
560
|
}
|
|
550
561
|
|
|
562
|
+
.overrideField-keNdpJ {
|
|
563
|
+
flex-direction: column;
|
|
564
|
+
gap: 3px;
|
|
565
|
+
margin-bottom: 0;
|
|
566
|
+
display: flex;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
.overrideLabel-ApMoTw {
|
|
570
|
+
color: var(--c15t-text-muted, #737373);
|
|
571
|
+
font-size: 11px;
|
|
572
|
+
font-weight: 600;
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
.overrideHint-yCfwGt {
|
|
576
|
+
color: var(--c15t-devtools-text-muted, #737373);
|
|
577
|
+
margin-top: 6px;
|
|
578
|
+
font-size: 11px;
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
.overrideActions-imdcn7 {
|
|
582
|
+
border-top: 1px dashed var(--c15t-border, #e3e3e3);
|
|
583
|
+
justify-content: space-between;
|
|
584
|
+
align-items: center;
|
|
585
|
+
gap: 8px;
|
|
586
|
+
margin-top: 8px;
|
|
587
|
+
padding-top: 8px;
|
|
588
|
+
display: flex;
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
.overrideActionButtons-gYOx1e {
|
|
592
|
+
flex-wrap: wrap;
|
|
593
|
+
gap: 6px;
|
|
594
|
+
display: flex;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
.overrideStatus-sty_qS {
|
|
598
|
+
color: var(--c15t-text-muted, #737373);
|
|
599
|
+
font-size: 11px;
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
.overrideStatusDirty-OUdDMw {
|
|
603
|
+
color: var(--c15t-devtools-badge-warning, #f59f0a);
|
|
604
|
+
}
|
|
605
|
+
|
|
551
606
|
.infoRow-RlB_0h {
|
|
552
607
|
padding: var(--c15t-space-xs, .25rem) 0;
|
|
553
608
|
justify-content: space-between;
|
|
@@ -640,6 +695,13 @@ var __webpack_modules__ = {
|
|
|
640
695
|
section: "section-a197cB",
|
|
641
696
|
sectionHeader: "sectionHeader-Xcljcw",
|
|
642
697
|
sectionTitle: "sectionTitle-RUiFld",
|
|
698
|
+
overrideField: "overrideField-keNdpJ",
|
|
699
|
+
overrideLabel: "overrideLabel-ApMoTw",
|
|
700
|
+
overrideHint: "overrideHint-yCfwGt",
|
|
701
|
+
overrideActions: "overrideActions-imdcn7",
|
|
702
|
+
overrideActionButtons: "overrideActionButtons-gYOx1e",
|
|
703
|
+
overrideStatus: "overrideStatus-sty_qS",
|
|
704
|
+
overrideStatusDirty: "overrideStatusDirty-OUdDMw",
|
|
643
705
|
infoRow: "infoRow-RlB_0h",
|
|
644
706
|
infoLabel: "infoLabel-_pbK33",
|
|
645
707
|
infoValue: "infoValue-flMl_e",
|
|
@@ -1122,16 +1184,23 @@ var __webpack_modules__ = {
|
|
|
1122
1184
|
___CSS_LOADER_EXPORT___.push([
|
|
1123
1185
|
module.id,
|
|
1124
1186
|
`.tabList-IyuiBE {
|
|
1187
|
+
align-items: center;
|
|
1125
1188
|
gap: var(--c15t-space-xs, .25rem);
|
|
1126
|
-
padding: var(--c15t-space-sm, .5rem) var(--c15t-space-
|
|
1189
|
+
padding: var(--c15t-space-sm, .5rem) var(--c15t-space-sm, .5rem);
|
|
1127
1190
|
border-bottom: 1px solid var(--c15t-border, #e3e3e3);
|
|
1128
1191
|
background-color: var(--c15t-surface, #fff);
|
|
1129
1192
|
scrollbar-width: none;
|
|
1130
1193
|
-ms-overflow-style: none;
|
|
1194
|
+
scroll-padding-inline-end: var(--c15t-space-sm, .5rem);
|
|
1131
1195
|
display: flex;
|
|
1132
1196
|
overflow-x: auto;
|
|
1133
1197
|
}
|
|
1134
1198
|
|
|
1199
|
+
.tabList-IyuiBE:after {
|
|
1200
|
+
content: "";
|
|
1201
|
+
flex: 0 0 var(--c15t-space-sm, .5rem);
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1135
1204
|
.tabList-IyuiBE::-webkit-scrollbar {
|
|
1136
1205
|
display: none;
|
|
1137
1206
|
}
|
|
@@ -1139,17 +1208,17 @@ var __webpack_modules__ = {
|
|
|
1139
1208
|
.tab-yfDEqg {
|
|
1140
1209
|
align-items: center;
|
|
1141
1210
|
gap: var(--c15t-space-xs, .25rem);
|
|
1142
|
-
padding: var(--c15t-space-xs, .25rem) var(--c15t-space-sm, .5rem);
|
|
1143
1211
|
border-radius: var(--c15t-radius-md, .5rem);
|
|
1144
1212
|
color: var(--c15t-text-muted, #737373);
|
|
1145
1213
|
font-family: inherit;
|
|
1146
|
-
font-size:
|
|
1214
|
+
font-size: 11px;
|
|
1147
1215
|
font-weight: var(--c15t-font-weight-medium, 500);
|
|
1148
1216
|
cursor: pointer;
|
|
1149
1217
|
white-space: nowrap;
|
|
1150
1218
|
transition: background-color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1)), color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1));
|
|
1151
1219
|
background-color: #0000;
|
|
1152
1220
|
border: none;
|
|
1221
|
+
padding: 3px 7px;
|
|
1153
1222
|
display: flex;
|
|
1154
1223
|
}
|
|
1155
1224
|
|
|
@@ -2284,13 +2353,13 @@ function consents_renderConsentsPanel(container, options) {
|
|
|
2284
2353
|
},
|
|
2285
2354
|
children: [
|
|
2286
2355
|
createButton({
|
|
2287
|
-
text: '
|
|
2356
|
+
text: 'Accept',
|
|
2288
2357
|
variant: 'primary',
|
|
2289
2358
|
small: true,
|
|
2290
2359
|
onClick: onAcceptAll
|
|
2291
2360
|
}),
|
|
2292
2361
|
createButton({
|
|
2293
|
-
text: '
|
|
2362
|
+
text: 'Reject',
|
|
2294
2363
|
variant: 'default',
|
|
2295
2364
|
small: true,
|
|
2296
2365
|
onClick: onRejectAll
|
|
@@ -2338,16 +2407,22 @@ function consents_renderConsentsPanel(container, options) {
|
|
|
2338
2407
|
function formatConsentName(name) {
|
|
2339
2408
|
return name.replace(/_/g, ' ').replace(/\b\w/g, (l)=>l.toUpperCase());
|
|
2340
2409
|
}
|
|
2410
|
+
let activeFilter = 'all';
|
|
2411
|
+
let selectedEventId = null;
|
|
2341
2412
|
function events_renderEventsPanel(container, options) {
|
|
2342
2413
|
const { getEvents, onClear } = options;
|
|
2343
2414
|
renderer_clearElement(container);
|
|
2344
|
-
const
|
|
2415
|
+
const allEvents = getEvents();
|
|
2416
|
+
const events = allEvents.filter((event)=>matchesFilter(event, activeFilter));
|
|
2417
|
+
if (!events.some((event)=>event.id === selectedEventId)) selectedEventId = events[0]?.id ?? null;
|
|
2418
|
+
const selectedEvent = events.find((event)=>event.id === selectedEventId) ?? null;
|
|
2345
2419
|
const header = renderer_div({
|
|
2346
2420
|
style: {
|
|
2347
2421
|
display: 'flex',
|
|
2348
2422
|
alignItems: 'center',
|
|
2349
2423
|
justifyContent: 'space-between',
|
|
2350
|
-
padding: '12px 16px 8px'
|
|
2424
|
+
padding: '12px 16px 8px',
|
|
2425
|
+
gap: '8px'
|
|
2351
2426
|
},
|
|
2352
2427
|
children: [
|
|
2353
2428
|
renderer_span({
|
|
@@ -2358,44 +2433,130 @@ function events_renderEventsPanel(container, options) {
|
|
|
2358
2433
|
textTransform: 'uppercase',
|
|
2359
2434
|
letterSpacing: '0.5px'
|
|
2360
2435
|
},
|
|
2361
|
-
text: `Events (${events.length})`
|
|
2436
|
+
text: `Events (${events.length}/${allEvents.length})`
|
|
2362
2437
|
}),
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2438
|
+
renderer_div({
|
|
2439
|
+
style: {
|
|
2440
|
+
display: 'flex',
|
|
2441
|
+
gap: '6px'
|
|
2442
|
+
},
|
|
2443
|
+
children: [
|
|
2444
|
+
createButton({
|
|
2445
|
+
text: 'Export',
|
|
2446
|
+
small: true,
|
|
2447
|
+
onClick: ()=>exportEvents(allEvents)
|
|
2448
|
+
}),
|
|
2449
|
+
createButton({
|
|
2450
|
+
text: 'Clear',
|
|
2451
|
+
small: true,
|
|
2452
|
+
onClick: ()=>{
|
|
2453
|
+
onClear();
|
|
2454
|
+
selectedEventId = null;
|
|
2455
|
+
events_renderEventsPanel(container, options);
|
|
2456
|
+
}
|
|
2457
|
+
})
|
|
2458
|
+
]
|
|
2367
2459
|
})
|
|
2368
2460
|
]
|
|
2369
2461
|
});
|
|
2370
2462
|
container.appendChild(header);
|
|
2463
|
+
container.appendChild(renderer_div({
|
|
2464
|
+
style: {
|
|
2465
|
+
display: 'flex',
|
|
2466
|
+
flexWrap: 'wrap',
|
|
2467
|
+
gap: '6px',
|
|
2468
|
+
padding: '0 16px 8px'
|
|
2469
|
+
},
|
|
2470
|
+
children: EVENT_FILTERS.map((filter)=>createFilterButton(filter, filter === activeFilter, ()=>{
|
|
2471
|
+
activeFilter = filter;
|
|
2472
|
+
selectedEventId = null;
|
|
2473
|
+
events_renderEventsPanel(container, options);
|
|
2474
|
+
}))
|
|
2475
|
+
}));
|
|
2371
2476
|
const eventList = renderer_div({
|
|
2372
2477
|
style: {
|
|
2373
2478
|
display: 'flex',
|
|
2374
2479
|
flexDirection: 'column',
|
|
2375
2480
|
gap: '4px',
|
|
2376
2481
|
padding: '0 12px 12px',
|
|
2377
|
-
maxHeight: '
|
|
2482
|
+
maxHeight: '300px',
|
|
2378
2483
|
overflowY: 'auto'
|
|
2379
2484
|
}
|
|
2380
2485
|
});
|
|
2381
|
-
if (0 === events.length) {
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
eventList.appendChild(eventItem);
|
|
2395
|
-
}
|
|
2486
|
+
if (0 === events.length) eventList.appendChild(renderer_div({
|
|
2487
|
+
style: {
|
|
2488
|
+
padding: '20px 16px',
|
|
2489
|
+
textAlign: 'center',
|
|
2490
|
+
color: 'var(--c15t-text-muted)',
|
|
2491
|
+
fontSize: 'var(--c15t-devtools-font-size-sm)'
|
|
2492
|
+
},
|
|
2493
|
+
text: 'No events match this filter'
|
|
2494
|
+
}));
|
|
2495
|
+
else for (const event of events)eventList.appendChild(createEventItem(event, event.id === selectedEventId, ()=>{
|
|
2496
|
+
selectedEventId = event.id;
|
|
2497
|
+
events_renderEventsPanel(container, options);
|
|
2498
|
+
}));
|
|
2396
2499
|
container.appendChild(eventList);
|
|
2500
|
+
container.appendChild(createPayloadSection(selectedEvent));
|
|
2501
|
+
}
|
|
2502
|
+
const EVENT_FILTERS = [
|
|
2503
|
+
'all',
|
|
2504
|
+
'error',
|
|
2505
|
+
'consent',
|
|
2506
|
+
'network',
|
|
2507
|
+
'iab'
|
|
2508
|
+
];
|
|
2509
|
+
function createFilterButton(filter, active, onClick) {
|
|
2510
|
+
return createButton({
|
|
2511
|
+
text: filter.toUpperCase(),
|
|
2512
|
+
small: true,
|
|
2513
|
+
variant: active ? 'primary' : 'default',
|
|
2514
|
+
onClick
|
|
2515
|
+
});
|
|
2516
|
+
}
|
|
2517
|
+
function matchesFilter(event, filter) {
|
|
2518
|
+
if ('all' === filter) return true;
|
|
2519
|
+
if ('error' === filter) return 'error' === event.type;
|
|
2520
|
+
if ('consent' === filter) return 'consent_set' === event.type || 'consent_save' === event.type || 'consent_reset' === event.type;
|
|
2521
|
+
if ('network' === filter) return 'network' === event.type;
|
|
2522
|
+
return 'iab' === event.type;
|
|
2397
2523
|
}
|
|
2398
|
-
function
|
|
2524
|
+
function createPayloadSection(event) {
|
|
2525
|
+
const payload = event?.data ? JSON.stringify(event.data, null, 2) : null;
|
|
2526
|
+
return renderer_div({
|
|
2527
|
+
style: {
|
|
2528
|
+
padding: '0 12px 12px'
|
|
2529
|
+
},
|
|
2530
|
+
children: [
|
|
2531
|
+
renderer_div({
|
|
2532
|
+
style: {
|
|
2533
|
+
fontSize: 'var(--c15t-devtools-font-size-xs)',
|
|
2534
|
+
fontWeight: '600',
|
|
2535
|
+
color: 'var(--c15t-text-muted)',
|
|
2536
|
+
textTransform: 'uppercase',
|
|
2537
|
+
letterSpacing: '0.5px',
|
|
2538
|
+
marginBottom: '6px'
|
|
2539
|
+
},
|
|
2540
|
+
text: 'Payload'
|
|
2541
|
+
}),
|
|
2542
|
+
renderer_div({
|
|
2543
|
+
className: styles_components_module.gridCard ?? '',
|
|
2544
|
+
style: {
|
|
2545
|
+
padding: '8px',
|
|
2546
|
+
fontFamily: 'ui-monospace, "Cascadia Code", "Source Code Pro", Menlo, Consolas, monospace',
|
|
2547
|
+
fontSize: '11px',
|
|
2548
|
+
color: 'var(--c15t-text-muted)',
|
|
2549
|
+
maxHeight: '140px',
|
|
2550
|
+
overflowY: 'auto',
|
|
2551
|
+
whiteSpace: 'pre-wrap',
|
|
2552
|
+
wordBreak: 'break-word'
|
|
2553
|
+
},
|
|
2554
|
+
text: payload || 'Select an event with payload data'
|
|
2555
|
+
})
|
|
2556
|
+
]
|
|
2557
|
+
});
|
|
2558
|
+
}
|
|
2559
|
+
function createEventItem(event, selected, onSelect) {
|
|
2399
2560
|
const time = formatTime(event.timestamp);
|
|
2400
2561
|
const icon = getEventIcon(event.type);
|
|
2401
2562
|
const color = getEventColor(event.type);
|
|
@@ -2406,8 +2567,11 @@ function createEventItem(event) {
|
|
|
2406
2567
|
alignItems: 'center',
|
|
2407
2568
|
gap: '8px',
|
|
2408
2569
|
padding: '6px 10px',
|
|
2409
|
-
fontSize: 'var(--c15t-devtools-font-size-xs)'
|
|
2570
|
+
fontSize: 'var(--c15t-devtools-font-size-xs)',
|
|
2571
|
+
cursor: 'pointer',
|
|
2572
|
+
borderColor: selected ? 'var(--c15t-devtools-badge-info, #3b82f6)' : 'var(--c15t-border)'
|
|
2410
2573
|
},
|
|
2574
|
+
onClick: onSelect,
|
|
2411
2575
|
children: [
|
|
2412
2576
|
renderer_span({
|
|
2413
2577
|
style: {
|
|
@@ -2436,6 +2600,21 @@ function createEventItem(event) {
|
|
|
2436
2600
|
]
|
|
2437
2601
|
});
|
|
2438
2602
|
}
|
|
2603
|
+
function exportEvents(events) {
|
|
2604
|
+
const json = JSON.stringify(events, null, 2);
|
|
2605
|
+
const blob = new Blob([
|
|
2606
|
+
json
|
|
2607
|
+
], {
|
|
2608
|
+
type: 'application/json'
|
|
2609
|
+
});
|
|
2610
|
+
const url = URL.createObjectURL(blob);
|
|
2611
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
2612
|
+
const a = document.createElement('a');
|
|
2613
|
+
a.href = url;
|
|
2614
|
+
a.download = `c15t-events-${timestamp}.json`;
|
|
2615
|
+
a.click();
|
|
2616
|
+
URL.revokeObjectURL(url);
|
|
2617
|
+
}
|
|
2439
2618
|
function formatTime(timestamp) {
|
|
2440
2619
|
const date = new Date(timestamp);
|
|
2441
2620
|
return date.toLocaleTimeString('en-US', {
|
|
@@ -2454,7 +2633,10 @@ function getEventIcon(type) {
|
|
|
2454
2633
|
return '○';
|
|
2455
2634
|
case 'error':
|
|
2456
2635
|
return '✕';
|
|
2457
|
-
case '
|
|
2636
|
+
case 'network':
|
|
2637
|
+
return '◉';
|
|
2638
|
+
case 'iab':
|
|
2639
|
+
return '◆';
|
|
2458
2640
|
default:
|
|
2459
2641
|
return '○';
|
|
2460
2642
|
}
|
|
@@ -2468,13 +2650,16 @@ function getEventColor(type) {
|
|
|
2468
2650
|
return 'var(--c15t-devtools-badge-warning, #f59e0b)';
|
|
2469
2651
|
case 'error':
|
|
2470
2652
|
return 'var(--c15t-devtools-badge-error, #ef4444)';
|
|
2471
|
-
case '
|
|
2653
|
+
case 'network':
|
|
2654
|
+
return 'var(--c15t-devtools-badge-warning, #f59e0b)';
|
|
2655
|
+
case 'iab':
|
|
2656
|
+
return 'var(--c15t-devtools-badge-info, #3b82f6)';
|
|
2472
2657
|
default:
|
|
2473
2658
|
return 'var(--c15t-text-muted)';
|
|
2474
2659
|
}
|
|
2475
2660
|
}
|
|
2476
2661
|
function iab_renderIabPanel(container, options) {
|
|
2477
|
-
const { getState, onReset } = options;
|
|
2662
|
+
const { getState, onSetPurposeConsent, onSetVendorConsent, onSetSpecialFeatureOptIn, onAcceptAll, onRejectAll, onSave, onReset } = options;
|
|
2478
2663
|
renderer_clearElement(container);
|
|
2479
2664
|
const state = getState();
|
|
2480
2665
|
if (!state) return void container.appendChild(renderer_div({
|
|
@@ -2552,7 +2737,9 @@ function iab_renderIabPanel(container, options) {
|
|
|
2552
2737
|
for (const [purposeId, consent] of purposeEntries){
|
|
2553
2738
|
const purposeInfo = purposes[purposeId];
|
|
2554
2739
|
const purposeName = purposeInfo?.name || `Purpose ${purposeId}`;
|
|
2555
|
-
purposeList.appendChild(createPurposeRow(purposeId, purposeName, Boolean(consent))
|
|
2740
|
+
purposeList.appendChild(createPurposeRow(purposeId, purposeName, Boolean(consent), (value)=>{
|
|
2741
|
+
onSetPurposeConsent(Number(purposeId), value);
|
|
2742
|
+
}));
|
|
2556
2743
|
}
|
|
2557
2744
|
const purposesSection = createSection({
|
|
2558
2745
|
title: `Purposes (${purposeEntries.length})`,
|
|
@@ -2578,7 +2765,9 @@ function iab_renderIabPanel(container, options) {
|
|
|
2578
2765
|
for (const [featureId, optIn] of specialFeatureEntries){
|
|
2579
2766
|
const featureInfo = specialFeatures[featureId];
|
|
2580
2767
|
const featureName = featureInfo?.name || `Special Feature ${featureId}`;
|
|
2581
|
-
specialFeatureList.appendChild(createPurposeRow(featureId, featureName, Boolean(optIn))
|
|
2768
|
+
specialFeatureList.appendChild(createPurposeRow(featureId, featureName, Boolean(optIn), (value)=>{
|
|
2769
|
+
onSetSpecialFeatureOptIn(Number(featureId), value);
|
|
2770
|
+
}, 'feature'));
|
|
2582
2771
|
}
|
|
2583
2772
|
const specialFeaturesSection = createSection({
|
|
2584
2773
|
title: `Special Features (${specialFeatureEntries.length})`,
|
|
@@ -2618,7 +2807,9 @@ function iab_renderIabPanel(container, options) {
|
|
|
2618
2807
|
overflowY: 'auto'
|
|
2619
2808
|
}
|
|
2620
2809
|
});
|
|
2621
|
-
for (const [vendorId, consent, vendorName] of iabVendors)vendorList.appendChild(createVendorRow(vendorId, vendorName, consent, 'iab')
|
|
2810
|
+
for (const [vendorId, consent, vendorName] of iabVendors)vendorList.appendChild(createVendorRow(vendorId, vendorName, consent, 'iab', (value)=>{
|
|
2811
|
+
onSetVendorConsent(Number(vendorId), value);
|
|
2812
|
+
}));
|
|
2622
2813
|
const vendorsSection = createSection({
|
|
2623
2814
|
title: `IAB Vendors (${iabVendors.length})`,
|
|
2624
2815
|
children: [
|
|
@@ -2637,7 +2828,9 @@ function iab_renderIabPanel(container, options) {
|
|
|
2637
2828
|
overflowY: 'auto'
|
|
2638
2829
|
}
|
|
2639
2830
|
});
|
|
2640
|
-
for (const [vendorId, consent, vendorName] of customVendors)customVendorList.appendChild(createVendorRow(vendorId, vendorName, consent, 'custom')
|
|
2831
|
+
for (const [vendorId, consent, vendorName] of customVendors)customVendorList.appendChild(createVendorRow(vendorId, vendorName, consent, 'custom', (value)=>{
|
|
2832
|
+
onSetVendorConsent(vendorId, value);
|
|
2833
|
+
}));
|
|
2641
2834
|
const customVendorsSection = createSection({
|
|
2642
2835
|
title: `Custom Vendors (${customVendors.length})`,
|
|
2643
2836
|
children: [
|
|
@@ -2659,15 +2852,40 @@ function iab_renderIabPanel(container, options) {
|
|
|
2659
2852
|
style: {
|
|
2660
2853
|
display: 'flex',
|
|
2661
2854
|
alignItems: 'center',
|
|
2662
|
-
justifyContent: '
|
|
2855
|
+
justifyContent: 'space-between',
|
|
2663
2856
|
padding: '12px 16px',
|
|
2664
2857
|
marginTop: 'auto',
|
|
2665
2858
|
borderTop: '1px solid var(--c15t-border)',
|
|
2666
2859
|
backgroundColor: 'var(--c15t-surface)'
|
|
2667
2860
|
},
|
|
2668
2861
|
children: [
|
|
2862
|
+
renderer_div({
|
|
2863
|
+
style: {
|
|
2864
|
+
display: 'flex',
|
|
2865
|
+
gap: '6px'
|
|
2866
|
+
},
|
|
2867
|
+
children: [
|
|
2868
|
+
createButton({
|
|
2869
|
+
text: 'Accept All',
|
|
2870
|
+
variant: 'primary',
|
|
2871
|
+
small: true,
|
|
2872
|
+
onClick: onAcceptAll
|
|
2873
|
+
}),
|
|
2874
|
+
createButton({
|
|
2875
|
+
text: 'Reject All',
|
|
2876
|
+
small: true,
|
|
2877
|
+
onClick: onRejectAll
|
|
2878
|
+
}),
|
|
2879
|
+
createButton({
|
|
2880
|
+
text: 'Save',
|
|
2881
|
+
variant: 'primary',
|
|
2882
|
+
small: true,
|
|
2883
|
+
onClick: onSave
|
|
2884
|
+
})
|
|
2885
|
+
]
|
|
2886
|
+
}),
|
|
2669
2887
|
createButton({
|
|
2670
|
-
text: 'Reset
|
|
2888
|
+
text: 'Reset',
|
|
2671
2889
|
variant: 'danger',
|
|
2672
2890
|
small: true,
|
|
2673
2891
|
onClick: onReset
|
|
@@ -2676,7 +2894,7 @@ function iab_renderIabPanel(container, options) {
|
|
|
2676
2894
|
});
|
|
2677
2895
|
container.appendChild(footer);
|
|
2678
2896
|
}
|
|
2679
|
-
function createPurposeRow(id, name, consent) {
|
|
2897
|
+
function createPurposeRow(id, name, consent, onChange, ariaKind = 'purpose') {
|
|
2680
2898
|
return renderer_div({
|
|
2681
2899
|
style: {
|
|
2682
2900
|
display: 'flex',
|
|
@@ -2699,14 +2917,28 @@ function createPurposeRow(id, name, consent) {
|
|
|
2699
2917
|
text: `${id}. ${name}`,
|
|
2700
2918
|
title: name
|
|
2701
2919
|
}),
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2920
|
+
renderer_div({
|
|
2921
|
+
style: {
|
|
2922
|
+
display: 'flex',
|
|
2923
|
+
alignItems: 'center',
|
|
2924
|
+
gap: '6px'
|
|
2925
|
+
},
|
|
2926
|
+
children: [
|
|
2927
|
+
createBadge({
|
|
2928
|
+
text: consent ? '✓' : '✕',
|
|
2929
|
+
variant: consent ? 'success' : 'error'
|
|
2930
|
+
}),
|
|
2931
|
+
createToggle({
|
|
2932
|
+
checked: consent,
|
|
2933
|
+
onChange,
|
|
2934
|
+
ariaLabel: `Toggle ${ariaKind} ${id}`
|
|
2935
|
+
})
|
|
2936
|
+
]
|
|
2705
2937
|
})
|
|
2706
2938
|
]
|
|
2707
2939
|
});
|
|
2708
2940
|
}
|
|
2709
|
-
function createVendorRow(id, name, consent, type) {
|
|
2941
|
+
function createVendorRow(id, name, consent, type, onChange) {
|
|
2710
2942
|
return renderer_div({
|
|
2711
2943
|
style: {
|
|
2712
2944
|
display: 'flex',
|
|
@@ -2753,16 +2985,21 @@ function createVendorRow(id, name, consent, type) {
|
|
|
2753
2985
|
createBadge({
|
|
2754
2986
|
text: consent ? '✓' : '✕',
|
|
2755
2987
|
variant: consent ? 'success' : 'error'
|
|
2988
|
+
}),
|
|
2989
|
+
createToggle({
|
|
2990
|
+
checked: consent,
|
|
2991
|
+
onChange,
|
|
2992
|
+
ariaLabel: `Toggle vendor ${id}`
|
|
2756
2993
|
})
|
|
2757
2994
|
]
|
|
2758
2995
|
});
|
|
2759
2996
|
}
|
|
2760
2997
|
function truncateText(text, maxLength) {
|
|
2761
2998
|
if (text.length <= maxLength) return text;
|
|
2762
|
-
return text.slice(0, maxLength - 3)
|
|
2999
|
+
return `${text.slice(0, maxLength - 3)}...`;
|
|
2763
3000
|
}
|
|
2764
3001
|
function location_renderLocationPanel(container, options) {
|
|
2765
|
-
const { getState,
|
|
3002
|
+
const { getState, onApplyOverrides, onClearOverrides } = options;
|
|
2766
3003
|
renderer_clearElement(container);
|
|
2767
3004
|
const state = getState();
|
|
2768
3005
|
if (!state) return void container.appendChild(renderer_div({
|
|
@@ -2783,145 +3020,230 @@ function location_renderLocationPanel(container, options) {
|
|
|
2783
3020
|
createCompactInfoCard('Jurisdiction', locationInfo?.jurisdiction || '—'),
|
|
2784
3021
|
createCompactInfoCard('Language', translationConfig?.defaultLanguage || '—')
|
|
2785
3022
|
];
|
|
3023
|
+
gridItems.push(createCompactInfoCard('GPC', getEffectiveGpcLabel(overrides?.gpc)));
|
|
2786
3024
|
if (state.model) gridItems.push(createCompactInfoCard('Model', getModelLabel(state.model)));
|
|
2787
3025
|
const locationGrid = createGrid({
|
|
2788
|
-
columns:
|
|
3026
|
+
columns: 3,
|
|
2789
3027
|
children: gridItems
|
|
2790
3028
|
});
|
|
2791
3029
|
container.appendChild(locationGrid);
|
|
3030
|
+
const initialDraft = getDraftFromOverrides(overrides);
|
|
3031
|
+
let appliedOverrides = normalizeOverrideDraft(initialDraft);
|
|
3032
|
+
let isSubmitting = false;
|
|
3033
|
+
const countryField = createOverrideSelect({
|
|
3034
|
+
label: 'Country',
|
|
3035
|
+
selectOptions: COUNTRY_OPTIONS,
|
|
3036
|
+
value: initialDraft.country
|
|
3037
|
+
});
|
|
3038
|
+
const regionField = createOverrideInput({
|
|
3039
|
+
label: 'Region',
|
|
3040
|
+
placeholder: 'e.g., CA, NY, BE',
|
|
3041
|
+
value: initialDraft.region
|
|
3042
|
+
});
|
|
3043
|
+
const languageField = createOverrideInput({
|
|
3044
|
+
label: 'Language',
|
|
3045
|
+
placeholder: 'e.g., de, fr, en-US',
|
|
3046
|
+
value: initialDraft.language
|
|
3047
|
+
});
|
|
3048
|
+
const gpcField = createOverrideSelect({
|
|
3049
|
+
label: 'GPC',
|
|
3050
|
+
selectOptions: GPC_OPTIONS,
|
|
3051
|
+
value: initialDraft.gpc
|
|
3052
|
+
});
|
|
3053
|
+
const formStatus = renderer_span({
|
|
3054
|
+
className: styles_components_module.overrideStatus,
|
|
3055
|
+
text: 'In sync'
|
|
3056
|
+
});
|
|
3057
|
+
const applyButton = createButton({
|
|
3058
|
+
text: 'Apply',
|
|
3059
|
+
variant: 'primary',
|
|
3060
|
+
small: true,
|
|
3061
|
+
disabled: true,
|
|
3062
|
+
onClick: ()=>{
|
|
3063
|
+
applyDraft();
|
|
3064
|
+
}
|
|
3065
|
+
});
|
|
3066
|
+
const revertButton = createButton({
|
|
3067
|
+
text: 'Revert',
|
|
3068
|
+
small: true,
|
|
3069
|
+
disabled: true,
|
|
3070
|
+
onClick: ()=>{
|
|
3071
|
+
setDraftValues(getDraftFromOverrides(appliedOverrides));
|
|
3072
|
+
updateFormState();
|
|
3073
|
+
}
|
|
3074
|
+
});
|
|
3075
|
+
const clearButton = createButton({
|
|
3076
|
+
text: 'Clear',
|
|
3077
|
+
small: true,
|
|
3078
|
+
onClick: ()=>{
|
|
3079
|
+
clearDraftAndOverrides();
|
|
3080
|
+
}
|
|
3081
|
+
});
|
|
3082
|
+
const overrideFieldsGrid = renderer_div({
|
|
3083
|
+
style: {
|
|
3084
|
+
display: 'grid',
|
|
3085
|
+
gridTemplateColumns: 'repeat(2, minmax(0, 1fr))',
|
|
3086
|
+
gap: '8px 10px'
|
|
3087
|
+
},
|
|
3088
|
+
children: [
|
|
3089
|
+
countryField.element,
|
|
3090
|
+
regionField.element,
|
|
3091
|
+
languageField.element,
|
|
3092
|
+
gpcField.element
|
|
3093
|
+
]
|
|
3094
|
+
});
|
|
2792
3095
|
const overrideSection = createSection({
|
|
2793
3096
|
title: 'Override Settings',
|
|
2794
|
-
actions: [
|
|
2795
|
-
createButton({
|
|
2796
|
-
text: 'Clear',
|
|
2797
|
-
small: true,
|
|
2798
|
-
onClick: onClearOverrides
|
|
2799
|
-
})
|
|
2800
|
-
],
|
|
2801
3097
|
children: [
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
onChange: (value)=>onSetOverrides({
|
|
2807
|
-
country: value || void 0
|
|
2808
|
-
})
|
|
2809
|
-
}),
|
|
2810
|
-
createOverrideInput({
|
|
2811
|
-
label: 'Region',
|
|
2812
|
-
placeholder: 'e.g., CA, NY, BE',
|
|
2813
|
-
value: overrides?.region || '',
|
|
2814
|
-
onChange: (value)=>onSetOverrides({
|
|
2815
|
-
region: value || void 0
|
|
2816
|
-
})
|
|
3098
|
+
overrideFieldsGrid,
|
|
3099
|
+
renderer_span({
|
|
3100
|
+
className: styles_components_module.overrideHint,
|
|
3101
|
+
text: 'GPC override only affects opt-out or unregulated jurisdictions.'
|
|
2817
3102
|
}),
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
3103
|
+
renderer_div({
|
|
3104
|
+
className: styles_components_module.overrideActions,
|
|
3105
|
+
children: [
|
|
3106
|
+
renderer_div({
|
|
3107
|
+
className: styles_components_module.overrideActionButtons,
|
|
3108
|
+
children: [
|
|
3109
|
+
revertButton,
|
|
3110
|
+
applyButton,
|
|
3111
|
+
clearButton
|
|
3112
|
+
]
|
|
3113
|
+
}),
|
|
3114
|
+
formStatus
|
|
3115
|
+
]
|
|
2825
3116
|
})
|
|
2826
3117
|
]
|
|
2827
3118
|
});
|
|
2828
3119
|
container.appendChild(overrideSection);
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
|
|
3120
|
+
countryField.control.addEventListener('change', updateFormState);
|
|
3121
|
+
regionField.control.addEventListener('input', updateFormState);
|
|
3122
|
+
languageField.control.addEventListener('input', updateFormState);
|
|
3123
|
+
gpcField.control.addEventListener('change', updateFormState);
|
|
3124
|
+
updateFormState();
|
|
3125
|
+
async function applyDraft() {
|
|
3126
|
+
if (isSubmitting) return;
|
|
3127
|
+
const draftOverrides = getDraftOverrides();
|
|
3128
|
+
if (overridesEqual(draftOverrides, appliedOverrides)) return;
|
|
3129
|
+
isSubmitting = true;
|
|
3130
|
+
updateFormState();
|
|
3131
|
+
try {
|
|
3132
|
+
await onApplyOverrides(draftOverrides);
|
|
3133
|
+
appliedOverrides = draftOverrides;
|
|
3134
|
+
} finally{
|
|
3135
|
+
isSubmitting = false;
|
|
3136
|
+
updateFormState();
|
|
3137
|
+
}
|
|
3138
|
+
}
|
|
3139
|
+
async function clearDraftAndOverrides() {
|
|
3140
|
+
if (isSubmitting) return;
|
|
3141
|
+
isSubmitting = true;
|
|
3142
|
+
updateFormState();
|
|
3143
|
+
try {
|
|
3144
|
+
await onClearOverrides();
|
|
3145
|
+
appliedOverrides = {};
|
|
3146
|
+
setDraftValues(getDraftFromOverrides(void 0));
|
|
3147
|
+
} finally{
|
|
3148
|
+
isSubmitting = false;
|
|
3149
|
+
updateFormState();
|
|
3150
|
+
}
|
|
3151
|
+
}
|
|
3152
|
+
function getDraftOverrides() {
|
|
3153
|
+
return normalizeOverrideDraft({
|
|
3154
|
+
country: countryField.control.value,
|
|
3155
|
+
region: regionField.control.value,
|
|
3156
|
+
language: languageField.control.value,
|
|
3157
|
+
gpc: gpcField.control.value
|
|
2840
3158
|
});
|
|
2841
|
-
|
|
3159
|
+
}
|
|
3160
|
+
function setDraftValues(draft) {
|
|
3161
|
+
countryField.control.value = draft.country;
|
|
3162
|
+
regionField.control.value = draft.region;
|
|
3163
|
+
languageField.control.value = draft.language;
|
|
3164
|
+
gpcField.control.value = draft.gpc;
|
|
3165
|
+
}
|
|
3166
|
+
function updateFormState() {
|
|
3167
|
+
const draftOverrides = getDraftOverrides();
|
|
3168
|
+
const hasDraftChanges = !overridesEqual(draftOverrides, appliedOverrides);
|
|
3169
|
+
applyButton.disabled = !hasDraftChanges || isSubmitting;
|
|
3170
|
+
revertButton.disabled = !hasDraftChanges || isSubmitting;
|
|
3171
|
+
clearButton.disabled = isSubmitting;
|
|
3172
|
+
formStatus.textContent = isSubmitting ? 'Applying...' : hasDraftChanges ? 'Unsaved changes' : hasOverridesValue(appliedOverrides) ? 'Overrides active' : 'No overrides';
|
|
3173
|
+
if (styles_components_module.overrideStatusDirty) formStatus.classList.toggle(styles_components_module.overrideStatusDirty, !isSubmitting && hasDraftChanges);
|
|
2842
3174
|
}
|
|
2843
3175
|
}
|
|
2844
3176
|
function createOverrideInput(options) {
|
|
2845
|
-
const { label, placeholder, value
|
|
2846
|
-
let debounceTimer = null;
|
|
3177
|
+
const { label, placeholder, value } = options;
|
|
2847
3178
|
const inputField = input({
|
|
2848
3179
|
className: `${styles_components_module.input ?? ''} ${styles_components_module.inputSmall ?? ''}`.trim(),
|
|
2849
3180
|
placeholder,
|
|
2850
|
-
value
|
|
2851
|
-
onInput: (e)=>{
|
|
2852
|
-
const target = e.target;
|
|
2853
|
-
if (debounceTimer) clearTimeout(debounceTimer);
|
|
2854
|
-
debounceTimer = setTimeout(()=>{
|
|
2855
|
-
onChange(target.value);
|
|
2856
|
-
}, 500);
|
|
2857
|
-
}
|
|
2858
|
-
});
|
|
2859
|
-
return renderer_div({
|
|
2860
|
-
style: {
|
|
2861
|
-
display: 'flex',
|
|
2862
|
-
alignItems: 'center',
|
|
2863
|
-
justifyContent: 'space-between',
|
|
2864
|
-
gap: '8px',
|
|
2865
|
-
marginBottom: '8px'
|
|
2866
|
-
},
|
|
2867
|
-
children: [
|
|
2868
|
-
renderer_div({
|
|
2869
|
-
style: {
|
|
2870
|
-
fontSize: 'var(--c15t-devtools-font-size-xs)',
|
|
2871
|
-
color: 'var(--c15t-devtools-text-muted)',
|
|
2872
|
-
minWidth: '60px'
|
|
2873
|
-
},
|
|
2874
|
-
text: label
|
|
2875
|
-
}),
|
|
2876
|
-
renderer_div({
|
|
2877
|
-
style: {
|
|
2878
|
-
flex: '1'
|
|
2879
|
-
},
|
|
2880
|
-
children: [
|
|
2881
|
-
inputField
|
|
2882
|
-
]
|
|
2883
|
-
})
|
|
2884
|
-
]
|
|
3181
|
+
value
|
|
2885
3182
|
});
|
|
3183
|
+
return {
|
|
3184
|
+
element: renderer_div({
|
|
3185
|
+
className: styles_components_module.overrideField,
|
|
3186
|
+
children: [
|
|
3187
|
+
renderer_span({
|
|
3188
|
+
className: styles_components_module.overrideLabel,
|
|
3189
|
+
text: label
|
|
3190
|
+
}),
|
|
3191
|
+
inputField
|
|
3192
|
+
]
|
|
3193
|
+
}),
|
|
3194
|
+
control: inputField
|
|
3195
|
+
};
|
|
2886
3196
|
}
|
|
2887
3197
|
function createOverrideSelect(options) {
|
|
2888
|
-
const { label, selectOptions, value
|
|
3198
|
+
const { label, selectOptions, value } = options;
|
|
2889
3199
|
const selectField = renderer_select({
|
|
2890
3200
|
className: `${styles_components_module.input ?? ''} ${styles_components_module.inputSmall ?? ''}`.trim(),
|
|
2891
3201
|
options: selectOptions,
|
|
2892
|
-
selectedValue: value
|
|
2893
|
-
onChange: (e)=>{
|
|
2894
|
-
const target = e.target;
|
|
2895
|
-
onChange(target.value);
|
|
2896
|
-
}
|
|
2897
|
-
});
|
|
2898
|
-
return renderer_div({
|
|
2899
|
-
style: {
|
|
2900
|
-
display: 'flex',
|
|
2901
|
-
alignItems: 'center',
|
|
2902
|
-
justifyContent: 'space-between',
|
|
2903
|
-
gap: '8px',
|
|
2904
|
-
marginBottom: '8px'
|
|
2905
|
-
},
|
|
2906
|
-
children: [
|
|
2907
|
-
renderer_div({
|
|
2908
|
-
style: {
|
|
2909
|
-
fontSize: 'var(--c15t-devtools-font-size-xs)',
|
|
2910
|
-
color: 'var(--c15t-devtools-text-muted)',
|
|
2911
|
-
minWidth: '60px'
|
|
2912
|
-
},
|
|
2913
|
-
text: label
|
|
2914
|
-
}),
|
|
2915
|
-
renderer_div({
|
|
2916
|
-
style: {
|
|
2917
|
-
flex: '1'
|
|
2918
|
-
},
|
|
2919
|
-
children: [
|
|
2920
|
-
selectField
|
|
2921
|
-
]
|
|
2922
|
-
})
|
|
2923
|
-
]
|
|
3202
|
+
selectedValue: value
|
|
2924
3203
|
});
|
|
3204
|
+
return {
|
|
3205
|
+
element: renderer_div({
|
|
3206
|
+
className: styles_components_module.overrideField,
|
|
3207
|
+
children: [
|
|
3208
|
+
renderer_span({
|
|
3209
|
+
className: styles_components_module.overrideLabel,
|
|
3210
|
+
text: label
|
|
3211
|
+
}),
|
|
3212
|
+
selectField
|
|
3213
|
+
]
|
|
3214
|
+
}),
|
|
3215
|
+
control: selectField
|
|
3216
|
+
};
|
|
3217
|
+
}
|
|
3218
|
+
function getDraftFromOverrides(overrides) {
|
|
3219
|
+
return {
|
|
3220
|
+
country: overrides?.country ?? '',
|
|
3221
|
+
region: overrides?.region ?? '',
|
|
3222
|
+
language: overrides?.language ?? '',
|
|
3223
|
+
gpc: overrides?.gpc === true ? 'true' : overrides?.gpc === false ? 'false' : ''
|
|
3224
|
+
};
|
|
3225
|
+
}
|
|
3226
|
+
function normalizeOverrideDraft(draft) {
|
|
3227
|
+
return {
|
|
3228
|
+
country: normalizeAlphaCode(draft.country),
|
|
3229
|
+
region: normalizeAlphaCode(draft.region),
|
|
3230
|
+
language: normalizeLanguageCode(draft.language),
|
|
3231
|
+
gpc: 'true' === draft.gpc ? true : 'false' === draft.gpc ? false : void 0
|
|
3232
|
+
};
|
|
3233
|
+
}
|
|
3234
|
+
function normalizeAlphaCode(value) {
|
|
3235
|
+
const normalized = value.trim().toUpperCase();
|
|
3236
|
+
return normalized || void 0;
|
|
3237
|
+
}
|
|
3238
|
+
function normalizeLanguageCode(value) {
|
|
3239
|
+
const normalized = value.trim();
|
|
3240
|
+
return normalized || void 0;
|
|
3241
|
+
}
|
|
3242
|
+
function overridesEqual(a, b) {
|
|
3243
|
+
return a.country === b.country && a.region === b.region && a.language === b.language && a.gpc === b.gpc;
|
|
3244
|
+
}
|
|
3245
|
+
function hasOverridesValue(overrides) {
|
|
3246
|
+
return Boolean(overrides.country || overrides.region || overrides.language || void 0 !== overrides.gpc);
|
|
2925
3247
|
}
|
|
2926
3248
|
const COUNTRY_OPTIONS = [
|
|
2927
3249
|
{
|
|
@@ -3045,6 +3367,32 @@ const COUNTRY_OPTIONS = [
|
|
|
3045
3367
|
label: 'ZA - South Africa'
|
|
3046
3368
|
}
|
|
3047
3369
|
];
|
|
3370
|
+
const GPC_OPTIONS = [
|
|
3371
|
+
{
|
|
3372
|
+
value: '',
|
|
3373
|
+
label: '-- Browser Default --'
|
|
3374
|
+
},
|
|
3375
|
+
{
|
|
3376
|
+
value: 'true',
|
|
3377
|
+
label: 'Force On (Simulated)'
|
|
3378
|
+
},
|
|
3379
|
+
{
|
|
3380
|
+
value: 'false',
|
|
3381
|
+
label: 'Force Off (Simulated)'
|
|
3382
|
+
}
|
|
3383
|
+
];
|
|
3384
|
+
function getEffectiveGpcLabel(gpcOverride) {
|
|
3385
|
+
if (true === gpcOverride) return 'On (Override)';
|
|
3386
|
+
if (false === gpcOverride) return 'Off (Override)';
|
|
3387
|
+
if ('undefined' == typeof window || 'undefined' == typeof navigator) return 'Unknown';
|
|
3388
|
+
try {
|
|
3389
|
+
const nav = navigator;
|
|
3390
|
+
const value = nav.globalPrivacyControl;
|
|
3391
|
+
return true === value || '1' === value ? 'Active' : 'Inactive';
|
|
3392
|
+
} catch {
|
|
3393
|
+
return 'Unknown';
|
|
3394
|
+
}
|
|
3395
|
+
}
|
|
3048
3396
|
function getModelLabel(model) {
|
|
3049
3397
|
switch(model){
|
|
3050
3398
|
case 'opt-in':
|
|
@@ -3061,9 +3409,11 @@ function createCompactInfoCard(label, value) {
|
|
|
3061
3409
|
return renderer_div({
|
|
3062
3410
|
className: styles_components_module.gridCard ?? '',
|
|
3063
3411
|
style: {
|
|
3412
|
+
padding: '6px 8px',
|
|
3413
|
+
minHeight: 'auto',
|
|
3064
3414
|
flexDirection: 'column',
|
|
3065
3415
|
alignItems: 'flex-start',
|
|
3066
|
-
gap: '
|
|
3416
|
+
gap: '1px'
|
|
3067
3417
|
},
|
|
3068
3418
|
children: [
|
|
3069
3419
|
renderer_span({
|
|
@@ -3088,34 +3438,38 @@ const dismissedResources = new Set();
|
|
|
3088
3438
|
function scanDOM(state) {
|
|
3089
3439
|
const results = [];
|
|
3090
3440
|
const configuredScripts = state.scripts || [];
|
|
3091
|
-
const
|
|
3441
|
+
const managedResources = [];
|
|
3092
3442
|
for (const script of configuredScripts)if (script.src) try {
|
|
3093
3443
|
const url = new URL(script.src, window.location.origin);
|
|
3094
|
-
if (url.hostname !== window.location.hostname)
|
|
3444
|
+
if (url.hostname !== window.location.hostname) managedResources.push({
|
|
3445
|
+
scriptId: script.id,
|
|
3446
|
+
domain: url.hostname,
|
|
3447
|
+
pathPrefix: normalizePathname(url.pathname)
|
|
3448
|
+
});
|
|
3095
3449
|
} catch {}
|
|
3096
3450
|
const scriptElements = document.querySelectorAll("script[src]");
|
|
3097
3451
|
for (const el of scriptElements){
|
|
3098
3452
|
const src = el.getAttribute('src');
|
|
3099
3453
|
if (!src) continue;
|
|
3100
|
-
const resource = checkResource(src, "script",
|
|
3454
|
+
const resource = checkResource(src, "script", managedResources);
|
|
3101
3455
|
if (resource) results.push(resource);
|
|
3102
3456
|
}
|
|
3103
3457
|
const iframeElements = document.querySelectorAll('iframe[src]');
|
|
3104
3458
|
for (const el of iframeElements){
|
|
3105
3459
|
const src = el.getAttribute('src');
|
|
3106
3460
|
if (!src) continue;
|
|
3107
|
-
const resource = checkResource(src, 'iframe',
|
|
3461
|
+
const resource = checkResource(src, 'iframe', managedResources);
|
|
3108
3462
|
if (resource) results.push(resource);
|
|
3109
3463
|
}
|
|
3110
3464
|
return results;
|
|
3111
3465
|
}
|
|
3112
|
-
function checkResource(src, type,
|
|
3466
|
+
function checkResource(src, type, managedResources) {
|
|
3113
3467
|
try {
|
|
3114
3468
|
const url = new URL(src, window.location.origin);
|
|
3115
3469
|
const domain = url.hostname;
|
|
3116
3470
|
if (domain === window.location.hostname) return null;
|
|
3117
3471
|
if ('data:' === url.protocol || 'blob:' === url.protocol) return null;
|
|
3118
|
-
const managedBy =
|
|
3472
|
+
const managedBy = findManagedScriptId(url, managedResources);
|
|
3119
3473
|
const isManaged = Boolean(managedBy);
|
|
3120
3474
|
return {
|
|
3121
3475
|
type,
|
|
@@ -3127,6 +3481,21 @@ function checkResource(src, type, managedDomains) {
|
|
|
3127
3481
|
} catch {}
|
|
3128
3482
|
return null;
|
|
3129
3483
|
}
|
|
3484
|
+
function findManagedScriptId(url, managedResources) {
|
|
3485
|
+
const domain = url.hostname;
|
|
3486
|
+
const path = normalizePathname(url.pathname);
|
|
3487
|
+
let bestMatch = null;
|
|
3488
|
+
for (const matcher of managedResources)if (matcher.domain === domain) {
|
|
3489
|
+
if ('/' === matcher.pathPrefix || path.startsWith(matcher.pathPrefix)) {
|
|
3490
|
+
if (!bestMatch || matcher.pathPrefix.length > bestMatch.pathPrefix.length) bestMatch = matcher;
|
|
3491
|
+
}
|
|
3492
|
+
}
|
|
3493
|
+
return bestMatch?.scriptId;
|
|
3494
|
+
}
|
|
3495
|
+
function normalizePathname(pathname) {
|
|
3496
|
+
const trimmed = pathname.trim();
|
|
3497
|
+
return trimmed.length > 0 ? trimmed : '/';
|
|
3498
|
+
}
|
|
3130
3499
|
function createDomScannerSection(state) {
|
|
3131
3500
|
let resultsContainer = null;
|
|
3132
3501
|
let lastScanResults = [];
|
|
@@ -3291,7 +3660,7 @@ const CODE_ICON = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" f
|
|
|
3291
3660
|
<polyline points="8 6 2 12 8 18"></polyline>
|
|
3292
3661
|
</svg>`;
|
|
3293
3662
|
function scripts_renderScriptsPanel(container, options) {
|
|
3294
|
-
const { getState } = options;
|
|
3663
|
+
const { getState, getEvents } = options;
|
|
3295
3664
|
renderer_clearElement(container);
|
|
3296
3665
|
const state = getState();
|
|
3297
3666
|
if (!state) return void container.appendChild(renderer_div({
|
|
@@ -3306,6 +3675,7 @@ function scripts_renderScriptsPanel(container, options) {
|
|
|
3306
3675
|
const scripts = state.scripts || [];
|
|
3307
3676
|
const loadedScripts = state.loadedScripts || {};
|
|
3308
3677
|
const networkBlocker = state.networkBlocker;
|
|
3678
|
+
const events = getEvents?.() ?? [];
|
|
3309
3679
|
if (0 === scripts.length) {
|
|
3310
3680
|
const scriptsSection = createSection({
|
|
3311
3681
|
title: 'Configured Scripts',
|
|
@@ -3388,6 +3758,20 @@ function scripts_renderScriptsPanel(container, options) {
|
|
|
3388
3758
|
]
|
|
3389
3759
|
});
|
|
3390
3760
|
container.appendChild(networkSection);
|
|
3761
|
+
const blockedRequestEvents = events.filter((event)=>'network' === event.type);
|
|
3762
|
+
const networkEventsSection = createSection({
|
|
3763
|
+
title: `Blocked Requests (${blockedRequestEvents.length})`,
|
|
3764
|
+
children: 0 === blockedRequestEvents.length ? [
|
|
3765
|
+
renderer_div({
|
|
3766
|
+
style: {
|
|
3767
|
+
fontSize: 'var(--c15t-devtools-font-size-xs)',
|
|
3768
|
+
color: 'var(--c15t-devtools-text-muted)'
|
|
3769
|
+
},
|
|
3770
|
+
text: 'No blocked network requests recorded in this session'
|
|
3771
|
+
})
|
|
3772
|
+
] : createBlockedRequestContent(blockedRequestEvents)
|
|
3773
|
+
});
|
|
3774
|
+
container.appendChild(networkEventsSection);
|
|
3391
3775
|
const loadedCount = Object.values(loadedScripts).filter(Boolean).length;
|
|
3392
3776
|
const totalCount = scripts.length;
|
|
3393
3777
|
const summarySection = createSection({
|
|
@@ -3413,12 +3797,127 @@ function scripts_renderScriptsPanel(container, options) {
|
|
|
3413
3797
|
}
|
|
3414
3798
|
function checkScriptConsent(state, category) {
|
|
3415
3799
|
if (!category) return true;
|
|
3800
|
+
if ('function' == typeof state.has) try {
|
|
3801
|
+
return state.has(category);
|
|
3802
|
+
} catch {}
|
|
3416
3803
|
if ('string' == typeof category) {
|
|
3417
3804
|
const consents = state.consents || {};
|
|
3418
3805
|
return true === consents[category];
|
|
3419
3806
|
}
|
|
3420
3807
|
return false;
|
|
3421
3808
|
}
|
|
3809
|
+
function createBlockedRequestContent(events) {
|
|
3810
|
+
const stats = new Map();
|
|
3811
|
+
for (const event of events){
|
|
3812
|
+
const ruleId = getEventRuleId(event) ?? 'unknown';
|
|
3813
|
+
stats.set(ruleId, (stats.get(ruleId) ?? 0) + 1);
|
|
3814
|
+
}
|
|
3815
|
+
const statsList = renderer_div({
|
|
3816
|
+
style: {
|
|
3817
|
+
display: 'flex',
|
|
3818
|
+
flexDirection: 'column',
|
|
3819
|
+
gap: '4px',
|
|
3820
|
+
marginBottom: '8px'
|
|
3821
|
+
},
|
|
3822
|
+
children: [
|
|
3823
|
+
...stats.entries()
|
|
3824
|
+
].sort((a, b)=>b[1] - a[1]).map(([ruleId, count])=>createInfoRow({
|
|
3825
|
+
label: 'unknown' === ruleId ? 'Unknown Rule' : `Rule: ${ruleId}`,
|
|
3826
|
+
value: `${count}`
|
|
3827
|
+
}))
|
|
3828
|
+
});
|
|
3829
|
+
const latestEvents = events.slice(0, 5);
|
|
3830
|
+
const latestList = renderer_div({
|
|
3831
|
+
style: {
|
|
3832
|
+
display: 'flex',
|
|
3833
|
+
flexDirection: 'column',
|
|
3834
|
+
gap: '4px'
|
|
3835
|
+
},
|
|
3836
|
+
children: latestEvents.map((event)=>createInfoRow({
|
|
3837
|
+
label: `${formatEventTime(event.timestamp)} ${getEventMethod(event)}`,
|
|
3838
|
+
value: scripts_truncateText(getEventUrl(event), 38)
|
|
3839
|
+
}))
|
|
3840
|
+
});
|
|
3841
|
+
return [
|
|
3842
|
+
statsList,
|
|
3843
|
+
latestList
|
|
3844
|
+
];
|
|
3845
|
+
}
|
|
3846
|
+
function getEventRuleId(event) {
|
|
3847
|
+
const data = event.data;
|
|
3848
|
+
const rule = data?.rule;
|
|
3849
|
+
const ruleId = rule?.id ?? data?.ruleId;
|
|
3850
|
+
return 'string' == typeof ruleId || 'number' == typeof ruleId ? String(ruleId) : void 0;
|
|
3851
|
+
}
|
|
3852
|
+
function getEventMethod(event) {
|
|
3853
|
+
const data = event.data;
|
|
3854
|
+
const method = data?.method;
|
|
3855
|
+
return 'string' == typeof method ? method.toUpperCase() : 'REQ';
|
|
3856
|
+
}
|
|
3857
|
+
function getEventUrl(event) {
|
|
3858
|
+
const data = event.data;
|
|
3859
|
+
const url = data?.url;
|
|
3860
|
+
return 'string' == typeof url ? url : event.message;
|
|
3861
|
+
}
|
|
3862
|
+
function formatEventTime(timestamp) {
|
|
3863
|
+
return new Date(timestamp).toLocaleTimeString('en-US', {
|
|
3864
|
+
hour12: false,
|
|
3865
|
+
hour: '2-digit',
|
|
3866
|
+
minute: '2-digit',
|
|
3867
|
+
second: '2-digit'
|
|
3868
|
+
});
|
|
3869
|
+
}
|
|
3870
|
+
function scripts_truncateText(text, maxLength) {
|
|
3871
|
+
if (text.length <= maxLength) return text;
|
|
3872
|
+
return `${text.slice(0, maxLength - 3)}...`;
|
|
3873
|
+
}
|
|
3874
|
+
const DEVTOOLS_OVERRIDES_STORAGE_KEY = 'c15t-devtools-overrides';
|
|
3875
|
+
function normalizeStringValue(value) {
|
|
3876
|
+
if ('string' != typeof value) return;
|
|
3877
|
+
const normalized = value.trim();
|
|
3878
|
+
return normalized.length > 0 ? normalized : void 0;
|
|
3879
|
+
}
|
|
3880
|
+
function normalizeBooleanValue(value) {
|
|
3881
|
+
return 'boolean' == typeof value ? value : void 0;
|
|
3882
|
+
}
|
|
3883
|
+
function normalizeOverrides(value) {
|
|
3884
|
+
if (!value || 'object' != typeof value) return null;
|
|
3885
|
+
const source = value;
|
|
3886
|
+
const overrides = {
|
|
3887
|
+
country: normalizeStringValue(source.country),
|
|
3888
|
+
region: normalizeStringValue(source.region),
|
|
3889
|
+
language: normalizeStringValue(source.language),
|
|
3890
|
+
gpc: normalizeBooleanValue(source.gpc)
|
|
3891
|
+
};
|
|
3892
|
+
return hasPersistedOverrides(overrides) ? overrides : null;
|
|
3893
|
+
}
|
|
3894
|
+
function hasPersistedOverrides(overrides) {
|
|
3895
|
+
return Boolean(overrides.country || overrides.region || overrides.language || void 0 !== overrides.gpc);
|
|
3896
|
+
}
|
|
3897
|
+
function override_storage_loadPersistedOverrides(storageKey = DEVTOOLS_OVERRIDES_STORAGE_KEY) {
|
|
3898
|
+
if ('undefined' == typeof window) return null;
|
|
3899
|
+
try {
|
|
3900
|
+
const stored = localStorage.getItem(storageKey);
|
|
3901
|
+
if (!stored) return null;
|
|
3902
|
+
const parsed = JSON.parse(stored);
|
|
3903
|
+
return normalizeOverrides(parsed);
|
|
3904
|
+
} catch {
|
|
3905
|
+
return null;
|
|
3906
|
+
}
|
|
3907
|
+
}
|
|
3908
|
+
function override_storage_persistOverrides(overrides, storageKey = DEVTOOLS_OVERRIDES_STORAGE_KEY) {
|
|
3909
|
+
if ('undefined' == typeof window) return;
|
|
3910
|
+
try {
|
|
3911
|
+
if (!hasPersistedOverrides(overrides)) return void localStorage.removeItem(storageKey);
|
|
3912
|
+
localStorage.setItem(storageKey, JSON.stringify(overrides));
|
|
3913
|
+
} catch {}
|
|
3914
|
+
}
|
|
3915
|
+
function override_storage_clearPersistedOverrides(storageKey = DEVTOOLS_OVERRIDES_STORAGE_KEY) {
|
|
3916
|
+
if ('undefined' == typeof window) return;
|
|
3917
|
+
try {
|
|
3918
|
+
localStorage.removeItem(storageKey);
|
|
3919
|
+
} catch {}
|
|
3920
|
+
}
|
|
3422
3921
|
const STORAGE_KEYS = {
|
|
3423
3922
|
C15T: 'c15t',
|
|
3424
3923
|
PENDING_SYNC: 'c15t:pending-consent-sync',
|
|
@@ -3556,12 +4055,37 @@ function store_connector_createStoreConnector(options = {}) {
|
|
|
3556
4055
|
const { namespace = 'c15tStore', onConnect, onStateChange, onDisconnect } = options;
|
|
3557
4056
|
let store = null;
|
|
3558
4057
|
let unsubscribe = null;
|
|
3559
|
-
let
|
|
4058
|
+
let reconnectTimeout = null;
|
|
4059
|
+
let reconnectAttempts = 0;
|
|
4060
|
+
let hasNotifiedDisconnect = false;
|
|
3560
4061
|
const listeners = new Set();
|
|
4062
|
+
const INITIAL_RETRY_DELAY_MS = 100;
|
|
4063
|
+
const MAX_RETRY_DELAY_MS = 2000;
|
|
4064
|
+
const DISCONNECT_NOTIFY_ATTEMPTS = 5;
|
|
4065
|
+
function clearReconnectTimer() {
|
|
4066
|
+
if (reconnectTimeout) {
|
|
4067
|
+
clearTimeout(reconnectTimeout);
|
|
4068
|
+
reconnectTimeout = null;
|
|
4069
|
+
}
|
|
4070
|
+
}
|
|
4071
|
+
function resetReconnectState() {
|
|
4072
|
+
reconnectAttempts = 0;
|
|
4073
|
+
hasNotifiedDisconnect = false;
|
|
4074
|
+
}
|
|
4075
|
+
function notifyDisconnectedOnce() {
|
|
4076
|
+
if (hasNotifiedDisconnect) return;
|
|
4077
|
+
hasNotifiedDisconnect = true;
|
|
4078
|
+
onDisconnect?.();
|
|
4079
|
+
}
|
|
3561
4080
|
function tryConnect() {
|
|
3562
4081
|
if ('undefined' == typeof window) return false;
|
|
3563
4082
|
const storeInstance = window[namespace];
|
|
3564
4083
|
if (storeInstance && 'function' == typeof storeInstance.getState) {
|
|
4084
|
+
if (store === storeInstance && unsubscribe) return true;
|
|
4085
|
+
if (unsubscribe) {
|
|
4086
|
+
unsubscribe();
|
|
4087
|
+
unsubscribe = null;
|
|
4088
|
+
}
|
|
3565
4089
|
store = storeInstance;
|
|
3566
4090
|
unsubscribe = store.subscribe((state)=>{
|
|
3567
4091
|
onStateChange?.(state);
|
|
@@ -3569,30 +4093,26 @@ function store_connector_createStoreConnector(options = {}) {
|
|
|
3569
4093
|
});
|
|
3570
4094
|
const currentState = store.getState();
|
|
3571
4095
|
onConnect?.(currentState, store);
|
|
3572
|
-
|
|
3573
|
-
|
|
3574
|
-
pollInterval = null;
|
|
3575
|
-
}
|
|
4096
|
+
clearReconnectTimer();
|
|
4097
|
+
resetReconnectState();
|
|
3576
4098
|
return true;
|
|
3577
4099
|
}
|
|
3578
4100
|
return false;
|
|
3579
4101
|
}
|
|
4102
|
+
function scheduleReconnect(immediate = false) {
|
|
4103
|
+
if (store || reconnectTimeout) return;
|
|
4104
|
+
const delay = immediate ? 0 : Math.min(INITIAL_RETRY_DELAY_MS * 2 ** Math.min(reconnectAttempts, 5), MAX_RETRY_DELAY_MS);
|
|
4105
|
+
reconnectTimeout = setTimeout(()=>{
|
|
4106
|
+
reconnectTimeout = null;
|
|
4107
|
+
reconnectAttempts++;
|
|
4108
|
+
if (tryConnect()) return;
|
|
4109
|
+
if (reconnectAttempts >= DISCONNECT_NOTIFY_ATTEMPTS) notifyDisconnectedOnce();
|
|
4110
|
+
scheduleReconnect();
|
|
4111
|
+
}, delay);
|
|
4112
|
+
}
|
|
3580
4113
|
function startPolling() {
|
|
3581
|
-
if (pollInterval) return;
|
|
3582
4114
|
if (tryConnect()) return;
|
|
3583
|
-
|
|
3584
|
-
const maxAttempts = 50;
|
|
3585
|
-
pollInterval = setInterval(()=>{
|
|
3586
|
-
attempts++;
|
|
3587
|
-
if (tryConnect()) return;
|
|
3588
|
-
if (attempts >= maxAttempts) {
|
|
3589
|
-
if (pollInterval) {
|
|
3590
|
-
clearInterval(pollInterval);
|
|
3591
|
-
pollInterval = null;
|
|
3592
|
-
}
|
|
3593
|
-
onDisconnect?.();
|
|
3594
|
-
}
|
|
3595
|
-
}, 100);
|
|
4115
|
+
scheduleReconnect(true);
|
|
3596
4116
|
}
|
|
3597
4117
|
startPolling();
|
|
3598
4118
|
return {
|
|
@@ -3606,11 +4126,13 @@ function store_connector_createStoreConnector(options = {}) {
|
|
|
3606
4126
|
listeners.delete(listener);
|
|
3607
4127
|
};
|
|
3608
4128
|
},
|
|
4129
|
+
retryConnection: ()=>{
|
|
4130
|
+
if (store) return;
|
|
4131
|
+
resetReconnectState();
|
|
4132
|
+
scheduleReconnect(true);
|
|
4133
|
+
},
|
|
3609
4134
|
destroy: ()=>{
|
|
3610
|
-
|
|
3611
|
-
clearInterval(pollInterval);
|
|
3612
|
-
pollInterval = null;
|
|
3613
|
-
}
|
|
4135
|
+
clearReconnectTimer();
|
|
3614
4136
|
if (unsubscribe) {
|
|
3615
4137
|
unsubscribe();
|
|
3616
4138
|
unsubscribe = null;
|
|
@@ -3629,14 +4151,61 @@ tokens_options.domAPI = styleDomAPI_default();
|
|
|
3629
4151
|
tokens_options.insertStyleElement = insertStyleElement_default();
|
|
3630
4152
|
injectStylesIntoStyleTag_default()(tokens.A, tokens_options);
|
|
3631
4153
|
tokens.A && tokens.A.locals && tokens.A.locals;
|
|
4154
|
+
function normalizeOverridesForPersistence(overrides) {
|
|
4155
|
+
return {
|
|
4156
|
+
country: overrides?.country?.trim() || void 0,
|
|
4157
|
+
region: overrides?.region?.trim() || void 0,
|
|
4158
|
+
language: overrides?.language?.trim() || void 0,
|
|
4159
|
+
gpc: overrides?.gpc
|
|
4160
|
+
};
|
|
4161
|
+
}
|
|
4162
|
+
function persistedOverridesEqual(a, b) {
|
|
4163
|
+
return a.country === b.country && a.region === b.region && a.language === b.language && a.gpc === b.gpc;
|
|
4164
|
+
}
|
|
4165
|
+
function getBlockedRequestMessage(payload) {
|
|
4166
|
+
const data = payload;
|
|
4167
|
+
const method = 'string' == typeof data?.method ? data.method.toUpperCase() : 'REQUEST';
|
|
4168
|
+
const url = 'string' == typeof data?.url ? data.url : 'unknown-url';
|
|
4169
|
+
return `Network blocked: ${method} ${url}`;
|
|
4170
|
+
}
|
|
3632
4171
|
function createDevToolsPanel(options) {
|
|
3633
4172
|
const { namespace = 'c15tStore' } = options;
|
|
4173
|
+
let originalEmbeddedNetworkBlockedCallback;
|
|
4174
|
+
let hasWrappedEmbeddedNetworkBlocker = false;
|
|
3634
4175
|
const stateManager = state_manager_createStateManager({
|
|
3635
4176
|
isOpen: true
|
|
3636
4177
|
});
|
|
3637
4178
|
const storeConnector = store_connector_createStoreConnector({
|
|
3638
4179
|
namespace,
|
|
3639
|
-
onConnect: ()=>
|
|
4180
|
+
onConnect: (state, store)=>{
|
|
4181
|
+
stateManager.setConnected(true);
|
|
4182
|
+
const currentNetworkBlocker = state.networkBlocker;
|
|
4183
|
+
if (currentNetworkBlocker && !hasWrappedEmbeddedNetworkBlocker) {
|
|
4184
|
+
originalEmbeddedNetworkBlockedCallback = currentNetworkBlocker.onRequestBlocked;
|
|
4185
|
+
hasWrappedEmbeddedNetworkBlocker = true;
|
|
4186
|
+
store.getState().setNetworkBlocker({
|
|
4187
|
+
...currentNetworkBlocker,
|
|
4188
|
+
onRequestBlocked: (payload)=>{
|
|
4189
|
+
stateManager.addEvent({
|
|
4190
|
+
type: 'network',
|
|
4191
|
+
message: getBlockedRequestMessage(payload),
|
|
4192
|
+
data: payload
|
|
4193
|
+
});
|
|
4194
|
+
if ('function' == typeof originalEmbeddedNetworkBlockedCallback) originalEmbeddedNetworkBlockedCallback(payload);
|
|
4195
|
+
}
|
|
4196
|
+
});
|
|
4197
|
+
}
|
|
4198
|
+
const persistedOverrides = override_storage_loadPersistedOverrides();
|
|
4199
|
+
if (persistedOverrides) {
|
|
4200
|
+
const currentOverrides = normalizeOverridesForPersistence(state.overrides);
|
|
4201
|
+
if (!persistedOverridesEqual(persistedOverrides, currentOverrides)) store.getState().setOverrides({
|
|
4202
|
+
country: persistedOverrides.country,
|
|
4203
|
+
region: persistedOverrides.region,
|
|
4204
|
+
language: persistedOverrides.language,
|
|
4205
|
+
gpc: persistedOverrides.gpc
|
|
4206
|
+
});
|
|
4207
|
+
}
|
|
4208
|
+
},
|
|
3640
4209
|
onDisconnect: ()=>stateManager.setConnected(false)
|
|
3641
4210
|
});
|
|
3642
4211
|
const container = renderer_div({
|
|
@@ -3685,29 +4254,61 @@ function createDevToolsPanel(options) {
|
|
|
3685
4254
|
case 'location':
|
|
3686
4255
|
location_renderLocationPanel(contentArea, {
|
|
3687
4256
|
getState: getStoreState,
|
|
3688
|
-
|
|
4257
|
+
onApplyOverrides: async (overrides)=>{
|
|
3689
4258
|
const store = storeConnector.getStore();
|
|
3690
4259
|
if (store) {
|
|
3691
|
-
const current = store.getState().overrides || {};
|
|
3692
4260
|
await store.getState().setOverrides({
|
|
3693
|
-
|
|
3694
|
-
|
|
4261
|
+
country: overrides.country,
|
|
4262
|
+
region: overrides.region,
|
|
4263
|
+
language: overrides.language,
|
|
4264
|
+
gpc: overrides.gpc
|
|
4265
|
+
});
|
|
4266
|
+
override_storage_persistOverrides({
|
|
4267
|
+
country: overrides.country,
|
|
4268
|
+
region: overrides.region,
|
|
4269
|
+
language: overrides.language,
|
|
4270
|
+
gpc: overrides.gpc
|
|
3695
4271
|
});
|
|
3696
4272
|
}
|
|
3697
4273
|
},
|
|
3698
4274
|
onClearOverrides: async ()=>{
|
|
3699
|
-
await storeConnector.getStore()?.getState().setOverrides(
|
|
4275
|
+
await storeConnector.getStore()?.getState().setOverrides({
|
|
4276
|
+
country: void 0,
|
|
4277
|
+
region: void 0,
|
|
4278
|
+
language: void 0,
|
|
4279
|
+
gpc: void 0
|
|
4280
|
+
});
|
|
4281
|
+
override_storage_clearPersistedOverrides();
|
|
3700
4282
|
}
|
|
3701
4283
|
});
|
|
3702
4284
|
break;
|
|
3703
4285
|
case "scripts":
|
|
3704
4286
|
scripts_renderScriptsPanel(contentArea, {
|
|
3705
|
-
getState: getStoreState
|
|
4287
|
+
getState: getStoreState,
|
|
4288
|
+
getEvents: ()=>stateManager.getState().eventLog
|
|
3706
4289
|
});
|
|
3707
4290
|
break;
|
|
3708
4291
|
case 'iab':
|
|
3709
4292
|
iab_renderIabPanel(contentArea, {
|
|
3710
4293
|
getState: getStoreState,
|
|
4294
|
+
onSetPurposeConsent: (purposeId, value)=>{
|
|
4295
|
+
storeConnector.getStore()?.getState().iab?.setPurposeConsent(purposeId, value);
|
|
4296
|
+
},
|
|
4297
|
+
onSetVendorConsent: (vendorId, value)=>{
|
|
4298
|
+
storeConnector.getStore()?.getState().iab?.setVendorConsent(vendorId, value);
|
|
4299
|
+
},
|
|
4300
|
+
onSetSpecialFeatureOptIn: (featureId, value)=>{
|
|
4301
|
+
storeConnector.getStore()?.getState().iab?.setSpecialFeatureOptIn(featureId, value);
|
|
4302
|
+
},
|
|
4303
|
+
onAcceptAll: ()=>{
|
|
4304
|
+
storeConnector.getStore()?.getState().iab?.acceptAll();
|
|
4305
|
+
},
|
|
4306
|
+
onRejectAll: ()=>{
|
|
4307
|
+
storeConnector.getStore()?.getState().iab?.rejectAll();
|
|
4308
|
+
},
|
|
4309
|
+
onSave: ()=>{
|
|
4310
|
+
storeConnector.getStore()?.getState().iab?.save();
|
|
4311
|
+
},
|
|
3711
4312
|
onReset: async ()=>{
|
|
3712
4313
|
const store = storeConnector.getStore();
|
|
3713
4314
|
if (store) await reset_consents_resetAllConsents(store);
|
|
@@ -3768,6 +4369,14 @@ function createDevToolsPanel(options) {
|
|
|
3768
4369
|
return {
|
|
3769
4370
|
element: container,
|
|
3770
4371
|
destroy: ()=>{
|
|
4372
|
+
const store = storeConnector.getStore();
|
|
4373
|
+
if (store && hasWrappedEmbeddedNetworkBlocker) {
|
|
4374
|
+
const currentNetworkBlocker = store.getState().networkBlocker;
|
|
4375
|
+
if (currentNetworkBlocker) store.getState().setNetworkBlocker({
|
|
4376
|
+
...currentNetworkBlocker,
|
|
4377
|
+
onRequestBlocked: originalEmbeddedNetworkBlockedCallback
|
|
4378
|
+
});
|
|
4379
|
+
}
|
|
3771
4380
|
unsubscribe();
|
|
3772
4381
|
tabsInstance.destroy();
|
|
3773
4382
|
storeConnector.destroy();
|