@salesforce/pwa-kit-create-app 3.3.0-preview.0 → 3.3.0

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.
@@ -1,4 +1,4 @@
1
1
  build
2
2
  coverage
3
3
  docs
4
- app/overrides/static
4
+ overrides/app/static
@@ -0,0 +1,475 @@
1
+ // Enhance the dw.ac namespace
2
+ (function(dw) {
3
+ if (typeof dw.ac === "undefined") {
4
+ return; // don't do anything if there was no <isactivedatahead> tag, that would create the ac namespace.
5
+ }
6
+ // Returns the value of the first cookie found whose name is accepted by the given function
7
+ function getCookieValue(/*function(x)*/ acceptFunction) {
8
+ var cookiePairs = document.cookie.split(';');
9
+ for (var i = 0; i < cookiePairs.length; i++)
10
+ {
11
+ var index = cookiePairs[i].indexOf('=');
12
+ if (index != -1) {
13
+ var name = trim(cookiePairs[i].substring(0, index));
14
+ if (acceptFunction(name)) {
15
+ return trim(unescape(cookiePairs[i].substring(index + 1)));
16
+ }
17
+ }
18
+ }
19
+
20
+ return null;
21
+ };
22
+
23
+ // trims a string, replacing the jquery.trim
24
+ function trim(/*string*/value) {
25
+ return value.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
26
+ };
27
+
28
+ // Sets a cookie with the given name and value
29
+ function setCookieValue(/*string*/ name, /*string*/ value, /*integer*/ millisToExpiry) {
30
+ var cookie = name + '=' + escape(value) + ';path=/';
31
+ if (millisToExpiry != -1) {
32
+ cookie += ";expires=" + expires.toGMTString();
33
+ }
34
+ document.cookie = cookie;
35
+ };
36
+
37
+ // URL encodes the given string to match the Java URLEncoder class
38
+ function urlencode(/*string*/ value) {
39
+ var convertByte = function(code) {
40
+ if(code < 32) {
41
+ //numbers lower than 32 are control chars, not printable
42
+ return '';
43
+ } else {
44
+ return '%' + new Number(code).toString(16).toUpperCase();
45
+ }
46
+ };
47
+
48
+ var encoded = '';
49
+ for (var i = 0; i < value.length; i++) {
50
+ var c = value.charCodeAt(i);
51
+ if (((c >= 97) && (c <= 122)) || ((c >= 65) && (c <= 90)) || ((c >= 48) && (c <= 57)) || (c == 46) || (c == 45) || (c == 42) || (c == 95)) {
52
+ encoded += value.charAt(i); // a-z A-z 0-9 . - * _
53
+ }
54
+ else if (c == 32) {
55
+ encoded += '+'; // (space)
56
+ }
57
+ else if (c < 128) {
58
+ encoded += convertByte(c);
59
+ }
60
+ else if ((c >= 128) && (c < 2048)) {
61
+ encoded += convertByte((c >> 6) | 0xC0);
62
+ encoded += convertByte((c & 0x3F) | 0x80);
63
+ }
64
+ else if ((c >= 2048) && (c < 65536)) {
65
+ encoded += convertByte((c >> 12) | 0xE0);
66
+ encoded += convertByte(((c >> 6) & 0x3F) | 0x80);
67
+ encoded += convertByte((c & 0x3F) | 0x80);
68
+ }
69
+ else if (c >= 65536) {
70
+ encoded += convertByte((c >> 18) | 0xF0);
71
+ encoded += convertByte(((c >> 12) & 0x3F) | 0x80);
72
+ encoded += convertByte(((c >> 6) & 0x3F) | 0x80);
73
+ encoded += convertByte((c & 0x3F) | 0x80);
74
+ }
75
+ }
76
+
77
+ return encoded;
78
+ }
79
+
80
+ // Returns the value of the analytics cookie set on the server
81
+ function getAnalyticsCookieValue() {
82
+ var acceptFunction = function(name) {
83
+ return (name.length > 5) && (name.substring(0, 5) === 'dwac_');
84
+ };
85
+ return getCookieValue(acceptFunction);
86
+ };
87
+
88
+ // Contextual information retrieved from the server
89
+ var analyticsContext = (function() {
90
+ if (dw.ac._analytics_enabled === "false") {
91
+ return {
92
+ enabled: false,
93
+ dwEnabled: false
94
+ };
95
+ }
96
+ var cookieValue = getAnalyticsCookieValue();
97
+ if (cookieValue == null) {
98
+ return {
99
+ visitorID: '__ANNONYMOUS__',
100
+ customer: '__ANNONYMOUS__',
101
+ siteCurrency: '',
102
+ sourceCode: '',
103
+ enabled: "true",
104
+ timeZone: dw.ac._timeZone,
105
+ dwEnabled: "true",
106
+ encoding: 'ISO-8859-1'
107
+ };
108
+ }
109
+
110
+ var tokens = cookieValue.split('|');
111
+
112
+ return {
113
+ visitorID: tokens[0],
114
+ repository: tokens[1],
115
+ customer: tokens[2],
116
+ sourceCode: tokens[3],
117
+ siteCurrency: tokens[4],
118
+ enabled: tokens[5] == "true",
119
+ timeZone: tokens[6],
120
+ dwEnabled: tokens[7] == "true",
121
+ encoding: 'ISO-8859-1'
122
+ };
123
+ }());
124
+
125
+ // Turn debugging on or off
126
+ var setDebugEnabled = function(enabled) {
127
+ if (typeof enabled != 'boolean') {
128
+ return;
129
+ }
130
+
131
+ setCookieValue('dwacdebug', '' + enabled, -1);
132
+ };
133
+
134
+ // Returns true if debug is enabled, false otherwise
135
+ function isDebugEnabled() {
136
+ var acceptFunction = function(name) {
137
+ return name === 'dwacdebug';
138
+ };
139
+ return getCookieValue(acceptFunction) === 'true';
140
+ };
141
+
142
+ // Map data structure
143
+ function Map() {
144
+ var data = [];
145
+
146
+ // Returns an array containing the entries in this map
147
+ this.getEntries = function() {
148
+ return data;
149
+ };
150
+
151
+ // Puts the given value in this map under the given key
152
+ this.put = function(/*object*/ key, /*object*/ value) {
153
+ for (var i = 0; i < data.length; i++) {
154
+ if (data[i].key == key) {
155
+ data[i].value = value;
156
+ return;
157
+ }
158
+ }
159
+
160
+ data.push({key: key, value: value});
161
+ };
162
+
163
+ // Puts all the key value pairs in the given map into this map
164
+ this.putAll = function(/*Map*/ map) {
165
+ var entries = map.getEntries();
166
+ for (var i = 0; i < entries.length; i++) {
167
+ this.put(entries[i].key, entries[i].value);
168
+ }
169
+ };
170
+
171
+ // Returns the value in this map under the given key, or null if there is no such value
172
+ this.get = function(/*object*/ key) {
173
+ for (var i = 0; i < data.length; i++) {
174
+ if (data[i].key == key) {
175
+ return data[i].value;
176
+ }
177
+ }
178
+
179
+ return null;
180
+ };
181
+
182
+ // Clears this map of entries
183
+ this.clear = function() {
184
+ data.length = 0;
185
+ };
186
+
187
+ // Returns if this map is empty of values
188
+ this.isEmpty = function() {
189
+ return data.length == 0;
190
+ }
191
+ };
192
+
193
+ // Delay in milliseconds before actually submitting data once some is ready
194
+ var SUBMIT_DELAY_MILLIS = 500;
195
+
196
+ // Set when the DOM is ready
197
+ var domReady = false;
198
+
199
+ // Timeout to submit data after a delay
200
+ var submitTimeout = null;
201
+
202
+ // Product impressions found on the page
203
+ var productImpressions = new Map();
204
+
205
+ // Product views found on the page
206
+ var productViews = new Map();
207
+
208
+ // Product recommendations found on the page
209
+ var productRecommendations = new Map();
210
+
211
+ // Applies values from the given source for fields defined in the given target
212
+ function applyFields(/*object*/ source, /*object*/ target) {
213
+ for (e in target) {
214
+ if (typeof source[e] != 'undefined') {
215
+ target[e] = source[e];
216
+ }
217
+ }
218
+ return target;
219
+ };
220
+
221
+ // Collects the given product impression, and returns true if it is valid or false if it is not
222
+ var collectProductImpression = function(/*object*/ configs) {
223
+ if (typeof configs != 'object') {
224
+ return false;
225
+ }
226
+
227
+ var pi = applyFields(configs, {id:null});
228
+
229
+ // Quit if no SKU provided or is invalid
230
+ if (typeof pi.id != 'string') {
231
+ return false;
232
+ }
233
+
234
+ // Throw out the impression if SKU already seen
235
+ var previousImpression = productImpressions.get(pi.id);
236
+ if (previousImpression != null) {
237
+ return false;
238
+ }
239
+
240
+ productImpressions.put(pi.id, pi);
241
+ return true;
242
+ };
243
+
244
+ // Collects the given product recommendation, and returns true if it is valid or false if it is not
245
+ var collectProductRecommendation = function(/*object*/ configs) {
246
+ if (typeof configs != 'object') {
247
+ return false;
248
+ }
249
+
250
+ var pr = applyFields(configs, {id:null});
251
+
252
+ // Quit if no SKU provided or is invalid
253
+ if (typeof pr.id != 'string') {
254
+ return false;
255
+ }
256
+
257
+ // Throw out the recommendation if SKU already seen
258
+ var previousRecommendation = productRecommendations.get(pr.id);
259
+ if (previousRecommendation != null) {
260
+ return false;
261
+ }
262
+
263
+ productRecommendations.put(pr.id, pr);
264
+ return true;
265
+ };
266
+
267
+ // Collects the given product view, and returns true if it is valid or false if it is not
268
+ var collectProductView = function(/*object*/ configs) {
269
+ if (typeof configs != 'object') {
270
+ return false;
271
+ }
272
+
273
+ var pv = applyFields(configs, {id:null});
274
+
275
+ // Quit if no SKU provided or is invalid
276
+ if (typeof pv.id != 'string') {
277
+ return false;
278
+ }
279
+
280
+ // Throw out the view if SKU already seen
281
+ var previousView = productViews.get(pv.id);
282
+ if (previousView != null) {
283
+ return false;
284
+ }
285
+
286
+ productViews.put(pv.id, pv);
287
+ return true;
288
+ };
289
+
290
+ // Returns a new Map with the same contents as the given Map,
291
+ // clearing the given Map in the process
292
+ function copyAndClearMap(/*Map*/ map) {
293
+ var copy = new Map();
294
+ copy.putAll(map);
295
+ map.clear();
296
+ return copy;
297
+ }
298
+
299
+ // Returns if there are collected data to submit
300
+ function containsProductDataToSubmit() {
301
+ return !productImpressions.isEmpty() || !productRecommendations.isEmpty()
302
+ || !productViews.isEmpty();
303
+ }
304
+
305
+ // Performs the actual submission of collected data for analytics processing
306
+ var performDataSubmission = function() {
307
+
308
+ if (dw.ac._analytics != null)
309
+ {
310
+ var collectedData = {
311
+ pageInfo: dw.ac._category,
312
+ productImpressions: productImpressions,
313
+ productViews: productViews,
314
+ productRecommendations: productRecommendations,
315
+ debugEnabled: isDebugEnabled()
316
+ };
317
+ dw.ac._analytics.trackPageViewWithProducts(analyticsContext, collectedData, null);
318
+ productImpressions.clear();
319
+ productViews.clear();
320
+ productRecommendations.clear();
321
+ dw.ac._events.length = 0;
322
+ }
323
+ };
324
+
325
+ // Submits the collected data for analytics processing after a short delay
326
+ function submitCollectedData() {
327
+ // don't submit the data before dom is ready, the data is still collected,
328
+ // when dom is ready, the onDocumentReady method will call this method again.
329
+ if(!domReady) {
330
+ return;
331
+ }
332
+
333
+ if (submitTimeout) {
334
+ clearTimeout(submitTimeout);
335
+ }
336
+
337
+ submitTimeout = setTimeout(performDataSubmission, SUBMIT_DELAY_MILLIS);
338
+ }
339
+
340
+ // Returns an object with the same properties as the given object, but with string type properties
341
+ // in the given array of names set to the URL encoded form of their values using the escape function
342
+ function escapeProperties(/*object*/ o, /*Array*/ props) {
343
+ if (typeof o == 'undefined') {
344
+ return;
345
+ }
346
+
347
+ var copy = {};
348
+ for (e in o) {
349
+ var escapeProp = false;
350
+ for (var i = 0; (i < props.length) && !escapeProp; i++) {
351
+ var prop = props[i];
352
+ if ((e === prop) && (typeof o[prop] == 'string')) {
353
+ escapeProp = true;
354
+ }
355
+ }
356
+
357
+ copy[e] = escapeProp ? urlencode(o[e]) : o[e];
358
+ }
359
+
360
+ return copy;
361
+ }
362
+
363
+ // Captures the given object data collected in subsequent events on the page,
364
+ // and returns true if the given object data is valid, or returns false if not
365
+ function captureObject(/*object*/ configs) {
366
+ if (typeof configs != 'object') {
367
+ return false;
368
+ }
369
+
370
+ if ((configs.type === dw.ac.EV_PRD_SEARCHHIT) || (configs.type === dw.ac.EV_PRD_SETPRODUCT)) {
371
+ return collectProductImpression(escapeProperties(configs, ['id']));
372
+ }
373
+
374
+ if (configs.type === dw.ac.EV_PRD_DETAIL) {
375
+ return collectProductView(escapeProperties(configs, ['id']));
376
+ }
377
+
378
+ if (configs.type === dw.ac.EV_PRD_RECOMMENDATION) {
379
+ return collectProductRecommendation(escapeProperties(configs, ['id']));
380
+ }
381
+
382
+ return false;
383
+ }
384
+
385
+ // Captures the given data collected in subsequent events on the page
386
+ function captureAndSend(/*object*/ configs) {
387
+ if (typeof configs == 'undefined') {
388
+ return;
389
+ }
390
+
391
+ // Support both array and single object cases
392
+ if (typeof configs === 'object') {
393
+ if (configs instanceof Array) {
394
+ for (var i = 0; i < configs.length; i++) {
395
+ captureObject(configs[i]);
396
+ }
397
+ }
398
+ else {
399
+ if (configs[0] instanceof Object) {
400
+ captureObject(configs[0]);
401
+ }
402
+ else {
403
+ captureObject(configs);
404
+ }
405
+ }
406
+ }
407
+
408
+ // Submit captured data if appropriate
409
+ if (domReady) {
410
+ submitCollectedData();
411
+ }
412
+ };
413
+
414
+ // Enhance existing capture function with submission step
415
+ dw.ac.capture = captureAndSend;
416
+
417
+ // expose debug API
418
+ dw.ac.setDebugEnabled = setDebugEnabled;
419
+
420
+ dw.ac._handleCollectedData = function () {
421
+ domReady = false;
422
+ dw.ac._events.forEach(captureAndSend);
423
+ domReady = true;
424
+ submitCollectedData();
425
+ };
426
+
427
+ dw.ac._scheduleDataSubmission = function () {
428
+ if (dw.ac._submitTimeout) {
429
+ clearTimeout(dw.ac._submitTimeout);
430
+ }
431
+ dw.ac._submitTimeout = setTimeout(dw.ac._handleCollectedData, 500);
432
+ };
433
+
434
+ // Added specifically for PWA kit to set currency for Analytics Context
435
+ dw.ac._setSiteCurrency = function setSiteCurrency(currency) {
436
+ analyticsContext.siteCurrency = currency;
437
+ };
438
+
439
+ // replace jQuery.ready() function
440
+ (function onDocumentReady(callback) {
441
+ // Catch cases where $(document).ready() is called after the browser event has already occurred.
442
+ if (document.readyState === "complete") {
443
+ // Handle it asynchronously to allow scripts the opportunity to delay ready
444
+ setTimeout(callback, 1);
445
+ }
446
+
447
+ // Mozilla, Opera and webkit nightlies currently support this event
448
+ if (document.addEventListener) {
449
+ DOMContentLoaded = function() {
450
+ document.removeEventListener("DOMContentLoaded", DOMContentLoaded, false);
451
+ callback();
452
+ };
453
+ // Use the handy event callback
454
+ document.addEventListener("DOMContentLoaded", DOMContentLoaded, false);
455
+ // A fallback to window.onload, that will always work
456
+ window.addEventListener("load", callback, false);
457
+ // If IE event model is used
458
+ } else if (document.attachEvent) {
459
+ DOMContentLoaded = function() {
460
+ // Make sure body exists, at least, in case IE gets a little overzealous
461
+ if (document.readyState === "complete") {
462
+ document.detachEvent("onreadystatechange", DOMContentLoaded);
463
+ callback();
464
+ }
465
+ };
466
+ // ensure firing before onload, maybe late but safe also for iframes
467
+ document.attachEvent("onreadystatechange", DOMContentLoaded);
468
+
469
+ // A fallback to window.onload, that will always work
470
+ window.attachEvent("onload", callback);
471
+ }
472
+ })(function() {
473
+ dw.ac._handleCollectedData();
474
+ });
475
+ }((window.dw||{})));
@@ -0,0 +1,502 @@
1
+ /*!
2
+ * dwAnalytics - Web Analytics Tracking
3
+ * Based partially on Piwik
4
+ *
5
+ * @link http://piwik.org
6
+ * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later
7
+ */
8
+
9
+ // Create dw namespace if necessary
10
+ if (typeof dw == 'undefined') {
11
+ var dw = {};
12
+ }
13
+
14
+ if (typeof dw.__dwAnalyticsLoaded == 'undefined')
15
+ {
16
+ dw.__dwAnalyticsLoaded = true;
17
+
18
+ // DWAnalytics singleton and namespace
19
+ dw.__dwAnalytics = function () {
20
+ /************************************************************
21
+ * Private data
22
+ ************************************************************/
23
+
24
+ var MAX_URL_LENGTH = 2000;
25
+
26
+ var expireDateTime,
27
+
28
+ /* plugins */
29
+ plugins = {},
30
+
31
+ /* alias frequently used globals for added minification */
32
+ documentAlias = document,
33
+ navigatorAlias = navigator,
34
+ screenAlias = screen,
35
+ windowAlias = window,
36
+ hostnameAlias = windowAlias.location.hostname;
37
+
38
+ /************************************************************
39
+ * Private methods
40
+ ************************************************************/
41
+
42
+ /*
43
+ * Is property (or variable) defined?
44
+ */
45
+ function isDefined(property) {
46
+ return typeof property !== 'undefined';
47
+ }
48
+
49
+ /*
50
+ * DWAnalytics Tracker class
51
+ *
52
+ * trackerUrl and trackerSiteId are optional arguments to the constructor
53
+ *
54
+ * See: Tracker.setTrackerUrl() and Tracker.setSiteId()
55
+ */
56
+ function Tracker(trackerUrl, siteId) {
57
+ /************************************************************
58
+ * Private members
59
+ ************************************************************/
60
+
61
+ var // Tracker URL
62
+ configTrackerUrl = trackerUrl + '?' || '?',
63
+
64
+ // Document URL
65
+ configCustomUrl,
66
+
67
+ // Document title
68
+ configTitle = documentAlias.title,
69
+
70
+ // Client-side data collection
71
+ browserHasCookies = '0',
72
+ pageReferrer,
73
+
74
+ // Plugin, Parameter name, MIME type, detected
75
+ pluginMap = {
76
+ // document types
77
+ pdf: ['pdf', 'application/pdf', '0'],
78
+ // media players
79
+ quicktime: ['qt', 'video/quicktime', '0'],
80
+ realplayer: ['realp', 'audio/x-pn-realaudio-plugin', '0'],
81
+ wma: ['wma', 'application/x-mplayer2', '0'],
82
+ // interactive multimedia
83
+ director: ['dir', 'application/x-director', '0'],
84
+ flash: ['fla', 'application/x-shockwave-flash', '0'],
85
+ // RIA
86
+ java: ['java', 'application/x-java-vm', '0'],
87
+ gears: ['gears', 'application/x-googlegears', '0'],
88
+ silverlight: ['ag', 'application/x-silverlight', '0']
89
+ },
90
+
91
+ // Guard against installing the link tracker more than once per Tracker instance
92
+ linkTrackingInstalled = false,
93
+
94
+ /*
95
+ * encode or escape
96
+ * - encodeURIComponent added in IE5.5
97
+ */
98
+ escapeWrapper = windowAlias.encodeURIComponent || escape,
99
+
100
+ /*
101
+ * decode or unescape
102
+ * - decodeURIComponent added in IE5.5
103
+ */
104
+ unescapeWrapper = windowAlias.decodeURIComponent || unescape,
105
+
106
+ /*
107
+ * registered (user-defined) hooks
108
+ */
109
+ registeredHooks = {};
110
+
111
+ /*
112
+ * Set cookie value
113
+ */
114
+ function setCookie(cookieName, value, daysToExpire, path, domain, secure) {
115
+ var expiryDate;
116
+
117
+ if (daysToExpire) {
118
+ // time is in milliseconds
119
+ expiryDate = new Date();
120
+ // there are 1000 * 60 * 60 * 24 milliseconds in a day (i.e., 86400000 or 8.64e7)
121
+ expiryDate.setTime(expiryDate.getTime() + daysToExpire * 8.64e7);
122
+ }
123
+
124
+ documentAlias.cookie = cookieName + '=' + escapeWrapper(value) +
125
+ (daysToExpire ? ';expires=' + expiryDate.toGMTString() : '') +
126
+ ';path=' + (path ? path : '/') +
127
+ (domain ? ';domain=' + domain : '') +
128
+ (secure ? ';secure' : '');
129
+ }
130
+
131
+ /*
132
+ * Get cookie value
133
+ */
134
+ function getCookie(cookieName) {
135
+ var cookiePattern = new RegExp('(^|;)[ ]*' + cookieName + '=([^;]*)'),
136
+
137
+ cookieMatch = cookiePattern.exec(documentAlias.cookie);
138
+
139
+ return cookieMatch ? unescapeWrapper(cookieMatch[2]) : 0;
140
+ }
141
+
142
+ /*
143
+ * Send image request to DWAnalytics server using GET.
144
+ * The infamous web bug is a transparent, single pixel (1x1) image
145
+ * Async with a delay of 100ms.
146
+ */
147
+ function getImage(urls) {
148
+ dw.__timeoutCallback = function()
149
+ {
150
+ for (var i = 0; i < urls.length; i++)
151
+ {
152
+ var image = new Image(1, 1);
153
+ image.onLoad = function () {};
154
+ image.src = urls[i];
155
+ }
156
+ };
157
+ setTimeout(dw.__timeoutCallback, 100);
158
+ }
159
+
160
+ /*
161
+ * Browser plugin tests
162
+ */
163
+ function detectBrowserPlugins() {
164
+ var i, mimeType;
165
+
166
+ // Safari and Opera
167
+ // IE6: typeof navigator.javaEnabled == 'unknown'
168
+ if (typeof navigatorAlias.javaEnabled !== 'undefined' && navigatorAlias.javaEnabled()) {
169
+ pluginMap.java[2] = '1';
170
+ }
171
+
172
+ // Firefox
173
+ if (typeof windowAlias.GearsFactory === 'function') {
174
+ pluginMap.gears[2] = '1';
175
+ }
176
+
177
+ if (navigatorAlias.mimeTypes && navigatorAlias.mimeTypes.length) {
178
+ for (i in pluginMap) {
179
+ mimeType = navigatorAlias.mimeTypes[pluginMap[i][1]];
180
+ if (mimeType && mimeType.enabledPlugin) {
181
+ pluginMap[i][2] = '1';
182
+ }
183
+ }
184
+ }
185
+ }
186
+
187
+ /*
188
+ * Get page referrer
189
+ */
190
+ function getReferrer() {
191
+ var referrer = '';
192
+ try {
193
+ referrer = top.document.referrer;
194
+ } catch (e) {
195
+ if (parent) {
196
+ try {
197
+ referrer = parent.document.referrer;
198
+ } catch (e2) {
199
+ referrer = '';
200
+ }
201
+ }
202
+ }
203
+ if (referrer === '') {
204
+ referrer = documentAlias.referrer;
205
+ }
206
+
207
+ return referrer;
208
+ }
209
+
210
+ /*
211
+ * Does browser have cookies enabled (for this site)?
212
+ */
213
+ function hasCookies() {
214
+ var testCookieName = '_pk_testcookie';
215
+ if (!isDefined(navigatorAlias.cookieEnabled)) {
216
+ setCookie(testCookieName, '1');
217
+ return getCookie(testCookieName) == '1' ? '1' : '0';
218
+ }
219
+
220
+ return navigatorAlias.cookieEnabled ? '1' : '0';
221
+ }
222
+
223
+ /*
224
+ * Log the page view / visit
225
+ */
226
+ function logPageView(analyticsContext, collectedData, customTitle) {
227
+ var id = Math.random();
228
+
229
+ var tuples = constructDataSet(analyticsContext, collectedData, customTitle, id);
230
+
231
+ if (collectedData != null && collectedData.debugEnabled) {
232
+ var text = '';
233
+ for (var i = 0; i < tuples.length; i++)
234
+ {
235
+ text += tuples[i][0] + '"=' + tuples[i][1] + '"\n';
236
+ }
237
+ alert(text);
238
+ }
239
+
240
+
241
+ var urls = createUrls(analyticsContext, configTrackerUrl, tuples, id);
242
+ getImage(urls);
243
+ }
244
+
245
+ /************************************************************
246
+ * Constructor
247
+ ************************************************************/
248
+
249
+ /*
250
+ * initialize tracker
251
+ */
252
+ pageReferrer = getReferrer();
253
+ browserHasCookies = hasCookies();
254
+ detectBrowserPlugins();
255
+
256
+ try {
257
+ process_anact_cookie();
258
+ } catch (err) {};
259
+
260
+ /************************************************************
261
+ * Public data and methods
262
+ ************************************************************/
263
+
264
+ return {
265
+ /*
266
+ * Log visit to this page (called from the bottom of the page).
267
+ */
268
+ trackPageView: function (customTitle) {
269
+ logPageView(null, null, customTitle);
270
+ },
271
+ /*
272
+ * Log visit to this page (called from the dwac script).
273
+ */
274
+ trackPageViewWithProducts: function (analyticsContext, collectedData, customTitle) {
275
+ logPageView(analyticsContext, collectedData, customTitle);
276
+ }
277
+ };
278
+
279
+
280
+ function appendToRequest(/*Array*/ tuple, /*string*/ request) {
281
+
282
+ var beginningChar = request.charAt(request.length - 1) == '?' ? '' : '&';
283
+ return request + beginningChar + tuple[0] + "=" + tuple[1];
284
+ }
285
+
286
+ function lengthOfTuple(/*Array*/ tuple) {
287
+ return tuple[0].length + tuple[1].length + 2;
288
+ }
289
+
290
+ function constructDataSet(/*object*/ analyticsContext, collectedData, /*string*/ customTitle, /*number*/ id) {
291
+ var tuples = [
292
+ ["url", escapeWrapper(isDefined(configCustomUrl) ? configCustomUrl : documentAlias.location.href)],
293
+ ["res", screenAlias.width + 'x' + screenAlias.height],
294
+ ["cookie", browserHasCookies],
295
+ ["ref", escapeWrapper(pageReferrer)],
296
+ ["title", escapeWrapper(isDefined(customTitle) && customTitle != null ? customTitle : configTitle)]
297
+ ];
298
+
299
+ // plugin data
300
+ for (var index in pluginMap) {
301
+ tuples.push([pluginMap[index][0], pluginMap[index][2]])
302
+ }
303
+
304
+ if (analyticsContext != null && analyticsContext.dwEnabled)
305
+ {
306
+ tuples.push(["dwac", id]);
307
+ tuples.push(["cmpn", analyticsContext.sourceCode]);
308
+ tuples.push(["tz", analyticsContext.timeZone]);
309
+
310
+ analyticsContext.category = dw.ac._category;
311
+ if (dw.ac._searchData) {
312
+ analyticsContext.searchData = dw.ac._searchData;
313
+ }
314
+
315
+ addProducts(analyticsContext, collectedData, tuples);
316
+ }
317
+
318
+ return tuples;
319
+ }
320
+
321
+ function addProducts(/*object*/ analyticsContext, /*object*/ collectedData, /*Array*/ tuples)
322
+ {
323
+ tuples.push(["pcc", analyticsContext.siteCurrency]);
324
+ tuples.push(["pct", analyticsContext.customer]);
325
+ tuples.push(["pcat", analyticsContext.category]);
326
+ if (analyticsContext.searchData) {
327
+ if (analyticsContext.searchData.q) tuples.push(["pst-q", analyticsContext.searchData.q]);
328
+ if (analyticsContext.searchData.searchID) tuples.push(["pst-id", analyticsContext.searchData.searchID]);
329
+ if (analyticsContext.searchData.refs) tuples.push(["pst-refs", analyticsContext.searchData.refs]);
330
+ if (analyticsContext.searchData.sort) tuples.push(["pst-sort", analyticsContext.searchData.sort]);
331
+ if (undefined != analyticsContext.searchData.persd) tuples.push(["pst-pers", analyticsContext.searchData.persd]);
332
+ if (analyticsContext.searchData.imageUUID) tuples.push(["pst-img", analyticsContext.searchData.imageUUID]);
333
+ if (analyticsContext.searchData.suggestedSearchText) tuples.push(["pst-sug", analyticsContext.searchData.suggestedSearchText]);
334
+ if (analyticsContext.searchData.locale) tuples.push(["pst-loc", analyticsContext.searchData.locale]);
335
+ if (analyticsContext.searchData.queryLocale) tuples.push(["pst-qloc", analyticsContext.searchData.queryLocale]);
336
+ if (undefined != analyticsContext.searchData.showProducts) tuples.push(["pst-show", analyticsContext.searchData.showProducts]);
337
+ }
338
+
339
+ var pies = collectedData.productImpressions.getEntries();
340
+ var pres = collectedData.productRecommendations.getEntries();
341
+ var pves = collectedData.productViews.getEntries();
342
+
343
+ var count = 0;
344
+ for (var i = 0; i < pies.length; i++) {
345
+ tuples.push([("pid-" + count), pies[i].value.id]);
346
+ tuples.push([("pev-" + count), "event3"]);
347
+ count++;
348
+ }
349
+
350
+ for (var j = 0; j < pres.length; j++) {
351
+ tuples.push([("pid-" + count), pres[j].value.id]);
352
+ tuples.push([("pev-" + count), "event3"]);
353
+ tuples.push([("evr4-" + count), 'Yes']);
354
+ count++;
355
+ }
356
+
357
+ for (var k = 0; k < pves.length; k++) {
358
+ tuples.push([("pid-" + count), pves[k].value.id]);
359
+ tuples.push([("pev-" + count), "event4"]);
360
+ count++;
361
+ }
362
+ }
363
+
364
+ function createUrls(analyticsContext, configTrackerUrl, tuples, id) {
365
+ var urls = [];
366
+ var request = configTrackerUrl;
367
+ for (var i = 0; i < tuples.length; i++) {
368
+ // we don't want to break up a product grouping, for example,
369
+ // ["pid-0","p1"],["pev-0","event3"],["evr4-0",'Yes'] should not be broken into two separate requests
370
+ var nextTupleIsProductAndWouldMakeRequestTooLong = (tuples[i][0].slice(0, "pid-".length) == "pid-")
371
+ && (lengthOfTuple(tuples[i])
372
+ + ((i + 1) < tuples.length ? lengthOfTuple(tuples[i + 1]) : 0)
373
+ + ((i + 2) < tuples.length ? lengthOfTuple(tuples[i + 2]) : 0)
374
+ + request.length > MAX_URL_LENGTH);
375
+
376
+ var nextTupleIsNotProductAndWouldMakeRequestTooLong = (tuples[i][0].slice(0, "pid-".length) != "pid-")
377
+ && (lengthOfTuple(tuples[i]) + request.length > MAX_URL_LENGTH);
378
+
379
+ if (nextTupleIsProductAndWouldMakeRequestTooLong || nextTupleIsNotProductAndWouldMakeRequestTooLong) {
380
+ urls.push(request);
381
+ // close the current request and create a new one,
382
+ // the new request should have the basic dwac, cmpn,tz, pcc, pct, pcat values
383
+ request = appendToRequest(["dwac", id], configTrackerUrl);
384
+ if (analyticsContext != null && analyticsContext.dwEnabled) {
385
+ request = appendToRequest(["cmpn", analyticsContext.sourceCode], request);
386
+ request = appendToRequest(["tz", analyticsContext.timeZone], request);
387
+ request = appendToRequest(["pcc", analyticsContext.siteCurrency], request);
388
+ request = appendToRequest(["pct", analyticsContext.customer], request);
389
+ request = appendToRequest(["pcat", analyticsContext.category], request);
390
+ if (analyticsContext.searchData) {
391
+ if (analyticsContext.searchData.q) appendToRequest(["pst-q", analyticsContext.searchData.q], request);
392
+ if (analyticsContext.searchData.searchID) appendToRequest(["pst-id", analyticsContext.searchData.searchID], request);
393
+ if (analyticsContext.searchData.refs) appendToRequest(["pst-refs", JSON.stringify(analyticsContext.searchData.refs)], request);
394
+ if (analyticsContext.searchData.sort) appendToRequest(["pst-sort", JSON.stringify(analyticsContext.searchData.sort)], request);
395
+ if (undefined != analyticsContext.searchData.persd) appendToRequest(["pst-pers", analyticsContext.searchData.persd], request);
396
+ if (analyticsContext.searchData.imageUUID) appendToRequest(["pst-img", analyticsContext.searchData.imageUUID], request);
397
+ if (analyticsContext.searchData.suggestedSearchText) appendToRequest(["pst-sug", analyticsContext.searchData.suggestedSearchText], request);
398
+ if (analyticsContext.searchData.locale) appendToRequest(["pst-loc", analyticsContext.searchData.locale], request);
399
+ if (analyticsContext.searchData.queryLocale) appendToRequest(["pst-qloc", analyticsContext.searchData.queryLocale], request);
400
+ if (undefined != analyticsContext.searchData.showProducts) appendToRequest(["pst-show", analyticsContext.searchData.showProducts], request);
401
+ }
402
+ }
403
+ }
404
+
405
+ request = appendToRequest(tuples[i], request);
406
+ }
407
+
408
+ // Add the "do not follow" cookie in the URL as a query param
409
+ // The cookie is set per-site, and gets applied to all sub-sites, if present
410
+ var doNotFollowCookieValue = getCookie('dw_dnt');
411
+
412
+ // If cookie not found
413
+ if (doNotFollowCookieValue === 0
414
+ || doNotFollowCookieValue === ''
415
+ || doNotFollowCookieValue === null
416
+ || doNotFollowCookieValue === false) {
417
+ // do nothing, meaning tracking is allowed
418
+ }
419
+ // Cookie found, i.e. value should be '0' or '1' (string values)
420
+ else {
421
+ // Set whatever the cookie value is
422
+ request = appendToRequest([ "dw_dnt", doNotFollowCookieValue ], request);
423
+ }
424
+
425
+ urls.push(request);
426
+ return urls;
427
+ }
428
+ }
429
+
430
+ function extractCookieValueAndRemoveCookie(cookieName) {
431
+ var cookieValue = extractEncodedCookieValue (cookieName);
432
+ if (cookieValue) {
433
+ document.cookie = cookieName + '=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT;';
434
+ }
435
+ return cookieValue;
436
+ };
437
+
438
+ function extractEncodedCookieValue (cookieName) {
439
+ return decodeURIComponent (
440
+ document.cookie.replace(
441
+ new RegExp('(?:(?:^|.*;)\\s*'
442
+ + encodeURIComponent(cookieName).replace(/[\-\.\+\*]/g, '\\$&')
443
+ + '\\s*\\=\\s*([^;]*).*$)|^.*$')
444
+ , '$1').replace(/\+/g, '%20')
445
+ ) || null;
446
+ }
447
+
448
+ function process_anact_cookie() {
449
+ if (dw.ac) {
450
+ dw.ac._anact=extractCookieValueAndRemoveCookie('__anact');
451
+ if ( dw.ac._anact && !dw.ac.eventsIsEmpty() ) {
452
+ return;
453
+ }
454
+ if ( dw.ac._anact_nohit_tag || dw.ac._anact ) {
455
+ var unescaped = dw.ac._anact_nohit_tag ? dw.ac._anact_nohit_tag : dw.ac._anact;
456
+ var jsonPayload = JSON.parse(unescaped);
457
+ if (jsonPayload) {
458
+ var payload = Array.isArray(jsonPayload) ? jsonPayload[0] : jsonPayload;
459
+ if (payload
460
+ && 'viewSearch' == payload.activityType
461
+ && payload.parameters) {
462
+ var params = payload.parameters;
463
+ var search_params = {};
464
+ search_params.q = params.searchText;
465
+ search_params.suggestedSearchText = params.suggestedSearchText;
466
+ search_params.persd = params.personalized;
467
+ search_params.refs = params.refinements;
468
+ search_params.sort = params.sorting_rule;
469
+ search_params.imageUUID = params.image_uuid;
470
+ search_params.showProducts = params.showProducts;
471
+ search_params.searchID = params.searchID;
472
+ search_params.locale = params.locale;
473
+ search_params.queryLocale = params.queryLocale;
474
+ dw.ac.applyContext({searchData: search_params});
475
+ var products = params.products;
476
+ if (products && Array.isArray(products)) {
477
+ for (i = 0; i < products.length; i++) {
478
+ if (products[i]) {
479
+ dw.ac._capture({ id : products[i].id, type : dw.ac.EV_PRD_SEARCHHIT });
480
+ }
481
+ }
482
+ }
483
+ }
484
+ }
485
+ }
486
+ }
487
+ };
488
+
489
+ /************************************************************
490
+ * Public data and methods
491
+ ************************************************************/
492
+
493
+ return {
494
+ /*
495
+ * Get Tracker
496
+ */
497
+ getTracker: function (analyticsUrl) {
498
+ return new Tracker(analyticsUrl);
499
+ }
500
+ };
501
+ }();
502
+ }
@@ -0,0 +1,43 @@
1
+ var dw = (window.dw || {});
2
+ dw.ac = {
3
+ _analytics: null,
4
+ _events: [],
5
+ _category: "",
6
+ _searchData: "",
7
+ _anact: "",
8
+ _anact_nohit_tag: "",
9
+ _analytics_enabled: "true",
10
+ _timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,
11
+ _capture: function(configs) {
12
+ if (Object.prototype.toString.call(configs) === "[object Array]") {
13
+ configs.forEach(captureObject);
14
+ return;
15
+ }
16
+ dw.ac._events.push(configs);
17
+ },
18
+ capture: function() {
19
+ dw.ac._capture(arguments);
20
+ // send to CQ as well:
21
+ if (window.CQuotient) {
22
+ window.CQuotient.trackEventsFromAC(arguments);
23
+ }
24
+ },
25
+ EV_PRD_SEARCHHIT: "searchhit",
26
+ EV_PRD_DETAIL: "detail",
27
+ EV_PRD_RECOMMENDATION: "recommendation",
28
+ EV_PRD_SETPRODUCT: "setproduct",
29
+ applyContext: function(context) {
30
+ if (typeof context === "object" && context.hasOwnProperty("category")) {
31
+ dw.ac._category = context.category;
32
+ }
33
+ if (typeof context === "object" && context.hasOwnProperty("searchData")) {
34
+ dw.ac._searchData = context.searchData;
35
+ }
36
+ },
37
+ setDWAnalytics: function(analytics) {
38
+ dw.ac._analytics = analytics;
39
+ },
40
+ eventsIsEmpty: function() {
41
+ return 0 == dw.ac._events.length;
42
+ }
43
+ };
@@ -4,7 +4,7 @@
4
4
  "license": "See license in LICENSE",
5
5
  "engines": {
6
6
  "node": "^16.0.0 || ^18.0.0",
7
- "npm": "^7.0.0 || ^8.0.0 || ^9.0.0"
7
+ "npm": "^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0"
8
8
  },
9
9
  "ccExtensibility": {
10
10
  "extends": "{{preset.templateSource.id}}",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforce/pwa-kit-create-app",
3
- "version": "3.3.0-preview.0",
3
+ "version": "3.3.0",
4
4
  "description": "Salesforce's project generator tool",
5
5
  "homepage": "https://github.com/SalesforceCommerceCloud/pwa-kit/tree/develop/packages/pwa-kit-create-app#readme",
6
6
  "bugs": {
@@ -38,13 +38,13 @@
38
38
  "tar": "^6.1.13"
39
39
  },
40
40
  "devDependencies": {
41
- "@salesforce/pwa-kit-dev": "3.3.0-preview.0",
42
- "internal-lib-build": "3.3.0-preview.0",
41
+ "@salesforce/pwa-kit-dev": "3.3.0",
42
+ "internal-lib-build": "3.3.0",
43
43
  "verdaccio": "^5.22.1"
44
44
  },
45
45
  "engines": {
46
46
  "node": "^16.11.0 || ^18.0.0",
47
- "npm": "^8.0.0 || ^9.0.0"
47
+ "npm": "^8.0.0 || ^9.0.0 || ^10.0.0"
48
48
  },
49
- "gitHead": "e96474c4e78bf0ab74c44fc6647f5614db71d769"
49
+ "gitHead": "93894bb7d823f3510e10affdb1eb8e6750b25822"
50
50
  }
Binary file
Binary file
Binary file
Binary file