@saasquatch/squatch-js 2.8.2-2 → 2.8.2-21

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.
@@ -1106,393 +1106,32 @@ function delay(duration) {
1106
1106
  setTimeout(resolve, duration);
1107
1107
  });
1108
1108
  }
1109
- const getSkeleton = ({
1110
- height = "500px",
1111
- skeletonBackgroundColor = "#e0e0e0",
1112
- skeletonShimmerColor = "#f5f5f5",
1113
- borderColor = "#ccc"
1114
- }) => {
1115
- return `
1116
- <style>
1117
- * {
1118
- box-sizing: border-box;
1119
- padding: 0;
1120
- margin: 0;
1121
- }
1122
-
1123
- .widget-container {
1124
- background: white;
1125
- width: 100%;
1126
- max-width: 900px;
1127
- padding: 40px;
1128
- border-radius: 12px;
1129
- box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
1130
- box-sizing: border-box;
1131
- }
1132
-
1133
- @keyframes shimmer {
1134
- 0% {
1135
- background-position: -100% 0;
1136
- }
1137
- 100% {
1138
- background-position: 100% 0;
1139
- }
1140
- }
1141
-
1142
- .skeleton {
1143
- background: ${skeletonBackgroundColor};
1144
- background: linear-gradient(
1145
- 90deg,
1146
- ${skeletonBackgroundColor} 25%,
1147
- ${skeletonShimmerColor} 50%,
1148
- ${skeletonBackgroundColor} 75%
1149
- );
1150
- background-size: 200% 100%;
1151
- animation: shimmer 1.5s infinite linear;
1152
- border-radius: 6px;
1153
- margin-bottom: 12px;
1154
- }
1155
-
1156
- .sk-title-lg {
1157
- height: 36px;
1158
- width: 50%;
1159
- margin-bottom: 16px;
1160
- }
1161
- .sk-title-md {
1162
- height: 28px;
1163
- width: 30%;
1164
- margin-bottom: 20px;
1165
- margin-top: 40px;
1166
- }
1167
- .sk-text {
1168
- height: 16px;
1169
- width: 80%;
1170
- margin-bottom: 8px;
1171
- }
1172
- .sk-text-short {
1173
- width: 40%;
1174
- }
1175
- .sk-label {
1176
- height: 14px;
1177
- width: 25%;
1178
- margin-bottom: 10px;
1179
- }
1180
-
1181
- .hero-section {
1182
- display: flex;
1183
- gap: 40px;
1184
- margin-bottom: 40px;
1185
- border-bottom: 1px solid ${borderColor};
1186
- padding-bottom: 40px;
1187
- flex-direction: row;
1188
- }
1189
- .hero-content {
1190
- flex: 1;
1191
- display: flex;
1192
- flex-direction: column;
1193
- justify-content: center;
1194
- }
1195
- .hero-image {
1196
- flex: 1;
1197
- height: 300px;
1198
- border-radius: 12px;
1199
- }
1200
-
1201
- .share-section {
1202
- margin-bottom: 40px;
1203
- }
1204
- .sk-input {
1205
- height: 50px;
1206
- width: 100%;
1207
- border-radius: 8px;
1208
- margin-bottom: 16px;
1209
- }
1210
- .social-buttons {
1211
- display: flex;
1212
- gap: 12px;
1213
- }
1214
- .sk-btn-social {
1215
- flex: 1;
1216
- height: 50px;
1217
- border-radius: 8px;
1218
- }
1219
-
1220
- .stats-section {
1221
- display: flex;
1222
- gap: 24px;
1223
- margin-bottom: 40px;
1224
- padding: 30px 0;
1225
- border-top: 1px solid ${borderColor};
1226
- border-bottom: 1px solid ${borderColor};
1227
- }
1228
- .stat-card {
1229
- flex: 1;
1230
- display: flex;
1231
- flex-direction: column;
1232
- align-items: center;
1233
- }
1234
- .stat-divider {
1235
- padding-left: 24px;
1236
- }
1237
-
1238
- .sk-stat-num {
1239
- height: 48px;
1240
- width: 120px;
1241
- margin-bottom: 8px;
1242
- }
1243
- .sk-stat-label {
1244
- height: 18px;
1245
- width: 80px;
1246
- }
1247
-
1248
- .table-header {
1249
- display: flex;
1250
- gap: 16px;
1251
- margin-bottom: 16px;
1252
- }
1253
- .sk-th {
1254
- height: 16px;
1255
- }
1256
- .table-row {
1257
- display: flex;
1258
- align-items: center;
1259
- gap: 16px;
1260
- padding: 16px 0;
1261
- border-bottom: 1px solid ${borderColor};
1262
- }
1263
-
1264
- .col-user {
1265
- flex: 2;
1266
- }
1267
- .col-status {
1268
- flex: 1;
1269
- }
1270
- .col-reward {
1271
- flex: 2;
1272
- }
1273
- .col-date {
1274
- flex: 1;
1275
- }
1276
-
1277
- .sk-badge {
1278
- height: 28px;
1279
- width: 90px;
1280
- border-radius: 14px;
1281
- }
1282
- .sk-reward-block {
1283
- height: 36px;
1284
- width: 100%;
1285
- border-radius: 6px;
1286
- }
1287
-
1288
- .pagination {
1289
- display: flex;
1290
- justify-content: flex-end;
1291
- gap: 8px;
1292
- margin-top: 24px;
1293
- }
1294
- .sk-btn-page {
1295
- height: 36px;
1296
- width: 64px;
1297
- border-radius: 6px;
1298
- margin-bottom: 0;
1299
- }
1300
-
1301
- @media (max-width: 768px) {
1302
- body {
1303
- padding: 20px;
1304
- }
1305
- .widget-container {
1306
- padding: 24px;
1307
- }
1308
-
1309
- .hero-section {
1310
- flex-direction: column-reverse;
1311
- gap: 24px;
1312
- }
1313
- .hero-image {
1314
- height: 220px;
1315
- width: 100%;
1316
- }
1317
- .sk-title-lg {
1318
- width: 80%;
1319
- }
1320
-
1321
- .col-date {
1322
- display: none;
1323
- }
1324
- }
1325
-
1326
- @media (max-width: 480px) {
1327
- body {
1328
- padding: 10px;
1329
- }
1330
- .widget-container {
1331
- padding: 16px;
1332
- }
1333
-
1334
- .sk-stat-num {
1335
- width: 80px;
1336
- height: 40px;
1337
- }
1338
-
1339
- .col-reward {
1340
- display: none;
1341
- }
1342
-
1343
- .col-user {
1344
- flex: 3;
1345
- }
1346
- .col-status {
1347
- flex: 2;
1348
- display: flex;
1349
- justify-content: flex-end;
1350
- }
1351
- }
1352
- </style>
1353
-
1354
- <div class="widget-container">
1355
- <div class="hero-section">
1356
- <div class="hero-content">
1357
- <div class="skeleton sk-title-lg"></div>
1358
- <div class="skeleton sk-text"></div>
1359
- <div class="skeleton sk-text sk-text-short"></div>
1360
- </div>
1361
- <div class="skeleton hero-image"></div>
1362
- </div>
1363
-
1364
- <div class="share-section">
1365
- <div class="skeleton sk-label"></div>
1366
- <div class="skeleton sk-input"></div>
1367
- <div class="social-buttons">
1368
- <div class="skeleton sk-btn-social"></div>
1369
- <div class="skeleton sk-btn-social"></div>
1370
- <div class="skeleton sk-btn-social"></div>
1371
- <div class="skeleton sk-btn-social"></div>
1372
- </div>
1373
- </div>
1374
-
1375
- <div
1376
- class="skeleton sk-title-md"
1377
- style="margin-top: 0; width: 30%; margin-left: auto; margin-right: auto"
1378
- ></div>
1379
- <div
1380
- class="skeleton sk-text"
1381
- style="width: 60%; margin-left: auto; margin-right: auto"
1382
- ></div>
1383
-
1384
- <div class="stats-section">
1385
- <div class="stat-card">
1386
- <div class="skeleton sk-stat-num"></div>
1387
- <div class="skeleton sk-stat-label"></div>
1388
- </div>
1389
- <div class="stat-card stat-divider">
1390
- <div class="skeleton sk-stat-num"></div>
1391
- <div class="skeleton sk-stat-label"></div>
1392
- </div>
1393
- </div>
1394
-
1395
- <div class="skeleton sk-title-md"></div>
1396
-
1397
- <div class="table-header">
1398
- <div class="skeleton sk-th col-user"></div>
1399
- <div class="skeleton sk-th col-status"></div>
1400
- <div class="skeleton sk-th col-reward"></div>
1401
- <div class="skeleton sk-th col-date"></div>
1402
- </div>
1403
-
1404
- <div class="table-row">
1405
- <div class="col-user">
1406
- <div class="skeleton sk-text" style="width: 70%; margin: 0"></div>
1407
- </div>
1408
- <div class="col-status">
1409
- <div class="skeleton sk-badge" style="margin: 0"></div>
1410
- </div>
1411
- <div class="col-reward">
1412
- <div class="skeleton sk-reward-block" style="margin: 0"></div>
1413
- </div>
1414
- <div class="col-date">
1415
- <div class="skeleton sk-text" style="width: 80%; margin: 0"></div>
1416
- </div>
1417
- </div>
1418
- <div class="table-row">
1419
- <div class="col-user">
1420
- <div class="skeleton sk-text" style="width: 60%; margin: 0"></div>
1421
- </div>
1422
- <div class="col-status">
1423
- <div class="skeleton sk-badge" style="margin: 0"></div>
1424
- </div>
1425
- <div class="col-reward">
1426
- <div class="skeleton sk-reward-block" style="margin: 0"></div>
1427
- </div>
1428
- <div class="col-date">
1429
- <div class="skeleton sk-text" style="width: 80%; margin: 0"></div>
1430
- </div>
1431
- </div>
1432
- <div class="table-row">
1433
- <div class="col-user">
1434
- <div class="skeleton sk-text" style="width: 75%; margin: 0"></div>
1435
- </div>
1436
- <div class="col-status">
1437
- <div class="skeleton sk-badge" style="margin: 0"></div>
1438
- </div>
1439
- <div class="col-reward">
1440
- <div class="skeleton sk-reward-block" style="margin: 0"></div>
1441
- </div>
1442
- <div class="col-date">
1443
- <div class="skeleton sk-text" style="width: 80%; margin: 0"></div>
1444
- </div>
1445
- </div>
1446
-
1447
- <div class="pagination">
1448
- <div class="skeleton sk-btn-page"></div>
1449
- <div class="skeleton sk-btn-page"></div>
1450
- </div>
1451
- </div>
1452
- `;
1453
- };
1454
1109
  const _log$7 = browserExports.debug("squatch-js:EMBEDwidget");
1455
1110
  class EmbedWidget extends Widget {
1456
1111
  constructor(params, container) {
1457
1112
  super(params);
1458
1113
  __publicField(this, "show", this.open);
1459
1114
  __publicField(this, "hide", this.close);
1460
- if (container) this.container = container;
1115
+ if (container) {
1116
+ this.container = container;
1117
+ }
1461
1118
  }
1462
1119
  async load() {
1463
1120
  var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
1464
- const brandingConfig = (_b = (_a2 = this.context.widgetConfig) == null ? void 0 : _a2.values) == null ? void 0 : _b.brandingConfig;
1465
- const initialHeight = brandingConfig == null ? void 0 : brandingConfig.loadingHeight;
1466
- const skeletonBackgroundColor = (_d = (_c = brandingConfig == null ? void 0 : brandingConfig.color) == null ? void 0 : _c.loadingSkeleton) == null ? void 0 : _d.background;
1467
- const skeletonShimmerColor = (_f = (_e = brandingConfig == null ? void 0 : brandingConfig.color) == null ? void 0 : _e.loadingSkeleton) == null ? void 0 : _f.animationBackground;
1468
- const borderColor = (_g = brandingConfig == null ? void 0 : brandingConfig.border) == null ? void 0 : _g.borderColor;
1469
- const sizes = (_h = brandingConfig == null ? void 0 : brandingConfig.widgetSize) == null ? void 0 : _h.embeddedWidgets;
1121
+ const brandingConfig2 = (_b = (_a2 = this.context.widgetConfig) == null ? void 0 : _a2.values) == null ? void 0 : _b.brandingConfig;
1122
+ const initialHeight = brandingConfig2 == null ? void 0 : brandingConfig2.loadingHeight;
1123
+ (_d = (_c = brandingConfig2 == null ? void 0 : brandingConfig2.color) == null ? void 0 : _c.loadingSkeleton) == null ? void 0 : _d.background;
1124
+ (_f = (_e = brandingConfig2 == null ? void 0 : brandingConfig2.color) == null ? void 0 : _e.loadingSkeleton) == null ? void 0 : _f.animationBackground;
1125
+ (_g = brandingConfig2 == null ? void 0 : brandingConfig2.border) == null ? void 0 : _g.borderColor;
1126
+ const sizes = (_h = brandingConfig2 == null ? void 0 : brandingConfig2.widgetSize) == null ? void 0 : _h.embeddedWidgets;
1470
1127
  const maxWidth = (sizes == null ? void 0 : sizes.maxWidth) ? formatWidth(sizes.maxWidth) : "";
1471
1128
  const minWidth = (sizes == null ? void 0 : sizes.minWidth) ? formatWidth(sizes.minWidth) : "";
1472
- console.log({
1473
- brandingConfig,
1474
- initialHeight,
1475
- widgetConfig: this.context.widgetConfig
1476
- });
1477
- const skeletonHTML = getSkeleton({
1478
- height: initialHeight,
1479
- skeletonBackgroundColor,
1480
- skeletonShimmerColor,
1481
- borderColor
1482
- });
1483
- const skeletonContainer = document.createElement("div");
1484
- skeletonContainer.innerHTML = skeletonHTML;
1485
1129
  const frame = this._createFrame({
1486
1130
  minWidth,
1487
1131
  maxWidth,
1488
1132
  initialHeight
1489
1133
  });
1490
1134
  const element = this._findElement();
1491
- frame.style.display = "none";
1492
- const injectContents = (target) => {
1493
- target.appendChild(skeletonContainer);
1494
- target.appendChild(frame);
1495
- };
1496
1135
  if ((_i = this.context) == null ? void 0 : _i.container) {
1497
1136
  element.style.visibility = "hidden";
1498
1137
  element.style.height = "0";
@@ -1503,16 +1142,15 @@ class EmbedWidget extends Widget {
1503
1142
  if (((_j = element.shadowRoot.lastChild) == null ? void 0 : _j.nodeName) === "IFRAME") {
1504
1143
  element.shadowRoot.replaceChild(frame, element.shadowRoot.lastChild);
1505
1144
  } else {
1506
- injectContents(element.shadowRoot);
1145
+ element.shadowRoot.appendChild(frame);
1507
1146
  }
1508
1147
  } else if (element.firstChild) {
1509
- element.innerHTML = "";
1510
- injectContents(element);
1148
+ element.replaceChild(frame, element.firstChild);
1511
1149
  } else {
1512
- injectContents(element);
1150
+ element.appendChild(frame);
1513
1151
  }
1514
1152
  } else if (!element.firstChild || element.firstChild.nodeName === "#text") {
1515
- injectContents(element);
1153
+ element.appendChild(frame);
1516
1154
  }
1517
1155
  const { contentWindow } = frame;
1518
1156
  if (!contentWindow) {
@@ -1520,16 +1158,15 @@ class EmbedWidget extends Widget {
1520
1158
  }
1521
1159
  const frameDoc = contentWindow.document;
1522
1160
  frameDoc.open();
1523
- console.log({ content: this.content, context: this.context, this: this });
1524
1161
  const domain = this.widgetApi.domain;
1525
1162
  frameDoc.write(`
1526
- ${((_k = brandingConfig == null ? void 0 : brandingConfig.main) == null ? void 0 : _k.brandFont) && `
1163
+ ${((_k = brandingConfig2 == null ? void 0 : brandingConfig2.main) == null ? void 0 : _k.brandFont) ? `
1527
1164
  <link rel="preconnect" href="https://fast${domain === "https://staging.referralsaasquatch.com" && "-staging"}.ssqt.io">
1528
1165
  <link rel="preconnect" href="https://fonts.gstatic.com">
1529
1166
  <link rel="preconnect" href="https://fonts.googleapis.com">
1530
1167
  <link rel="preload" href="https://fonts.googleapis.com/css2?family=${encodeURIComponent(
1531
- (_l = brandingConfig == null ? void 0 : brandingConfig.main) == null ? void 0 : _l.brandFont
1532
- )}">`}
1168
+ (_l = brandingConfig2 == null ? void 0 : brandingConfig2.main) == null ? void 0 : _l.brandFont
1169
+ )}" as="style">` : ""}
1533
1170
  <script src="${this.npmCdn}/resize-observer-polyfill@1.5.x"><\/script>
1534
1171
  <style data-styles>
1535
1172
  html { visibility:hidden;}
@@ -1539,10 +1176,6 @@ class EmbedWidget extends Widget {
1539
1176
  `);
1540
1177
  frameDoc.close();
1541
1178
  domready(frameDoc, async () => {
1542
- if (skeletonContainer && skeletonContainer.parentNode) {
1543
- skeletonContainer.parentNode.removeChild(skeletonContainer);
1544
- }
1545
- frame.style.display = "block";
1546
1179
  const _sqh = contentWindow.squatch || contentWindow.widgetIdent;
1547
1180
  frame.height = initialHeight || frameDoc.body.scrollHeight;
1548
1181
  console.log({ height: frameDoc.body.scrollHeight });
@@ -1644,8 +1277,8 @@ class PopupWidget extends Widget {
1644
1277
  _createPopupDialog() {
1645
1278
  var _a2, _b, _c;
1646
1279
  const dialog = document.createElement("dialog");
1647
- const brandingConfig = (_b = (_a2 = this.context.widgetConfig) == null ? void 0 : _a2.values) == null ? void 0 : _b.brandingConfig;
1648
- const sizes = (_c = brandingConfig == null ? void 0 : brandingConfig.widgetSize) == null ? void 0 : _c.popupWidgets;
1280
+ const brandingConfig2 = (_b = (_a2 = this.context.widgetConfig) == null ? void 0 : _a2.values) == null ? void 0 : _b.brandingConfig;
1281
+ const sizes = (_c = brandingConfig2 == null ? void 0 : brandingConfig2.widgetSize) == null ? void 0 : _c.popupWidgets;
1649
1282
  const minWidth = (sizes == null ? void 0 : sizes.minWidth) ? formatWidth(sizes.minWidth) : "auto";
1650
1283
  const maxWidth = (sizes == null ? void 0 : sizes.maxWidth) ? formatWidth(sizes.maxWidth) : "500px";
1651
1284
  dialog.id = this.id;
@@ -2108,125 +1741,470 @@ const deepMerge = (target, source) => {
2108
1741
  [prop]: isDeep(prop) ? deepMerge(target[prop], source[prop]) : source[prop]
2109
1742
  })).reduce((a, b) => ({ ...a, ...b }), {});
2110
1743
  return {
2111
- ...target,
2112
- ...replaced
1744
+ ...target,
1745
+ ...replaced
1746
+ };
1747
+ };
1748
+ function b64decode(input) {
1749
+ const binary = atob(input.replace(/_/g, "/").replace(/-/g, "+"));
1750
+ const bytes = new Uint8Array(binary.length);
1751
+ for (let i = 0; i < binary.length; i++) {
1752
+ bytes[i] = binary.charCodeAt(i);
1753
+ }
1754
+ return new TextDecoder("utf8").decode(bytes);
1755
+ }
1756
+ function b64encode(input) {
1757
+ const encodedInput = new TextEncoder().encode(input);
1758
+ const binary = Array.from(
1759
+ encodedInput,
1760
+ (byte) => String.fromCodePoint(byte)
1761
+ ).join("");
1762
+ return btoa(binary).replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
1763
+ }
1764
+ function getTopDomain() {
1765
+ var i, h, weird_cookie = "weird_get_top_level_domain=cookie", hostname = document.location.hostname.split(".");
1766
+ for (i = hostname.length - 1; i >= 0; i--) {
1767
+ h = hostname.slice(i).join(".");
1768
+ document.cookie = weird_cookie + ";domain=." + h + ";";
1769
+ if (document.cookie.indexOf(weird_cookie) > -1) {
1770
+ document.cookie = weird_cookie.split("=")[0] + "=;domain=." + h + ";expires=Thu, 01 Jan 1970 00:00:01 GMT;";
1771
+ return h;
1772
+ }
1773
+ }
1774
+ }
1775
+ function _pushCookie() {
1776
+ const queryString = window.location.search;
1777
+ const urlParams = new URLSearchParams(queryString);
1778
+ const refParam = urlParams.get("_saasquatch") || "";
1779
+ if (refParam) {
1780
+ let paramsJSON = "", existingCookie = "", reEncodedCookie = "";
1781
+ try {
1782
+ paramsJSON = JSON.parse(b64decode(refParam));
1783
+ } catch (error) {
1784
+ _log$4("Unable to decode params", error);
1785
+ return;
1786
+ }
1787
+ try {
1788
+ existingCookie = JSON.parse(b64decode(api$1.get("_saasquatch")));
1789
+ _log$4("existing cookie", existingCookie);
1790
+ } catch (error) {
1791
+ _log$4("Unable to retrieve cookie", error);
1792
+ }
1793
+ try {
1794
+ const domain = getTopDomain();
1795
+ _log$4("domain retrieved:", domain);
1796
+ if (existingCookie) {
1797
+ const newCookie = deepMerge(existingCookie, paramsJSON);
1798
+ reEncodedCookie = b64encode(JSON.stringify(newCookie));
1799
+ _log$4("cookie to store:", newCookie);
1800
+ } else {
1801
+ reEncodedCookie = b64encode(JSON.stringify(paramsJSON));
1802
+ _log$4("cookie to store:", paramsJSON);
1803
+ }
1804
+ api$1.set("_saasquatch", reEncodedCookie, {
1805
+ expires: 365,
1806
+ secure: false,
1807
+ sameSite: "Lax",
1808
+ domain,
1809
+ path: "/"
1810
+ });
1811
+ } catch (error) {
1812
+ _log$4("Unable to set cookie", error);
1813
+ }
1814
+ }
1815
+ }
1816
+ const _log$3 = browserExports.debug("squatch-js");
1817
+ function _getAutoConfig() {
1818
+ var _a2;
1819
+ const queryString = window.location.search;
1820
+ const urlParams = new URLSearchParams(queryString);
1821
+ const refParam = urlParams.get("_saasquatchExtra") || "";
1822
+ if (!refParam) {
1823
+ _log$3("No _saasquatchExtra param");
1824
+ return;
1825
+ }
1826
+ const config = validateConfig({
1827
+ tenantAlias: "UNKNOWN"
1828
+ });
1829
+ if (!config.domain) {
1830
+ _log$3("domain must be provided in config to use _saasquatchExtra");
1831
+ return;
1832
+ }
1833
+ let raw;
1834
+ try {
1835
+ raw = JSON.parse(b64decode(refParam));
1836
+ } catch (e) {
1837
+ _log$3("Unable to decode _saasquatchExtra config");
1838
+ return;
1839
+ }
1840
+ function normalizeDomain(domain) {
1841
+ return domain.replace(/^https?:\/\//, "");
1842
+ }
1843
+ const normalizedDomain = normalizeDomain(config.domain);
1844
+ const tenantAlias = Object.keys((raw == null ? void 0 : raw[normalizedDomain]) || {})[0];
1845
+ const widgetConfig = (_a2 = raw == null ? void 0 : raw[normalizedDomain]) == null ? void 0 : _a2[tenantAlias];
1846
+ if (!widgetConfig) {
1847
+ _log$3("_saasquatchExtra did not have an expected structure");
1848
+ return void 0;
1849
+ }
1850
+ const { autoPopupWidgetType, ...rest } = widgetConfig;
1851
+ return {
1852
+ widgetConfig: {
1853
+ widgetType: autoPopupWidgetType,
1854
+ displayOnLoad: true,
1855
+ ...rest
1856
+ },
1857
+ squatchConfig: {
1858
+ ...config,
1859
+ tenantAlias
1860
+ }
2113
1861
  };
1862
+ }
1863
+ const getSkeleton = ({
1864
+ height = "500px",
1865
+ skeletonBackgroundColor = "#e0e0e0",
1866
+ skeletonShimmerColor = "#f5f5f5",
1867
+ borderColor = "#ccc"
1868
+ }) => {
1869
+ return `
1870
+ <style>
1871
+ * {
1872
+ box-sizing: border-box;
1873
+ padding: 0;
1874
+ margin: 0;
1875
+ }
1876
+
1877
+ .widget-container {
1878
+ background: white;
1879
+ width: 100%;
1880
+ max-width: 900px;
1881
+ padding: 40px;
1882
+ border-radius: 12px;
1883
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
1884
+ box-sizing: border-box;
1885
+ }
1886
+
1887
+ @keyframes shimmer {
1888
+ 0% {
1889
+ background-position: -100% 0;
1890
+ }
1891
+ 100% {
1892
+ background-position: 100% 0;
1893
+ }
1894
+ }
1895
+
1896
+ .skeleton {
1897
+ background: ${skeletonBackgroundColor};
1898
+ background: linear-gradient(
1899
+ 90deg,
1900
+ ${skeletonBackgroundColor} 25%,
1901
+ ${skeletonShimmerColor} 50%,
1902
+ ${skeletonBackgroundColor} 75%
1903
+ );
1904
+ background-size: 200% 100%;
1905
+ animation: shimmer 1.5s infinite linear;
1906
+ border-radius: 6px;
1907
+ margin-bottom: 12px;
1908
+ }
1909
+
1910
+ .sk-title-lg {
1911
+ height: 36px;
1912
+ width: 50%;
1913
+ margin-bottom: 16px;
1914
+ }
1915
+ .sk-title-md {
1916
+ height: 28px;
1917
+ width: 30%;
1918
+ margin-bottom: 20px;
1919
+ margin-top: 40px;
1920
+ }
1921
+ .sk-text {
1922
+ height: 16px;
1923
+ width: 80%;
1924
+ margin-bottom: 8px;
1925
+ }
1926
+ .sk-text-short {
1927
+ width: 40%;
1928
+ }
1929
+ .sk-label {
1930
+ height: 14px;
1931
+ width: 25%;
1932
+ margin-bottom: 10px;
1933
+ }
1934
+
1935
+ .hero-section {
1936
+ display: flex;
1937
+ gap: 40px;
1938
+ margin-bottom: 40px;
1939
+ border-bottom: 1px solid ${borderColor};
1940
+ padding-bottom: 40px;
1941
+ flex-direction: row;
1942
+ }
1943
+ .hero-content {
1944
+ flex: 1;
1945
+ display: flex;
1946
+ flex-direction: column;
1947
+ justify-content: center;
1948
+ }
1949
+ .hero-image {
1950
+ flex: 1;
1951
+ height: 300px;
1952
+ border-radius: 12px;
1953
+ }
1954
+
1955
+ .share-section {
1956
+ margin-bottom: 40px;
1957
+ }
1958
+ .sk-input {
1959
+ height: 50px;
1960
+ width: 100%;
1961
+ border-radius: 8px;
1962
+ margin-bottom: 16px;
1963
+ }
1964
+ .social-buttons {
1965
+ display: flex;
1966
+ gap: 12px;
1967
+ }
1968
+ .sk-btn-social {
1969
+ flex: 1;
1970
+ height: 50px;
1971
+ border-radius: 8px;
1972
+ }
1973
+
1974
+ .stats-section {
1975
+ display: flex;
1976
+ gap: 24px;
1977
+ margin-bottom: 40px;
1978
+ padding: 30px 0;
1979
+ border-top: 1px solid ${borderColor};
1980
+ border-bottom: 1px solid ${borderColor};
1981
+ }
1982
+ .stat-card {
1983
+ flex: 1;
1984
+ display: flex;
1985
+ flex-direction: column;
1986
+ align-items: center;
1987
+ }
1988
+ .stat-divider {
1989
+ padding-left: 24px;
1990
+ }
1991
+
1992
+ .sk-stat-num {
1993
+ height: 48px;
1994
+ width: 120px;
1995
+ margin-bottom: 8px;
1996
+ }
1997
+ .sk-stat-label {
1998
+ height: 18px;
1999
+ width: 80px;
2000
+ }
2001
+
2002
+ .table-header {
2003
+ display: flex;
2004
+ gap: 16px;
2005
+ margin-bottom: 16px;
2006
+ }
2007
+ .sk-th {
2008
+ height: 16px;
2009
+ }
2010
+ .table-row {
2011
+ display: flex;
2012
+ align-items: center;
2013
+ gap: 16px;
2014
+ padding: 16px 0;
2015
+ border-bottom: 1px solid ${borderColor};
2016
+ }
2017
+
2018
+ .col-user {
2019
+ flex: 2;
2020
+ }
2021
+ .col-status {
2022
+ flex: 1;
2023
+ }
2024
+ .col-reward {
2025
+ flex: 2;
2026
+ }
2027
+ .col-date {
2028
+ flex: 1;
2029
+ }
2030
+
2031
+ .sk-badge {
2032
+ height: 28px;
2033
+ width: 90px;
2034
+ border-radius: 14px;
2035
+ }
2036
+ .sk-reward-block {
2037
+ height: 36px;
2038
+ width: 100%;
2039
+ border-radius: 6px;
2040
+ }
2041
+
2042
+ .pagination {
2043
+ display: flex;
2044
+ justify-content: flex-end;
2045
+ gap: 8px;
2046
+ margin-top: 24px;
2047
+ }
2048
+ .sk-btn-page {
2049
+ height: 36px;
2050
+ width: 64px;
2051
+ border-radius: 6px;
2052
+ margin-bottom: 0;
2053
+ }
2054
+
2055
+ @media (max-width: 768px) {
2056
+ body {
2057
+ padding: 20px;
2058
+ }
2059
+ .widget-container {
2060
+ padding: 24px;
2061
+ }
2062
+
2063
+ .hero-section {
2064
+ flex-direction: column-reverse;
2065
+ gap: 24px;
2066
+ }
2067
+ .hero-image {
2068
+ height: 220px;
2069
+ width: 100%;
2070
+ }
2071
+ .sk-title-lg {
2072
+ width: 80%;
2073
+ }
2074
+
2075
+ .col-date {
2076
+ display: none;
2077
+ }
2078
+ }
2079
+
2080
+ @media (max-width: 480px) {
2081
+ body {
2082
+ padding: 10px;
2083
+ }
2084
+ .widget-container {
2085
+ padding: 16px;
2086
+ }
2087
+
2088
+ .sk-stat-num {
2089
+ width: 80px;
2090
+ height: 40px;
2091
+ }
2092
+
2093
+ .col-reward {
2094
+ display: none;
2095
+ }
2096
+
2097
+ .col-user {
2098
+ flex: 3;
2099
+ }
2100
+ .col-status {
2101
+ flex: 2;
2102
+ display: flex;
2103
+ justify-content: flex-end;
2104
+ }
2105
+ }
2106
+ </style>
2107
+
2108
+ <div class="widget-container">
2109
+ <div class="hero-section">
2110
+ <div class="hero-content">
2111
+ <div class="skeleton sk-title-lg"></div>
2112
+ <div class="skeleton sk-text"></div>
2113
+ <div class="skeleton sk-text sk-text-short"></div>
2114
+ </div>
2115
+ <div class="skeleton hero-image"></div>
2116
+ </div>
2117
+
2118
+ <div class="share-section">
2119
+ <div class="skeleton sk-label"></div>
2120
+ <div class="skeleton sk-input"></div>
2121
+ <div class="social-buttons">
2122
+ <div class="skeleton sk-btn-social"></div>
2123
+ <div class="skeleton sk-btn-social"></div>
2124
+ <div class="skeleton sk-btn-social"></div>
2125
+ <div class="skeleton sk-btn-social"></div>
2126
+ </div>
2127
+ </div>
2128
+
2129
+ <div
2130
+ class="skeleton sk-title-md"
2131
+ style="margin-top: 0; width: 30%; margin-left: auto; margin-right: auto"
2132
+ ></div>
2133
+ <div
2134
+ class="skeleton sk-text"
2135
+ style="width: 60%; margin-left: auto; margin-right: auto"
2136
+ ></div>
2137
+
2138
+ <div class="stats-section">
2139
+ <div class="stat-card">
2140
+ <div class="skeleton sk-stat-num"></div>
2141
+ <div class="skeleton sk-stat-label"></div>
2142
+ </div>
2143
+ <div class="stat-card stat-divider">
2144
+ <div class="skeleton sk-stat-num"></div>
2145
+ <div class="skeleton sk-stat-label"></div>
2146
+ </div>
2147
+ </div>
2148
+
2149
+ <div class="skeleton sk-title-md"></div>
2150
+
2151
+ <div class="table-header">
2152
+ <div class="skeleton sk-th col-user"></div>
2153
+ <div class="skeleton sk-th col-status"></div>
2154
+ <div class="skeleton sk-th col-reward"></div>
2155
+ <div class="skeleton sk-th col-date"></div>
2156
+ </div>
2157
+
2158
+ <div class="table-row">
2159
+ <div class="col-user">
2160
+ <div class="skeleton sk-text" style="width: 70%; margin: 0"></div>
2161
+ </div>
2162
+ <div class="col-status">
2163
+ <div class="skeleton sk-badge" style="margin: 0"></div>
2164
+ </div>
2165
+ <div class="col-reward">
2166
+ <div class="skeleton sk-reward-block" style="margin: 0"></div>
2167
+ </div>
2168
+ <div class="col-date">
2169
+ <div class="skeleton sk-text" style="width: 80%; margin: 0"></div>
2170
+ </div>
2171
+ </div>
2172
+ <div class="table-row">
2173
+ <div class="col-user">
2174
+ <div class="skeleton sk-text" style="width: 60%; margin: 0"></div>
2175
+ </div>
2176
+ <div class="col-status">
2177
+ <div class="skeleton sk-badge" style="margin: 0"></div>
2178
+ </div>
2179
+ <div class="col-reward">
2180
+ <div class="skeleton sk-reward-block" style="margin: 0"></div>
2181
+ </div>
2182
+ <div class="col-date">
2183
+ <div class="skeleton sk-text" style="width: 80%; margin: 0"></div>
2184
+ </div>
2185
+ </div>
2186
+ <div class="table-row">
2187
+ <div class="col-user">
2188
+ <div class="skeleton sk-text" style="width: 75%; margin: 0"></div>
2189
+ </div>
2190
+ <div class="col-status">
2191
+ <div class="skeleton sk-badge" style="margin: 0"></div>
2192
+ </div>
2193
+ <div class="col-reward">
2194
+ <div class="skeleton sk-reward-block" style="margin: 0"></div>
2195
+ </div>
2196
+ <div class="col-date">
2197
+ <div class="skeleton sk-text" style="width: 80%; margin: 0"></div>
2198
+ </div>
2199
+ </div>
2200
+
2201
+ <div class="pagination">
2202
+ <div class="skeleton sk-btn-page"></div>
2203
+ <div class="skeleton sk-btn-page"></div>
2204
+ </div>
2205
+ </div>
2206
+ `;
2114
2207
  };
2115
- function b64decode(input) {
2116
- const binary = atob(input.replace(/_/g, "/").replace(/-/g, "+"));
2117
- const bytes = new Uint8Array(binary.length);
2118
- for (let i = 0; i < binary.length; i++) {
2119
- bytes[i] = binary.charCodeAt(i);
2120
- }
2121
- return new TextDecoder("utf8").decode(bytes);
2122
- }
2123
- function b64encode(input) {
2124
- const encodedInput = new TextEncoder().encode(input);
2125
- const binary = Array.from(
2126
- encodedInput,
2127
- (byte) => String.fromCodePoint(byte)
2128
- ).join("");
2129
- return btoa(binary).replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
2130
- }
2131
- function getTopDomain() {
2132
- var i, h, weird_cookie = "weird_get_top_level_domain=cookie", hostname = document.location.hostname.split(".");
2133
- for (i = hostname.length - 1; i >= 0; i--) {
2134
- h = hostname.slice(i).join(".");
2135
- document.cookie = weird_cookie + ";domain=." + h + ";";
2136
- if (document.cookie.indexOf(weird_cookie) > -1) {
2137
- document.cookie = weird_cookie.split("=")[0] + "=;domain=." + h + ";expires=Thu, 01 Jan 1970 00:00:01 GMT;";
2138
- return h;
2139
- }
2140
- }
2141
- }
2142
- function _pushCookie() {
2143
- const queryString = window.location.search;
2144
- const urlParams = new URLSearchParams(queryString);
2145
- const refParam = urlParams.get("_saasquatch") || "";
2146
- if (refParam) {
2147
- let paramsJSON = "", existingCookie = "", reEncodedCookie = "";
2148
- try {
2149
- paramsJSON = JSON.parse(b64decode(refParam));
2150
- } catch (error) {
2151
- _log$4("Unable to decode params", error);
2152
- return;
2153
- }
2154
- try {
2155
- existingCookie = JSON.parse(b64decode(api$1.get("_saasquatch")));
2156
- _log$4("existing cookie", existingCookie);
2157
- } catch (error) {
2158
- _log$4("Unable to retrieve cookie", error);
2159
- }
2160
- try {
2161
- const domain = getTopDomain();
2162
- _log$4("domain retrieved:", domain);
2163
- if (existingCookie) {
2164
- const newCookie = deepMerge(existingCookie, paramsJSON);
2165
- reEncodedCookie = b64encode(JSON.stringify(newCookie));
2166
- _log$4("cookie to store:", newCookie);
2167
- } else {
2168
- reEncodedCookie = b64encode(JSON.stringify(paramsJSON));
2169
- _log$4("cookie to store:", paramsJSON);
2170
- }
2171
- api$1.set("_saasquatch", reEncodedCookie, {
2172
- expires: 365,
2173
- secure: false,
2174
- sameSite: "Lax",
2175
- domain,
2176
- path: "/"
2177
- });
2178
- } catch (error) {
2179
- _log$4("Unable to set cookie", error);
2180
- }
2181
- }
2182
- }
2183
- const _log$3 = browserExports.debug("squatch-js");
2184
- function _getAutoConfig() {
2185
- var _a2;
2186
- const queryString = window.location.search;
2187
- const urlParams = new URLSearchParams(queryString);
2188
- const refParam = urlParams.get("_saasquatchExtra") || "";
2189
- if (!refParam) {
2190
- _log$3("No _saasquatchExtra param");
2191
- return;
2192
- }
2193
- const config = validateConfig({
2194
- tenantAlias: "UNKNOWN"
2195
- });
2196
- if (!config.domain) {
2197
- _log$3("domain must be provided in config to use _saasquatchExtra");
2198
- return;
2199
- }
2200
- let raw;
2201
- try {
2202
- raw = JSON.parse(b64decode(refParam));
2203
- } catch (e) {
2204
- _log$3("Unable to decode _saasquatchExtra config");
2205
- return;
2206
- }
2207
- function normalizeDomain(domain) {
2208
- return domain.replace(/^https?:\/\//, "");
2209
- }
2210
- const normalizedDomain = normalizeDomain(config.domain);
2211
- const tenantAlias = Object.keys((raw == null ? void 0 : raw[normalizedDomain]) || {})[0];
2212
- const widgetConfig = (_a2 = raw == null ? void 0 : raw[normalizedDomain]) == null ? void 0 : _a2[tenantAlias];
2213
- if (!widgetConfig) {
2214
- _log$3("_saasquatchExtra did not have an expected structure");
2215
- return void 0;
2216
- }
2217
- const { autoPopupWidgetType, ...rest } = widgetConfig;
2218
- return {
2219
- widgetConfig: {
2220
- widgetType: autoPopupWidgetType,
2221
- displayOnLoad: true,
2222
- ...rest
2223
- },
2224
- squatchConfig: {
2225
- ...config,
2226
- tenantAlias
2227
- }
2228
- };
2229
- }
2230
2208
  const _log$2 = browserExports.debug("squatch-js:decodeUserJwt");
2231
2209
  function decodeUserJwt(tokenStr) {
2232
2210
  var _a2;
@@ -2460,12 +2438,21 @@ class DeclarativeEmbedWidget extends DeclarativeWidget {
2460
2438
  }
2461
2439
  }
2462
2440
  async connectedCallback() {
2463
- var _a2, _b;
2464
2441
  this.loaded = true;
2465
2442
  this.container = this.getAttribute("container");
2443
+ brandingConfig == null ? void 0 : brandingConfig.loadingHeight;
2444
+ const skeletonHTML = getSkeleton({});
2445
+ const skeletonContainer = document.createElement("div");
2446
+ skeletonContainer.id = "loading-skeleton";
2447
+ skeletonContainer.innerHTML = skeletonHTML;
2448
+ const root = this.shadowRoot || this.attachShadow({ mode: "open" });
2449
+ root.innerHTML = "";
2450
+ root.appendChild(skeletonContainer);
2466
2451
  await this.renderWidget();
2467
- const slot = (_a2 = this.shadowRoot && Array.from(this.shadowRoot.children)) == null ? void 0 : _a2.find((c) => c.tagName === "SLOT");
2468
- if (slot) (_b = this.shadowRoot) == null ? void 0 : _b.removeChild(slot);
2452
+ const loadingElement = root.getElementById("loading-skeleton");
2453
+ if (loadingElement) {
2454
+ loadingElement.remove();
2455
+ }
2469
2456
  if (this.getAttribute("open") !== null) this.open();
2470
2457
  }
2471
2458
  }
@@ -2492,9 +2479,29 @@ class DeclarativePopupWidget extends DeclarativeWidget {
2492
2479
  }
2493
2480
  }
2494
2481
  async connectedCallback() {
2482
+ var _a2;
2495
2483
  this.loaded = true;
2496
2484
  this.container = this.getAttribute("container");
2485
+ const skeletonHTML = `
2486
+ <div>
2487
+ <h1>Dynamic Content</h1>
2488
+ <p>This content was dynamically added to the widget before it loaded.</p>
2489
+ </div>
2490
+ `;
2491
+ const skeletonContainer = document.createElement("div");
2492
+ skeletonContainer.id = "loading-skeleton";
2493
+ skeletonContainer.innerHTML = skeletonHTML;
2494
+ if (!this.shadowRoot) {
2495
+ this.attachShadow({ mode: "open" });
2496
+ }
2497
+ if (this.shadowRoot) {
2498
+ this.shadowRoot.innerHTML = skeletonHTML;
2499
+ }
2497
2500
  await this.renderWidget();
2501
+ const loadingElement = (_a2 = this.shadowRoot) == null ? void 0 : _a2.getElementById("loading-skeleton");
2502
+ if (loadingElement) {
2503
+ loadingElement.remove();
2504
+ }
2498
2505
  if (this.getAttribute("open") !== null) this.open();
2499
2506
  }
2500
2507
  }