@saasquatch/squatch-js 2.7.0-3 → 2.7.0-4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/squatch.cjs.js +2119 -7
- package/dist/squatch.cjs.js.map +1 -1
- package/dist/squatch.esm.js +2161 -0
- package/dist/squatch.esm.js.map +1 -0
- package/dist/squatch.js +2125 -9
- package/dist/squatch.js.map +1 -1
- package/dist/squatch.min.js +6 -0
- package/package.json +8 -8
- package/vite.config.ts +10 -3
- package/coverage/clover.xml +0 -917
- package/coverage/coverage-final.json +0 -21
- package/coverage/lcov-report/base.css +0 -224
- package/coverage/lcov-report/block-navigation.js +0 -87
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/prettify.css +0 -1
- package/coverage/lcov-report/prettify.js +0 -2
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +0 -196
- package/coverage/lcov.info +0 -1669
- package/dist/squatch.es.js +0 -1623
- package/dist/squatch.es.js.map +0 -1
- package/dist copy/api/AnalyticsApi.d.ts +0 -32
- package/dist copy/api/EventsApi.d.ts +0 -52
- package/dist copy/api/WidgetApi.d.ts +0 -64
- package/dist copy/api/graphql.d.ts +0 -1
- package/dist copy/async.d.ts +0 -20
- package/dist copy/docs.d.ts +0 -1
- package/dist copy/globals.d.ts +0 -4
- package/dist copy/squatch.cjs.js +0 -48
- package/dist copy/squatch.d.ts +0 -122
- package/dist copy/squatch.es.js +0 -1622
- package/dist copy/squatch.esm.js +0 -2317
- package/dist copy/squatch.esm.js.map +0 -1
- package/dist copy/squatch.js +0 -2337
- package/dist copy/squatch.js.map +0 -1
- package/dist copy/types.d.ts +0 -109
- package/dist copy/utils/cookieUtils.d.ts +0 -3
- package/dist copy/utils/decodeUserJwt.d.ts +0 -2
- package/dist copy/utils/domready.d.ts +0 -6
- package/dist copy/utils/io.d.ts +0 -5
- package/dist copy/utils/utmUtils.d.ts +0 -14
- package/dist copy/utils/validate.d.ts +0 -12
- package/dist copy/widgets/EmbedWidget.d.ts +0 -25
- package/dist copy/widgets/PopupWidget.d.ts +0 -30
- package/dist copy/widgets/Widget.d.ts +0 -57
- package/dist copy/widgets/Widgets.d.ts +0 -112
- package/dist copy/widgets/declarative/DeclarativeWidget.d.ts +0 -100
- package/dist copy/widgets/declarative/DeclarativeWidgets.d.ts +0 -35
package/dist copy/squatch.esm.js
DELETED
|
@@ -1,2317 +0,0 @@
|
|
|
1
|
-
import debug$1, { debug } from 'debug';
|
|
2
|
-
import Cookies from 'js-cookie';
|
|
3
|
-
|
|
4
|
-
function _extends() {
|
|
5
|
-
_extends = Object.assign || function (target) {
|
|
6
|
-
for (var i = 1; i < arguments.length; i++) {
|
|
7
|
-
var source = arguments[i];
|
|
8
|
-
|
|
9
|
-
for (var key in source) {
|
|
10
|
-
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
11
|
-
target[key] = source[key];
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
return target;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
return _extends.apply(this, arguments);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function _objectWithoutPropertiesLoose(source, excluded) {
|
|
23
|
-
if (source == null) return {};
|
|
24
|
-
var target = {};
|
|
25
|
-
var sourceKeys = Object.keys(source);
|
|
26
|
-
var key, i;
|
|
27
|
-
|
|
28
|
-
for (i = 0; i < sourceKeys.length; i++) {
|
|
29
|
-
key = sourceKeys[i];
|
|
30
|
-
if (excluded.indexOf(key) >= 0) continue;
|
|
31
|
-
target[key] = source[key];
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
return target;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
var DEFAULT_DOMAIN = "https://app.referralsaasquatch.com";
|
|
38
|
-
var DEFAULT_NPM_CDN = "https://fast.ssqt.io/npm";
|
|
39
|
-
var DEFAULT_NAMESPACE = "squatch";
|
|
40
|
-
var IMPACT_NAMESPACE = "impact";
|
|
41
|
-
|
|
42
|
-
function validateConfig(_raw) {
|
|
43
|
-
if (typeof _raw !== "object") throw new Error("config must be an object");
|
|
44
|
-
var tenant = window.squatchTenant;
|
|
45
|
-
var config = getConfig();
|
|
46
|
-
var raw = {
|
|
47
|
-
tenantAlias: (_raw == null ? void 0 : _raw["tenantAlias"]) || tenant,
|
|
48
|
-
domain: (_raw == null ? void 0 : _raw["domain"]) || (config == null ? void 0 : config.domain),
|
|
49
|
-
npmCdn: (_raw == null ? void 0 : _raw["npmCdn"]) || (config == null ? void 0 : config.npmCdn),
|
|
50
|
-
debug: (_raw == null ? void 0 : _raw["debug"]) || (config == null ? void 0 : config.debug)
|
|
51
|
-
};
|
|
52
|
-
if (typeof raw.tenantAlias !== "string") throw new Error("tenantAlias not provided");
|
|
53
|
-
var tenantAlias = raw.tenantAlias;
|
|
54
|
-
var domain = typeof raw.domain === "string" && raw.domain || DEFAULT_DOMAIN;
|
|
55
|
-
var debug = typeof raw.debug === "boolean" && raw.debug || false;
|
|
56
|
-
var npmCdn = typeof raw.npmCdn === "string" && raw.npmCdn || DEFAULT_NPM_CDN;
|
|
57
|
-
return {
|
|
58
|
-
tenantAlias,
|
|
59
|
-
domain,
|
|
60
|
-
debug,
|
|
61
|
-
npmCdn
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
function isObject$1(obj) {
|
|
65
|
-
return typeof obj === "object" && !Array.isArray(obj) && obj !== null;
|
|
66
|
-
}
|
|
67
|
-
function validateLocale(locale) {
|
|
68
|
-
if (locale && /^[a-z]{2}_(?:[A-Z]{2}|[0-9]{3})$/.test(locale)) {
|
|
69
|
-
return locale;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
function validateWidgetConfig(raw) {
|
|
73
|
-
if (!isObject$1(raw)) throw new Error("Widget properties must be an object");
|
|
74
|
-
if (!(raw != null && raw["user"])) throw new Error("Required properties missing.");
|
|
75
|
-
return raw;
|
|
76
|
-
}
|
|
77
|
-
function validatePasswordlessConfig(raw) {
|
|
78
|
-
if (!isObject$1(raw)) throw new Error("Widget properties must be an object");
|
|
79
|
-
return raw;
|
|
80
|
-
}
|
|
81
|
-
function getToken() {
|
|
82
|
-
return window.impactToken || window.squatchToken;
|
|
83
|
-
}
|
|
84
|
-
function getConfig() {
|
|
85
|
-
return window.impactConfig || window.squatchConfig;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
debug("squatch-js:io");
|
|
89
|
-
|
|
90
|
-
async function doQuery(url, query, variables, jwt) {
|
|
91
|
-
var token = jwt || getToken();
|
|
92
|
-
|
|
93
|
-
var headers = _extends({
|
|
94
|
-
Accept: "application/json",
|
|
95
|
-
"Content-Type": "application/json"
|
|
96
|
-
}, token ? {
|
|
97
|
-
Authorization: "Bearer " + token
|
|
98
|
-
} : {}, {
|
|
99
|
-
"X-SaaSquatch-Referrer": window ? window.location.href : ""
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
try {
|
|
103
|
-
var res = await fetch(url, {
|
|
104
|
-
method: "POST",
|
|
105
|
-
body: JSON.stringify({
|
|
106
|
-
query,
|
|
107
|
-
variables
|
|
108
|
-
}),
|
|
109
|
-
headers
|
|
110
|
-
});
|
|
111
|
-
if (!res.ok) throw new Error(await res.text());
|
|
112
|
-
return await res.json();
|
|
113
|
-
} catch (e) {
|
|
114
|
-
throw e;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
async function doGet(url, jwt) {
|
|
118
|
-
if (jwt === void 0) {
|
|
119
|
-
jwt = "";
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
var headers = {
|
|
123
|
-
Accept: "application/json",
|
|
124
|
-
"Content-Type": "application/json"
|
|
125
|
-
};
|
|
126
|
-
var token = jwt || getToken();
|
|
127
|
-
if (token) headers["X-SaaSquatch-User-Token"] = token;
|
|
128
|
-
|
|
129
|
-
try {
|
|
130
|
-
var res = await fetch(url, {
|
|
131
|
-
method: "GET",
|
|
132
|
-
credentials: "include",
|
|
133
|
-
headers
|
|
134
|
-
});
|
|
135
|
-
var reply = await res.text();
|
|
136
|
-
if (!res.ok) throw new Error(reply);
|
|
137
|
-
return reply ? JSON.parse(reply) : reply;
|
|
138
|
-
} catch (e) {
|
|
139
|
-
throw e;
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
async function doPost(url, data, jwt) {
|
|
143
|
-
var headers = {
|
|
144
|
-
Accept: "application/json",
|
|
145
|
-
"Content-Type": "application/json"
|
|
146
|
-
};
|
|
147
|
-
var token = jwt || getToken();
|
|
148
|
-
if (token) headers["X-SaaSquatch-User-Token"] = token;
|
|
149
|
-
|
|
150
|
-
try {
|
|
151
|
-
var res = await fetch(url, {
|
|
152
|
-
method: "POST",
|
|
153
|
-
body: data,
|
|
154
|
-
headers
|
|
155
|
-
});
|
|
156
|
-
var reply = await res.text();
|
|
157
|
-
if (!res.ok) throw new Error(reply);
|
|
158
|
-
return reply ? JSON.parse(reply) : reply;
|
|
159
|
-
} catch (e) {
|
|
160
|
-
throw e;
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
async function doPut(url, data, jwt) {
|
|
164
|
-
var headers = {
|
|
165
|
-
Accept: "application/json",
|
|
166
|
-
"Content-Type": "application/json",
|
|
167
|
-
"X-SaaSquatch-Referrer": window ? window.location.href : ""
|
|
168
|
-
};
|
|
169
|
-
var token = jwt || getToken();
|
|
170
|
-
if (token) headers["X-SaaSquatch-User-Token"] = token;
|
|
171
|
-
|
|
172
|
-
try {
|
|
173
|
-
var res = await fetch(url, {
|
|
174
|
-
headers,
|
|
175
|
-
method: "PUT",
|
|
176
|
-
credentials: "include",
|
|
177
|
-
body: data
|
|
178
|
-
});
|
|
179
|
-
var reply = await res.text();
|
|
180
|
-
if (!res.ok) throw new Error(reply);
|
|
181
|
-
return reply ? JSON.parse(reply) : reply;
|
|
182
|
-
} catch (e) {
|
|
183
|
-
throw e;
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
var RENDER_WIDGET_QUERY = "\n query renderWidget ($user: UserIdInput, $engagementMedium: UserEngagementMedium, $widgetType: WidgetType, $locale: RSLocale) {\n renderWidget(user: $user, engagementMedium: $engagementMedium, widgetType: $widgetType, locale: $locale) {\n template\n user {\n id\n accountId\n }\n jsOptions\n widgetConfig {\n values\n }\n }\n }\n";
|
|
188
|
-
|
|
189
|
-
/**
|
|
190
|
-
*
|
|
191
|
-
* The WidgetApi class is a wrapper around the Widget Endpoints of the SaaSquatch REST API.
|
|
192
|
-
*
|
|
193
|
-
*/
|
|
194
|
-
|
|
195
|
-
class WidgetApi {
|
|
196
|
-
/**
|
|
197
|
-
* Initialize a new {@link WidgetApi} instance.
|
|
198
|
-
*
|
|
199
|
-
* @param {ConfigOptions} config Config details
|
|
200
|
-
*
|
|
201
|
-
* @example <caption>Browser example</caption>
|
|
202
|
-
* var squatchApi = new squatch.WidgetApi({tenantAlias:'test_12b5bo1b25125'});
|
|
203
|
-
*
|
|
204
|
-
* @example <caption>Browserify/Webpack example</caption>
|
|
205
|
-
* var WidgetApi = require('@saasquatch/squatch-js').WidgetApi;
|
|
206
|
-
* var squatchApi = new WidgetApi({tenantAlias:'test_12b5bo1b25125'});
|
|
207
|
-
*
|
|
208
|
-
* @example <caption>Babel+Browserify/Webpack example</caption>
|
|
209
|
-
* import {WidgetApi} from '@saasquatch/squatch-js';
|
|
210
|
-
* let squatchApi = new WidgetApi({tenantAlias:'test_12b5bo1b25125'});
|
|
211
|
-
*/
|
|
212
|
-
constructor(config) {
|
|
213
|
-
this.tenantAlias = void 0;
|
|
214
|
-
this.domain = void 0;
|
|
215
|
-
this.npmCdn = void 0;
|
|
216
|
-
this.referralCookie = this.squatchReferralCookie;
|
|
217
|
-
var raw = config;
|
|
218
|
-
var clean = validateConfig(raw);
|
|
219
|
-
this.tenantAlias = clean.tenantAlias;
|
|
220
|
-
this.domain = clean.domain;
|
|
221
|
-
this.npmCdn = clean.npmCdn;
|
|
222
|
-
}
|
|
223
|
-
/**
|
|
224
|
-
* Creates/upserts user, requests widget template.
|
|
225
|
-
*
|
|
226
|
-
* @param {Object} params Parameters for request
|
|
227
|
-
* @param {Object?} params.user The user details
|
|
228
|
-
* @param {string} params.user.id The user id
|
|
229
|
-
* @param {string} params.user.accountId The user account id
|
|
230
|
-
* @param {WidgetType} params.widgetType The content of the widget.
|
|
231
|
-
* @param {EngagementMedium?} params.engagementMedium How to display the widget.
|
|
232
|
-
* @param {string?} params.jwt the JSON Web Token (JWT) that is used
|
|
233
|
-
* to validate the data (can be disabled)
|
|
234
|
-
*
|
|
235
|
-
* @return {Promise} string if true, with the widget template, jsOptions and user details.
|
|
236
|
-
*/
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
upsertUser(params) {
|
|
240
|
-
var raw = params;
|
|
241
|
-
var clean = validateWidgetConfig(raw);
|
|
242
|
-
var {
|
|
243
|
-
widgetType,
|
|
244
|
-
engagementMedium = "POPUP",
|
|
245
|
-
jwt,
|
|
246
|
-
locale,
|
|
247
|
-
user
|
|
248
|
-
} = clean;
|
|
249
|
-
var tenantAlias = encodeURIComponent(this.tenantAlias);
|
|
250
|
-
var accountId = user.accountId ? encodeURIComponent(user.accountId) : null;
|
|
251
|
-
var userId = user.id ? encodeURIComponent(user.id) : null;
|
|
252
|
-
|
|
253
|
-
var optionalParams = _buildParams({
|
|
254
|
-
widgetType,
|
|
255
|
-
engagementMedium,
|
|
256
|
-
locale
|
|
257
|
-
});
|
|
258
|
-
|
|
259
|
-
var path = "/api/v1/" + tenantAlias + "/widget/account/" + accountId + "/user/" + userId + "/upsert" + optionalParams;
|
|
260
|
-
var url = this.domain + path;
|
|
261
|
-
var cookies = (Cookies || window.Cookies).get("_saasquatch");
|
|
262
|
-
if (cookies) user["cookies"] = cookies;
|
|
263
|
-
return doPut(url, JSON.stringify(user), jwt);
|
|
264
|
-
}
|
|
265
|
-
/**
|
|
266
|
-
* Requests widget template
|
|
267
|
-
*
|
|
268
|
-
* @param {Object} params Parameters for request
|
|
269
|
-
* @param {Object} params.user The user details
|
|
270
|
-
* @param {string} params.user.id The user id
|
|
271
|
-
* @param {string} params.user.accountId The user account id
|
|
272
|
-
* @param {WidgetType} params.widgetType The content of the widget.
|
|
273
|
-
* @param {EngagementMedium} params.engagementMedium How to display the widget.
|
|
274
|
-
* @param {string} params.jwt the JSON Web Token (JWT) that is used
|
|
275
|
-
* to validate the data (can be disabled)
|
|
276
|
-
* @return {Promise} template html if true.
|
|
277
|
-
*/
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
render(params) {
|
|
281
|
-
var _clean$locale;
|
|
282
|
-
|
|
283
|
-
var raw = params;
|
|
284
|
-
var clean = validatePasswordlessConfig(raw);
|
|
285
|
-
var {
|
|
286
|
-
widgetType,
|
|
287
|
-
engagementMedium = "POPUP",
|
|
288
|
-
jwt,
|
|
289
|
-
user
|
|
290
|
-
} = clean;
|
|
291
|
-
var tenantAlias = encodeURIComponent(this.tenantAlias);
|
|
292
|
-
var accountId = user != null && user.accountId ? encodeURIComponent(user.accountId) : null;
|
|
293
|
-
var userId = user != null && user.id ? encodeURIComponent(user.id) : null;
|
|
294
|
-
var locale = (_clean$locale = clean.locale) != null ? _clean$locale : validateLocale(navigator.language.replace(/\-/g, "_"));
|
|
295
|
-
var path = "/api/v1/" + tenantAlias + "/graphql";
|
|
296
|
-
var url = this.domain + path;
|
|
297
|
-
return new Promise(async (resolve, reject) => {
|
|
298
|
-
try {
|
|
299
|
-
var _res$data;
|
|
300
|
-
|
|
301
|
-
var res = await doQuery(url, RENDER_WIDGET_QUERY, {
|
|
302
|
-
user: userId && accountId ? {
|
|
303
|
-
id: userId,
|
|
304
|
-
accountId
|
|
305
|
-
} : null,
|
|
306
|
-
engagementMedium,
|
|
307
|
-
widgetType,
|
|
308
|
-
locale
|
|
309
|
-
}, jwt);
|
|
310
|
-
resolve(res == null ? void 0 : (_res$data = res.data) == null ? void 0 : _res$data.renderWidget);
|
|
311
|
-
} catch (e) {
|
|
312
|
-
reject(e);
|
|
313
|
-
}
|
|
314
|
-
});
|
|
315
|
-
}
|
|
316
|
-
/**
|
|
317
|
-
* Looks up the referral code of the current user, if there is any.
|
|
318
|
-
*
|
|
319
|
-
* @return {Promise<ReferralCookie>} code referral code if true.
|
|
320
|
-
*/
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
async squatchReferralCookie() {
|
|
324
|
-
var tenantAlias = encodeURIComponent(this.tenantAlias);
|
|
325
|
-
|
|
326
|
-
var _saasquatch = (Cookies || window.Cookies).get("_saasquatch") || "";
|
|
327
|
-
|
|
328
|
-
var cookie = _saasquatch ? "?cookies=" + encodeURIComponent(_saasquatch) : "";
|
|
329
|
-
var url = this.domain + "/a/" + tenantAlias + "/widgets/squatchcookiejson" + cookie;
|
|
330
|
-
var response = await doGet(url);
|
|
331
|
-
return Promise.resolve(_extends({}, response, {
|
|
332
|
-
encodedCookie: _saasquatch
|
|
333
|
-
}));
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
} // builds a param string for widgets
|
|
337
|
-
|
|
338
|
-
function _buildParams(_ref) {
|
|
339
|
-
var {
|
|
340
|
-
widgetType,
|
|
341
|
-
engagementMedium,
|
|
342
|
-
locale
|
|
343
|
-
} = _ref;
|
|
344
|
-
var queryParams = new URLSearchParams();
|
|
345
|
-
queryParams.append("engagementMedium", engagementMedium);
|
|
346
|
-
if (widgetType) queryParams.append("widgetType", widgetType);
|
|
347
|
-
if (locale) queryParams.append("locale", locale);
|
|
348
|
-
return "?" + queryParams.toString();
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
// @ts-check
|
|
352
|
-
/**
|
|
353
|
-
*
|
|
354
|
-
* The AnalyticsApi class is a wrapper around the Analytics Endpoints of
|
|
355
|
-
* the SaaSquatch REST API. Used to record Widget events.
|
|
356
|
-
*
|
|
357
|
-
* @hidden
|
|
358
|
-
*/
|
|
359
|
-
|
|
360
|
-
class AnalyticsApi {
|
|
361
|
-
/**
|
|
362
|
-
* Initialize a new {@link AnalyticsApi} instance.
|
|
363
|
-
*
|
|
364
|
-
* @param {Object} config Config details
|
|
365
|
-
* @param {string} [config.domain='https://app.referralsaasquatch.com'] The server domain.
|
|
366
|
-
*
|
|
367
|
-
*/
|
|
368
|
-
constructor(config) {
|
|
369
|
-
var _getConfig;
|
|
370
|
-
|
|
371
|
-
this.domain = void 0;
|
|
372
|
-
var raw = config;
|
|
373
|
-
|
|
374
|
-
var clean = _validateAnalyticsConfig(raw);
|
|
375
|
-
|
|
376
|
-
this.domain = (clean == null ? void 0 : clean["domain"]) || ((_getConfig = getConfig()) == null ? void 0 : _getConfig.domain) || DEFAULT_DOMAIN;
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
pushAnalyticsLoadEvent(params) {
|
|
380
|
-
if (!params.externalUserId || !params.externalAccountId) return;
|
|
381
|
-
var tenantAlias = encodeURIComponent(params.tenantAlias);
|
|
382
|
-
var accountId = encodeURIComponent(params.externalAccountId);
|
|
383
|
-
var userId = encodeURIComponent(params.externalUserId);
|
|
384
|
-
var engagementMedium = encodeURIComponent(params.engagementMedium);
|
|
385
|
-
var programId = params.programId ? "&programId=" + encodeURIComponent(params.programId) : "";
|
|
386
|
-
var path = "/a/" + tenantAlias + "/widgets/analytics/loaded?externalAccountId=" + accountId + "&externalUserId=" + userId + "&engagementMedium=" + engagementMedium + programId;
|
|
387
|
-
var url = this.domain + path;
|
|
388
|
-
return doPost(url, JSON.stringify({}));
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
pushAnalyticsShareClickedEvent(params) {
|
|
392
|
-
var tenantAlias = encodeURIComponent(params.tenantAlias);
|
|
393
|
-
var accountId = encodeURIComponent(params.externalAccountId);
|
|
394
|
-
var userId = encodeURIComponent(params.externalUserId);
|
|
395
|
-
var engagementMedium = encodeURIComponent(params.engagementMedium);
|
|
396
|
-
var shareMedium = encodeURIComponent(params.shareMedium);
|
|
397
|
-
var path = "/a/" + tenantAlias + "/widgets/analytics/shared?externalAccountId=" + accountId + "&externalUserId=" + userId + "&engagementMedium=" + engagementMedium + "&shareMedium=" + shareMedium;
|
|
398
|
-
var url = this.domain + path;
|
|
399
|
-
return doPost(url, JSON.stringify({}));
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
function _validateAnalyticsConfig(raw) {
|
|
405
|
-
if (!isObject$1(raw)) throw new Error("'options' should be an object");
|
|
406
|
-
return raw;
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
/** @hidden */
|
|
410
|
-
|
|
411
|
-
var _log$8 = debug("squatch-js:widget");
|
|
412
|
-
/*
|
|
413
|
-
* The Widget class is the base class for the different widget types available
|
|
414
|
-
*
|
|
415
|
-
* Creates an `iframe` in which the html content of the widget gets embedded.
|
|
416
|
-
* Uses element-resize-detector (https://github.com/wnr/element-resize-detector)
|
|
417
|
-
* for listening to the height of the widget content and make the iframe responsive.
|
|
418
|
-
*
|
|
419
|
-
*/
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
class Widget {
|
|
423
|
-
constructor(params) {
|
|
424
|
-
var _params$context;
|
|
425
|
-
|
|
426
|
-
this.type = void 0;
|
|
427
|
-
this.content = void 0;
|
|
428
|
-
this.analyticsApi = void 0;
|
|
429
|
-
this.widgetApi = void 0;
|
|
430
|
-
this.context = void 0;
|
|
431
|
-
this.npmCdn = void 0;
|
|
432
|
-
this.container = void 0;
|
|
433
|
-
this.loadEventListener = null;
|
|
434
|
-
|
|
435
|
-
_log$8("widget initializing ...");
|
|
436
|
-
|
|
437
|
-
this.content = params.content === "error" ? this._error(params.rsCode) : params.content;
|
|
438
|
-
this.type = params.type;
|
|
439
|
-
this.widgetApi = params.api;
|
|
440
|
-
this.npmCdn = params.npmCdn;
|
|
441
|
-
this.analyticsApi = new AnalyticsApi({
|
|
442
|
-
domain: params.domain
|
|
443
|
-
});
|
|
444
|
-
this.context = params.context;
|
|
445
|
-
this.container = ((_params$context = params.context) == null ? void 0 : _params$context.container) || params.container;
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
_findElement() {
|
|
449
|
-
var element;
|
|
450
|
-
|
|
451
|
-
if (typeof this.container === "string") {
|
|
452
|
-
// selector is a string
|
|
453
|
-
element = document.querySelector(this.container);
|
|
454
|
-
|
|
455
|
-
_log$8("loading widget with selector", element); // selector is an HTML element
|
|
456
|
-
|
|
457
|
-
} else if (this.container instanceof HTMLElement) {
|
|
458
|
-
element = this.container;
|
|
459
|
-
|
|
460
|
-
_log$8("loading widget with container", element); // garbage container found
|
|
461
|
-
|
|
462
|
-
} else if (this.container) {
|
|
463
|
-
element = null;
|
|
464
|
-
|
|
465
|
-
_log$8("container must be an HTMLElement or string", this.container); // find element on page
|
|
466
|
-
|
|
467
|
-
} else {
|
|
468
|
-
element = document.querySelector("#squatchembed") || document.querySelector(".squatchembed") || document.querySelector("#impactembed") || document.querySelector(".impactembed");
|
|
469
|
-
|
|
470
|
-
_log$8("loading widget with default selector", element);
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
if (!(element instanceof HTMLElement)) throw new Error("element with selector '" + (this.container || "#squatchembed, .squatchembed, #impactembed, or .impactembed") + "' not found.'");
|
|
474
|
-
return element;
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
_createFrame() {
|
|
478
|
-
var frame = document.createElement("iframe");
|
|
479
|
-
frame["squatchJsApi"] = this;
|
|
480
|
-
frame.id = "squatchFrame";
|
|
481
|
-
frame.width = "100%";
|
|
482
|
-
frame.src = "about:blank";
|
|
483
|
-
frame.scrolling = "no";
|
|
484
|
-
frame.setAttribute("style", "border: 0; background-color: none; width: 1px; min-width: 100%;");
|
|
485
|
-
return frame;
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
_findFrame() {
|
|
489
|
-
var element = this.container ? this._findElement() : document.body;
|
|
490
|
-
var parent = element.shadowRoot || element;
|
|
491
|
-
return parent.querySelector("iframe#squatchFrame");
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
_detachLoadEventListener(frameDoc) {
|
|
495
|
-
if (this.loadEventListener) {
|
|
496
|
-
frameDoc.removeEventListener("sq:user-registration", this.loadEventListener);
|
|
497
|
-
this.loadEventListener = null;
|
|
498
|
-
}
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
_attachLoadEventListener(frameDoc, sqh) {
|
|
502
|
-
if (this.loadEventListener === null) {
|
|
503
|
-
this.loadEventListener = e => {
|
|
504
|
-
this._loadEvent(_extends({}, sqh, {
|
|
505
|
-
userId: e.detail.userId,
|
|
506
|
-
accountId: e.detail.accountId
|
|
507
|
-
}));
|
|
508
|
-
};
|
|
509
|
-
|
|
510
|
-
frameDoc.addEventListener("sq:user-registration", this.loadEventListener);
|
|
511
|
-
}
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
_loadEvent(sqh) {
|
|
515
|
-
var _this$analyticsApi$pu;
|
|
516
|
-
|
|
517
|
-
if (!sqh) return; // No non-truthy value
|
|
518
|
-
|
|
519
|
-
if (!isObject$1(sqh)) {
|
|
520
|
-
throw new Error("Widget Load event identity property is not an object");
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
var params;
|
|
524
|
-
|
|
525
|
-
if ("programId" in sqh) {
|
|
526
|
-
if (!sqh.tenantAlias || !sqh.accountId || !sqh.userId || !sqh.engagementMedium) throw new Error("Widget Load event missing required properties");
|
|
527
|
-
params = {
|
|
528
|
-
tenantAlias: sqh.tenantAlias,
|
|
529
|
-
externalAccountId: sqh.accountId,
|
|
530
|
-
externalUserId: sqh.userId,
|
|
531
|
-
engagementMedium: sqh.engagementMedium,
|
|
532
|
-
programId: sqh.programId
|
|
533
|
-
};
|
|
534
|
-
} else {
|
|
535
|
-
var {
|
|
536
|
-
analytics,
|
|
537
|
-
mode
|
|
538
|
-
} = sqh;
|
|
539
|
-
params = {
|
|
540
|
-
tenantAlias: analytics.attributes.tenant,
|
|
541
|
-
externalAccountId: analytics.attributes.accountId,
|
|
542
|
-
externalUserId: analytics.attributes.userId,
|
|
543
|
-
engagementMedium: mode.widgetMode
|
|
544
|
-
};
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
(_this$analyticsApi$pu = this.analyticsApi.pushAnalyticsLoadEvent(params)) == null ? void 0 : _this$analyticsApi$pu.then(response => {
|
|
548
|
-
_log$8(params.engagementMedium + " loaded event recorded.");
|
|
549
|
-
}).catch(ex => {
|
|
550
|
-
_log$8("ERROR: pushAnalyticsLoadEvent() " + ex);
|
|
551
|
-
});
|
|
552
|
-
}
|
|
553
|
-
|
|
554
|
-
_shareEvent(sqh, medium) {
|
|
555
|
-
if (sqh) {
|
|
556
|
-
this.analyticsApi.pushAnalyticsShareClickedEvent({
|
|
557
|
-
tenantAlias: sqh.analytics.attributes.tenant,
|
|
558
|
-
externalAccountId: sqh.analytics.attributes.accountId,
|
|
559
|
-
externalUserId: sqh.analytics.attributes.userId,
|
|
560
|
-
engagementMedium: sqh.mode.widgetMode,
|
|
561
|
-
shareMedium: medium
|
|
562
|
-
}).then(response => {
|
|
563
|
-
_log$8(sqh.mode.widgetMode + " share " + medium + " event recorded. " + response);
|
|
564
|
-
}).catch(ex => {
|
|
565
|
-
_log$8("ERROR: pushAnalyticsShareClickedEvent() " + ex);
|
|
566
|
-
});
|
|
567
|
-
}
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
_error(rs, mode, style) {
|
|
571
|
-
if (mode === void 0) {
|
|
572
|
-
mode = "modal";
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
if (style === void 0) {
|
|
576
|
-
style = "";
|
|
577
|
-
}
|
|
578
|
-
|
|
579
|
-
var errorTemplate = "<!DOCTYPE html>\n <!--[if IE 7]><html class=\"ie7 oldie\" lang=\"en\"><![endif]-->\n <!--[if IE 8]><html class=\"ie8 oldie\" lang=\"en\"><![endif]-->\n <!--[if gt IE 8]><!--><html lang=\"en\"><!--<![endif]-->\n <head>\n <link rel=\"stylesheet\" media=\"all\" href=\"https://fast.ssqt.io/assets/css/widget/errorpage.css\">\n <style>\n " + style + "\n </style>\n </head>\n <body>\n\n <div class=\"squatch-container " + mode + "\" style=\"width:100%\">\n <div class=\"errorheader\">\n <button type=\"button\" class=\"close\" onclick=\"window.frameElement.squatchJsApi.close();\">×</button>\n <p class=\"errortitle\">Error</p>\n </div>\n <div class=\"errorbody\">\n <div class=\"sadface\"><img src=\"https://fast.ssqt.io/assets/images/face.png\"></div>\n <h4>Our referral program is temporarily unavailable.</h4><br>\n <p>Please reload the page or check back later.</p>\n <p>If the persists please contact our support team.</p>\n <br>\n <br>\n <div class=\"right-align errtxt\">\n Error Code: " + rs + "\n </div>\n </div>\n </div>\n </body>\n </html>";
|
|
580
|
-
return errorTemplate;
|
|
581
|
-
}
|
|
582
|
-
|
|
583
|
-
async _findInnerContainer(frame) {
|
|
584
|
-
var {
|
|
585
|
-
contentWindow
|
|
586
|
-
} = frame;
|
|
587
|
-
if (!contentWindow) throw new Error("Squatch.js frame inner frame is empty");
|
|
588
|
-
var frameDoc = contentWindow.document;
|
|
589
|
-
|
|
590
|
-
function search() {
|
|
591
|
-
var containers = frameDoc.getElementsByTagName("sqh-global-container");
|
|
592
|
-
var legacyContainers = frameDoc.getElementsByClassName("squatch-container");
|
|
593
|
-
var fallback = containers.length > 0 ? containers[0] : legacyContainers.length > 0 ? legacyContainers[0] : null;
|
|
594
|
-
return fallback;
|
|
595
|
-
}
|
|
596
|
-
|
|
597
|
-
var found = null;
|
|
598
|
-
|
|
599
|
-
for (var i = 0; i < 5; i++) {
|
|
600
|
-
found = search();
|
|
601
|
-
if (found) break;
|
|
602
|
-
await delay(100);
|
|
603
|
-
}
|
|
604
|
-
|
|
605
|
-
if (!found) {
|
|
606
|
-
return frameDoc.body;
|
|
607
|
-
}
|
|
608
|
-
|
|
609
|
-
return found;
|
|
610
|
-
}
|
|
611
|
-
/**
|
|
612
|
-
* Reloads the current widget, makes updated request to API and renders result.
|
|
613
|
-
* Primarily for Classic widgets with registration
|
|
614
|
-
* @param param0 Form field values
|
|
615
|
-
* @param jwt JWT for API authentication
|
|
616
|
-
*/
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
reload(_ref, jwt) {
|
|
620
|
-
var {
|
|
621
|
-
email,
|
|
622
|
-
firstName,
|
|
623
|
-
lastName
|
|
624
|
-
} = _ref;
|
|
625
|
-
|
|
626
|
-
var frame = this._findFrame();
|
|
627
|
-
|
|
628
|
-
if (!frame) throw new Error("Could not find widget iframe");
|
|
629
|
-
var frameWindow = frame.contentWindow;
|
|
630
|
-
var engagementMedium = this.context.engagementMedium || "POPUP";
|
|
631
|
-
|
|
632
|
-
if (!frameWindow) {
|
|
633
|
-
throw new Error("Frame needs a content window");
|
|
634
|
-
}
|
|
635
|
-
|
|
636
|
-
var response;
|
|
637
|
-
|
|
638
|
-
if (this.context.type === "upsert") {
|
|
639
|
-
if (!this.context.user) throw new Error("Can't reload without user ids");
|
|
640
|
-
var userObj = {
|
|
641
|
-
email: email || null,
|
|
642
|
-
firstName: firstName || null,
|
|
643
|
-
lastName: lastName || null,
|
|
644
|
-
id: this.context.user.id,
|
|
645
|
-
accountId: this.context.user.accountId
|
|
646
|
-
};
|
|
647
|
-
response = this.widgetApi.upsertUser({
|
|
648
|
-
user: userObj,
|
|
649
|
-
engagementMedium,
|
|
650
|
-
widgetType: this.type,
|
|
651
|
-
jwt
|
|
652
|
-
});
|
|
653
|
-
} else if (this.context.type === "passwordless") {
|
|
654
|
-
response = this.widgetApi.render({
|
|
655
|
-
user: undefined,
|
|
656
|
-
engagementMedium,
|
|
657
|
-
widgetType: this.type,
|
|
658
|
-
jwt: undefined
|
|
659
|
-
});
|
|
660
|
-
} else {
|
|
661
|
-
throw new Error("can't reload an error widget");
|
|
662
|
-
}
|
|
663
|
-
|
|
664
|
-
response.then(_ref2 => {
|
|
665
|
-
var {
|
|
666
|
-
template
|
|
667
|
-
} = _ref2;
|
|
668
|
-
|
|
669
|
-
if (template) {
|
|
670
|
-
this.content = template; // Support for classic widget registration forms
|
|
671
|
-
|
|
672
|
-
this.__deprecated__register(frame, {
|
|
673
|
-
email,
|
|
674
|
-
engagementMedium
|
|
675
|
-
}, () => {
|
|
676
|
-
this.load(); // @ts-ignore -- open exists in the PopupWidget, so this call will always exist when it's called.
|
|
677
|
-
|
|
678
|
-
engagementMedium === "POPUP" && this.open();
|
|
679
|
-
});
|
|
680
|
-
}
|
|
681
|
-
}).catch(_ref3 => {
|
|
682
|
-
var {
|
|
683
|
-
message
|
|
684
|
-
} = _ref3;
|
|
685
|
-
|
|
686
|
-
_log$8("" + message);
|
|
687
|
-
});
|
|
688
|
-
}
|
|
689
|
-
|
|
690
|
-
__deprecated__register(frame, params, onClick) {
|
|
691
|
-
var frameWindow = frame.contentWindow;
|
|
692
|
-
var frameDoc = frameWindow.document;
|
|
693
|
-
var showStatsBtn = frameDoc.createElement("button");
|
|
694
|
-
var registerForm = frameDoc.getElementsByClassName("squatch-register")[0];
|
|
695
|
-
|
|
696
|
-
if (registerForm) {
|
|
697
|
-
showStatsBtn.className = "btn btn-primary";
|
|
698
|
-
showStatsBtn.id = "show-stats-btn";
|
|
699
|
-
showStatsBtn.textContent = this.type === "REFERRER_WIDGET" ? "Show Stats" : "Show Reward";
|
|
700
|
-
var widgetStyle = params.engagementMedium === "POPUP" ? "margin-top: 10px; max-width: 130px; width: 100%;" : "margin-top: 10px;";
|
|
701
|
-
showStatsBtn.setAttribute("style", widgetStyle);
|
|
702
|
-
showStatsBtn.onclick = onClick; // @ts-ignore -- expect register form to be a stylable element
|
|
703
|
-
|
|
704
|
-
registerForm.style.paddingTop = "30px";
|
|
705
|
-
registerForm.innerHTML = "<p><strong>" + params.email + "</strong><br>Has been successfully registered</p>";
|
|
706
|
-
registerForm.appendChild(showStatsBtn);
|
|
707
|
-
}
|
|
708
|
-
}
|
|
709
|
-
|
|
710
|
-
}
|
|
711
|
-
|
|
712
|
-
function delay(duration) {
|
|
713
|
-
return new Promise(resolve => {
|
|
714
|
-
setTimeout(resolve, duration);
|
|
715
|
-
});
|
|
716
|
-
}
|
|
717
|
-
|
|
718
|
-
/*!
|
|
719
|
-
* domready (c) Dustin Diaz 2014 - License MIT
|
|
720
|
-
*
|
|
721
|
-
*/
|
|
722
|
-
function domready(targetDoc, fn) {
|
|
723
|
-
var fns = [];
|
|
724
|
-
var listener;
|
|
725
|
-
var doc = targetDoc;
|
|
726
|
-
var hack = doc.documentElement.doScroll;
|
|
727
|
-
var domContentLoaded = "DOMContentLoaded";
|
|
728
|
-
var loaded = (hack ? /^loaded|^c/ : /^loaded|^i|^c/).test(doc.readyState);
|
|
729
|
-
if (!loaded) doc.addEventListener(domContentLoaded, listener = () => {
|
|
730
|
-
doc.removeEventListener(domContentLoaded, listener);
|
|
731
|
-
loaded = true;
|
|
732
|
-
|
|
733
|
-
while (listener = fns.shift()) {
|
|
734
|
-
listener();
|
|
735
|
-
}
|
|
736
|
-
}); // @ts-ignore
|
|
737
|
-
|
|
738
|
-
return loaded ? setTimeout(fn, 0) : fns.push(fn);
|
|
739
|
-
}
|
|
740
|
-
|
|
741
|
-
// @ts-check
|
|
742
|
-
|
|
743
|
-
var _log$7 = debug("squatch-js:EMBEDwidget");
|
|
744
|
-
/**
|
|
745
|
-
* An EmbedWidget is displayed inline in part of your page.
|
|
746
|
-
*
|
|
747
|
-
* To create an EmbedWidget use {@link Widgets}
|
|
748
|
-
*
|
|
749
|
-
* @example
|
|
750
|
-
* const widget = new EmbedWidget({ ... })
|
|
751
|
-
* widget.load() // Loads widget into the DOM
|
|
752
|
-
* widget.open() // Makes the iframe container visible
|
|
753
|
-
* widget.close() // Hides the iframe container
|
|
754
|
-
*/
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
class EmbedWidget extends Widget {
|
|
758
|
-
constructor(params, container) {
|
|
759
|
-
super(params);
|
|
760
|
-
this.show = this.open;
|
|
761
|
-
this.hide = this.close;
|
|
762
|
-
if (container) this.container = container;
|
|
763
|
-
}
|
|
764
|
-
|
|
765
|
-
async load() {
|
|
766
|
-
var _this$context;
|
|
767
|
-
|
|
768
|
-
var frame = this._createFrame();
|
|
769
|
-
|
|
770
|
-
var element = this._findElement();
|
|
771
|
-
|
|
772
|
-
if ((_this$context = this.context) != null && _this$context.container) {
|
|
773
|
-
// Custom container is used
|
|
774
|
-
element.style.visibility = "hidden";
|
|
775
|
-
element.style.height = "0";
|
|
776
|
-
element.style["overflow-y"] = "hidden";
|
|
777
|
-
}
|
|
778
|
-
|
|
779
|
-
if (this.container) {
|
|
780
|
-
if (element.shadowRoot) {
|
|
781
|
-
var _element$shadowRoot$l;
|
|
782
|
-
|
|
783
|
-
if (((_element$shadowRoot$l = element.shadowRoot.lastChild) == null ? void 0 : _element$shadowRoot$l.nodeName) === "IFRAME") {
|
|
784
|
-
element.shadowRoot.replaceChild(frame, element.shadowRoot.lastChild);
|
|
785
|
-
} else {
|
|
786
|
-
element.shadowRoot.appendChild(frame);
|
|
787
|
-
}
|
|
788
|
-
} // Widget reloaded - replace existing element
|
|
789
|
-
else if (element.firstChild) {
|
|
790
|
-
element.replaceChild(frame, element.firstChild); // Add iframe for the first time
|
|
791
|
-
} else {
|
|
792
|
-
element.appendChild(frame);
|
|
793
|
-
}
|
|
794
|
-
} else if (!element.firstChild || element.firstChild.nodeName === "#text") {
|
|
795
|
-
element.appendChild(frame);
|
|
796
|
-
}
|
|
797
|
-
|
|
798
|
-
var {
|
|
799
|
-
contentWindow
|
|
800
|
-
} = frame;
|
|
801
|
-
|
|
802
|
-
if (!contentWindow) {
|
|
803
|
-
throw new Error("Frame needs a content window");
|
|
804
|
-
}
|
|
805
|
-
|
|
806
|
-
var frameDoc = contentWindow.document;
|
|
807
|
-
frameDoc.open();
|
|
808
|
-
frameDoc.write(this.content);
|
|
809
|
-
frameDoc.write("<script src=\"" + this.npmCdn + "/resize-observer-polyfill@1.5.x\"></script>");
|
|
810
|
-
frameDoc.close();
|
|
811
|
-
domready(frameDoc, async () => {
|
|
812
|
-
var _sqh = contentWindow.squatch || contentWindow.widgetIdent; // @ts-ignore -- number will be cast to string by browsers
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
frame.height = frameDoc.body.scrollHeight; // Adjust frame height when size of body changes
|
|
816
|
-
|
|
817
|
-
/* istanbul ignore next: hard to test */
|
|
818
|
-
|
|
819
|
-
var ro = new contentWindow["ResizeObserver"](entries => {
|
|
820
|
-
for (var entry of entries) {
|
|
821
|
-
var {
|
|
822
|
-
height
|
|
823
|
-
} = entry.contentRect; // @ts-ignore -- number will be cast to string by browsers
|
|
824
|
-
|
|
825
|
-
frame.height = height;
|
|
826
|
-
}
|
|
827
|
-
});
|
|
828
|
-
var container = await this._findInnerContainer(frame);
|
|
829
|
-
ro.observe(container);
|
|
830
|
-
|
|
831
|
-
if (this._shouldFireLoadEvent()) {
|
|
832
|
-
this._loadEvent(_sqh);
|
|
833
|
-
|
|
834
|
-
_log$7("loaded");
|
|
835
|
-
} else if (frameDoc) {
|
|
836
|
-
this._attachLoadEventListener(frameDoc, _sqh);
|
|
837
|
-
}
|
|
838
|
-
});
|
|
839
|
-
}
|
|
840
|
-
/**
|
|
841
|
-
* Un-hide if element is available and refresh data
|
|
842
|
-
*/
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
open() {
|
|
846
|
-
var frame = this._findFrame();
|
|
847
|
-
|
|
848
|
-
if (!frame) return _log$7("no target element to open");
|
|
849
|
-
if (!frame.contentWindow) return _log$7("Frame needs a content window");
|
|
850
|
-
|
|
851
|
-
var element = this._findElement();
|
|
852
|
-
|
|
853
|
-
element.style.visibility = "unset";
|
|
854
|
-
element.style.height = "auto";
|
|
855
|
-
element.style["overflow-y"] = "auto";
|
|
856
|
-
frame.contentWindow.document.dispatchEvent(new CustomEvent("sq:refresh"));
|
|
857
|
-
|
|
858
|
-
var _sqh = frame.contentWindow.squatch || frame.contentWindow.widgetIdent;
|
|
859
|
-
|
|
860
|
-
if (this.context.user) {
|
|
861
|
-
this._loadEvent(_sqh);
|
|
862
|
-
|
|
863
|
-
_log$7("loaded");
|
|
864
|
-
} else {
|
|
865
|
-
if (!frame.contentDocument) return;
|
|
866
|
-
|
|
867
|
-
this._attachLoadEventListener(frame.contentDocument, _sqh);
|
|
868
|
-
}
|
|
869
|
-
}
|
|
870
|
-
|
|
871
|
-
close() {
|
|
872
|
-
var frame = this._findFrame();
|
|
873
|
-
|
|
874
|
-
if (!frame) return _log$7("no target element to close");
|
|
875
|
-
if (frame.contentDocument) this._detachLoadEventListener(frame.contentDocument);
|
|
876
|
-
|
|
877
|
-
var element = this._findElement();
|
|
878
|
-
|
|
879
|
-
element.style.visibility = "hidden";
|
|
880
|
-
element.style.height = "0";
|
|
881
|
-
element.style["overflow-y"] = "hidden";
|
|
882
|
-
|
|
883
|
-
_log$7("Embed widget closed");
|
|
884
|
-
}
|
|
885
|
-
|
|
886
|
-
_error(rs, mode, style) {
|
|
887
|
-
if (mode === void 0) {
|
|
888
|
-
mode = "embed";
|
|
889
|
-
}
|
|
890
|
-
|
|
891
|
-
if (style === void 0) {
|
|
892
|
-
style = "";
|
|
893
|
-
}
|
|
894
|
-
|
|
895
|
-
return super._error(rs, mode, style);
|
|
896
|
-
}
|
|
897
|
-
|
|
898
|
-
_shouldFireLoadEvent() {
|
|
899
|
-
var noContainer = !this.container;
|
|
900
|
-
var isComponent = this.container instanceof HTMLElement && (this.container.tagName.startsWith("SQUATCH-") || this.container.tagName.startsWith("IMPACT-"));
|
|
901
|
-
var isVerified = !!this.context.user;
|
|
902
|
-
return isVerified && (noContainer || isComponent);
|
|
903
|
-
}
|
|
904
|
-
|
|
905
|
-
}
|
|
906
|
-
|
|
907
|
-
// @ts-check
|
|
908
|
-
|
|
909
|
-
var _log$6 = debug("squatch-js:POPUPwidget");
|
|
910
|
-
|
|
911
|
-
var popupId = 0;
|
|
912
|
-
/**
|
|
913
|
-
* The PopupWidget is used to display popups (also known as "Modals").
|
|
914
|
-
* Popups widgets are rendered on top of other elements in a page.
|
|
915
|
-
*
|
|
916
|
-
* To create a PopupWidget use {@link Widgets}
|
|
917
|
-
*
|
|
918
|
-
* @example
|
|
919
|
-
* const widget = new PopupWidget({ ... })
|
|
920
|
-
* widget.load() // Loads the widget into a dialog element
|
|
921
|
-
* widget.open() // Opens the dialog element
|
|
922
|
-
* widget.close() // Hides the dialog element
|
|
923
|
-
*/
|
|
924
|
-
|
|
925
|
-
class PopupWidget extends Widget {
|
|
926
|
-
constructor(params, trigger) {
|
|
927
|
-
if (trigger === void 0) {
|
|
928
|
-
trigger = ".squatchpop";
|
|
929
|
-
}
|
|
930
|
-
|
|
931
|
-
super(params);
|
|
932
|
-
this.trigger = void 0;
|
|
933
|
-
this.id = void 0;
|
|
934
|
-
this.show = this.open;
|
|
935
|
-
this.hide = this.close;
|
|
936
|
-
this.trigger = trigger;
|
|
937
|
-
|
|
938
|
-
if (this.container) {
|
|
939
|
-
this.id = "squatchModal";
|
|
940
|
-
} else {
|
|
941
|
-
this.id = popupId === 0 ? "squatchModal" : "squatchModal__" + popupId;
|
|
942
|
-
popupId = popupId + 1;
|
|
943
|
-
}
|
|
944
|
-
|
|
945
|
-
document.head.insertAdjacentHTML("beforeend", "<style>#" + this.id + "::-webkit-scrollbar { display: none; }</style>");
|
|
946
|
-
}
|
|
947
|
-
|
|
948
|
-
_initialiseCTA() {
|
|
949
|
-
if (!this.trigger) return;
|
|
950
|
-
var triggerElement;
|
|
951
|
-
|
|
952
|
-
try {
|
|
953
|
-
triggerElement
|
|
954
|
-
/* HTMLButton */
|
|
955
|
-
= document.querySelector(this.trigger) || document.querySelector(".impactpop");
|
|
956
|
-
if (this.trigger && !triggerElement) _log$6("No element found with trigger selector", this.trigger);
|
|
957
|
-
} catch (_unused) {
|
|
958
|
-
_log$6("Not a valid selector", this.trigger);
|
|
959
|
-
} // Trigger is optional
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
if (triggerElement) {
|
|
963
|
-
triggerElement.onclick = () => {
|
|
964
|
-
this.open();
|
|
965
|
-
};
|
|
966
|
-
}
|
|
967
|
-
}
|
|
968
|
-
|
|
969
|
-
_createPopupDialog() {
|
|
970
|
-
var dialog = document.createElement("dialog");
|
|
971
|
-
dialog.id = this.id;
|
|
972
|
-
dialog.setAttribute("style", "width: 100%; max-width: 500px; border: none; padding: 0;");
|
|
973
|
-
|
|
974
|
-
var onClick = e => {
|
|
975
|
-
e.stopPropagation();
|
|
976
|
-
if (e.target === dialog) dialog.close();
|
|
977
|
-
};
|
|
978
|
-
|
|
979
|
-
dialog.addEventListener("click", onClick);
|
|
980
|
-
return dialog;
|
|
981
|
-
}
|
|
982
|
-
|
|
983
|
-
async load() {
|
|
984
|
-
var _dialogParent$lastChi;
|
|
985
|
-
|
|
986
|
-
var frame = this._createFrame();
|
|
987
|
-
|
|
988
|
-
this._initialiseCTA();
|
|
989
|
-
|
|
990
|
-
var element = this.container ? this._findElement() : document.body;
|
|
991
|
-
var dialogParent = element.shadowRoot || element;
|
|
992
|
-
|
|
993
|
-
var dialog = this._createPopupDialog();
|
|
994
|
-
|
|
995
|
-
dialog.appendChild(frame);
|
|
996
|
-
|
|
997
|
-
if (((_dialogParent$lastChi = dialogParent.lastChild) == null ? void 0 : _dialogParent$lastChi.nodeName) === "DIALOG") {
|
|
998
|
-
// Was reloaded
|
|
999
|
-
dialogParent.replaceChild(dialog, dialogParent.lastChild);
|
|
1000
|
-
} else {
|
|
1001
|
-
// First time rendering
|
|
1002
|
-
dialogParent.appendChild(dialog);
|
|
1003
|
-
}
|
|
1004
|
-
|
|
1005
|
-
var {
|
|
1006
|
-
contentWindow
|
|
1007
|
-
} = frame;
|
|
1008
|
-
|
|
1009
|
-
if (!contentWindow) {
|
|
1010
|
-
throw new Error("Frame needs a content window");
|
|
1011
|
-
}
|
|
1012
|
-
|
|
1013
|
-
var frameDoc = contentWindow.document;
|
|
1014
|
-
frameDoc.open();
|
|
1015
|
-
frameDoc.write(this.content);
|
|
1016
|
-
frameDoc.write("<script src=\"" + this.npmCdn + "/resize-observer-polyfill@1.5.x\"></script>");
|
|
1017
|
-
frameDoc.close();
|
|
1018
|
-
|
|
1019
|
-
_log$6("Popup template loaded into iframe");
|
|
1020
|
-
|
|
1021
|
-
await this._setupResizeHandler(frame);
|
|
1022
|
-
}
|
|
1023
|
-
|
|
1024
|
-
async _setupResizeHandler(frame) {
|
|
1025
|
-
var {
|
|
1026
|
-
contentWindow
|
|
1027
|
-
} = frame;
|
|
1028
|
-
|
|
1029
|
-
if (!contentWindow) {
|
|
1030
|
-
throw new Error("Frame needs a content window");
|
|
1031
|
-
}
|
|
1032
|
-
|
|
1033
|
-
var frameDoc = contentWindow.document; // Adjust frame height when size of body changes
|
|
1034
|
-
|
|
1035
|
-
domready(frameDoc, async () => {
|
|
1036
|
-
frameDoc.body.style.overflowY = "hidden";
|
|
1037
|
-
frame.height = frameDoc.body.offsetHeight + "px"; // Adjust frame height when size of body changes
|
|
1038
|
-
|
|
1039
|
-
var ro = new contentWindow["ResizeObserver"](entries => {
|
|
1040
|
-
for (var entry of entries) {
|
|
1041
|
-
var {
|
|
1042
|
-
top,
|
|
1043
|
-
bottom
|
|
1044
|
-
} = entry.contentRect;
|
|
1045
|
-
var computedHeight = bottom + top;
|
|
1046
|
-
frame.height = computedHeight + ""; // Don't let anything else set the height of this element
|
|
1047
|
-
|
|
1048
|
-
entry.target.style = "";
|
|
1049
|
-
}
|
|
1050
|
-
});
|
|
1051
|
-
ro.observe(await this._findInnerContainer(frame));
|
|
1052
|
-
});
|
|
1053
|
-
}
|
|
1054
|
-
|
|
1055
|
-
open() {
|
|
1056
|
-
var element = this.container ? this._findElement() : document.body;
|
|
1057
|
-
var parent = element.shadowRoot || element;
|
|
1058
|
-
var dialog = parent.querySelector("#" + this.id);
|
|
1059
|
-
if (!dialog) throw new Error("Could not determine container div");
|
|
1060
|
-
dialog.showModal();
|
|
1061
|
-
|
|
1062
|
-
var frame = this._findFrame();
|
|
1063
|
-
|
|
1064
|
-
if (!frame) throw new Error("Could not find iframe");
|
|
1065
|
-
var {
|
|
1066
|
-
contentWindow
|
|
1067
|
-
} = frame;
|
|
1068
|
-
if (!contentWindow) throw new Error("Squatch.js has an empty iframe");
|
|
1069
|
-
var frameDoc = contentWindow.document; // Adjust frame height when size of body changes
|
|
1070
|
-
|
|
1071
|
-
domready(frameDoc, () => {
|
|
1072
|
-
var _frame$contentDocumen;
|
|
1073
|
-
|
|
1074
|
-
var _sqh = contentWindow.squatch || contentWindow.widgetIdent;
|
|
1075
|
-
|
|
1076
|
-
(_frame$contentDocumen = frame.contentDocument) == null ? void 0 : _frame$contentDocumen.dispatchEvent(new CustomEvent("sq:refresh"));
|
|
1077
|
-
|
|
1078
|
-
if (this.context.user) {
|
|
1079
|
-
this._loadEvent(_sqh);
|
|
1080
|
-
|
|
1081
|
-
_log$6("Popup opened");
|
|
1082
|
-
} else {
|
|
1083
|
-
this._attachLoadEventListener(frameDoc, _sqh);
|
|
1084
|
-
}
|
|
1085
|
-
});
|
|
1086
|
-
}
|
|
1087
|
-
|
|
1088
|
-
close() {
|
|
1089
|
-
var frame = this._findFrame();
|
|
1090
|
-
|
|
1091
|
-
if (frame != null && frame.contentDocument) this._detachLoadEventListener(frame.contentDocument);
|
|
1092
|
-
var element = this.container ? this._findElement() : document.body;
|
|
1093
|
-
var parent = element.shadowRoot || element;
|
|
1094
|
-
var dialog = parent.querySelector("#" + this.id);
|
|
1095
|
-
if (!dialog) throw new Error("Could not determine container div");
|
|
1096
|
-
dialog.close();
|
|
1097
|
-
|
|
1098
|
-
_log$6("Popup closed");
|
|
1099
|
-
}
|
|
1100
|
-
|
|
1101
|
-
_clickedOutside(_ref) {
|
|
1102
|
-
}
|
|
1103
|
-
|
|
1104
|
-
_error(rs, mode, style) {
|
|
1105
|
-
if (mode === void 0) {
|
|
1106
|
-
mode = "modal";
|
|
1107
|
-
}
|
|
1108
|
-
|
|
1109
|
-
if (style === void 0) {
|
|
1110
|
-
style = "";
|
|
1111
|
-
}
|
|
1112
|
-
|
|
1113
|
-
var _style = "body { margin: 0; } .modal { box-shadow: none; border: 0; }";
|
|
1114
|
-
return super._error(rs, mode, style || _style);
|
|
1115
|
-
}
|
|
1116
|
-
|
|
1117
|
-
}
|
|
1118
|
-
|
|
1119
|
-
var _log$5 = debug("squatch-js:widgets");
|
|
1120
|
-
/**
|
|
1121
|
-
* `Widgets` is a factory for creating widgets. It's possible to build your own widgets using the
|
|
1122
|
-
* {@link WidgetApi} but most people will prefer to use these easy methods.
|
|
1123
|
-
* @class
|
|
1124
|
-
*/
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
class Widgets {
|
|
1128
|
-
/**
|
|
1129
|
-
* Instance of {@link WidgetApi}
|
|
1130
|
-
*/
|
|
1131
|
-
|
|
1132
|
-
/**
|
|
1133
|
-
* Tenant alias of SaaSquatch tenant
|
|
1134
|
-
*/
|
|
1135
|
-
|
|
1136
|
-
/**
|
|
1137
|
-
* SaaSquatch domain for API requests
|
|
1138
|
-
* @default "https://app.referralsaasquatch.com"
|
|
1139
|
-
*/
|
|
1140
|
-
|
|
1141
|
-
/**
|
|
1142
|
-
* Hosted CDN for npm packages
|
|
1143
|
-
* @default "https://fast.ssqt.io/npm"
|
|
1144
|
-
*/
|
|
1145
|
-
|
|
1146
|
-
/**
|
|
1147
|
-
* Initialize a new {@link Widgets} instance.
|
|
1148
|
-
*
|
|
1149
|
-
* @param {ConfigOptions} config Config details
|
|
1150
|
-
*
|
|
1151
|
-
* @example <caption>Browser example</caption>
|
|
1152
|
-
* var widgets = new squatch.Widgets({tenantAlias:'test_12b5bo1b25125'});
|
|
1153
|
-
*
|
|
1154
|
-
* @example <caption>Browserify/Webpack example</caption>
|
|
1155
|
-
* var Widgets = require('@saasquatch/squatch-js').Widgets;
|
|
1156
|
-
* var widgets = new Widgets({tenantAlias:'test_12b5bo1b25125'});
|
|
1157
|
-
*
|
|
1158
|
-
* @example <caption>Babel+Browserify/Webpack example</caption>
|
|
1159
|
-
* import {Widgets} from '@saasquatch/squatch-js';
|
|
1160
|
-
* let widgets = new Widgets({tenantAlias:'test_12b5bo1b25125'});
|
|
1161
|
-
*/
|
|
1162
|
-
constructor(configin) {
|
|
1163
|
-
this.api = void 0;
|
|
1164
|
-
this.tenantAlias = void 0;
|
|
1165
|
-
this.domain = void 0;
|
|
1166
|
-
this.npmCdn = void 0;
|
|
1167
|
-
var config = validateConfig(configin);
|
|
1168
|
-
this.tenantAlias = config.tenantAlias;
|
|
1169
|
-
this.domain = config.domain;
|
|
1170
|
-
this.npmCdn = config.npmCdn;
|
|
1171
|
-
this.api = new WidgetApi(config);
|
|
1172
|
-
}
|
|
1173
|
-
/**
|
|
1174
|
-
* This function calls the {@link WidgetApi.upsertUser} method, and it renders
|
|
1175
|
-
* the widget if it is successful. Otherwise it shows the "error" widget.
|
|
1176
|
-
*
|
|
1177
|
-
* @param {Object} config Config details
|
|
1178
|
-
* @param {Object} config.user The user details
|
|
1179
|
-
* @param {string} config.user.id The user id
|
|
1180
|
-
* @param {string} config.user.accountId The user account id
|
|
1181
|
-
* @param {WidgetType} config.widgetType The content of the widget
|
|
1182
|
-
* @param {EngagementMedium} config.engagementMedium How to display the widget
|
|
1183
|
-
* @param {string} config.jwt the JSON Web Token (JWT) that is used to validate the data (can be disabled)
|
|
1184
|
-
* @param {HTMLElement | string | undefined} config.container Element to load the widget into
|
|
1185
|
-
* @param {string | undefined} config.trigger Trigger element for opening the popup widget
|
|
1186
|
-
*
|
|
1187
|
-
* @return {Promise<WidgetResult>} json object if true, with a Widget and user details
|
|
1188
|
-
*/
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
async upsertUser(config) {
|
|
1192
|
-
var raw = config;
|
|
1193
|
-
var clean = validateWidgetConfig(raw);
|
|
1194
|
-
|
|
1195
|
-
try {
|
|
1196
|
-
var response = await this.api.upsertUser(clean);
|
|
1197
|
-
return {
|
|
1198
|
-
widget: this._renderWidget(response, clean, {
|
|
1199
|
-
type: "upsert",
|
|
1200
|
-
user: clean.user,
|
|
1201
|
-
engagementMedium: config.engagementMedium,
|
|
1202
|
-
container: config.container,
|
|
1203
|
-
trigger: config.trigger
|
|
1204
|
-
}),
|
|
1205
|
-
user: response.user
|
|
1206
|
-
};
|
|
1207
|
-
} catch (err) {
|
|
1208
|
-
_log$5(err);
|
|
1209
|
-
|
|
1210
|
-
if (err.apiErrorCode) {
|
|
1211
|
-
this._renderErrorWidget(err, config.engagementMedium);
|
|
1212
|
-
}
|
|
1213
|
-
|
|
1214
|
-
throw new Error(err);
|
|
1215
|
-
}
|
|
1216
|
-
}
|
|
1217
|
-
/**
|
|
1218
|
-
* This function calls the {@link WidgetApi.render} method, and it renders
|
|
1219
|
-
* the widget if it is successful. Otherwise it shows the "error" widget.
|
|
1220
|
-
*
|
|
1221
|
-
* @param {Object} config Config details
|
|
1222
|
-
* @param {Object} config.user The user details
|
|
1223
|
-
* @param {string} config.user.id The user id
|
|
1224
|
-
* @param {string} config.user.accountId The user account id
|
|
1225
|
-
* @param {WidgetType} config.widgetType The content of the widget
|
|
1226
|
-
* @param {EngagementMedium} config.engagementMedium How to display the widget
|
|
1227
|
-
* @param {string} config.jwt the JSON Web Token (JWT) that is used
|
|
1228
|
-
* to validate the data (can be disabled)
|
|
1229
|
-
*
|
|
1230
|
-
* @return {Promise<WidgetResult>} json object if true, with a Widget and user details
|
|
1231
|
-
*/
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
async render(config) {
|
|
1235
|
-
var raw = config;
|
|
1236
|
-
var clean = validatePasswordlessConfig(raw);
|
|
1237
|
-
|
|
1238
|
-
try {
|
|
1239
|
-
var response = await this.api.render(clean);
|
|
1240
|
-
return {
|
|
1241
|
-
widget: this._renderWidget(response, clean, {
|
|
1242
|
-
type: "passwordless",
|
|
1243
|
-
engagementMedium: clean.engagementMedium,
|
|
1244
|
-
container: clean.container,
|
|
1245
|
-
trigger: clean.trigger
|
|
1246
|
-
}),
|
|
1247
|
-
user: response.user
|
|
1248
|
-
};
|
|
1249
|
-
} catch (err) {
|
|
1250
|
-
if (err.apiErrorCode) {
|
|
1251
|
-
this._renderErrorWidget(err, clean.engagementMedium);
|
|
1252
|
-
}
|
|
1253
|
-
|
|
1254
|
-
throw new Error(err);
|
|
1255
|
-
}
|
|
1256
|
-
}
|
|
1257
|
-
/**
|
|
1258
|
-
* Autofills a referral code into an element when someone has been referred.
|
|
1259
|
-
* Uses {@link WidgetApi.squatchReferralCookie} behind the scenes.
|
|
1260
|
-
*
|
|
1261
|
-
* @param selector Element class/id selector, or a callback function
|
|
1262
|
-
* @returns
|
|
1263
|
-
*/
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
async autofill(selector) {
|
|
1267
|
-
var input = selector;
|
|
1268
|
-
|
|
1269
|
-
if (typeof input === "function") {
|
|
1270
|
-
try {
|
|
1271
|
-
var response = await this.api.squatchReferralCookie();
|
|
1272
|
-
input(response);
|
|
1273
|
-
} catch (e) {
|
|
1274
|
-
_log$5("Autofill error", e);
|
|
1275
|
-
|
|
1276
|
-
throw new Error(e);
|
|
1277
|
-
}
|
|
1278
|
-
|
|
1279
|
-
return;
|
|
1280
|
-
}
|
|
1281
|
-
|
|
1282
|
-
if (typeof input !== "string") throw new Error("Autofill accepts a string or function");
|
|
1283
|
-
var elems = document.querySelectorAll(input);
|
|
1284
|
-
var elem;
|
|
1285
|
-
|
|
1286
|
-
if (elems.length > 0) {
|
|
1287
|
-
// Only use the first element found
|
|
1288
|
-
elem = elems[0];
|
|
1289
|
-
} else {
|
|
1290
|
-
_log$5("Element id/class or function missing");
|
|
1291
|
-
|
|
1292
|
-
throw new Error("Element id/class or function missing");
|
|
1293
|
-
}
|
|
1294
|
-
|
|
1295
|
-
try {
|
|
1296
|
-
var _response = await this.api.squatchReferralCookie();
|
|
1297
|
-
|
|
1298
|
-
elem.value = _response.codes[0];
|
|
1299
|
-
} catch (e) {
|
|
1300
|
-
throw new Error(e);
|
|
1301
|
-
}
|
|
1302
|
-
}
|
|
1303
|
-
/**
|
|
1304
|
-
* @hidden
|
|
1305
|
-
* @param {Object} response The json object return from the WidgetApi
|
|
1306
|
-
* @param {Object} config Config details
|
|
1307
|
-
* @param {string} config.widgetType The widget type (REFERRER_WIDGET, CONVERSION_WIDGET)
|
|
1308
|
-
* @param {string} config.engagementMedium (POPUP, EMBED)
|
|
1309
|
-
* @returns {Widget} widget (PopupWidget or EmbedWidget)
|
|
1310
|
-
*/
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
_renderWidget(response, config, context) {
|
|
1314
|
-
var _opts$widget;
|
|
1315
|
-
|
|
1316
|
-
_log$5("Rendering Widget...");
|
|
1317
|
-
|
|
1318
|
-
if (!response) throw new Error("Unable to get a response");
|
|
1319
|
-
var widget;
|
|
1320
|
-
var displayOnLoad = !!config.displayOnLoad;
|
|
1321
|
-
var opts = response.jsOptions || {};
|
|
1322
|
-
var params = {
|
|
1323
|
-
content: response.template,
|
|
1324
|
-
type: config.widgetType || ((_opts$widget = opts.widget) == null ? void 0 : _opts$widget.defaultWidgetType),
|
|
1325
|
-
api: this.api,
|
|
1326
|
-
domain: this.domain,
|
|
1327
|
-
npmCdn: this.npmCdn,
|
|
1328
|
-
context: context
|
|
1329
|
-
};
|
|
1330
|
-
|
|
1331
|
-
if (opts.widgetUrlMappings) {
|
|
1332
|
-
opts.widgetUrlMappings.forEach(rule => {
|
|
1333
|
-
if (Widgets._matchesUrl(rule.url)) {
|
|
1334
|
-
var _response$user, _response$user$referr;
|
|
1335
|
-
|
|
1336
|
-
if (rule.widgetType !== "CONVERSION_WIDGET" || (_response$user = response.user) != null && (_response$user$referr = _response$user.referredBy) != null && _response$user$referr.code) {
|
|
1337
|
-
displayOnLoad = rule.displayOnLoad;
|
|
1338
|
-
|
|
1339
|
-
_log$5("Display " + rule.widgetType + " on " + rule.url);
|
|
1340
|
-
} else {
|
|
1341
|
-
_log$5("Don't display " + rule.widgetType + " when no referral on widget rule match " + rule.url);
|
|
1342
|
-
}
|
|
1343
|
-
}
|
|
1344
|
-
});
|
|
1345
|
-
}
|
|
1346
|
-
|
|
1347
|
-
if (opts.fuelTankAutofillUrls) {
|
|
1348
|
-
_log$5("We found a fuel tank autofill!");
|
|
1349
|
-
|
|
1350
|
-
opts.fuelTankAutofillUrls.forEach(_ref => {
|
|
1351
|
-
var {
|
|
1352
|
-
url,
|
|
1353
|
-
formSelector
|
|
1354
|
-
} = _ref;
|
|
1355
|
-
|
|
1356
|
-
if (Widgets._matchesUrl(url)) {
|
|
1357
|
-
var _response$user2, _response$user2$refer;
|
|
1358
|
-
|
|
1359
|
-
_log$5("Fuel Tank URL matches");
|
|
1360
|
-
|
|
1361
|
-
if ((_response$user2 = response.user) != null && (_response$user2$refer = _response$user2.referredBy) != null && _response$user2$refer.code) {
|
|
1362
|
-
var formAutofill = document.querySelector(formSelector);
|
|
1363
|
-
|
|
1364
|
-
if (formAutofill) {
|
|
1365
|
-
var _response$user$referr2;
|
|
1366
|
-
|
|
1367
|
-
formAutofill.value = ((_response$user$referr2 = response.user.referredBy.referredReward) == null ? void 0 : _response$user$referr2.fuelTankCode) || "";
|
|
1368
|
-
} else {
|
|
1369
|
-
_log$5(new Error("Element with id/class " + formSelector + " was not found."));
|
|
1370
|
-
}
|
|
1371
|
-
}
|
|
1372
|
-
}
|
|
1373
|
-
});
|
|
1374
|
-
}
|
|
1375
|
-
|
|
1376
|
-
if (config.engagementMedium === "EMBED") {
|
|
1377
|
-
widget = this._renderEmbedWidget(params);
|
|
1378
|
-
} else {
|
|
1379
|
-
widget = this._renderPopupWidget(params);
|
|
1380
|
-
if (displayOnLoad) widget.open();
|
|
1381
|
-
}
|
|
1382
|
-
|
|
1383
|
-
return widget;
|
|
1384
|
-
}
|
|
1385
|
-
|
|
1386
|
-
_renderPopupWidget(params) {
|
|
1387
|
-
var widget = new PopupWidget(params, params.context.trigger);
|
|
1388
|
-
widget.load();
|
|
1389
|
-
return widget;
|
|
1390
|
-
}
|
|
1391
|
-
|
|
1392
|
-
_renderEmbedWidget(params) {
|
|
1393
|
-
var widget = new EmbedWidget(params, params.context.container);
|
|
1394
|
-
widget.load();
|
|
1395
|
-
return widget;
|
|
1396
|
-
}
|
|
1397
|
-
/**
|
|
1398
|
-
* @hidden
|
|
1399
|
-
* @param {Object} error The json object containing the error details
|
|
1400
|
-
* @param {string} em The engagementMedium
|
|
1401
|
-
* @returns {void}
|
|
1402
|
-
*/
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
_renderErrorWidget(props, em) {
|
|
1406
|
-
if (em === void 0) {
|
|
1407
|
-
em = "POPUP";
|
|
1408
|
-
}
|
|
1409
|
-
|
|
1410
|
-
var {
|
|
1411
|
-
apiErrorCode,
|
|
1412
|
-
rsCode,
|
|
1413
|
-
message
|
|
1414
|
-
} = props;
|
|
1415
|
-
|
|
1416
|
-
_log$5(new Error(apiErrorCode + " (" + rsCode + ") " + message));
|
|
1417
|
-
|
|
1418
|
-
var params = {
|
|
1419
|
-
content: "error",
|
|
1420
|
-
rsCode,
|
|
1421
|
-
api: this.api,
|
|
1422
|
-
domain: this.domain,
|
|
1423
|
-
npmCdn: this.npmCdn,
|
|
1424
|
-
type: "ERROR_WIDGET",
|
|
1425
|
-
context: {
|
|
1426
|
-
type: "error"
|
|
1427
|
-
}
|
|
1428
|
-
};
|
|
1429
|
-
var widget;
|
|
1430
|
-
|
|
1431
|
-
if (em === "EMBED") {
|
|
1432
|
-
widget = new EmbedWidget(params);
|
|
1433
|
-
widget.load();
|
|
1434
|
-
} else if (em === "POPUP") {
|
|
1435
|
-
widget = new PopupWidget(params);
|
|
1436
|
-
widget.load();
|
|
1437
|
-
}
|
|
1438
|
-
}
|
|
1439
|
-
/**
|
|
1440
|
-
* @hidden
|
|
1441
|
-
* @param {string} rule A regular expression
|
|
1442
|
-
* @returns {boolean} true if rule matches Url, false otherwise
|
|
1443
|
-
*/
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
static _matchesUrl(rule) {
|
|
1447
|
-
// If there were no matches, null is returned.
|
|
1448
|
-
return window.location.href.match(new RegExp(rule)) ? true : false;
|
|
1449
|
-
}
|
|
1450
|
-
|
|
1451
|
-
}
|
|
1452
|
-
|
|
1453
|
-
/**
|
|
1454
|
-
*
|
|
1455
|
-
* The EventsApi class is a wrapper around the open endpoints of the SaaSquatch REST API.
|
|
1456
|
-
*
|
|
1457
|
-
*/
|
|
1458
|
-
|
|
1459
|
-
class EventsApi {
|
|
1460
|
-
/**
|
|
1461
|
-
* Initialize a new {@link EventsApi} instance.
|
|
1462
|
-
*
|
|
1463
|
-
* @param {ConfigOptions} config Config details
|
|
1464
|
-
*
|
|
1465
|
-
* @example <caption>Browser example</caption>
|
|
1466
|
-
* var squatchApi = new squatch.EventsApi({tenantAlias:'test_12b5bo1b25125'});
|
|
1467
|
-
*
|
|
1468
|
-
* @example <caption>Browserify/Webpack example</caption>
|
|
1469
|
-
* var EventsApi = require('@saasquatch/squatch-js').EventsApi;
|
|
1470
|
-
* var squatchApi = new EventsApi({tenantAlias:'test_12b5bo1b25125'});
|
|
1471
|
-
*
|
|
1472
|
-
* @example <caption>Babel+Browserify/Webpack example</caption>
|
|
1473
|
-
* import {EventsApi} from '@saasquatch/squatch-js';
|
|
1474
|
-
* let squatchApi = new EventsApi({tenantAlias:'test_12b5bo1b25125'});
|
|
1475
|
-
*/
|
|
1476
|
-
constructor(config) {
|
|
1477
|
-
this.tenantAlias = void 0;
|
|
1478
|
-
this.domain = void 0;
|
|
1479
|
-
var raw = config; // Flags that we need to validate anything we use from this type
|
|
1480
|
-
|
|
1481
|
-
var clean = validateConfig(raw);
|
|
1482
|
-
this.tenantAlias = clean.tenantAlias;
|
|
1483
|
-
this.domain = clean.domain;
|
|
1484
|
-
}
|
|
1485
|
-
/**
|
|
1486
|
-
* Track an event for a user
|
|
1487
|
-
*
|
|
1488
|
-
* @param params Parameters for request
|
|
1489
|
-
* @param options.jwt the JSON Web Token (JWT) that is used to authenticate the user
|
|
1490
|
-
*
|
|
1491
|
-
* @return An ID to confirm the event has been accepted for asynchronous processing
|
|
1492
|
-
*/
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
track(params, options) {
|
|
1496
|
-
var raw = params;
|
|
1497
|
-
var rawOpts = options;
|
|
1498
|
-
|
|
1499
|
-
var body = _validateEvent(raw);
|
|
1500
|
-
|
|
1501
|
-
var {
|
|
1502
|
-
jwt
|
|
1503
|
-
} = _validateTrackOptions(rawOpts);
|
|
1504
|
-
|
|
1505
|
-
var ta = encodeURIComponent(this.tenantAlias);
|
|
1506
|
-
var userId = encodeURIComponent(body.userId);
|
|
1507
|
-
var accountId = encodeURIComponent(body.accountId);
|
|
1508
|
-
var path = "/api/v1/" + ta + "/open/account/" + accountId + "/user/" + userId + "/events";
|
|
1509
|
-
var url = this.domain + path;
|
|
1510
|
-
return doPost(url, JSON.stringify(body), jwt);
|
|
1511
|
-
}
|
|
1512
|
-
|
|
1513
|
-
}
|
|
1514
|
-
|
|
1515
|
-
function _validateEvent(raw) {
|
|
1516
|
-
if (!isObject$1(raw)) throw new Error("tracking parameter must be an object");
|
|
1517
|
-
if (!(raw != null && raw["accountId"])) throw new Error("accountId field is required");
|
|
1518
|
-
if (!(raw != null && raw["events"])) throw new Error("events field is required");
|
|
1519
|
-
if (!(raw != null && raw["userId"])) throw new Error("userId field is required");
|
|
1520
|
-
var clean = raw;
|
|
1521
|
-
if (!Array.isArray(clean.events)) throw new Error("'events' should be an array");
|
|
1522
|
-
return clean;
|
|
1523
|
-
}
|
|
1524
|
-
|
|
1525
|
-
function _validateTrackOptions(raw) {
|
|
1526
|
-
if (!isObject$1(raw)) throw new Error("'options' should be an object");
|
|
1527
|
-
return raw;
|
|
1528
|
-
}
|
|
1529
|
-
|
|
1530
|
-
/** @hidden */
|
|
1531
|
-
|
|
1532
|
-
function asyncLoad() {
|
|
1533
|
-
var _window;
|
|
1534
|
-
|
|
1535
|
-
var namespace = window[IMPACT_NAMESPACE] ? IMPACT_NAMESPACE : DEFAULT_NAMESPACE;
|
|
1536
|
-
var cached = ((_window = window["_" + namespace]) == null ? void 0 : _window.ready) || [];
|
|
1537
|
-
var declarativeCache = window.impactOnReady || window.squatchOnReady;
|
|
1538
|
-
var readyFns = [...cached, declarativeCache].filter(a => !!a); // Run all of this in a setTimeout because we need to wait for the squatch module to finish loading
|
|
1539
|
-
|
|
1540
|
-
setTimeout(() => {
|
|
1541
|
-
// Exit early if module wasn't loaded onto window
|
|
1542
|
-
if (!window[DEFAULT_NAMESPACE]) return; // Set window.impact as an alias for window.squatch.
|
|
1543
|
-
|
|
1544
|
-
window[IMPACT_NAMESPACE] = window[DEFAULT_NAMESPACE]; // Run all the ready functions in a set timeout to they happen after namespace aliasing.
|
|
1545
|
-
|
|
1546
|
-
readyFns.forEach(cb => cb()); // Perform auto popup
|
|
1547
|
-
|
|
1548
|
-
window[DEFAULT_NAMESPACE]._auto(); // @ts-ignore -- intentionally deletes `_squatch` to cleanup initialization
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
window["_" + namespace] = undefined;
|
|
1552
|
-
delete window["_" + namespace];
|
|
1553
|
-
}, 0);
|
|
1554
|
-
}
|
|
1555
|
-
|
|
1556
|
-
/** @hidden */
|
|
1557
|
-
|
|
1558
|
-
var _log$4 = debug("squatch-js");
|
|
1559
|
-
|
|
1560
|
-
var isObject = item => typeof item === "object" && !Array.isArray(item);
|
|
1561
|
-
|
|
1562
|
-
var deepMerge = (target, source) => {
|
|
1563
|
-
var isDeep = prop => isObject(source[prop]) && target.hasOwnProperty(prop) && isObject(target[prop]);
|
|
1564
|
-
|
|
1565
|
-
var replaced = Object.getOwnPropertyNames(source).map(prop => ({
|
|
1566
|
-
[prop]: isDeep(prop) ? deepMerge(target[prop], source[prop]) : source[prop]
|
|
1567
|
-
})).reduce((a, b) => _extends({}, a, b), {});
|
|
1568
|
-
return _extends({}, target, replaced);
|
|
1569
|
-
}; // inspired by https://github.com/panva/jose/blob/3c4ad55c92bcd9cbc0512438819717d185c41fb2/src/util/decode_jwt.ts#L22
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
function b64decode(input) {
|
|
1573
|
-
var binary = atob(input.replace(/_/g, "/").replace(/-/g, "+"));
|
|
1574
|
-
var bytes = new Uint8Array(binary.length);
|
|
1575
|
-
|
|
1576
|
-
for (var i = 0; i < binary.length; i++) {
|
|
1577
|
-
bytes[i] = binary.charCodeAt(i);
|
|
1578
|
-
}
|
|
1579
|
-
|
|
1580
|
-
return new TextDecoder("utf8").decode(bytes);
|
|
1581
|
-
} // Suggestion from https://developer.mozilla.org/en-US/docs/Glossary/Base64#the_unicode_problem
|
|
1582
|
-
|
|
1583
|
-
function b64encode(input) {
|
|
1584
|
-
var encodedInput = new TextEncoder().encode(input);
|
|
1585
|
-
var binary = Array.from(encodedInput, byte => String.fromCodePoint(byte)).join("");
|
|
1586
|
-
return btoa(binary).replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
|
|
1587
|
-
} // https://stackoverflow.com/a/11319865
|
|
1588
|
-
|
|
1589
|
-
function getTopDomain() {
|
|
1590
|
-
var i,
|
|
1591
|
-
h,
|
|
1592
|
-
weird_cookie = "weird_get_top_level_domain=cookie",
|
|
1593
|
-
hostname = document.location.hostname.split(".");
|
|
1594
|
-
|
|
1595
|
-
for (i = hostname.length - 1; i >= 0; i--) {
|
|
1596
|
-
h = hostname.slice(i).join(".");
|
|
1597
|
-
document.cookie = weird_cookie + ";domain=." + h + ";";
|
|
1598
|
-
|
|
1599
|
-
if (document.cookie.indexOf(weird_cookie) > -1) {
|
|
1600
|
-
// We were able to store a cookie! This must be it
|
|
1601
|
-
document.cookie = weird_cookie.split("=")[0] + "=;domain=." + h + ";expires=Thu, 01 Jan 1970 00:00:01 GMT;";
|
|
1602
|
-
return h;
|
|
1603
|
-
}
|
|
1604
|
-
}
|
|
1605
|
-
}
|
|
1606
|
-
|
|
1607
|
-
function _pushCookie() {
|
|
1608
|
-
var queryString = window.location.search;
|
|
1609
|
-
var urlParams = new URLSearchParams(queryString);
|
|
1610
|
-
var refParam = urlParams.get("_saasquatch") || ""; // do nothing if no params
|
|
1611
|
-
|
|
1612
|
-
if (refParam) {
|
|
1613
|
-
var paramsJSON = "",
|
|
1614
|
-
existingCookie = "",
|
|
1615
|
-
reEncodedCookie = "";
|
|
1616
|
-
|
|
1617
|
-
try {
|
|
1618
|
-
paramsJSON = JSON.parse(b64decode(refParam));
|
|
1619
|
-
} catch (error) {
|
|
1620
|
-
_log$4("Unable to decode params", error); // don't merge invalid params
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
return;
|
|
1624
|
-
}
|
|
1625
|
-
|
|
1626
|
-
try {
|
|
1627
|
-
existingCookie = JSON.parse(b64decode(Cookies.get("_saasquatch")));
|
|
1628
|
-
|
|
1629
|
-
_log$4("existing cookie", existingCookie);
|
|
1630
|
-
} catch (error) {
|
|
1631
|
-
_log$4("Unable to retrieve cookie", error);
|
|
1632
|
-
} // don't merge if there's no existing object
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
try {
|
|
1636
|
-
var domain = getTopDomain();
|
|
1637
|
-
|
|
1638
|
-
_log$4("domain retrieved:", domain);
|
|
1639
|
-
|
|
1640
|
-
if (existingCookie) {
|
|
1641
|
-
var newCookie = deepMerge(existingCookie, paramsJSON);
|
|
1642
|
-
reEncodedCookie = b64encode(JSON.stringify(newCookie));
|
|
1643
|
-
|
|
1644
|
-
_log$4("cookie to store:", newCookie);
|
|
1645
|
-
} else {
|
|
1646
|
-
reEncodedCookie = b64encode(JSON.stringify(paramsJSON));
|
|
1647
|
-
|
|
1648
|
-
_log$4("cookie to store:", paramsJSON);
|
|
1649
|
-
}
|
|
1650
|
-
|
|
1651
|
-
Cookies.set("_saasquatch", reEncodedCookie, {
|
|
1652
|
-
expires: 365,
|
|
1653
|
-
secure: false,
|
|
1654
|
-
sameSite: "Lax",
|
|
1655
|
-
domain,
|
|
1656
|
-
path: "/"
|
|
1657
|
-
});
|
|
1658
|
-
} catch (error) {
|
|
1659
|
-
_log$4("Unable to set cookie", error);
|
|
1660
|
-
}
|
|
1661
|
-
}
|
|
1662
|
-
}
|
|
1663
|
-
|
|
1664
|
-
/** @hidden */
|
|
1665
|
-
|
|
1666
|
-
var _log$3 = debug("squatch-js");
|
|
1667
|
-
|
|
1668
|
-
function _getAutoConfig(configIn) {
|
|
1669
|
-
var queryString = window.location.search;
|
|
1670
|
-
var urlParams = new URLSearchParams(queryString);
|
|
1671
|
-
var refParam = urlParams.get("_saasquatchExtra") || "";
|
|
1672
|
-
|
|
1673
|
-
if (!refParam) {
|
|
1674
|
-
_log$3("No _saasquatchExtra param");
|
|
1675
|
-
|
|
1676
|
-
return;
|
|
1677
|
-
}
|
|
1678
|
-
|
|
1679
|
-
var raw;
|
|
1680
|
-
|
|
1681
|
-
try {
|
|
1682
|
-
raw = JSON.parse(b64decode(refParam));
|
|
1683
|
-
} catch (e) {
|
|
1684
|
-
_log$3("Unable to decode _saasquatchExtra config");
|
|
1685
|
-
|
|
1686
|
-
return;
|
|
1687
|
-
}
|
|
1688
|
-
|
|
1689
|
-
var {
|
|
1690
|
-
domain,
|
|
1691
|
-
tenantAlias,
|
|
1692
|
-
widgetConfig
|
|
1693
|
-
} = convertExtraToConfig(raw);
|
|
1694
|
-
|
|
1695
|
-
if (!domain || !tenantAlias || !widgetConfig) {
|
|
1696
|
-
_log$3("_saasquatchExtra did not have an expected structure");
|
|
1697
|
-
|
|
1698
|
-
return undefined;
|
|
1699
|
-
}
|
|
1700
|
-
|
|
1701
|
-
var {
|
|
1702
|
-
autoPopupWidgetType
|
|
1703
|
-
} = widgetConfig,
|
|
1704
|
-
rest = _objectWithoutPropertiesLoose(widgetConfig, ["autoPopupWidgetType"]);
|
|
1705
|
-
|
|
1706
|
-
return {
|
|
1707
|
-
widgetConfig: _extends({
|
|
1708
|
-
widgetType: autoPopupWidgetType,
|
|
1709
|
-
displayOnLoad: true
|
|
1710
|
-
}, rest),
|
|
1711
|
-
squatchConfig: _extends({}, configIn ? {
|
|
1712
|
-
configIn
|
|
1713
|
-
} : {}, {
|
|
1714
|
-
domain,
|
|
1715
|
-
tenantAlias
|
|
1716
|
-
})
|
|
1717
|
-
};
|
|
1718
|
-
}
|
|
1719
|
-
/**
|
|
1720
|
-
* Deconstructs _saasquatchExtra into domain, tenantAlias, and widgetConfig
|
|
1721
|
-
* @param obj {Record<string, any>} Expected to be of the form `{ [appDomain]: { [tenantAlias]: { autoPopupWidgetType: [widgetType], [rest]?: ... } } }`
|
|
1722
|
-
*/
|
|
1723
|
-
|
|
1724
|
-
function convertExtraToConfig(obj) {
|
|
1725
|
-
var _obj$_domain;
|
|
1726
|
-
|
|
1727
|
-
var _domain = Object.keys(obj || {})[0];
|
|
1728
|
-
var tenantAlias = Object.keys((obj == null ? void 0 : obj[_domain]) || {})[0];
|
|
1729
|
-
var widgetConfig = obj == null ? void 0 : (_obj$_domain = obj[_domain]) == null ? void 0 : _obj$_domain[tenantAlias]; // domain in _saasquatchExtra doesn't contain "https://"
|
|
1730
|
-
|
|
1731
|
-
var domain = _domain ? "https://" + _domain : undefined;
|
|
1732
|
-
return {
|
|
1733
|
-
domain,
|
|
1734
|
-
tenantAlias,
|
|
1735
|
-
widgetConfig
|
|
1736
|
-
};
|
|
1737
|
-
}
|
|
1738
|
-
|
|
1739
|
-
var _log$2 = debug("squatch-js:decodeUserJwt");
|
|
1740
|
-
|
|
1741
|
-
function decodeUserJwt(tokenStr) {
|
|
1742
|
-
try {
|
|
1743
|
-
var _JSON$parse;
|
|
1744
|
-
|
|
1745
|
-
var base64Url = tokenStr.split(".")[1];
|
|
1746
|
-
if (base64Url === undefined) return null;
|
|
1747
|
-
var jsonStr = b64decode(base64Url);
|
|
1748
|
-
return (_JSON$parse = JSON.parse(jsonStr)) == null ? void 0 : _JSON$parse.user;
|
|
1749
|
-
} catch (e) {
|
|
1750
|
-
_log$2(e);
|
|
1751
|
-
|
|
1752
|
-
return null;
|
|
1753
|
-
}
|
|
1754
|
-
}
|
|
1755
|
-
|
|
1756
|
-
var _log$1 = debug$1("squatch-js:DeclarativeWidget");
|
|
1757
|
-
/**
|
|
1758
|
-
* Abstract class for building web-components that render SaaSquatch widgets to the DOM
|
|
1759
|
-
* @abstract
|
|
1760
|
-
* @example
|
|
1761
|
-
* class TestWidgetElement extends DeclarativeWidget {}
|
|
1762
|
-
* const testWidget = new TestWidgetElement()
|
|
1763
|
-
* testWidget.widgetType = 'w/widget-type'
|
|
1764
|
-
* testWidget.type = 'EMBED'
|
|
1765
|
-
* testWidget.renderWidget()
|
|
1766
|
-
*/
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
class DeclarativeWidget extends HTMLElement {
|
|
1770
|
-
/**
|
|
1771
|
-
* Configuration overrides
|
|
1772
|
-
* @default window.squatchConfig
|
|
1773
|
-
*/
|
|
1774
|
-
|
|
1775
|
-
/**
|
|
1776
|
-
* Signed JWT containing user information
|
|
1777
|
-
* @default window.squatchToken
|
|
1778
|
-
*/
|
|
1779
|
-
|
|
1780
|
-
/**
|
|
1781
|
-
* Tenant alias of SaaSquatch tenant
|
|
1782
|
-
* @default window.squatchTenant
|
|
1783
|
-
*/
|
|
1784
|
-
|
|
1785
|
-
/**
|
|
1786
|
-
* widgetType of widget to load
|
|
1787
|
-
*/
|
|
1788
|
-
|
|
1789
|
-
/**
|
|
1790
|
-
* Locale to render the widget in
|
|
1791
|
-
*/
|
|
1792
|
-
|
|
1793
|
-
/**
|
|
1794
|
-
* Instance of {@link WidgetApi}
|
|
1795
|
-
*/
|
|
1796
|
-
|
|
1797
|
-
/**
|
|
1798
|
-
* Instance of {@link AnalyticsApi}
|
|
1799
|
-
*/
|
|
1800
|
-
|
|
1801
|
-
/**
|
|
1802
|
-
* Instance of {@link EmbedWidget} or {@link PopupWidget}
|
|
1803
|
-
*/
|
|
1804
|
-
|
|
1805
|
-
/**
|
|
1806
|
-
* Determines whether to render the widget as an embedding widget or popup widget
|
|
1807
|
-
*/
|
|
1808
|
-
|
|
1809
|
-
/**
|
|
1810
|
-
* Container element to contain the widget iframe
|
|
1811
|
-
* @default this
|
|
1812
|
-
*/
|
|
1813
|
-
|
|
1814
|
-
/**
|
|
1815
|
-
* Flag for if the component has been loaded or not
|
|
1816
|
-
* @hidden
|
|
1817
|
-
*/
|
|
1818
|
-
constructor() {
|
|
1819
|
-
super();
|
|
1820
|
-
this.config = void 0;
|
|
1821
|
-
this.token = void 0;
|
|
1822
|
-
this.tenant = void 0;
|
|
1823
|
-
this.widgetType = void 0;
|
|
1824
|
-
this.locale = void 0;
|
|
1825
|
-
this.widgetApi = void 0;
|
|
1826
|
-
this.analyticsApi = void 0;
|
|
1827
|
-
this.widgetInstance = void 0;
|
|
1828
|
-
this.type = void 0;
|
|
1829
|
-
this.container = void 0;
|
|
1830
|
-
this.element = void 0;
|
|
1831
|
-
this.loaded = void 0;
|
|
1832
|
-
|
|
1833
|
-
this._setWidget = (template, config) => {
|
|
1834
|
-
var _this$config;
|
|
1835
|
-
|
|
1836
|
-
var params = {
|
|
1837
|
-
api: this.widgetApi,
|
|
1838
|
-
content: template,
|
|
1839
|
-
context: {
|
|
1840
|
-
type: config.type,
|
|
1841
|
-
user: config.user,
|
|
1842
|
-
container: this.container || undefined,
|
|
1843
|
-
engagementMedium: this.type
|
|
1844
|
-
},
|
|
1845
|
-
type: this.widgetType,
|
|
1846
|
-
domain: ((_this$config = this.config) == null ? void 0 : _this$config.domain) || DEFAULT_DOMAIN,
|
|
1847
|
-
npmCdn: DEFAULT_NPM_CDN,
|
|
1848
|
-
container: this
|
|
1849
|
-
};
|
|
1850
|
-
|
|
1851
|
-
if (this.type === "EMBED") {
|
|
1852
|
-
return new EmbedWidget(params);
|
|
1853
|
-
} else {
|
|
1854
|
-
var useFirstChildTrigger = this.firstChild ? null : undefined;
|
|
1855
|
-
return new PopupWidget(params, useFirstChildTrigger);
|
|
1856
|
-
}
|
|
1857
|
-
};
|
|
1858
|
-
|
|
1859
|
-
this.setErrorWidget = e => {
|
|
1860
|
-
var _this$config2;
|
|
1861
|
-
|
|
1862
|
-
var params = {
|
|
1863
|
-
api: this.widgetApi,
|
|
1864
|
-
content: "error",
|
|
1865
|
-
context: {
|
|
1866
|
-
type: "error",
|
|
1867
|
-
container: this.container || undefined
|
|
1868
|
-
},
|
|
1869
|
-
type: "ERROR_WIDGET",
|
|
1870
|
-
domain: ((_this$config2 = this.config) == null ? void 0 : _this$config2.domain) || DEFAULT_DOMAIN,
|
|
1871
|
-
npmCdn: DEFAULT_NPM_CDN,
|
|
1872
|
-
container: this
|
|
1873
|
-
};
|
|
1874
|
-
|
|
1875
|
-
if (this.type === "EMBED") {
|
|
1876
|
-
return new EmbedWidget(params);
|
|
1877
|
-
} else {
|
|
1878
|
-
var useFirstChildTrigger = this.firstChild ? null : undefined;
|
|
1879
|
-
return new PopupWidget(params, useFirstChildTrigger);
|
|
1880
|
-
}
|
|
1881
|
-
};
|
|
1882
|
-
|
|
1883
|
-
this.reload = this.renderWidget;
|
|
1884
|
-
this.show = this.open;
|
|
1885
|
-
this.hide = this.close;
|
|
1886
|
-
this.attachShadow({
|
|
1887
|
-
mode: "open"
|
|
1888
|
-
}).innerHTML = "<style>:host { display: block; }</style><slot></slot>";
|
|
1889
|
-
this.config = getConfig();
|
|
1890
|
-
this.token = getToken();
|
|
1891
|
-
this.tenant = window.squatchTenant;
|
|
1892
|
-
this.container = this;
|
|
1893
|
-
}
|
|
1894
|
-
|
|
1895
|
-
_setupApis(config) {
|
|
1896
|
-
var _this$config3, _this$config4;
|
|
1897
|
-
|
|
1898
|
-
if (!this.tenant) throw new Error("tenantAlias not provided");
|
|
1899
|
-
this.widgetApi = new WidgetApi({
|
|
1900
|
-
tenantAlias: (config == null ? void 0 : config.tenantAlias) || this.tenant,
|
|
1901
|
-
domain: (config == null ? void 0 : config.domain) || ((_this$config3 = this.config) == null ? void 0 : _this$config3.domain) || DEFAULT_DOMAIN
|
|
1902
|
-
});
|
|
1903
|
-
this.analyticsApi = new AnalyticsApi({
|
|
1904
|
-
domain: (config == null ? void 0 : config.domain) || ((_this$config4 = this.config) == null ? void 0 : _this$config4.domain) || DEFAULT_DOMAIN
|
|
1905
|
-
});
|
|
1906
|
-
}
|
|
1907
|
-
|
|
1908
|
-
async renderPasswordlessVariant() {
|
|
1909
|
-
this._setupApis();
|
|
1910
|
-
|
|
1911
|
-
_log$1("Rendering as an Instant Access widget");
|
|
1912
|
-
|
|
1913
|
-
return await this.widgetApi.render({
|
|
1914
|
-
engagementMedium: this.type,
|
|
1915
|
-
widgetType: this.widgetType,
|
|
1916
|
-
locale: this.locale
|
|
1917
|
-
}).then(res => this._setWidget(res.template, {
|
|
1918
|
-
type: "passwordless"
|
|
1919
|
-
})).catch(this.setErrorWidget);
|
|
1920
|
-
}
|
|
1921
|
-
|
|
1922
|
-
async renderUserUpsertVariant() {
|
|
1923
|
-
this._setupApis();
|
|
1924
|
-
|
|
1925
|
-
var userObj = decodeUserJwt(this.token);
|
|
1926
|
-
|
|
1927
|
-
if (!userObj) {
|
|
1928
|
-
return this.setErrorWidget(Error("No user object in token."));
|
|
1929
|
-
}
|
|
1930
|
-
|
|
1931
|
-
_log$1("Rendering as a Verified widget");
|
|
1932
|
-
|
|
1933
|
-
var widgetInstance = await this.widgetApi.upsertUser({
|
|
1934
|
-
user: userObj,
|
|
1935
|
-
locale: this.locale,
|
|
1936
|
-
engagementMedium: this.type,
|
|
1937
|
-
widgetType: this.widgetType,
|
|
1938
|
-
jwt: this.token
|
|
1939
|
-
}).then(res => this._setWidget(res.template, {
|
|
1940
|
-
type: "upsert",
|
|
1941
|
-
user: userObj
|
|
1942
|
-
})).catch(this.setErrorWidget);
|
|
1943
|
-
return widgetInstance;
|
|
1944
|
-
}
|
|
1945
|
-
|
|
1946
|
-
/**
|
|
1947
|
-
* Fetches widget content from SaaSquatch and builds a Widget instance to support rendering the widget in the DOM
|
|
1948
|
-
* @returns Instance of either {@link EmbedWidget} or {@link PopupWidget} depending on `this.type`
|
|
1949
|
-
* @throws Throws an Error if `widgetType` is undefined
|
|
1950
|
-
*/
|
|
1951
|
-
async getWidgetInstance() {
|
|
1952
|
-
var widgetInstance;
|
|
1953
|
-
this.widgetType = this.getAttribute("widget") || undefined;
|
|
1954
|
-
this.locale = this.getAttribute("locale") || this.locale;
|
|
1955
|
-
if (!this.widgetType) throw new Error("No widget has been specified");
|
|
1956
|
-
|
|
1957
|
-
if (!this.token) {
|
|
1958
|
-
widgetInstance = await this.renderPasswordlessVariant();
|
|
1959
|
-
} else {
|
|
1960
|
-
widgetInstance = await this.renderUserUpsertVariant();
|
|
1961
|
-
}
|
|
1962
|
-
|
|
1963
|
-
this.widgetInstance = widgetInstance;
|
|
1964
|
-
if (this.widgetInstance) this.dispatchEvent(new CustomEvent("sq:widget-loaded"));
|
|
1965
|
-
return widgetInstance;
|
|
1966
|
-
}
|
|
1967
|
-
/**
|
|
1968
|
-
* Calls {@link getWidgetInstance} to build the Widget instance and loads the widget iframe into the DOM
|
|
1969
|
-
*/
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
async renderWidget() {
|
|
1973
|
-
await this.getWidgetInstance();
|
|
1974
|
-
await this.widgetInstance.load();
|
|
1975
|
-
}
|
|
1976
|
-
/**
|
|
1977
|
-
* Builds a Widget instance for the default error widget
|
|
1978
|
-
* @returns Instance of either {@link EmbedWidget} or {@link PopupWidget} depending on `this.type`
|
|
1979
|
-
*/
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
/**
|
|
1983
|
-
* Calls `open` method of `widgetInstance`
|
|
1984
|
-
* @throws Throws an Error if called before the widget has loaded
|
|
1985
|
-
*/
|
|
1986
|
-
open() {
|
|
1987
|
-
if (!this.widgetInstance) throw new Error("Widget has not loaded yet");
|
|
1988
|
-
this.widgetInstance.open();
|
|
1989
|
-
}
|
|
1990
|
-
/**
|
|
1991
|
-
* Calls `close` method of `widgetInstance`
|
|
1992
|
-
* @throws Throws an Error if called before the widget has loaded
|
|
1993
|
-
*/
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
close() {
|
|
1997
|
-
if (!this.widgetInstance) throw new Error("Widget has not loaded yet");
|
|
1998
|
-
this.widgetInstance.close();
|
|
1999
|
-
}
|
|
2000
|
-
|
|
2001
|
-
}
|
|
2002
|
-
|
|
2003
|
-
/**
|
|
2004
|
-
* Base class for `squatch-embed` web-component
|
|
2005
|
-
* @extends {DeclarativeWidget}
|
|
2006
|
-
* @class
|
|
2007
|
-
* @example
|
|
2008
|
-
* window.createCustomElement('squatch-embed', DeclarativeEmbedWidget)
|
|
2009
|
-
* const widget = document.querySelector('squatch-embed') as DeclarativeEmbedWidget
|
|
2010
|
-
* widget.open()
|
|
2011
|
-
* widget.close()
|
|
2012
|
-
* widget.reload()
|
|
2013
|
-
*/
|
|
2014
|
-
|
|
2015
|
-
class DeclarativeEmbedWidget extends DeclarativeWidget {
|
|
2016
|
-
constructor() {
|
|
2017
|
-
super();
|
|
2018
|
-
/**
|
|
2019
|
-
* @static
|
|
2020
|
-
*/
|
|
2021
|
-
|
|
2022
|
-
this.type = "EMBED";
|
|
2023
|
-
this.loaded = false;
|
|
2024
|
-
}
|
|
2025
|
-
|
|
2026
|
-
static get observedAttributes() {
|
|
2027
|
-
return ["widget", "locale"];
|
|
2028
|
-
}
|
|
2029
|
-
|
|
2030
|
-
attributeChangedCallback(attr, oldVal, newVal) {
|
|
2031
|
-
if (oldVal === newVal || !this.loaded) return; // nothing to do
|
|
2032
|
-
|
|
2033
|
-
switch (attr) {
|
|
2034
|
-
case "locale":
|
|
2035
|
-
case "widget":
|
|
2036
|
-
this.connectedCallback();
|
|
2037
|
-
break;
|
|
2038
|
-
}
|
|
2039
|
-
}
|
|
2040
|
-
|
|
2041
|
-
async connectedCallback() {
|
|
2042
|
-
var _ref, _this$shadowRoot;
|
|
2043
|
-
|
|
2044
|
-
this.loaded = true;
|
|
2045
|
-
this.container = this.getAttribute("container");
|
|
2046
|
-
await this.renderWidget();
|
|
2047
|
-
var slot = (_ref = this.shadowRoot && Array.from(this.shadowRoot.children)) == null ? void 0 : _ref.find(c => c.tagName === "SLOT");
|
|
2048
|
-
if (slot) (_this$shadowRoot = this.shadowRoot) == null ? void 0 : _this$shadowRoot.removeChild(slot);
|
|
2049
|
-
if (this.getAttribute("open") !== null) this.open();
|
|
2050
|
-
}
|
|
2051
|
-
|
|
2052
|
-
}
|
|
2053
|
-
/**
|
|
2054
|
-
* Base class for `squatch-popup` web-component
|
|
2055
|
-
* @extends {DeclarativeWidget}
|
|
2056
|
-
* @class
|
|
2057
|
-
* @example
|
|
2058
|
-
* window.createCustomElement('squatch-popup', DeclarativePopupWidget)
|
|
2059
|
-
* const widget = document.querySelector('squatch-popup') as DeclarativePopupWidget
|
|
2060
|
-
* widget.open()
|
|
2061
|
-
* widget.close()
|
|
2062
|
-
* widget.reload()
|
|
2063
|
-
*/
|
|
2064
|
-
|
|
2065
|
-
class DeclarativePopupWidget extends DeclarativeWidget {
|
|
2066
|
-
constructor() {
|
|
2067
|
-
super();
|
|
2068
|
-
/**
|
|
2069
|
-
* @static
|
|
2070
|
-
*/
|
|
2071
|
-
|
|
2072
|
-
this.type = "POPUP";
|
|
2073
|
-
this.loaded = false;
|
|
2074
|
-
this.addEventListener("click", e => {
|
|
2075
|
-
e.stopPropagation();
|
|
2076
|
-
this.open();
|
|
2077
|
-
});
|
|
2078
|
-
}
|
|
2079
|
-
|
|
2080
|
-
static get observedAttributes() {
|
|
2081
|
-
return ["widget", "locale"];
|
|
2082
|
-
}
|
|
2083
|
-
|
|
2084
|
-
attributeChangedCallback(attr, oldVal, newVal) {
|
|
2085
|
-
if (oldVal === newVal || !this.loaded) return; // nothing to do
|
|
2086
|
-
|
|
2087
|
-
switch (attr) {
|
|
2088
|
-
case "locale":
|
|
2089
|
-
case "widget":
|
|
2090
|
-
this.connectedCallback();
|
|
2091
|
-
break;
|
|
2092
|
-
}
|
|
2093
|
-
}
|
|
2094
|
-
|
|
2095
|
-
async connectedCallback() {
|
|
2096
|
-
this.loaded = true;
|
|
2097
|
-
this.container = this.getAttribute("container");
|
|
2098
|
-
await this.renderWidget();
|
|
2099
|
-
if (this.getAttribute("open") !== null) this.open();
|
|
2100
|
-
}
|
|
2101
|
-
|
|
2102
|
-
}
|
|
2103
|
-
|
|
2104
|
-
class SquatchEmbed extends DeclarativeEmbedWidget {}
|
|
2105
|
-
|
|
2106
|
-
class SquatchPopup extends DeclarativePopupWidget {}
|
|
2107
|
-
|
|
2108
|
-
class ImpactEmbed extends DeclarativeEmbedWidget {}
|
|
2109
|
-
|
|
2110
|
-
class ImpactPopup extends DeclarativePopupWidget {}
|
|
2111
|
-
|
|
2112
|
-
if (!window.customElements.get("squatch-embed")) window.customElements.define("squatch-embed", SquatchEmbed);
|
|
2113
|
-
if (!window.customElements.get("impact-embed")) window.customElements.define("impact-embed", ImpactEmbed);
|
|
2114
|
-
if (!window.customElements.get("squatch-popup")) window.customElements.define("squatch-popup", SquatchPopup);
|
|
2115
|
-
if (!window.customElements.get("impact-popup")) window.customElements.define("impact-popup", ImpactPopup);
|
|
2116
|
-
|
|
2117
|
-
// @ts-check
|
|
2118
|
-
function help() {
|
|
2119
|
-
console.log("Having trouble using Squatch.js? Go to https://docs.referralsaasquatch.com/developer/ for tutorials, references and error codes.");
|
|
2120
|
-
}
|
|
2121
|
-
|
|
2122
|
-
var _window$squatch;
|
|
2123
|
-
// debug.disable("squatch-js*");
|
|
2124
|
-
|
|
2125
|
-
/** @hidden */
|
|
2126
|
-
|
|
2127
|
-
var _log = debug("squatch-js");
|
|
2128
|
-
/** @hidden */
|
|
2129
|
-
|
|
2130
|
-
var _api = null;
|
|
2131
|
-
/** @hidden */
|
|
2132
|
-
|
|
2133
|
-
var _widgets = null;
|
|
2134
|
-
/** @hidden */
|
|
2135
|
-
|
|
2136
|
-
var _events = null;
|
|
2137
|
-
/**
|
|
2138
|
-
* A static instance of the {@link WidgetApi} created when you call {@link #init init}.
|
|
2139
|
-
*
|
|
2140
|
-
* Read the {@link WidgetApi} docs.
|
|
2141
|
-
*
|
|
2142
|
-
* @returns WidgetApi static instance
|
|
2143
|
-
* @example
|
|
2144
|
-
* squatch.api().render({ ... })
|
|
2145
|
-
* squatch.api().upsertUser({ ... })
|
|
2146
|
-
* squatch.api().squatchReferralCookie()
|
|
2147
|
-
*/
|
|
2148
|
-
|
|
2149
|
-
function api() {
|
|
2150
|
-
if (!_api) init({});
|
|
2151
|
-
return _api;
|
|
2152
|
-
}
|
|
2153
|
-
/**
|
|
2154
|
-
* A static instance of the {@link Widgets} created when you call {@link #init init}.
|
|
2155
|
-
*
|
|
2156
|
-
* Read the {@link Widgets} docs.
|
|
2157
|
-
*
|
|
2158
|
-
* @returns static instance
|
|
2159
|
-
* @example
|
|
2160
|
-
* squatch.widgets().render({ widgetType: "w/widget-type" })
|
|
2161
|
-
* squatch.widgets().upsertUser({ user: { ... }, widgetType: "w/widget-type" })
|
|
2162
|
-
* squatch.widgets().autofill(".referral-code")
|
|
2163
|
-
*/
|
|
2164
|
-
|
|
2165
|
-
function widgets() {
|
|
2166
|
-
if (!_widgets) init({});
|
|
2167
|
-
return _widgets;
|
|
2168
|
-
}
|
|
2169
|
-
/**
|
|
2170
|
-
* A static instance of the {@link EventsApi} created when you call {@link #init init}.
|
|
2171
|
-
*
|
|
2172
|
-
* Read the {@link EventsApi} docs.
|
|
2173
|
-
*
|
|
2174
|
-
* @returns EventsApi static instance
|
|
2175
|
-
*
|
|
2176
|
-
* @example
|
|
2177
|
-
* squatch.events().track({ ... })
|
|
2178
|
-
*/
|
|
2179
|
-
|
|
2180
|
-
function events() {
|
|
2181
|
-
if (!_events) init({});
|
|
2182
|
-
return _events;
|
|
2183
|
-
}
|
|
2184
|
-
/**
|
|
2185
|
-
* Entry-point for high level API to render a widget using the instance of {@link Widgets} created when you call {@link #init init}.
|
|
2186
|
-
*
|
|
2187
|
-
* Read the {@link Widgets.render} docs.
|
|
2188
|
-
*
|
|
2189
|
-
* @example
|
|
2190
|
-
* squatch.widget().then(res => {
|
|
2191
|
-
* const widget = res.widget
|
|
2192
|
-
* }).catch(e => console.error("Did not render widget:", e))
|
|
2193
|
-
*/
|
|
2194
|
-
|
|
2195
|
-
function widget(widgetConfig) {
|
|
2196
|
-
var _widgets2;
|
|
2197
|
-
|
|
2198
|
-
return (_widgets2 = widgets()) == null ? void 0 : _widgets2.render(widgetConfig);
|
|
2199
|
-
}
|
|
2200
|
-
/**
|
|
2201
|
-
* Extracts widget configuration from `_saasquatchExtra` UTM parameter. Initialises `squatch` and renders the widget as a {@link PopupWidget} via static instanct of {@link Widgets}.
|
|
2202
|
-
*
|
|
2203
|
-
* Called by default on startup via the loader script.
|
|
2204
|
-
* @private
|
|
2205
|
-
*/
|
|
2206
|
-
|
|
2207
|
-
function _auto(configIn) {
|
|
2208
|
-
var configs = _getAutoConfig(configIn);
|
|
2209
|
-
|
|
2210
|
-
if (configs) {
|
|
2211
|
-
var _widgets3;
|
|
2212
|
-
|
|
2213
|
-
var {
|
|
2214
|
-
squatchConfig,
|
|
2215
|
-
widgetConfig
|
|
2216
|
-
} = configs;
|
|
2217
|
-
init(squatchConfig);
|
|
2218
|
-
return (_widgets3 = widgets()) == null ? void 0 : _widgets3.render(widgetConfig);
|
|
2219
|
-
}
|
|
2220
|
-
}
|
|
2221
|
-
/**
|
|
2222
|
-
* Initializes the static `squatch` global. This sets up:
|
|
2223
|
-
*
|
|
2224
|
-
* - `squatch.api()` a static instance of the {@link WidgetApi}
|
|
2225
|
-
* - `squatch.widgets()` a static instance of {@link Widgets}
|
|
2226
|
-
* - `squatch.events()` a static instance of {@link EventsApi}
|
|
2227
|
-
*
|
|
2228
|
-
* @param config Configuration details
|
|
2229
|
-
*
|
|
2230
|
-
* @example
|
|
2231
|
-
* squatch.init({
|
|
2232
|
-
* tenantAlias:'test_basbtabstq51v',
|
|
2233
|
-
* });
|
|
2234
|
-
*/
|
|
2235
|
-
|
|
2236
|
-
function init(configIn) {
|
|
2237
|
-
var raw = configIn;
|
|
2238
|
-
var config = validateConfig(raw);
|
|
2239
|
-
|
|
2240
|
-
if (config.tenantAlias.match("^test") || config.debug) {
|
|
2241
|
-
debug.enable("squatch-js*");
|
|
2242
|
-
} else {
|
|
2243
|
-
debug.disable();
|
|
2244
|
-
}
|
|
2245
|
-
|
|
2246
|
-
_log("initializing ...");
|
|
2247
|
-
|
|
2248
|
-
_api = new WidgetApi(config);
|
|
2249
|
-
_widgets = new Widgets(config);
|
|
2250
|
-
_events = new EventsApi(config);
|
|
2251
|
-
|
|
2252
|
-
_log("Widget API instance", _api);
|
|
2253
|
-
|
|
2254
|
-
_log("Widgets instance", _widgets);
|
|
2255
|
-
|
|
2256
|
-
_log("Events API instance", _events);
|
|
2257
|
-
}
|
|
2258
|
-
/**
|
|
2259
|
-
* Squatch.js can't start safely making operations until it's "ready". This
|
|
2260
|
-
* function detects that state.
|
|
2261
|
-
*
|
|
2262
|
-
* @param fn A callback once Squatch.js is ready.
|
|
2263
|
-
*
|
|
2264
|
-
* @example
|
|
2265
|
-
* squatch.ready(function() {
|
|
2266
|
-
* console.log("ready!");
|
|
2267
|
-
* squatch.api().upsertUser({ ... });
|
|
2268
|
-
* });
|
|
2269
|
-
*/
|
|
2270
|
-
|
|
2271
|
-
function ready(fn) {
|
|
2272
|
-
fn();
|
|
2273
|
-
}
|
|
2274
|
-
/**
|
|
2275
|
-
* Autofills a referral code into an element when someone has been referred.
|
|
2276
|
-
* Uses {@link WidgetApi.squatchReferralCookie} behind the scenes.
|
|
2277
|
-
*
|
|
2278
|
-
* @param {string} selector Element class/id
|
|
2279
|
-
* @returns {void}
|
|
2280
|
-
*
|
|
2281
|
-
* @example
|
|
2282
|
-
* squatch.autofill("input.referral-code")
|
|
2283
|
-
* squatch.autofill("input#referral-code")
|
|
2284
|
-
*/
|
|
2285
|
-
|
|
2286
|
-
function autofill(selector) {
|
|
2287
|
-
// @ts-ignore -- will throw occasionally throw a null pointer exception at runtime
|
|
2288
|
-
widgets().autofill(selector);
|
|
2289
|
-
}
|
|
2290
|
-
/**
|
|
2291
|
-
* Manually set the _saasquatch cookie as a 1st party cookie if available as a URL parameter on the current page.
|
|
2292
|
-
* This runs automatically immediately when squatch-js is loaded, except when window.SaaSquatchDoNotAutoDrop is true.
|
|
2293
|
-
* Use this function manually if you have a single page application or custom routing that causes the `_saasquatch` URL parameter to not be set when Squatch.js loads.
|
|
2294
|
-
|
|
2295
|
-
* It is safe to run this function multiple times. If the `_saasquatch` URL parameter is invalid or missing it will not clear the 1st party cookie.
|
|
2296
|
-
|
|
2297
|
-
*
|
|
2298
|
-
* @returns {void}
|
|
2299
|
-
*
|
|
2300
|
-
* @example
|
|
2301
|
-
* squatch.pushCookie();
|
|
2302
|
-
*/
|
|
2303
|
-
|
|
2304
|
-
function pushCookie() {
|
|
2305
|
-
_pushCookie();
|
|
2306
|
-
}
|
|
2307
|
-
|
|
2308
|
-
if (typeof document !== "undefined" && !window.SaaSquatchDoNotAutoDrop) {
|
|
2309
|
-
pushCookie();
|
|
2310
|
-
} // Show message if squatchjs has already been loaded on the page
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
if ((_window$squatch = window["squatch"]) != null && _window$squatch.init) _log("Squatchjs is being loaded more than once. This may lead to multiple load events being sent, duplicated widgets, and inaccurate analytics.");
|
|
2314
|
-
if (typeof document !== "undefined") asyncLoad();
|
|
2315
|
-
|
|
2316
|
-
export { DeclarativeEmbedWidget, DeclarativePopupWidget, EmbedWidget, PopupWidget, WidgetApi, Widgets, _auto, api, autofill, events, help, init, pushCookie, ready, widget, widgets };
|
|
2317
|
-
//# sourceMappingURL=squatch.esm.js.map
|