mod-build 3.6.75-beta.2 → 4.0.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/.eslintignore +3 -0
  2. package/.eslintrc +18 -0
  3. package/CHANGELOG.md +2 -252
  4. package/README.md +16 -263
  5. package/gulp-tasks/grab-cdn.js +0 -10
  6. package/package.json +18 -68
  7. package/siteconfig.js +38 -0
  8. package/src/data/footer.js +117 -0
  9. package/src/data/seasons.js +5 -7
  10. package/src/index.html +18 -0
  11. package/src/main.js +45 -0
  12. package/src/scripts/has-qs-params.js +6 -5
  13. package/src/scripts/url-cleaner.js +3 -3
  14. package/src/scripts/utils.js +178 -0
  15. package/src/styles/home.scss +1 -0
  16. package/src/templates/_partials/scripts/deferred-styles.html +16 -16
  17. package/src/templates/_partials/scripts/vwo-redirect-callback.html +43 -45
  18. package/src/templates/components/head.html +70 -0
  19. package/tasks/clean.js +13 -0
  20. package/tasks/grab-cdn.js +107 -0
  21. package/tasks/grab-form-helpers.js +94 -0
  22. package/tasks/grab-shared-components.js +81 -0
  23. package/tasks/grab-shared-scripts.js +267 -0
  24. package/tasks/serve.js +15 -0
  25. package/tasks/templates.js +168 -0
  26. package/template.js +801 -0
  27. package/vite.config.js +56 -0
  28. package/.eslintrc.yml +0 -59
  29. package/src/data/common.js +0 -704
  30. package/src/data/components/qs-footer.js +0 -55
  31. package/src/data/components/quote-footer.js +0 -73
  32. package/src/scripts/apt-block.js +0 -919
  33. package/src/scripts/components/custom-selects.js +0 -48
  34. package/src/scripts/components/radio-panels.js +0 -45
  35. package/src/scripts/es6-1.js +0 -6
  36. package/src/scripts/es6-2.js +0 -2
  37. package/src/scripts/qs-form.js +0 -839
  38. package/src/scripts/vendor/maxmind-geoip2.js +0 -2
  39. package/src/scripts/vendor/swiper.min.js +0 -13
  40. package/src/styles/apt-block.scss +0 -888
  41. package/src/templates/_partials/apt-block.html +0 -30
  42. package/src/templates/_partials/scripts/analytics.html +0 -4
  43. package/src/templates/_partials/scripts/go-page-hiding-snippet.html +0 -8
  44. package/src/templates/_partials/scripts/google-maps.html +0 -1
  45. package/src/templates/_partials/scripts/google-optimize.html +0 -12
  46. package/src/templates/_partials/scripts/gtm-editorials/body/google-tag-manager-body.html +0 -5
  47. package/src/templates/_partials/scripts/gtm-editorials/head/google-tag-manager-head.html +0 -10
  48. package/src/templates/_partials/scripts/gtm-hil/body/google-tag-manager-body.html +0 -5
  49. package/src/templates/_partials/scripts/gtm-hil/head/google-tag-manager-head.html +0 -10
  50. package/src/templates/_partials/scripts/gtm-pro/body/google-tag-manager-body.html +0 -5
  51. package/src/templates/_partials/scripts/gtm-pro/head/google-tag-manager-head.html +0 -10
  52. package/src/templates/_partials/scripts/gtm-quote/body/google-tag-manager-body.html +0 -5
  53. package/src/templates/_partials/scripts/gtm-quote/head/google-tag-manager-head.html +0 -9
  54. package/src/templates/_partials/scripts/gtm-whitelabel/body/mod-google-tag-manager-body.html +0 -5
  55. package/src/templates/_partials/scripts/gtm-whitelabel/body/non-mod-google-tag-manager-body.html +0 -5
  56. package/src/templates/_partials/scripts/gtm-whitelabel/head/mod-google-tag-manager-head.html +0 -10
  57. package/src/templates/_partials/scripts/gtm-whitelabel/head/non-mod-google-tag-manager-head.html +0 -9
  58. package/src/templates/_partials/scripts/gtm-wordpress/body/google-tag-manager-body.html +0 -5
  59. package/src/templates/_partials/scripts/gtm-wordpress/head/google-tag-manager-head.html +0 -9
  60. package/src/templates/_partials/scripts/visual-website-optimizer.html +0 -5
  61. package/src/templates/index.html +0 -46
  62. /package/{src → public}/favicon.ico +0 -0
@@ -1,839 +0,0 @@
1
- /* global modUtils modForm heap dataLayer pintrk */
2
- /* exported QSForm */
3
-
4
- /**
5
- * This file extends modForm to make requests to Quinstreet API endpoints
6
- */
7
-
8
- /**
9
- * Get API domain based on whether this is testing or production env
10
- * @returns {String} QS domain to use
11
- */
12
- modForm.getQSApiDomain = function() {
13
- var domain = 'https://hsleadpost1.quinstage.com/',
14
- env = modUtils.getEnv();
15
-
16
- if (env === 'production') {
17
- domain = 'https://hs.leadpost.net/';
18
- }
19
-
20
- return domain;
21
- };
22
-
23
- /**
24
- * Add predefined data to the form
25
- */
26
- modForm.addRequiredQSFieldsToForm = function() {
27
- var _this = this,
28
- requiredFields = {
29
- HomePhoneConsentLanguage: $.trim(
30
- _this.opts.form.find(_this.opts.tcpaCopy).text()
31
- )
32
- };
33
-
34
- $.each(requiredFields, function(name, value) {
35
- _this.appendFormInput(name, value, true);
36
- });
37
- };
38
-
39
- /**
40
- * Get default quad link based on page domain
41
- * @returns {Object} Quad Link object value
42
- */
43
- modForm.getDefaultQuadByDomain = function() {
44
- var page = this.opts.websiteName.replace(/(qa|staging|www)./g, '');
45
- // TODO: Remove m. values since we only use the desktop url
46
- var defaultQuadLinkValue = {
47
- 'modernize.com': {
48
- f: '202008141721060',
49
- s: '26393',
50
- c: {
51
- 'GUTTER_COVERS': '1673169',
52
- 'HOME_SECURITY': '1673170',
53
- 'HOME_WARRANTY': '1673171'
54
- }
55
- },
56
- 'go.jacuzzi.com': {
57
- c: '1674074',
58
- s: '3086',
59
- f: '202011031614490'
60
- },
61
- 'm.go.jacuzzi.com': {
62
- c: '1674074',
63
- s: '3086',
64
- f: '202011031614490'
65
- },
66
- 'americanhomewarranty.org': {
67
- c: '1673835',
68
- s: '3086',
69
- f: '202010191645170'
70
- },
71
- 'm.americanhomewarranty.org': {
72
- c: '1673835',
73
- s: '3086',
74
- f: '202010191645170'
75
- },
76
- 'homewindowprices.org': {
77
- c: '1673838',
78
- s: '3086',
79
- f: '202010191645180'
80
- },
81
- 'm.homewindowprices.org': {
82
- c: '1673838',
83
- s: '3086',
84
- f: '202010191645180'
85
- },
86
- 'mygutterguards.com': {
87
- c: '1673836',
88
- s: '3086',
89
- f: '202010191645180'
90
- },
91
- 'm.mygutterguards.com': {
92
- c: '1673836',
93
- s: '3086',
94
- f: '202010191645180'
95
- },
96
- 'tophottubs.org': {
97
- c: '1673840',
98
- s: '3086',
99
- f: '202010191645190'
100
- },
101
- 'm.tophottubs.org': {
102
- c: '1673840',
103
- s: '3086',
104
- f: '202010191645190'
105
- },
106
- 'americanstandardwalkinbaths.com': {
107
- c: '1665214',
108
- s: '28354',
109
- f: '201906181327550'
110
- },
111
- 'm.americanstandardwalkinbaths.com': {
112
- c: '1665215',
113
- s: '28354',
114
- f: '201906181327560'
115
- },
116
- 'bathandshower.org': {
117
- c: '1667476',
118
- s: '26393',
119
- f: '201910011622070'
120
- },
121
- 'm.bathandshower.org': {
122
- c: '1667460',
123
- s: '26401',
124
- f: '201910011622030'
125
- },
126
- 'bathandshowerpros.com': {
127
- c: '1658267',
128
- s: '26393',
129
- f: '201809211357520'
130
- },
131
- 'm.bathandshowerpros.com': {
132
- c: '1658263',
133
- s: '26401',
134
- f: '201809211352160'
135
- },
136
- 'quotes.bathwraps.com': {
137
- c: '1660429',
138
- s: '26393',
139
- f: '201812121510250'
140
- },
141
- 'm.bathwraps.com': {
142
- c: '1660426',
143
- s: '26401',
144
- f: '201812121509080'
145
- },
146
- 'craftmaticbeds.com': {
147
- c: '655234',
148
- s: '3086',
149
- f: '201008201638230'
150
- },
151
- 'emedicalalerts.com': {
152
- c: '1647425',
153
- s: '26393',
154
- f: '201711071755250'
155
- },
156
- 'm.emedicalalerts.com': {
157
- c: '1647405',
158
- s: '26401',
159
- f: '201711071755190'
160
- },
161
- 'flooringpricer.com': {
162
- c: '1668109',
163
- s: '26393',
164
- f: '201910231539300'
165
- },
166
- 'm.flooringpricer.com': {
167
- c: '1668101',
168
- s: '26401',
169
- f: '201910231539280'
170
- },
171
- 'findyourwindows.com': {
172
- c: '1654347',
173
- s: '26393',
174
- f: '201805111614390'
175
- },
176
- 'm.findyourwindows.com': {
177
- c: '1654331',
178
- s: '26401',
179
- f: '201805111612300'
180
- },
181
- 'homesecurityprices.org': {
182
- c: '1658310',
183
- s: '26393',
184
- f: '201809211526510'
185
- },
186
- 'm.homesecurityprices.org': {
187
- c: '1658305',
188
- s: '26401',
189
- f: '201809211509250'
190
- },
191
- 'quotes.improvementcenter.com': {
192
- 'bathrooms': {
193
- c: '1652517',
194
- s: '26393',
195
- f: '201803221337450'
196
- },
197
- 'gutters': {
198
- c: '1614214',
199
- s: '3086',
200
- f: '201608311104250'
201
- },
202
- 'stairlifts': {
203
- c: '1658469',
204
- s: '26393',
205
- f: '201809260926260'
206
- },
207
- 'walkintubs': {
208
- c: '1647588',
209
- s: '26393',
210
- f: '201711081408530'
211
- }
212
- },
213
- 'bathrooms.improvementcenter.com': {
214
- c: '1652509',
215
- s: '26401',
216
- f: '201803221337420'
217
- },
218
- 'gutters.improvementcenter.com': {
219
- c: '1635550',
220
- s: '16479',
221
- f: '201703010604120'
222
- },
223
- 'stairlifts.improvementcenter.com': {
224
- c: '1658465',
225
- s: '26401',
226
- f: '201809260926240'
227
- },
228
- 'walkintubs.improvementcenter.com': {
229
- c: '1647564',
230
- s: '26401',
231
- f: '201711081408460'
232
- },
233
- 'kitchensandcabinets.com': {
234
- c: '1652648',
235
- s: '26393',
236
- f: '201803261349020'
237
- },
238
- 'm.kitchensandcabinets.com': {
239
- c: '1652624',
240
- s: '26401',
241
- f: '201803261348550'
242
- },
243
- 'lifemedicalalerts.com': {
244
- c: '1647427',
245
- s: '26393',
246
- f: '201711071755260'
247
- },
248
- 'm.lifemedicalalerts.com': {
249
- c: '1647407',
250
- s: '26401',
251
- f: '201711071755200'
252
- },
253
- 'go.medicalguardian.com': {
254
- c: '1654232',
255
- s: '26393',
256
- f: '201805101622250'
257
- },
258
- 'mysolarcost.com': {
259
- c: '1645537',
260
- s: '3086',
261
- f: '201709221027450'
262
- },
263
- 'm.mysolarcost.com': {
264
- c: '1645592',
265
- s: '16479',
266
- f: '201709221044340'
267
- },
268
- 'roofingcosts.org': {
269
- c: '1673843',
270
- s: '3086',
271
- f: '202010191645200'
272
- },
273
- 'm.roofingcosts.org': {
274
- c: '1673843',
275
- s: '3086',
276
- f: '202010191645200'
277
- },
278
- 'securitypricer.com': {
279
- c: '1673856',
280
- s: '3086',
281
- f: '202010191645230'
282
- },
283
- 'm.securitypricer.com': {
284
- c: '1673856',
285
- s: '3086',
286
- f: '202010191645230'
287
- },
288
- 'walkinbathtubs.org': {
289
- c: '1673846',
290
- s: '3086',
291
- f: '202010191645210'
292
- },
293
- 'm.walkinbathtubs.org': {
294
- c: '1673846',
295
- s: '3086',
296
- f: '202010191645210'
297
- },
298
- 'walkintubprices.org': {
299
- c: '1673842',
300
- s: '3086',
301
- f: '202010191645200'
302
- },
303
- 'm.walkintubprices.org': {
304
- c: '1673842',
305
- s: '3086',
306
- f: '202010191645200'
307
- },
308
- 'walkintubforseniors.com': {
309
- c: '1647590',
310
- s: '26393',
311
- f: '201711081408540'
312
- },
313
- 'm.walkintubforseniors.com': {
314
- c: '1647566',
315
- s: '26401',
316
- f: '201711081408470'
317
- },
318
- 'plans.selecthomewarranty.com': {
319
- c: '1674075',
320
- s: '3086',
321
- f: '202011031614490'
322
- },
323
- 'm.plans.selecthomewarranty.com': {
324
- c: '1674075',
325
- s: '3086',
326
- f: '202011031614490'
327
- },
328
- 'powerhomesolarpanels.com': {
329
- c: '1676761',
330
- s: '3086',
331
- f: '202105251631450'
332
- },
333
- 'hvacpros.org': {
334
- c: '1670084',
335
- s: '26393',
336
- f: '202002181631370'
337
- },
338
- 'm.hvacpros.org': {
339
- c: '1670076',
340
- s: '26401',
341
- f: '202002181625140'
342
- },
343
- 'homewarrantyplans.org': {
344
- c: '1668109',
345
- s: '26393',
346
- f: '201910231539300'
347
- },
348
- 'm.homewarrantyplans.org': {
349
- c: '1667462',
350
- s: '26401',
351
- f: '201910011622030'
352
- },
353
- 'kitchencabinetrefacing.org': {
354
- c: '1668109',
355
- s: '26393',
356
- f: '201910231539300'
357
- },
358
- 'm.kitchencabinetrefacing.org': {
359
- c: '1670076',
360
- s: '26401',
361
- f: '202002181625140'
362
- }
363
- };
364
-
365
- if (page === 'quotes.improvementcenter.com') {
366
- const service = window.location.pathname.replace(/\//g , "");
367
- return defaultQuadLinkValue[page][service];
368
- }
369
-
370
- return defaultQuadLinkValue[page];
371
- };
372
-
373
- /**
374
- * Get default site (Attribute 42)
375
- * @returns {String} Default site value or page url
376
- */
377
- modForm.getDefaultSiteByDomain = function() {
378
- var page = this.opts.websiteName.replace(/(qa|staging|www)./g, '');
379
-
380
- return page;
381
- };
382
-
383
- /**
384
- * Get default quad link based on service
385
- * @param {String} service - Landing Page service (vertical)
386
- * @returns {String} Quad Link
387
- */
388
- modForm.getDefaultQuad = function(service) {
389
- var finalLink = '';
390
- var valuesByDomain = this.getDefaultQuadByDomain();
391
-
392
- if (valuesByDomain) {
393
- var c = typeof valuesByDomain.c === 'object' ? valuesByDomain.c[service] : valuesByDomain.c;
394
- finalLink = 'http://o1.qnsr.com/cgi/r?;n=203;c=' + c + ';s=' + valuesByDomain.s + ';x=7936;f=' + valuesByDomain.f + ';u=j;z=TIMESTAMP;&default=yes';
395
- }
396
-
397
- return finalLink;
398
- };
399
-
400
- /**
401
- * Load maxmind script if it's not loaded yet, and then get ip address
402
- */
403
- modForm.getIpAddress = function() {
404
- var _this = this;
405
-
406
- this.opts.form.one('focus', ':input', function() {
407
- if (typeof geoip2 === 'undefined') {
408
- var script = document.createElement('script');
409
- script.src = 'https://' + (modUtils.getEnv() !== 'production' ? 'qa.' : '') + 'modernize.com/quote/resources/mod-site/scripts/vendor/maxmind-geoip2.js';
410
- $('body').append(script);
411
- }
412
-
413
- setTimeout(function() {
414
- if (typeof geoip2 !== 'undefined') {
415
- geoip2.city(function(geoipResponse) {
416
- if (geoipResponse.traits.ip_address) {
417
- _this.opts.ipAddress = geoipResponse.traits.ip_address;
418
- }
419
- });
420
- }
421
- }, 500);
422
- });
423
- };
424
-
425
- modForm.heapIdentify = function() {
426
- // Heap Identify once we get a click key value
427
- if (typeof this.opts.quadLinkParams.CLK !== 'undefined') {
428
- modUtils.heap('removeEventProperty', ['qsclickkey']);
429
- modUtils.heap('identify', [this.opts.quadLinkParams.CLK, 'ID']);
430
- }
431
- };
432
-
433
- /**
434
- * Init Quinstreet form opts
435
- */
436
- modForm.initQSForm = function() {
437
- this.opts.tagIDTest = '203838617'; // Use this if there is no quadlink params
438
- this.opts.tagIDLive = '204673056'; // Use this if there is no quadlink params
439
- this.opts.leadSubmitApi = 'hs/tyPage/matches.jsp';
440
- this.opts.trafficDetailsApi = 'api/TrafficDetails/get';
441
- this.opts.isWirelesssApi = 'api/isWireless/';
442
- this.opts.websiteName = window.location.host;
443
- this.opts.resultsPage = (this.opts.resultsPage ? this.opts.resultsPage : '/my/results/');
444
- this.opts.errorRedirectPath = (this.opts.errorRedirectPath ? this.opts.errorRedirectPath : '/my/results/');
445
- this.opts.landingPage = window.location.hostname + window.location.pathname;
446
- this.opts.quadLinkParams = {};
447
-
448
- // We check if there's a quad link on the query string
449
- // If not we get the default link
450
- var _this = this,
451
- apiUrl = this.getQSApiDomain() + this.opts.trafficDetailsApi,
452
- currentParams = modUtils.getUrlParamsToObject(),
453
- hasQuadLink = currentParams.hasOwnProperty('quadlink'),
454
- hastagID = currentParams.hasOwnProperty('tagID'),
455
- qsParams = ['CCID', 'CLK', 'QTR'],
456
- marketingParams = ['ad', 'sp', 'fb', 'mt', 'adposition', 'dev', 'gclid', 'ki', 'sq', 'fb_ad_id', 'fb_adset_id', 'fb_campaign_id', 'placement', 'PartnerSourceID', 'sub2_id'],
457
- hasQsParams = Object.keys(currentParams).some(function(param) {
458
- return qsParams.includes(param);
459
- });
460
-
461
- if (hasQsParams) {
462
- for (var param in currentParams) {
463
- if (qsParams.includes(param) && typeof currentParams[param] !== 'undefined') {
464
- _this.opts.quadLinkParams[param] = currentParams[param];
465
- }
466
- }
467
-
468
- _this.heapIdentify();
469
- } else {
470
- var data = {
471
- WebSiteName: this.opts.websiteName,
472
- quadlink: '',
473
- defaultQuad: '',
474
- tagID: ''
475
- },
476
- quadLinkUrl = '',
477
- quadLinkType = '';
478
-
479
- if (hastagID) {
480
- quadLinkUrl = currentParams.tagID;
481
- quadLinkType = 'tagID';
482
- } else {
483
- quadLinkUrl = (hasQuadLink ? currentParams.quadlink : this.getDefaultQuad(this.opts.vertical));
484
- quadLinkType = (hasQuadLink ? 'quadlink' : 'defaultQuad');
485
- }
486
-
487
- data[quadLinkType] = quadLinkUrl;
488
-
489
- for (var param in currentParams) {
490
- if (marketingParams.includes(param)) {
491
- data[param] = currentParams[param];
492
- }
493
- }
494
-
495
- if (quadLinkUrl !== '') {
496
- // Async call after we've initialized the QS form to make a background request with the quadlink found on the url
497
- $.ajax({
498
- type: 'POST',
499
- url: apiUrl,
500
- contentType: 'application/json',
501
- data: JSON.stringify(data),
502
- crossDomain: true,
503
- success: function(response, status, xhr) {
504
- if (response && xhr.status === 200) {
505
- for (var value in response) {
506
- if (qsParams.includes(value) && response.hasOwnProperty(value)) {
507
- _this.opts.quadLinkParams[value] = response[value];
508
- }
509
- }
510
- _this.heapIdentify();
511
- }
512
- }
513
- });
514
- }
515
- }
516
-
517
- this.addRequiredQSFieldsToForm();
518
- this.getIpAddress();
519
- };
520
-
521
- modForm.getOS = function() {
522
- var userAgent = window.navigator.userAgent,
523
- osNaming = {
524
- 'Mac': 'MacOs',
525
- 'Win': 'Windows',
526
- 'like Mac': 'iOs',
527
- 'Linux': 'Linux',
528
- 'Android': 'Android',
529
- 'CrOS': 'chromeOs'
530
- },
531
- os = 'Other';
532
-
533
- // Looking for the match based on what we find on userAgent string
534
- $.each(osNaming, function(match, name) {
535
- if (userAgent.indexOf(match) !== -1) {
536
- os = name;
537
- }
538
- });
539
-
540
- return os;
541
- };
542
-
543
- modForm.getPhoneNumberType = function(phoneNumber) {
544
- var _this = this,
545
- phoneType = 'Wireless',
546
- apiUrl = _this.getQSApiDomain() + this.opts.isWirelesssApi + '/' + phoneNumber + '/get';
547
-
548
- $.ajax({
549
- type: 'GET',
550
- url: apiUrl,
551
- async: false,
552
- crossDomain: true,
553
- success: function(response, status, xhr) {
554
- if (response.status === 'Success' && response.Result === 'false') {
555
- phoneType = 'NonWireless';
556
- }
557
- }
558
- });
559
-
560
- return phoneType;
561
- };
562
-
563
- /**
564
- * This function processes form attribution data, setting important values like tracking params and response format type
565
- * @param {Object} formData - form data
566
- * @returns {Object} formatted form data
567
- */
568
- modForm.preprocessQSFormData = function(formData) {
569
- var formattedData = {},
570
- qsFieldsTranslation = {
571
- 'FN': 'firstName',
572
- 'LN': 'lastName',
573
- 'HP': 'homePhone',
574
- 'EM': 'email',
575
- 'S1': 'address',
576
- 'CT': 'city',
577
- 'SP': 'state',
578
- 'PC': 'zip',
579
- 'OwnHome': 'homeowner',
580
- 'leadid_token': 'leadToken',
581
- 'TrustedFormToken': 'xxTrustedFormToken'
582
- },
583
- modFieldsToRemove = ['session', 'sessionToken', 'usid', 'landingPage', 'tcpa', 'tcpaText', 'xxTrustedFormToken', 'xxTrustedFormCertUrl', 'inertZip', 'homeowner', 'zip1'];
584
-
585
- var quadLinkParams = this.opts.quadLinkParams;
586
-
587
- // If we have parameters from the quadlink request we add these to the form data
588
- if (Object.keys(quadLinkParams).length !== 0) {
589
- for (var param in quadLinkParams) {
590
- if (quadLinkParams.hasOwnProperty(param)) {
591
- formattedData[param] = quadLinkParams[param];
592
- }
593
- }
594
-
595
- formattedData.HEAPID = quadLinkParams.CLK;
596
- formattedData.HeapUserID = quadLinkParams.CLK;
597
- } else if (modUtils.getUrlParamsToObject().hasOwnProperty('tagID')) {
598
- const {tagID} = modUtils.getUrlParamsToObject();
599
- formattedData.tagID = tagID;
600
- } else {
601
- formattedData.tagID = (modUtils.getEnv() === 'production' ? this.opts.tagIDLive : this.opts.tagIDTest);
602
- }
603
-
604
- // Setting VWO campaign data if there is an active test
605
- if (window._vwo_campaignData && Object.keys(window._vwo_campaignData).length !== 0) {
606
- formattedData.VWOID = Object.keys(window._vwo_campaignData)[0];
607
- formattedData.VWOVariationName = Object.values(window._vwo_campaignData)[0].n;
608
- }
609
-
610
- // Setting Heap Session ID
611
- const heapCookie = modUtils.getCookie('_hp2_id.' + window.heap.appid);
612
-
613
- if (heapCookie) {
614
- const heapCookieDataObj = JSON.parse(decodeURIComponent(heapCookie));
615
- formattedData.HeapSessionID = heapCookieDataObj.sessionId;
616
- }
617
-
618
- // Translating our form fields name to Quinstreet nomenclature
619
- $.each(qsFieldsTranslation, function(name, value) {
620
- formattedData[name] = formData[value];
621
- delete formData[value];
622
- });
623
-
624
- // Remove unnecessary fields (for now we're doing it this way, will look for a better way in the future)
625
- modFieldsToRemove.forEach(function(field) {
626
- delete formData[field];
627
- });
628
-
629
- // Pass on any other fields that are still in formData
630
- formattedData = Object.assign(formattedData, formData);
631
-
632
- // Predefined values
633
- formattedData.service = this.opts.vertical;
634
- formattedData.site = this.getDefaultSiteByDomain();
635
- formattedData.OperatingSystem = this.getOS();
636
- formattedData.HomePhoneType = this.getPhoneNumberType(formattedData.HP.replace(/\D/g,''));
637
- formattedData.HomePhoneConsent = 'Yes';
638
- formattedData.responseFormat = 'json';
639
-
640
- if (this.opts.ipAddress) {
641
- formattedData.IPAddress = this.opts.ipAddress;
642
- }
643
-
644
- return formattedData;
645
- };
646
-
647
- /**
648
- * Submit form data to Quinstreet API endpoint
649
- * @param {Object} formData - form data
650
- * @param {Function} successCallback - success callback
651
- * @param {Function} errorCallback - error callback
652
- */
653
- modForm.submitFormDataToQSApi = function(formData, successCallback, errorCallback) {
654
- var _this = this,
655
- apiUrl = _this.getQSApiDomain() + _this.opts.leadSubmitApi;
656
-
657
- _this.opts.formData = formData;
658
-
659
- if (_this.isSubmitting === false) {
660
- _this.isSubmitting = true;
661
-
662
- $.ajax({
663
- type: 'POST',
664
- url: apiUrl,
665
- data: formData,
666
- crossDomain: true,
667
- success: function(response, status, xhr) {
668
- if ('function' === typeof successCallback) {
669
- successCallback(response);
670
- }
671
-
672
- _this.processQSFormSubmitSuccess(response, xhr);
673
- },
674
- error: function(xhr, status, error) {
675
- // If there was an error, we first look for any error callback first
676
- if (typeof errorCallback === 'function') {
677
- errorCallback(xhr, status, error);
678
- }
679
- },
680
- complete: function() {
681
- _this.isSubmitting = false;
682
- _this.switchFormLoadingState();
683
- }
684
- });
685
- }
686
- };
687
-
688
- /**
689
- * Process form after succesful submit
690
- * @param {Object} response - response data
691
- * @param {Object} xhr - xhr
692
- * @returns {Boolean} Submission status
693
- */
694
- modForm.processQSFormSubmitSuccess = function(response, xhr) {
695
- var cookieData,
696
- responseData = response.RESPONSE,
697
- dataCaptureKey = responseData.DCK;
698
-
699
- // If submission was succesful
700
- if (dataCaptureKey != null && xhr.status === 200) {
701
- var clickKeyUUID = this.opts.formData.CLK;
702
-
703
- // Setting GA User ID and several custom dimensions after a successful form submit request
704
- if (typeof dataLayer !== 'undefined') {
705
- dataLayer.push({
706
- event: 'formSubmit',
707
- userId: clickKeyUUID,
708
- lastProjectId: dataCaptureKey,
709
- projectId: dataCaptureKey,
710
- projectClass: this.opts.formData.service
711
- });
712
- }
713
-
714
- // Sending GA Event to keep track of all non-TYP conversions, including this one
715
- modUtils.gaSend({
716
- hitType: 'event',
717
- eventCategory: 'HRC General',
718
- eventAction: 'User converted on non-TYP experience',
719
- eventLabel: window.location.pathname
720
- }, this.opts.gaTracker);
721
-
722
- // Redshift Transforms that normally happen on the TYP
723
- heap.addEventProperties({
724
- // eslint-disable-next-line camelcase
725
- project_id: dataCaptureKey,
726
- // eslint-disable-next-line camelcase
727
- data_capture_key: dataCaptureKey,
728
- // eslint-disable-next-line camelcase
729
- form_path: this.opts.landingPage,
730
- qsclickkey: clickKeyUUID
731
- });
732
-
733
- // Adding VWO data as heap event properties
734
- if (window._vis_data && Object.keys(window._vis_data).length !== 0) {
735
- var visData = window._vis_data,
736
- vwoCampaigns = {};
737
-
738
- $.each(visData, function(testID, testVariation) {
739
- vwoCampaigns['VWO Test ID'] = testID.replace(/\D+/g, '');
740
- vwoCampaigns['VWO Variation Name'] = testVariation;
741
- });
742
-
743
- heap.addEventProperties(vwoCampaigns);
744
- }
745
-
746
- // Alternate heap conversion event for Homeowner Lead Form Conversion combo event
747
- modUtils.heap('track', ['Homeowner Lead Conversion']);
748
-
749
- // Fire all conversion pixels
750
- if (typeof dataLayer !== 'undefined') {
751
- dataLayer.push({
752
- event: 'Homeowner Lead Conversion',
753
- isQSPage: 'true'
754
- });
755
- }
756
-
757
- // Track checkout in Pinterest
758
- if ('undefined' !== typeof pintrk) {
759
- pintrk('track', 'checkout', {
760
- order_id: 'undefined' !== typeof dataCaptureKey ? dataCaptureKey : null // eslint-disable-line camelcase
761
- });
762
- }
763
-
764
- // Save response and quadlink params to cookie and redirect to the corresponding thankyou page
765
- cookieData = Object.assign({}, this.opts.quadLinkParams, responseData);
766
-
767
- // Set personal information
768
- cookieData.PROJECT = {
769
- 'FIRSTNAME': this.opts.formData.FN,
770
- 'LASTNAME': this.opts.formData.LN
771
- };
772
-
773
- modUtils.setCookie('qsLeadData', JSON.stringify(cookieData));
774
-
775
- if ('function' === typeof this.opts.formSubmitSuccessCallback) {
776
- if (this.opts.formSubmitSuccessCallback(responseData) === false) {
777
- return false;
778
- }
779
- }
780
-
781
- // Set results page to HRC if the site is eligible, there's a DCK
782
- // and the current page is not a quote emerging trade page (these should not redirect to the HRC)
783
- if (this.isQsSiteEligibleForHrc() && responseData.HASHEDDCK) {
784
- window.projectId = responseData.HASHEDDCK;
785
- this.opts.resultsPage = this.getProjExUrl();
786
- this.opts.resultsPage += (this.opts.resultsPage.indexOf('?') < 0 ? '?' : '&') + 'DCK=' + dataCaptureKey;
787
- }
788
-
789
- // Append TY to HRC URL for QS tracking purpose
790
- if (typeof this.opts.appendTyToHrcUrl !== 'undefined' && this.opts.appendTyToHrcUrl === true) {
791
- this.opts.resultsPage += (this.opts.resultsPage.indexOf('?') < 0 ? '?' : '&') + (responseData.MATCHES.length > 0 ? 'ThankYou' : 'Sorry');
792
- }
793
-
794
- // Renamed thankyou page to results page to be more explicit that TYP is dying
795
- if (this.opts.resultsPage) {
796
- window.location.href = this.opts.resultsPage;
797
- }
798
- // Handling errors, conditional is when no DCK is found
799
- } else {
800
- this.switchFormLoadingState(false);
801
-
802
- if ('function' === typeof this.opts.formSubmitErrorCallback) {
803
- if (this.opts.formSubmitErrorCallback(responseData) === false) {
804
- return false;
805
- }
806
- }
807
-
808
- // We need to override errorRedirectPath if we don't want to redirect to my/results
809
- window.location.href = this.opts.errorRedirectPath;
810
- }
811
- };
812
-
813
- /**
814
- * Check if current domain is eligible for HRC
815
- *
816
- * @returns {Boolean}
817
- */
818
- modForm.isQsSiteEligibleForHrc = function() {
819
- var landingPage = this.opts.landingPage,
820
- eligibleDomains = [
821
- 'modernize.local',
822
- 'qa.modernize.com',
823
- 'modernize.com'
824
- ],
825
- nonEligiblePaths = [
826
- 'gutter-guards',
827
- 'home-warranty',
828
- 'home-security',
829
- 'medicalalerts',
830
- 'bathandshowerremodel'
831
- ];
832
-
833
- var isEligible = (eligibleDomains.indexOf(this.getDefaultSiteByDomain()) > -1 &&
834
- !nonEligiblePaths.some(function(path) {
835
- return landingPage.indexOf('quote/' + path) > -1;
836
- }));
837
-
838
- return isEligible;
839
- };