@sitepulse/web 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +2 -0
- package/dist/index.js +82 -3
- package/dist/index.mjs +82 -3
- package/dist/renderer.d.ts +1 -0
- package/dist/web-sdk/src/index.d.ts +2 -0
- package/dist/web-sdk/src/renderer.d.ts +1 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -4,8 +4,10 @@ export * from "./renderer";
|
|
|
4
4
|
export * from "./evaluator";
|
|
5
5
|
export interface SitePulseConfig {
|
|
6
6
|
siteId: string;
|
|
7
|
+
apiHost?: string;
|
|
7
8
|
endpointUrl?: string;
|
|
8
9
|
campaignsEndpointUrl?: string;
|
|
10
|
+
submissionsEndpointUrl?: string;
|
|
9
11
|
flushIntervalMs?: number;
|
|
10
12
|
autoTrack?: boolean;
|
|
11
13
|
autoFetchCampaigns?: boolean;
|
package/dist/index.js
CHANGED
|
@@ -1052,7 +1052,8 @@ function renderCampaignDOM(campaign, handlers = {}) {
|
|
|
1052
1052
|
const emailVal = entries.email || entries.email_address || entries.newsletter_email || null;
|
|
1053
1053
|
handlers.onSubmit?.(entries);
|
|
1054
1054
|
if (typeof fetch !== "undefined") {
|
|
1055
|
-
|
|
1055
|
+
const submitEndpoint = handlers.submissionsEndpointUrl || "/api/campaigns/submit";
|
|
1056
|
+
fetch(submitEndpoint, {
|
|
1056
1057
|
method: "POST",
|
|
1057
1058
|
headers: { "Content-Type": "application/json" },
|
|
1058
1059
|
body: JSON.stringify({
|
|
@@ -1240,6 +1241,7 @@ function renderCampaignDOM(campaign, handlers = {}) {
|
|
|
1240
1241
|
let originalPaddingTop = null;
|
|
1241
1242
|
let originalPaddingBottom = null;
|
|
1242
1243
|
let resizeObserver = null;
|
|
1244
|
+
const shiftedElements = [];
|
|
1243
1245
|
if (isBanner && typeof document !== "undefined" && document.body) {
|
|
1244
1246
|
try {
|
|
1245
1247
|
const isBottom = design.position === "bottom";
|
|
@@ -1261,14 +1263,64 @@ function renderCampaignDOM(campaign, handlers = {}) {
|
|
|
1261
1263
|
}
|
|
1262
1264
|
} catch {
|
|
1263
1265
|
}
|
|
1266
|
+
const findTopFixedElements = () => {
|
|
1267
|
+
const candidates = [];
|
|
1268
|
+
try {
|
|
1269
|
+
const elements = Array.from(
|
|
1270
|
+
document.querySelectorAll(
|
|
1271
|
+
'header, nav, [role="banner"], [class*="header"], [class*="navbar"], [class*="nav-fixed"], [class*="sticky"]'
|
|
1272
|
+
)
|
|
1273
|
+
);
|
|
1274
|
+
Array.from(document.body.children).forEach((child) => {
|
|
1275
|
+
if (child instanceof HTMLElement && child !== wrapper && child !== overlayEl && !elements.includes(child)) {
|
|
1276
|
+
elements.push(child);
|
|
1277
|
+
}
|
|
1278
|
+
});
|
|
1279
|
+
for (const el of elements) {
|
|
1280
|
+
if (el === wrapper || el === overlayEl || !el.isConnected) continue;
|
|
1281
|
+
const style = window.getComputedStyle(el);
|
|
1282
|
+
const pos = style.position;
|
|
1283
|
+
if (pos === "fixed" || pos === "sticky") {
|
|
1284
|
+
const rect = el.getBoundingClientRect();
|
|
1285
|
+
if (rect.top <= 15 && rect.height > 0 && rect.height < window.innerHeight * 0.5) {
|
|
1286
|
+
candidates.push(el);
|
|
1287
|
+
}
|
|
1288
|
+
}
|
|
1289
|
+
}
|
|
1290
|
+
} catch {
|
|
1291
|
+
}
|
|
1292
|
+
return candidates;
|
|
1293
|
+
};
|
|
1264
1294
|
const updateOffset = () => {
|
|
1265
1295
|
if (!wrapper || !document.body) return;
|
|
1266
1296
|
const bannerHeight = wrapper.offsetHeight;
|
|
1267
1297
|
if (bannerHeight > 0) {
|
|
1268
1298
|
if (isBottom) {
|
|
1269
1299
|
document.body.style.paddingBottom = `${basePaddingBottom + bannerHeight}px`;
|
|
1300
|
+
document.documentElement.style.setProperty(
|
|
1301
|
+
"--sitepulse-bottom-banner-height",
|
|
1302
|
+
`${bannerHeight}px`
|
|
1303
|
+
);
|
|
1270
1304
|
} else {
|
|
1271
1305
|
document.body.style.paddingTop = `${basePaddingTop + bannerHeight}px`;
|
|
1306
|
+
document.documentElement.style.setProperty(
|
|
1307
|
+
"--sitepulse-top-banner-height",
|
|
1308
|
+
`${bannerHeight}px`
|
|
1309
|
+
);
|
|
1310
|
+
document.documentElement.classList.add("has-sitepulse-top-banner");
|
|
1311
|
+
const fixedHeaders = findTopFixedElements();
|
|
1312
|
+
for (const el of fixedHeaders) {
|
|
1313
|
+
if (!shiftedElements.some((r) => r.el === el)) {
|
|
1314
|
+
shiftedElements.push({
|
|
1315
|
+
el,
|
|
1316
|
+
originalTop: el.style.top,
|
|
1317
|
+
originalTransform: el.style.transform,
|
|
1318
|
+
originalTransition: el.style.transition
|
|
1319
|
+
});
|
|
1320
|
+
el.style.transition = el.style.transition ? `${el.style.transition}, transform 0.2s ease` : "transform 0.2s ease";
|
|
1321
|
+
el.style.transform = `translateY(${bannerHeight}px)`;
|
|
1322
|
+
}
|
|
1323
|
+
}
|
|
1272
1324
|
}
|
|
1273
1325
|
}
|
|
1274
1326
|
};
|
|
@@ -1301,6 +1353,23 @@ function renderCampaignDOM(campaign, handlers = {}) {
|
|
|
1301
1353
|
if (originalPaddingBottom !== null) {
|
|
1302
1354
|
document.body.style.paddingBottom = originalPaddingBottom;
|
|
1303
1355
|
}
|
|
1356
|
+
document.documentElement.style.setProperty(
|
|
1357
|
+
"--sitepulse-top-banner-height",
|
|
1358
|
+
"0px"
|
|
1359
|
+
);
|
|
1360
|
+
document.documentElement.style.setProperty(
|
|
1361
|
+
"--sitepulse-bottom-banner-height",
|
|
1362
|
+
"0px"
|
|
1363
|
+
);
|
|
1364
|
+
document.documentElement.classList.remove("has-sitepulse-top-banner");
|
|
1365
|
+
for (const record of shiftedElements) {
|
|
1366
|
+
if (record.el && record.el.isConnected) {
|
|
1367
|
+
record.el.style.transform = record.originalTransform;
|
|
1368
|
+
record.el.style.transition = record.originalTransition;
|
|
1369
|
+
record.el.style.top = record.originalTop;
|
|
1370
|
+
}
|
|
1371
|
+
}
|
|
1372
|
+
shiftedElements.length = 0;
|
|
1304
1373
|
} catch {
|
|
1305
1374
|
}
|
|
1306
1375
|
}
|
|
@@ -1456,9 +1525,18 @@ var SitePulseClient = class {
|
|
|
1456
1525
|
registeredCampaignTeardowns = [];
|
|
1457
1526
|
init(config) {
|
|
1458
1527
|
const isReinit = this.initialized;
|
|
1528
|
+
let inferredBase = "";
|
|
1529
|
+
if (typeof document !== "undefined" && document.currentScript?.src) {
|
|
1530
|
+
try {
|
|
1531
|
+
inferredBase = new URL(document.currentScript.src).origin;
|
|
1532
|
+
} catch {
|
|
1533
|
+
}
|
|
1534
|
+
}
|
|
1535
|
+
const defaultHost = config.apiHost || inferredBase || (typeof window !== "undefined" && window.location.hostname === "localhost" && window.location.port === "3000" ? "" : "https://sitepulse-app-ten.vercel.app");
|
|
1459
1536
|
this.config = {
|
|
1460
|
-
endpointUrl: "/api/collect",
|
|
1461
|
-
campaignsEndpointUrl: "/api/campaigns/active",
|
|
1537
|
+
endpointUrl: defaultHost ? `${defaultHost}/api/collect` : "/api/collect",
|
|
1538
|
+
campaignsEndpointUrl: defaultHost ? `${defaultHost}/api/campaigns/active` : "/api/campaigns/active",
|
|
1539
|
+
submissionsEndpointUrl: defaultHost ? `${defaultHost}/api/campaigns/submit` : "/api/campaigns/submit",
|
|
1462
1540
|
flushIntervalMs: 5e3,
|
|
1463
1541
|
autoTrack: true,
|
|
1464
1542
|
autoFetchCampaigns: true,
|
|
@@ -1617,6 +1695,7 @@ var SitePulseClient = class {
|
|
|
1617
1695
|
campaignName: campaign.name
|
|
1618
1696
|
});
|
|
1619
1697
|
const dom = renderCampaignDOM(campaign, {
|
|
1698
|
+
submissionsEndpointUrl: handlers.submissionsEndpointUrl || this.config?.submissionsEndpointUrl,
|
|
1620
1699
|
onLinkClick: (url, eventName) => {
|
|
1621
1700
|
this.track("campaign_click", {
|
|
1622
1701
|
campaignId: campaign.id,
|
package/dist/index.mjs
CHANGED
|
@@ -1013,7 +1013,8 @@ function renderCampaignDOM(campaign, handlers = {}) {
|
|
|
1013
1013
|
const emailVal = entries.email || entries.email_address || entries.newsletter_email || null;
|
|
1014
1014
|
handlers.onSubmit?.(entries);
|
|
1015
1015
|
if (typeof fetch !== "undefined") {
|
|
1016
|
-
|
|
1016
|
+
const submitEndpoint = handlers.submissionsEndpointUrl || "/api/campaigns/submit";
|
|
1017
|
+
fetch(submitEndpoint, {
|
|
1017
1018
|
method: "POST",
|
|
1018
1019
|
headers: { "Content-Type": "application/json" },
|
|
1019
1020
|
body: JSON.stringify({
|
|
@@ -1201,6 +1202,7 @@ function renderCampaignDOM(campaign, handlers = {}) {
|
|
|
1201
1202
|
let originalPaddingTop = null;
|
|
1202
1203
|
let originalPaddingBottom = null;
|
|
1203
1204
|
let resizeObserver = null;
|
|
1205
|
+
const shiftedElements = [];
|
|
1204
1206
|
if (isBanner && typeof document !== "undefined" && document.body) {
|
|
1205
1207
|
try {
|
|
1206
1208
|
const isBottom = design.position === "bottom";
|
|
@@ -1222,14 +1224,64 @@ function renderCampaignDOM(campaign, handlers = {}) {
|
|
|
1222
1224
|
}
|
|
1223
1225
|
} catch {
|
|
1224
1226
|
}
|
|
1227
|
+
const findTopFixedElements = () => {
|
|
1228
|
+
const candidates = [];
|
|
1229
|
+
try {
|
|
1230
|
+
const elements = Array.from(
|
|
1231
|
+
document.querySelectorAll(
|
|
1232
|
+
'header, nav, [role="banner"], [class*="header"], [class*="navbar"], [class*="nav-fixed"], [class*="sticky"]'
|
|
1233
|
+
)
|
|
1234
|
+
);
|
|
1235
|
+
Array.from(document.body.children).forEach((child) => {
|
|
1236
|
+
if (child instanceof HTMLElement && child !== wrapper && child !== overlayEl && !elements.includes(child)) {
|
|
1237
|
+
elements.push(child);
|
|
1238
|
+
}
|
|
1239
|
+
});
|
|
1240
|
+
for (const el of elements) {
|
|
1241
|
+
if (el === wrapper || el === overlayEl || !el.isConnected) continue;
|
|
1242
|
+
const style = window.getComputedStyle(el);
|
|
1243
|
+
const pos = style.position;
|
|
1244
|
+
if (pos === "fixed" || pos === "sticky") {
|
|
1245
|
+
const rect = el.getBoundingClientRect();
|
|
1246
|
+
if (rect.top <= 15 && rect.height > 0 && rect.height < window.innerHeight * 0.5) {
|
|
1247
|
+
candidates.push(el);
|
|
1248
|
+
}
|
|
1249
|
+
}
|
|
1250
|
+
}
|
|
1251
|
+
} catch {
|
|
1252
|
+
}
|
|
1253
|
+
return candidates;
|
|
1254
|
+
};
|
|
1225
1255
|
const updateOffset = () => {
|
|
1226
1256
|
if (!wrapper || !document.body) return;
|
|
1227
1257
|
const bannerHeight = wrapper.offsetHeight;
|
|
1228
1258
|
if (bannerHeight > 0) {
|
|
1229
1259
|
if (isBottom) {
|
|
1230
1260
|
document.body.style.paddingBottom = `${basePaddingBottom + bannerHeight}px`;
|
|
1261
|
+
document.documentElement.style.setProperty(
|
|
1262
|
+
"--sitepulse-bottom-banner-height",
|
|
1263
|
+
`${bannerHeight}px`
|
|
1264
|
+
);
|
|
1231
1265
|
} else {
|
|
1232
1266
|
document.body.style.paddingTop = `${basePaddingTop + bannerHeight}px`;
|
|
1267
|
+
document.documentElement.style.setProperty(
|
|
1268
|
+
"--sitepulse-top-banner-height",
|
|
1269
|
+
`${bannerHeight}px`
|
|
1270
|
+
);
|
|
1271
|
+
document.documentElement.classList.add("has-sitepulse-top-banner");
|
|
1272
|
+
const fixedHeaders = findTopFixedElements();
|
|
1273
|
+
for (const el of fixedHeaders) {
|
|
1274
|
+
if (!shiftedElements.some((r) => r.el === el)) {
|
|
1275
|
+
shiftedElements.push({
|
|
1276
|
+
el,
|
|
1277
|
+
originalTop: el.style.top,
|
|
1278
|
+
originalTransform: el.style.transform,
|
|
1279
|
+
originalTransition: el.style.transition
|
|
1280
|
+
});
|
|
1281
|
+
el.style.transition = el.style.transition ? `${el.style.transition}, transform 0.2s ease` : "transform 0.2s ease";
|
|
1282
|
+
el.style.transform = `translateY(${bannerHeight}px)`;
|
|
1283
|
+
}
|
|
1284
|
+
}
|
|
1233
1285
|
}
|
|
1234
1286
|
}
|
|
1235
1287
|
};
|
|
@@ -1262,6 +1314,23 @@ function renderCampaignDOM(campaign, handlers = {}) {
|
|
|
1262
1314
|
if (originalPaddingBottom !== null) {
|
|
1263
1315
|
document.body.style.paddingBottom = originalPaddingBottom;
|
|
1264
1316
|
}
|
|
1317
|
+
document.documentElement.style.setProperty(
|
|
1318
|
+
"--sitepulse-top-banner-height",
|
|
1319
|
+
"0px"
|
|
1320
|
+
);
|
|
1321
|
+
document.documentElement.style.setProperty(
|
|
1322
|
+
"--sitepulse-bottom-banner-height",
|
|
1323
|
+
"0px"
|
|
1324
|
+
);
|
|
1325
|
+
document.documentElement.classList.remove("has-sitepulse-top-banner");
|
|
1326
|
+
for (const record of shiftedElements) {
|
|
1327
|
+
if (record.el && record.el.isConnected) {
|
|
1328
|
+
record.el.style.transform = record.originalTransform;
|
|
1329
|
+
record.el.style.transition = record.originalTransition;
|
|
1330
|
+
record.el.style.top = record.originalTop;
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1333
|
+
shiftedElements.length = 0;
|
|
1265
1334
|
} catch {
|
|
1266
1335
|
}
|
|
1267
1336
|
}
|
|
@@ -1417,9 +1486,18 @@ var SitePulseClient = class {
|
|
|
1417
1486
|
registeredCampaignTeardowns = [];
|
|
1418
1487
|
init(config) {
|
|
1419
1488
|
const isReinit = this.initialized;
|
|
1489
|
+
let inferredBase = "";
|
|
1490
|
+
if (typeof document !== "undefined" && document.currentScript?.src) {
|
|
1491
|
+
try {
|
|
1492
|
+
inferredBase = new URL(document.currentScript.src).origin;
|
|
1493
|
+
} catch {
|
|
1494
|
+
}
|
|
1495
|
+
}
|
|
1496
|
+
const defaultHost = config.apiHost || inferredBase || (typeof window !== "undefined" && window.location.hostname === "localhost" && window.location.port === "3000" ? "" : "https://sitepulse-app-ten.vercel.app");
|
|
1420
1497
|
this.config = {
|
|
1421
|
-
endpointUrl: "/api/collect",
|
|
1422
|
-
campaignsEndpointUrl: "/api/campaigns/active",
|
|
1498
|
+
endpointUrl: defaultHost ? `${defaultHost}/api/collect` : "/api/collect",
|
|
1499
|
+
campaignsEndpointUrl: defaultHost ? `${defaultHost}/api/campaigns/active` : "/api/campaigns/active",
|
|
1500
|
+
submissionsEndpointUrl: defaultHost ? `${defaultHost}/api/campaigns/submit` : "/api/campaigns/submit",
|
|
1423
1501
|
flushIntervalMs: 5e3,
|
|
1424
1502
|
autoTrack: true,
|
|
1425
1503
|
autoFetchCampaigns: true,
|
|
@@ -1578,6 +1656,7 @@ var SitePulseClient = class {
|
|
|
1578
1656
|
campaignName: campaign.name
|
|
1579
1657
|
});
|
|
1580
1658
|
const dom = renderCampaignDOM(campaign, {
|
|
1659
|
+
submissionsEndpointUrl: handlers.submissionsEndpointUrl || this.config?.submissionsEndpointUrl,
|
|
1581
1660
|
onLinkClick: (url, eventName) => {
|
|
1582
1661
|
this.track("campaign_click", {
|
|
1583
1662
|
campaignId: campaign.id,
|
package/dist/renderer.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ export interface CampaignActionHandlers {
|
|
|
14
14
|
onEventClick?: (eventName: string) => void;
|
|
15
15
|
onSubmit?: (formData: Record<string, string>) => void;
|
|
16
16
|
onClose?: () => void;
|
|
17
|
+
submissionsEndpointUrl?: string;
|
|
17
18
|
}
|
|
18
19
|
export declare function renderHeadingBlock(block: Extract<ContentBlock, {
|
|
19
20
|
type: "heading";
|
|
@@ -4,8 +4,10 @@ export * from "./renderer";
|
|
|
4
4
|
export * from "./evaluator";
|
|
5
5
|
export interface SitePulseConfig {
|
|
6
6
|
siteId: string;
|
|
7
|
+
apiHost?: string;
|
|
7
8
|
endpointUrl?: string;
|
|
8
9
|
campaignsEndpointUrl?: string;
|
|
10
|
+
submissionsEndpointUrl?: string;
|
|
9
11
|
flushIntervalMs?: number;
|
|
10
12
|
autoTrack?: boolean;
|
|
11
13
|
autoFetchCampaigns?: boolean;
|
|
@@ -14,6 +14,7 @@ export interface CampaignActionHandlers {
|
|
|
14
14
|
onEventClick?: (eventName: string) => void;
|
|
15
15
|
onSubmit?: (formData: Record<string, string>) => void;
|
|
16
16
|
onClose?: () => void;
|
|
17
|
+
submissionsEndpointUrl?: string;
|
|
17
18
|
}
|
|
18
19
|
export declare function renderHeadingBlock(block: Extract<ContentBlock, {
|
|
19
20
|
type: "heading";
|