web-manager 4.3.2 → 4.3.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/_legacy/index.js DELETED
@@ -1,1854 +0,0 @@
1
- /*
2
- https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events
3
- https://gomakethings.com/listening-for-click-events-with-vanilla-javascript/
4
-
5
- JQUERY Ready
6
- https://github.com/jquery/jquery/blob/master/src/core/ready.js
7
- https://github.com/julienschmidt/contentloaded/blob/master/contentloaded.js
8
- https://github.com/dperini/ContentLoaded/blob/master/src/contentloaded.js
9
- https://github.com/pirxpilot/domready/blob/master/index.js
10
- * https://gomakethings.com/a-native-javascript-equivalent-of-jquerys-ready-method/
11
-
12
- */
13
- /**
14
- * DEPENDENCIES
15
- */
16
- // @TODO: code split these: http://jonathancreamer.com/advanced-webpack-part-2-code-splitting/
17
- // var ajax = require('./lib/ajax.js');
18
- var dom = require('./lib/dom.js');
19
- // var query = require('./lib/query.js');
20
- var utilities = require('./lib/utilities.js');
21
- var storage = require('./lib/storage.js');
22
- var account;
23
- var debug;
24
-
25
- // var ajax;
26
- // var dom;
27
- // var query;
28
- // var utilities;
29
- // var storage;
30
-
31
- // Shortcuts
32
- var select;
33
- var loadScript;
34
- var store;
35
-
36
-
37
- /**
38
- * MODULE
39
- */
40
- function getIEVersion() {
41
- // https://makandracards.com/makandra/53475-minimal-javascript-function-to-detect-version-of-internet-explorer-or-edge
42
- var match = /\b(MSIE |Trident.*?rv:|Edge\/)(\d+)/.exec(navigator.userAgent);
43
- if (match) {return parseInt(match[2])};
44
- }
45
-
46
- function isSupportedBrowser() {
47
- var ieVersion = getIEVersion();
48
-
49
- // IE 10 and below
50
- if (ieVersion && ieVersion <= 11) {
51
- return false;
52
- }
53
-
54
- return true;
55
- }
56
-
57
- function Manager() {
58
- var self = this;
59
-
60
- /**
61
- * OPTIONS
62
- */
63
- self.properties = {
64
- options: {
65
- page: {},
66
- global: {},
67
- },
68
- page: {
69
- code: '',
70
- url: '',
71
- status: {
72
- initilizing: false,
73
- ready: false,
74
- authReady: false,
75
- },
76
- // initReady: false,
77
- // initSecondaryReady: false,
78
- queryString: {},
79
- // libErrors: [],
80
- isSupportedBrowser: isSupportedBrowser(),
81
- startTime: new Date(),
82
- // auth: {
83
- // status: undefined,
84
- // lastAction: 'unknown',
85
- // },
86
- },
87
- global: {
88
- version: '',
89
- url: '',
90
- functionsUrl: '',
91
- apiUrl: '',
92
- buildTime: 0,
93
- cacheBreaker: '',
94
- brand: {
95
- name: 'default'
96
- },
97
- contact: {
98
- email: '',
99
- },
100
- download: {
101
- windows: '',
102
- mac: '',
103
- linuxDebian: '',
104
- linuxSnap: '',
105
- },
106
- extension: {
107
- chrome: '',
108
- firefox: '',
109
- edge: '',
110
- opera: '',
111
- safari: '',
112
- },
113
- validRedirectHosts: [],
114
- },
115
- auth: {
116
- user: false
117
- },
118
- references: {
119
- serviceWorker: undefined
120
- },
121
- meta: {
122
- environment: 'production'
123
- }
124
- };
125
-
126
- try {
127
- self.properties.page.url = window.location.href;
128
- } catch (e) {
129
-
130
- }
131
-
132
- select = self.dom().select;
133
- loadScript = self.dom().loadScript;
134
- store = self.storage();
135
- }
136
-
137
- /**
138
- * METHODS
139
- */
140
- Manager.prototype.get = function(path) {
141
- var self = this;
142
-
143
- return utilities.get(self, 'properties.' + path);
144
- }
145
-
146
- Manager.prototype.set = function(path, value) {
147
- var self = this;
148
-
149
- return utilities.set(self, 'properties.' + path, value);
150
- }
151
-
152
- Manager.prototype.setEventListeners = function() {
153
- var self = this;
154
-
155
- // Setup click handler
156
- document.addEventListener('click', function (event) {
157
- var target = event.target;
158
-
159
- // auth events
160
- if (target.matches('.auth-signin-email-btn')) {
161
- self.auth().signIn('email');
162
- } else if (target.matches('.auth-signup-email-btn')) {
163
- self.auth().signUp('email');
164
- } else if (target.matches('.auth-signin-provider-btn')) {
165
- self.auth().signIn(target.getAttribute('data-provider'));
166
- } else if (target.matches('.auth-signup-provider-btn')) {
167
- self.auth().signUp(target.getAttribute('data-provider'));
168
- } else if (target.matches('.auth-signout-all-btn')) {
169
- self.auth().signOut();
170
- } else if (target.matches('.auth-forgot-email-btn')) {
171
- self.auth().forgot();
172
- } else if (target.matches('#prechat-btn')) {
173
- load_chatsy(self, self.properties.options);
174
- } else if (target.matches('.auth-subscribe-notifications-btn')) {
175
- self.notifications().subscribe()
176
- } else if (target.matches('.master-alert-close')) {
177
- target.parentElement.setAttribute('hidden', true);
178
- }
179
-
180
- // Autorequest
181
- if (!self._notificationRequested && self.properties.options.pushNotifications.autoRequest) {
182
- self._notificationRequested = true;
183
-
184
- setTimeout(function () {
185
- self.notifications().subscribe()
186
- }, self.properties.options.pushNotifications.autoRequest * 1000);
187
- }
188
-
189
- });
190
-
191
- // Mouse leave event
192
- document.addEventListener('mouseleave', function () {
193
- showExitPopup(self);
194
- });
195
-
196
- // Window blur event
197
- window.addEventListener('blur', function () {
198
- showExitPopup(self);
199
- });
200
-
201
- // Re-focus events
202
- window.addEventListener('focus', function () {
203
- refreshNewVersion(self);
204
- });
205
- window.addEventListener('online', function () {
206
- refreshNewVersion(self);
207
- });
208
- setInterval(function () {
209
- refreshNewVersion(self);
210
- }, 1000 * 60 * 60); // Fetch new version every 1 hour
211
-
212
- }
213
-
214
- function _authStateHandler(self, user) {
215
- // self.log('----authStateHandler', user);
216
- if (!user || user.isAnonymous) {
217
- return _authHandle_out(self);
218
- }
219
-
220
- _authHandle_in_normal(self, user);
221
-
222
- self.notifications().subscribe().catch(function (e) {
223
- console.error(e);
224
- });
225
- }
226
-
227
- // MOVED TO UJ - 12/15/23
228
- // function _authHandle_in(self, user) {
229
- // // self.log('_authHandle_in', user);
230
- // // if (self.properties.page.status.didSignUp) {
231
- // var done;
232
- // var hoursSinceCreation = Math.abs(new Date() - new Date(+user.metadata.createdAt)) / 36e5;
233
-
234
- // function _done() {
235
- // if (!done) {
236
- // done = true;
237
- // store.set('didSignUp', true)
238
- // _authHandle_in_normal(self, user);
239
- // }
240
- // }
241
-
242
- // if (!store.get('didSignUp') && hoursSinceCreation < 0.5) {
243
- // user.getIdToken(false)
244
- // .then(function(token) {
245
-
246
- // fetch('https://us-central1-' + self.properties.options.libraries.firebase_app.config.projectId + '.cloudfunctions.net/bm_api', {
247
- // method: 'POST',
248
- // body: JSON.stringify({
249
- // authenticationToken: token,
250
- // command: 'user:sign-up',
251
- // payload: {
252
- // newsletterSignUp: select('.auth-newsletter-input').getValue(),
253
- // // affiliateCode: store.get('auth.affiliateCode', ''),
254
- // affiliateCode: store.get('affiliateCode', ''),
255
- // },
256
- // }),
257
- // })
258
- // .catch(function () {})
259
- // .finally(_done);
260
-
261
- // setTimeout(function () {
262
- // _done()
263
- // }, 5000);
264
-
265
- // })
266
- // .catch(function(error) {
267
- // console.error(error);
268
- // _done();
269
- // });
270
- // } else {
271
- // _done();
272
- // }
273
- // }
274
-
275
-
276
-
277
- function _authHandle_in_normal(self, user) {
278
- var returnUrl = self.properties.page.queryString.get('auth_redirect');
279
-
280
- // Check if we have a return URL and it is valid
281
- if (returnUrl && self.isValidRedirectUrl(returnUrl)) {
282
- window.location.href = decodeURIComponent(returnUrl);
283
- return;
284
- }
285
-
286
- // If auth is prohibited, redirect to the prohibited page
287
- if (self.properties.options.auth.state === 'prohibited') {
288
- window.location.href = self.properties.options.auth.sends.prohibited;
289
- return;
290
- }
291
-
292
- // Handle visibility
293
- // select('.auth-signedin-true-element').show();
294
- // select('.auth-signedin-false-element').hide();
295
- select('.auth-signedin-true-element').each(function ($el) {
296
- var $el2 = select($el);
297
- $el2.show();
298
-
299
- console.warn('DEPRECATED: auth-signedin-true-element', $el);
300
- });
301
- select('.auth-signedin-false-element').each(function ($el) {
302
- var $el2 = select($el);
303
- $el2.hide();
304
-
305
- console.warn('DEPRECATED: auth-signedin-false-element', $el);
306
- });
307
- _authHandleState(self, 'signed-in');
308
-
309
- // Set user email
310
- select('.auth-email-element').each(function(e, i) {
311
- if (e.tagName === 'INPUT') {
312
- select(e).setValue(user.email)
313
- } else {
314
- select(e).setInnerHTML(user.email)
315
- }
316
- });
317
-
318
- // Set user id
319
- select('.auth-uid-element').each(function(e, i) {
320
- if (e.tagName === 'INPUT') {
321
- select(e).setValue(user.uid)
322
- } else {
323
- select(e).setInnerHTML(user.uid)
324
- }
325
- });
326
- }
327
-
328
- function _authHandle_out(self) {
329
- // If auth is required, redirect to the required page
330
- if (self.properties.options.auth.state === 'required') {
331
- var sendSplit = self.properties.options.auth.sends.required.split('?');
332
- var newQuery = new URLSearchParams(sendSplit[1]);
333
- newQuery.set('auth_redirect', window.location.href);
334
- window.location.href = sendSplit[0] + '?' + newQuery.toString();
335
- return;
336
- }
337
-
338
- // select('.auth-signedin-true-element').hide();
339
- // select('.auth-signedin-false-element').show();
340
- select('.auth-signedin-true-element').each(function ($el) {
341
- var $el2 = select($el);
342
- $el2.hide();
343
-
344
- console.warn('DEPRECATED: auth-signedin-true-element', $el);
345
- });
346
- select('.auth-signedin-false-element').each(function ($el) {
347
- var $el2 = select($el);
348
- $el2.show();
349
-
350
- console.warn('DEPRECATED: auth-signedin-false-element', $el);
351
- });
352
-
353
- _authHandleState(self, 'signed-out');
354
- }
355
-
356
- function _authHandleState(self, state) {
357
- var $stateAll = select('.auth-state-listener');
358
-
359
- // Loop through all elements with the class and hide first
360
- $stateAll
361
- .each(function ($el) {
362
- $el.setAttribute('hidden', true);
363
- })
364
-
365
- // Loop through all elements with the class and check the data-state attribute
366
- $stateAll
367
- .each(function ($el) {
368
- var s = $el.getAttribute('data-state');
369
-
370
- // If we are in the correct status
371
- if (s !== state) {
372
- // Hide the element
373
- return $el.setAttribute('hidden', true);
374
- }
375
-
376
- // Show the element
377
- $el.removeAttribute('hidden');
378
- })
379
- }
380
-
381
- Manager.prototype.ready = function(fn, options) {
382
- var self = this;
383
- var waitFor = true;
384
-
385
- options = options || {};
386
- options.interval = options.interval || 100;
387
-
388
- waitFor = !options.waitFor || (options.waitFor && options.waitFor())
389
-
390
- if (!utilities.get(this, 'properties.page.status.ready', false) || !waitFor) {
391
- setTimeout(function () {
392
- self.ready(fn, options);
393
- }, options.interval);
394
- } else {
395
- // Performance
396
- self.performance().mark('manager_ready');
397
-
398
- return fn();
399
- }
400
- }
401
-
402
- Manager.prototype.serviceWorker = function() {
403
- var self = this;
404
- var SWAvailable = 'serviceWorker' in navigator;
405
-
406
- if (SWAvailable) {
407
- try {
408
- var swref = self.properties.references.serviceWorker.active || navigator.serviceWorker.controller;
409
- } catch (e) {}
410
- }
411
-
412
- return {
413
- postMessage: function() {
414
- // var args = getArgs(arguments);
415
- var args = arguments;
416
- if (!SWAvailable) {return};
417
-
418
- try {
419
- var messageChannel = new MessageChannel();
420
- messageChannel.port1.onmessage = function(event) {
421
- if (!event.data.error && args[1]) {
422
- args[1](event.data);
423
- }
424
- };
425
- // navigator.serviceWorker.controller.postMessage(args[0], [messageChannel.port2]);
426
- swref.postMessage(args[0], [messageChannel.port2]);
427
- } catch (e) {
428
- console.error(e);
429
- }
430
-
431
- // if (!navigator.serviceWorker.controller) {
432
- // self.log('postMessage...');
433
- // setTimeout(function () {
434
- // self.serviceWorker().postMessage(args[0], args[1]);
435
- // }, 100);
436
- // } else {
437
- // // post message: https://stackoverflow.com/questions/30177782/chrome-serviceworker-postmessage
438
- // var messageChannel = new MessageChannel();
439
- // messageChannel.port1.onmessage = function(event) {
440
- // if (!event.data.error && args[1]) {
441
- // args[1](event.data);
442
- // }
443
- // };
444
- // navigator.serviceWorker.controller.postMessage(args[0], [messageChannel.port2])
445
- // }
446
- }
447
- }
448
- }
449
-
450
- // init with polyfills
451
- Manager.prototype.init = function(configuration, callback) {
452
- var self = this;
453
- var status = self.properties.page.status;
454
-
455
- if (
456
- !status.ready
457
- && !status.initilizing
458
- ) {
459
- // Performance
460
- self.performance().mark('manager_init');
461
-
462
- // set initializing to true
463
- self.properties.page.status.initializing = true;
464
-
465
- // set other properties
466
- self.properties.meta.environment = window.location.host.match(/:40|ngrok/)
467
- ? 'development'
468
- : 'production';
469
-
470
- // Load polyfills
471
- init_loadPolyfills(self, configuration, function() {
472
- self.properties.page.status.initializing = false;
473
-
474
- // set options
475
- var options_defaults = {
476
- // debug: {
477
- // environment: self.properties.meta.environment,
478
- // },
479
- // queryString: {
480
- // saveToStorage: false
481
- // },
482
- pushNotifications: {
483
- autoRequest: 60, // how long to wait before auto ask, 0 to disable
484
- },
485
- serviceWorker: {
486
- path: '',
487
- },
488
- // polyFill: false,
489
- auth: {
490
- state: 'default', // required, prohibited, default
491
- sends: {
492
- required: '/signup',
493
- prohibited: '/',
494
- },
495
- },
496
- refreshNewVersion: {
497
- enabled: true,
498
- },
499
- exitPopup: {
500
- enabled: true,
501
- config: {
502
- timeout: 1000 * 60 * 60 * 4,
503
- handler: null,
504
- title: 'Special Offer!',
505
- message: 'Get 15% off your purchase of our <strong>Premium plans</strong>. <br><br> Get access to all features and unlimited usage.',
506
- okButton: {
507
- text: 'Claim 15% Discount',
508
- link: '/pricing?utm_source=exit-popup&utm_medium=popup&utm_campaign={pathname}',
509
- },
510
- },
511
- },
512
- libraries: {
513
- firebase_app: {
514
- enabled: true,
515
- load: false,
516
- config: {
517
- apiKey: '',
518
- authDomain: '',
519
- databaseURL: '',
520
- projectId: '',
521
- storageBucket: '',
522
- messagingSenderId: '',
523
- appId: '',
524
- measurementId: '',
525
- },
526
- },
527
- firebase_auth: {
528
- enabled: true,
529
- load: false,
530
- },
531
- firebase_firestore: {
532
- enabled: true,
533
- load: false,
534
- },
535
- firebase_messaging: {
536
- enabled: true,
537
- load: false,
538
- },
539
- firebase_appCheck: {
540
- enabled: true,
541
- load: false,
542
- config: {
543
- siteKey: '',
544
- },
545
- },
546
- lazysizes: {
547
- enabled: true,
548
- },
549
- sentry: {
550
- enabled: true,
551
- config: {
552
- dsn: '',
553
- release: '',
554
- replaysSessionSampleRate: 0.01,
555
- replaysOnErrorSampleRate: 0.01,
556
- },
557
- },
558
- chatsy: {
559
- enabled: true,
560
- config: {
561
- accountId: '',
562
- chatId: '',
563
- settings: {
564
- openChatButton: {
565
- background: '#237afc',
566
- text: '#fff',
567
- },
568
- },
569
- },
570
- },
571
- cookieconsent: {
572
- enabled: true,
573
- config: {
574
- palette: {
575
- popup: {
576
- background: '#237afc',
577
- text: '#fff',
578
- },
579
- button: {
580
- background: '#fff',
581
- text: '#237afc',
582
- },
583
- },
584
- theme: 'classic',
585
- position: 'bottom-left',
586
- type: '',
587
- showLink: false,
588
- content: {
589
- message: 'We use cookies to ensure you get the best experience on our website. By continuing to use the site, you agree to our<a href="/terms" class="cc-link" style="padding-right: 0">terms of service</a>.',
590
- // dismiss: 'Got it!',
591
- dismiss: 'I understand',
592
- },
593
- },
594
- },
595
- },
596
- };
597
-
598
- var options_user = {};
599
- function eachRecursive(obj, parent) {
600
- parent = (!parent) ? '' : parent;
601
-
602
- for (var key in obj) {
603
- if (typeof obj[key] === 'object' && obj[key] !== null && !Array.isArray(obj[key])) {
604
- eachRecursive(obj[key], parent + key + '.');
605
- } else {
606
- utilities.set(options_user, parent + key, utilities.get(options_defaults, parent + key) );
607
- var t_globalItem = utilities.get(configuration, 'global.settings.' + parent + key, undefined);
608
- var t_pageItem = utilities.get(configuration, 'page.settings.' + parent + key, undefined);
609
- if (typeof t_globalItem !== 'undefined') {
610
- utilities.set(options_user, parent + key, t_globalItem);
611
- }
612
- if (typeof t_pageItem !== 'undefined') {
613
- utilities.set(options_user, parent + key, t_pageItem);
614
- }
615
- }
616
- }
617
- }
618
-
619
- eachRecursive(options_defaults);
620
- self.properties.options = options_user;
621
-
622
- // set non-option properties
623
- self.properties.global.app = configuration.global.app;
624
- self.properties.global.version = configuration.global.version;
625
- self.properties.global.url = configuration.global.url;
626
- self.properties.global.buildTime = new Date((+configuration.global.buildTime * 1000) || new Date());
627
- self.properties.global.cacheBreaker = configuration.global.cacheBreaker;
628
-
629
- self.properties.global.brand = configuration.global.brand;
630
- self.properties.global.contact = configuration.global.contact;
631
- self.properties.global.download = configuration.global.download;
632
- self.properties.global.extension = configuration.global.extension;
633
-
634
- self.properties.global.validRedirectHosts = configuration.global.validRedirectHosts;
635
- self.properties.meta.environment = utilities.get(configuration, 'global.settings.debug.environment', self.properties.meta.environment);
636
- self.properties.page.queryString = new URLSearchParams(window.location.search);
637
-
638
- // set global properties
639
- self.properties.global.apiUrl = getApiUrl(self.properties.global.url);
640
- self.properties.global.functionsUrl = 'https://us-central1-' + self.properties.options.libraries.firebase_app.config.projectId + '.cloudfunctions.net';
641
-
642
- // set page properties
643
- var pagePathname = window.location.pathname;
644
- var redirect = false;
645
-
646
- var previousUTMTimestamp = new Date(store.get('utm.timestamp', 0));
647
- var UTMDifferenceInHours = (new Date() - previousUTMTimestamp) / 36e5;
648
-
649
- self.properties.page.queryString.forEach(function (value, key) {
650
- if (key.startsWith('utm_') && UTMDifferenceInHours > 72) {
651
- store.set('utm.tags.' + key, value);
652
- store.set('utm.timestamp', new Date().toISOString());
653
- }
654
-
655
- if (key === 'aff') {
656
- store.set('affiliateCode', value);
657
- }
658
-
659
- if (key === 'redirect') {
660
- // redirect = decodeURIComponent(value) // 9/22/23 - Removed this and replace without the decode
661
- redirect = value;
662
- }
663
- })
664
-
665
- // Redirect if we have a redirect query
666
- if (redirect && self.isValidRedirectUrl(redirect)) {
667
- return window.location.href = redirect;
668
- }
669
-
670
- // Detect if we are on a page that requires authentication
671
- if (pagePathname.match(/\/(authentication-required|authentication-success|authentication-token|forgot|oauth2|signin|signout|signup)/)) {
672
- import('./helpers/auth-pages.js')
673
- .then(function(mod) {
674
- mod.default()
675
- })
676
- }
677
-
678
- // load critical libraries
679
- function postCrucial() {
680
- // console.log('HERE 5');
681
-
682
- // handle firebase user
683
- if (typeof firebase !== 'undefined' && firebase.auth) {
684
- firebase.auth().onAuthStateChanged(function(user) {
685
- self.properties.page.status.authReady = true;
686
- self.properties.auth.user = user || false;
687
- _authStateHandler(self, user);
688
- })
689
- }
690
-
691
- // setup
692
- self.setEventListeners();
693
-
694
- // display outdated if it is
695
- try {
696
- if (!self.properties.page.isSupportedBrowser) {
697
- var box = document.getElementsByClassName('master-alert-outdated')[0];
698
- box.removeAttribute('hidden');
699
- }
700
- } catch (e) {
701
- console.error(e);
702
- }
703
-
704
- // run the init callback
705
- self.properties.page.status.ready = true;
706
-
707
- try {
708
- callback();
709
- } catch (e) {
710
- console.error(e);
711
- }
712
-
713
- var chatsyOps = options_user.libraries.chatsy;
714
- if (chatsyOps.enabled) {
715
- var $preChatBtn = select('#prechat-btn');
716
- var $preChatBtnSvg = select('#prechat-btn svg path');
717
- var openChatButtonSettings = chatsyOps.config.settings.openChatButton;
718
-
719
- $preChatBtn.css({
720
- background: openChatButtonSettings.background,
721
- })
722
- .show();
723
-
724
- $preChatBtnSvg.each(function ($el) {
725
- $el.setAttribute('fill', openChatButtonSettings.text)
726
- })
727
-
728
- window.chatsy = {};
729
- window.chatsy.open = function() {
730
- $preChatBtn.get(0).click();
731
- }
732
- }
733
-
734
- // load non-critical libraries
735
- load_lazysizes(self, options_user);
736
- load_cookieconsent(self, options_user);
737
- subscriptionManager(self, options_user);
738
-
739
- // self.log('Manager', self);
740
- return;
741
- }
742
-
743
- Promise.all([
744
- load_sentry(self, options_user),
745
- load_firebase(self, options_user),
746
- ])
747
- .then(function() {
748
- postCrucial();
749
- })
750
- .catch(function (e) {
751
- console.error('Lib error', e);
752
- })
753
- })
754
-
755
- } else {
756
- return;
757
- }
758
-
759
- }
760
-
761
- Manager.prototype.sentry = function() {
762
- // var en = (Sentry && Sentry)
763
- return {
764
- configureScope: function (cb) {
765
- try {
766
- Sentry.configureScope(function (scope) {
767
- cb(scope);
768
- })
769
- } catch (e) {
770
-
771
- }
772
- },
773
- captureException: function (e) {
774
- try {
775
- Sentry.captureException(e)
776
- } catch (e) {
777
-
778
- }
779
- }
780
- };
781
- }
782
-
783
- Manager.prototype.auth = function() {
784
- var self = this;
785
- var firebaseActive = typeof firebase !== 'undefined';
786
- var $error = select('.auth-error-message-element');
787
-
788
- function _displayError(msg) {
789
- console.error(msg);
790
- $error.show().setInnerHTML(msg);
791
- }
792
- function _preDisplayError() {
793
- $error.hide().setInnerHTML('');
794
- }
795
-
796
- function setAuthButtonDisabled(button, status) {
797
- var el = select('.auth-' + button + '-email-btn');
798
- var disabled = 'disabled';
799
- if (status) {
800
- el.setAttribute(disabled, true);
801
- } else {
802
- el.removeAttribute(disabled);
803
- }
804
- }
805
-
806
- function selectAuthInput(mode, input) {
807
- var prefix = '.auth-';
808
- var inputSelector = prefix + input + '-input';
809
- var formSelector = prefix + mode + '-form ';
810
- var formInput = select(formSelector + inputSelector);
811
- var input = select(inputSelector);
812
-
813
- return formInput.exists() ? formInput : input;
814
- }
815
-
816
- function resolveAuthInputValue(existing, mode, input) {
817
- var result = existing || selectAuthInput(mode, input).getValue();
818
-
819
- return input === 'email' ? result.trim().toLowerCase() : result;
820
- }
821
-
822
- function uxHandler(email, password, passwordConfirm, mode) {
823
- if (!email) {
824
- selectAuthInput(mode, 'email').get(0).focus();
825
- } else {
826
- selectAuthInput(mode, 'password').get(0).focus();
827
- if (mode === 'signup') {
828
- selectAuthInput(mode, 'password-confirm').get(0).focus();
829
- }
830
- }
831
- }
832
-
833
- return {
834
- isAuthenticated: function () {
835
- return firebaseActive ? !!firebase.auth().currentUser : false;
836
- },
837
- getUser: function () {
838
- var defaultUser = {email: null, uid: null};
839
- return firebaseActive ? firebase.auth().currentUser || defaultUser : defaultUser;
840
- },
841
- ready: function (fn, options) {
842
- options = options || {};
843
- options.interval = options.interval || 100;
844
-
845
- if (!utilities.get(self, 'properties.page.status.authReady', false)) {
846
- setTimeout(function () {
847
- self.auth().ready(fn, options);
848
- }, options.interval);
849
- } else {
850
-
851
- // Set up listener for redirect (for provider login)
852
- // @@@ DISABLED NOV 8, 2023
853
- // if (!self._redirectResultSetup) {
854
- // self._redirectResultSetup = true;
855
- // firebase.auth()
856
- // .getRedirectResult()
857
- // .catch(function (error) {
858
- // _displayError(error.message);
859
- // });
860
- // }
861
-
862
- // Performance
863
- self.performance().mark('manager_authReady');
864
-
865
- return fn(self.auth().getUser());
866
- }
867
- },
868
- signIn: function (method, email, password) {
869
- var mode = 'signin';
870
- method = method || 'email';
871
- _preDisplayError();
872
- // self.log('Signin attempt: ', method, email, password);
873
- if (method === 'email') {
874
- // email = (email || select('.auth-email-input').getValue()).trim().toLowerCase();
875
- email = resolveAuthInputValue(email, mode, 'email');
876
- // password = password || select('.auth-password-input').getValue();
877
- password = resolveAuthInputValue(password, mode, 'password');
878
- // console.log('Signin attempt: ', method, email, password);
879
-
880
- // Handler
881
- uxHandler(email, password, undefined, mode);
882
-
883
- // signinButtonDisabled(true);
884
- setAuthButtonDisabled(mode, true);
885
-
886
- firebase.auth().signInWithEmailAndPassword(email, password)
887
- .then(function(credential) {
888
- // _postAuthSubscriptionCheck(self)
889
- // .then(function () {
890
- //
891
- // })
892
- self.properties.page.status.didSignIn = true;
893
- // signinButtonDisabled(false);
894
- setAuthButtonDisabled(mode, false);
895
- // self.log('Good signin');
896
- })
897
- .catch(function(error) {
898
- // signinButtonDisabled(false);
899
- setAuthButtonDisabled(mode, false);
900
- _displayError(error.message);
901
- // self.log('Error', error.message);
902
- });
903
- } else {
904
- firebase.auth().signInWithRedirect(new firebase.auth.OAuthProvider(method))
905
- .catch(function (e) {
906
- _displayError(e);
907
- })
908
- }
909
- },
910
- signUp: function(method, email, password, passwordConfirm) {
911
- var mode = 'signup';
912
- method = method || 'email';
913
-
914
- _preDisplayError();
915
- // self.log('Signup attempt: ', method, email, password, passwordConfirm);
916
- // var acceptedTerms
917
- // var termEl = select('.auth-terms-input');
918
- // if (termEl.exists() && !termEl.getValue() === true) {
919
- // _displayError('Please review and accept our terms.');
920
- // return;
921
- // }
922
- var termsSelector = '.auth-terms-input';
923
- var termSpecificEl = select('.auth-signup-form ' + termsSelector)
924
- var termGenericEl = select(termsSelector)
925
- if ((termSpecificEl.exists() && !termSpecificEl.getValue() === true) || (termGenericEl.exists() && !termGenericEl.getValue() === true)) {
926
- _displayError('Please review and accept our terms.');
927
- return;
928
- }
929
-
930
- if (method === 'email') {
931
- // email = (email || select('.auth-email-input').getValue()).trim().toLowerCase();
932
- email = resolveAuthInputValue(email, mode, 'email');
933
- // password = password || select('.auth-password-input').getValue();
934
- password = resolveAuthInputValue(password, mode, 'password');
935
- // passwordConfirm = passwordConfirm || select('.auth-password-confirm-input').getValue();
936
- passwordConfirm = resolveAuthInputValue(passwordConfirm, mode, 'password-confirm');
937
- // console.log('Signup attempt: ', method, email, password, passwordConfirm);
938
-
939
- // Handler
940
- uxHandler(email, password, passwordConfirm, mode);
941
-
942
- if (password === passwordConfirm) {
943
- // signupButtonDisabled(true);
944
- setAuthButtonDisabled(mode, true);
945
- firebase.auth().createUserWithEmailAndPassword(email, password)
946
- .then(function(credential) {
947
- // self.properties.page.status.didSignUp = true;
948
- // self.log('Good signup');
949
- // signupButtonDisabled(false);
950
- })
951
- .catch(function(error) {
952
- // signupButtonDisabled(false);
953
- setAuthButtonDisabled(mode, false);
954
- _displayError(error.message);
955
- // self.log('error', error.message);
956
- });
957
- } else {
958
- _displayError("Passwords don't match.");
959
- }
960
- } else {
961
- self.auth().signIn(method);
962
- }
963
-
964
- },
965
- signOut: function() {
966
- // self.log('signOut()');
967
- // var self = this;
968
- return firebase.auth().signOut()
969
- .catch(function(e) {
970
- console.error(e);
971
- // self.log('signOut failed: ', error);
972
- });
973
- // return firebase.auth().signOut()
974
- // .then(function() {
975
- // // self.log('signOut success.');
976
- // })
977
- // .catch(function(e) {
978
- // // console.error(e);
979
- // // self.log('signOut failed: ', error);
980
- // });
981
- },
982
- forgot: function(email) {
983
- // self.log('forgot()');
984
- var mode = 'forgot';
985
- // email = email || select('.auth-email-input').getValue();
986
- email = resolveAuthInputValue(email, mode, 'email')
987
-
988
- // forgotButtonDisabled(true);
989
- setAuthButtonDisabled(mode, true);
990
- _preDisplayError();
991
-
992
- firebase.auth().sendPasswordResetEmail(email)
993
- .then(function() {
994
- // forgotButtonDisabled(false);
995
- setAuthButtonDisabled(mode, false);
996
- // self.log('forgot success.');
997
- _displayError('A reset link has been sent to you.');
998
- })
999
- .catch(function(error) {
1000
- // forgotButtonDisabled(false);
1001
- setAuthButtonDisabled(mode, false);
1002
- // self.log('forgot failed: ', error);
1003
- _displayError(error.message);
1004
- });
1005
- },
1006
-
1007
- }
1008
- }
1009
-
1010
- //@@@NOTIFICATIONS
1011
- Manager.prototype.notifications = function(options) {
1012
- var self = this;
1013
- var supported = (typeof firebase.messaging !== 'undefined') && ('serviceWorker' in navigator) && ('Notification' in window);
1014
-
1015
- return {
1016
- isSubscribed: function () {
1017
- return new Promise(function(resolve, reject) {
1018
- // Log
1019
- // self.log('isSubscribed()');
1020
-
1021
- // Check if subscribed
1022
- return resolve(supported && Notification.permission === 'granted');
1023
- })
1024
- },
1025
- subscribe: function () {
1026
- return new Promise(function(resolve, reject) {
1027
- // Log
1028
- // self.log('subscribe()');
1029
-
1030
- // Check if supported
1031
- if (!supported) {
1032
- return resolve(false)
1033
- }
1034
-
1035
- // Ask for permission
1036
- firebase.messaging()
1037
- .getToken({
1038
- serviceWorkerRegistration: self.properties.references.serviceWorker,
1039
- })
1040
- .then(function (token) {
1041
- var user = self.auth().getUser();
1042
- var localSubscription = store.get('notifications', {});
1043
- var localHash = localSubscription.token + '|' + localSubscription.uid;
1044
- var userHash = token + '|' + user.uid;
1045
- // console.log('user', user);
1046
- // console.log('localHash', localHash);
1047
- // console.log('userHash', userHash);
1048
-
1049
- // var override = false;
1050
- var currentDate = new Date();
1051
- var dateDifference = (currentDate.getTime() - new Date(localSubscription.lastSynced || 0).getTime()) / (1000 * 3600 * 24);
1052
-
1053
- // Run if local hash is different than the user hash OR it was last updated more than 1 day ago
1054
- if (localHash !== userHash || dateDifference > 1) {
1055
- var timestamp = currentDate.toISOString();
1056
- var timestampUNIX = Math.floor((+new Date(timestamp)) / 1000);
1057
- var subscriptionRef = firebase.firestore().doc('notifications/' + token);
1058
-
1059
- function saveLocal() {
1060
- // console.log('---------saveLocal');
1061
- // self.log('Saved local token: ', token);
1062
- store.set('notifications', {uid: user.uid, token: token, lastSynced: timestamp});
1063
- }
1064
-
1065
- function saveServer(doc) {
1066
- // Run if it (DOES NOT EXIST on server) OR (it does AND the uid field is null AND the current user is not null)
1067
- if (!doc.exists || (doc.exists && !self.utilities().get(doc.data(), 'owner.uid', '') && user.uid)) {
1068
- subscriptionRef
1069
- .set(
1070
- {
1071
- created: {
1072
- timestamp: timestamp,
1073
- timestampUNIX: timestampUNIX,
1074
- },
1075
- owner: {
1076
- uid: user.uid,
1077
- },
1078
- token: token,
1079
- url: window.location.href,
1080
- tags: ['general'],
1081
- },
1082
- {
1083
- merge: true,
1084
- },
1085
- )
1086
- .then(function(data) {
1087
- // self.log('Updated token:', token);
1088
- saveLocal();
1089
- resolve(true);
1090
- })
1091
- } else {
1092
- saveLocal();
1093
- // self.log('Skip sync because server data exists');
1094
- resolve(false);
1095
- }
1096
- }
1097
-
1098
- // Get the doc first and then run a check to see if it needs to be updated
1099
- subscriptionRef
1100
- .get()
1101
- .then(function (doc) {
1102
- saveServer(doc);
1103
- })
1104
- .catch(function () {
1105
- saveServer({exists: false})
1106
- })
1107
- } else {
1108
- // self.log('Skip sync because recently done');
1109
- resolve(false);
1110
- }
1111
-
1112
- })
1113
- .catch(function (e) {
1114
- reject(e);
1115
- })
1116
- })
1117
- }
1118
- }
1119
- }
1120
-
1121
- /*
1122
- HELPERS
1123
- */
1124
- function subscriptionManager(self, options_user) {
1125
- if (
1126
- !('serviceWorker' in navigator)
1127
- || (typeof firebase === 'undefined')
1128
- || (typeof firebase.messaging === 'undefined')
1129
- ) {
1130
- return
1131
- }
1132
-
1133
- // service worker guide: https://developers.google.com/web/updates/2018/06/fresher-sw
1134
- navigator.serviceWorker.register(
1135
- '/' + (options_user.serviceWorker.path || 'master-service-worker.js')
1136
- + '?config=' + encodeURIComponent(JSON.stringify({
1137
- name: self.properties.global.brand.name,
1138
- app: self.properties.global.app,
1139
- env: self.properties.meta.environment,
1140
- v: self.properties.global.version,
1141
- cb: self.properties.global.cacheBreaker,
1142
- firebase: options_user.libraries.firebase_app.config
1143
- }))
1144
- )
1145
- .then(function (registration) {
1146
- // Force Firebase to use the service worker
1147
- // firebase.messaging().useServiceWorker(registration);
1148
-
1149
- // Set the registration to the properties
1150
- self.properties.references.serviceWorker = registration;
1151
-
1152
- // TODO: https://googlechrome.github.io/samples/service-worker/post-message/
1153
- // --- leverage this example ^^^ for caching! It's grat and you can do one page at a time through postMessage!
1154
-
1155
- // function listenForWaitingServiceWorker(reg, callback) {
1156
- // function awaitStateChange() {
1157
- // reg.installing.addEventListener('statechange', function() {
1158
- // if (this.state === 'installed') callback(reg);
1159
- // });
1160
- // }
1161
- // if (!reg) return;
1162
- // if (reg.waiting) return callback(reg);
1163
- // if (reg.installing) awaitStateChange();
1164
- // reg.addEventListener('updatefound', awaitStateChange);
1165
- // }
1166
- //
1167
- // // reload once when the new Service Worker starts activating
1168
- // var refreshing;
1169
- // navigator.serviceWorker.addEventListener('controllerchange',
1170
- // function() {
1171
- // if (refreshing) return;
1172
- // refreshing = true;
1173
- // window.location.reload();
1174
- // }
1175
- // );
1176
- // function promptUserToRefresh(reg) {
1177
- // // this is just an example
1178
- // // don't use window.confirm in real life; it's terrible
1179
- // if (window.confirm("New version available! OK to refresh?")) {
1180
- // reg.waiting.postMessage({command: 'skipWaiting'});
1181
- // }
1182
- // }
1183
- // listenForWaitingServiceWorker(registration, promptUserToRefresh);
1184
-
1185
- // self.log('SW Registered.');
1186
- //@@@NOTIFICATIONS
1187
- // _setupTokenRefreshHandler(self);
1188
-
1189
- // Force update the service worker
1190
- registration.update();
1191
-
1192
- // Normally, notifications are not displayed when user is ON PAGE but we will display it here anyway
1193
- try {
1194
- firebase.messaging().onMessage(function (payload) {
1195
- // Get the notification data
1196
- var notification = payload.notification;
1197
- var data = payload.data;
1198
-
1199
- // Get the click action
1200
- var clickAction = notification.click_action || data.click_action;
1201
-
1202
- // Log
1203
- console.log('Message received', payload, clickAction);
1204
-
1205
- // Display notification
1206
- new Notification(notification.title, notification)
1207
- .onclick = function(event) {
1208
- // Log
1209
- console.log('Notification clicked', clickAction);
1210
-
1211
- // Quit if there is no click action
1212
- if (!clickAction) {
1213
- return;
1214
- }
1215
-
1216
- // prevent the browser from focusing the Notification's tab
1217
- event.preventDefault();
1218
-
1219
- // Open the click action
1220
- window.open(clickAction, '_blank');
1221
- }
1222
- })
1223
- } catch (e) {
1224
- console.error(e);
1225
- }
1226
- })
1227
- .catch(function (e) {
1228
- // console.log('***2');
1229
- console.error(e);
1230
- });
1231
-
1232
- // Service Worker Ready
1233
- // navigator.serviceWorker.ready.then(function(registration) {
1234
- // });
1235
- }
1236
-
1237
- function showExitPopup(self) {
1238
- var exitPopupSettings = self.properties.options.exitPopup;
1239
-
1240
- if (!exitPopupSettings.enabled) {
1241
- return;
1242
- };
1243
-
1244
- var lastTriggered = new Date(storage.get('exitPopup.lastTriggered', 0));
1245
- var now = new Date();
1246
- var diff = now - lastTriggered;
1247
-
1248
- if (diff < exitPopupSettings.config.timeout) {
1249
- return;
1250
- };
1251
-
1252
- showBootstrapModal(exitPopupSettings);
1253
- }
1254
-
1255
- function showBootstrapModal(exitPopupSettings) {
1256
- var proceed = exitPopupSettings.config.handler
1257
- ? exitPopupSettings.config.handler()
1258
- : true;
1259
-
1260
- if (!proceed) {
1261
- return;
1262
- }
1263
-
1264
- var $el = document.getElementById('modal-exit-popup');
1265
- try {
1266
- var modal = new bootstrap.Modal($el);
1267
- modal.show();
1268
- $el.removeAttribute('hidden');
1269
-
1270
- var $title = $el.querySelector('.modal-title');
1271
- var $message = $el.querySelector('.modal-body');
1272
- var $okButton = $el.querySelector('.modal-footer .btn-primary');
1273
- var config = exitPopupSettings.config;
1274
-
1275
- var link = config.okButton.link
1276
- .replace(/{pathname}/ig, window.location.pathname)
1277
-
1278
- $title.innerHTML = config.title;
1279
- $message.innerHTML = config.message;
1280
- $okButton.innerHTML = config.okButton.text;
1281
- $okButton.setAttribute('href', link);
1282
-
1283
- storage.set('exitPopup.lastTriggered', new Date().toISOString());
1284
- } catch (e) {
1285
- console.warn(e);
1286
- }
1287
- }
1288
-
1289
- function refreshNewVersion(self) {
1290
- // console.log('refreshNewVersion()');
1291
-
1292
- // Skip if not enabled
1293
- if (!self.properties.options.refreshNewVersion.enabled) {
1294
- return;
1295
- }
1296
-
1297
- // Make request to get the build time (live)
1298
- fetch('/build.json?cb=' + new Date().getTime())
1299
- .then(function (res) {
1300
- if (res.ok) {
1301
- return res.json();
1302
- } else {
1303
- throw new Error('Bad response');
1304
- }
1305
- })
1306
- .then(function (data) {
1307
- var buildTimeCurrent = self.properties.global.buildTime;
1308
- var buildTimeLive = new Date(data.timestamp);
1309
-
1310
- // Set buildTimeCurrent to 1 hour ahead to account for the npm-build time which will ALWAYS be set to later since it happens later
1311
- buildTimeCurrent.setHours(buildTimeCurrent.getHours() + 1);
1312
-
1313
- // Log
1314
- // console.log('refreshNewVersion()', data, buildTimeCurrent, buildTimeLive);
1315
-
1316
- // If the live time is newer, refresh
1317
- if (buildTimeCurrent < buildTimeLive) {
1318
- console.log('refreshNewVersion(): Refreshing...');
1319
-
1320
- if (self.isDevelopment()) {
1321
- return;
1322
- }
1323
-
1324
- // Force page reload
1325
- window.onbeforeunload = function () {
1326
- return undefined;
1327
- }
1328
-
1329
- // Refresh
1330
- window.location.reload(true);
1331
- }
1332
- })
1333
- .catch(function (e) {
1334
- console.error(e);
1335
- })
1336
- }
1337
-
1338
- /*
1339
- EXTERNAL LIBS
1340
- */
1341
- var load_firebase = function(self, options) {
1342
- return new Promise(function(resolve, reject) {
1343
- // Set shortcuts
1344
- var setting = options.libraries.firebase_app
1345
-
1346
- // Skip if not enabled
1347
- if (!setting.enabled) {
1348
- return resolve();
1349
- }
1350
-
1351
- // Setup Firebase
1352
- function _post() {
1353
- // Initialize Firebase
1354
- window.app = firebase.initializeApp(setting.config);
1355
-
1356
- // Load Firebase libraries
1357
- Promise.all([
1358
- load_firebase_auth(self, options),
1359
- load_firebase_firestore(self, options),
1360
- load_firebase_messaging(self, options),
1361
- load_firebase_appCheck(self, options),
1362
- ])
1363
- .then(resolve)
1364
- .catch(reject);
1365
- }
1366
-
1367
- // Load Firebase
1368
- if (setting.load) {
1369
- setting.load(self)
1370
- .then(_post)
1371
- .catch(reject);
1372
- } else {
1373
- // import('firebase/app')
1374
- import('firebase/compat/app')
1375
- .then(function(mod) {
1376
- window.firebase = mod.default;
1377
- _post()
1378
- })
1379
- .catch(reject);
1380
- }
1381
- });
1382
- }
1383
-
1384
- var load_firebase_auth = function(self, options) {
1385
- return new Promise(function(resolve, reject) {
1386
- // Set shortcuts
1387
- var setting = options.libraries.firebase_auth;
1388
-
1389
- // Skip if not enabled
1390
- if (!setting.enabled) {
1391
- return resolve();
1392
- }
1393
-
1394
- // Load Firebase Auth
1395
- if (setting.load) {
1396
- setting.load(self)
1397
- .then(resolve)
1398
- .catch(reject);
1399
- } else {
1400
- // import('firebase/auth')
1401
- import('firebase/compat/auth')
1402
- .then(resolve)
1403
- .catch(reject);
1404
- }
1405
- });
1406
- }
1407
-
1408
- var load_firebase_firestore = function(self, options) {
1409
- return new Promise(function(resolve, reject) {
1410
- // Set shortcuts
1411
- var setting = options.libraries.firebase_firestore;
1412
-
1413
- // Skip if not enabled
1414
- if (!setting.enabled) {
1415
- return resolve();
1416
- }
1417
-
1418
- // Load Firebase Firestore
1419
- if (setting.load) {
1420
- setting.load(self)
1421
- .then(resolve)
1422
- .catch(reject);
1423
- } else {
1424
- // import('firebase/firestore')
1425
- import('firebase/compat/firestore')
1426
- .then(resolve)
1427
- .catch(reject);
1428
- }
1429
- });
1430
- }
1431
-
1432
- var load_firebase_messaging = function(self, options) {
1433
- return new Promise(function(resolve, reject) {
1434
- // Set shortcuts
1435
- var setting = options.libraries.firebase_messaging;
1436
-
1437
- // Skip if not enabled
1438
- if (!setting.enabled) {
1439
- return resolve();
1440
- }
1441
-
1442
- // Load Firebase Messaging
1443
- if (setting.load) {
1444
- setting.load(self)
1445
- .then(resolve)
1446
- .catch(reject);
1447
- } else {
1448
- // import('firebase/messaging')
1449
- import('firebase/compat/messaging')
1450
- .then(resolve)
1451
- .catch(reject);
1452
- }
1453
- });
1454
- }
1455
-
1456
- var load_firebase_appCheck = function(self, options) {
1457
- return new Promise(function(resolve, reject) {
1458
- // Set shortcuts
1459
- var setting = options.libraries.firebase_appCheck;
1460
-
1461
- // Skip if not enabled
1462
- if (!setting.enabled) {
1463
- return resolve();
1464
- }
1465
-
1466
- // Load Firebase AppCheck
1467
- if (setting.load) {
1468
- setting.load(self)
1469
- .then(resolve)
1470
- .catch(reject);
1471
- } else {
1472
- // import('firebase/app-check')
1473
- import('firebase/compat/app-check')
1474
- .then(function (mod) {
1475
- var appCheck = firebase.appCheck;
1476
- var siteKey = setting.config.siteKey;
1477
-
1478
- if (!siteKey) {
1479
- return resolve();
1480
- }
1481
-
1482
- appCheck().activate(
1483
- new appCheck.ReCaptchaEnterpriseProvider(siteKey),
1484
- true,
1485
- );
1486
-
1487
- resolve();
1488
- })
1489
- .catch(reject);
1490
- }
1491
- });
1492
- }
1493
-
1494
- var load_lazysizes = function(self, options) {
1495
- return new Promise(function(resolve, reject) {
1496
- // Skip if not enabled
1497
- if (!options.libraries.lazysizes.enabled) {
1498
- return resolve();
1499
- }
1500
-
1501
- // Load Lazysizes
1502
- import('lazysizes')
1503
- .then(function (mod) {
1504
- window.lazysizes = mod.default;
1505
-
1506
- // configs come from official lazysizes demo
1507
- var expand = Math.max(Math.min(document.documentElement.clientWidth, document.documentElement.clientHeight, 1222) - 1, 359);
1508
- window.lazySizesConfig = {
1509
- loadMode: 1,
1510
- expand: expand,
1511
- expFactor: expand < 380 ? 3 : 2,
1512
- };
1513
- // self.log('Loaded Lazysizes.');
1514
- })
1515
- .catch(reject);
1516
- });
1517
- }
1518
-
1519
- var load_cookieconsent = function(self, options) {
1520
- return new Promise(function(resolve, reject) {
1521
- // Skip if not enabled
1522
- if (!options.libraries.cookieconsent.enabled) {
1523
- return resolve();
1524
- }
1525
-
1526
- // Load Cookieconsent
1527
- import('cookieconsent')
1528
- .then(function(mod) {
1529
- window.cookieconsent.initialise(options.libraries.cookieconsent.config);
1530
- // self.log('Loaded Cookieconsent.');
1531
- resolve();
1532
- })
1533
- .catch(reject);
1534
- });
1535
- }
1536
-
1537
- var load_chatsy = function(self, options) {
1538
- return new Promise(function(resolve, reject) {
1539
- // Skip if not enabled or already requested
1540
- if (!options.libraries.chatsy.enabled || self.properties.page._chatsyRequested) {
1541
- return resolve();
1542
- }
1543
-
1544
- var chatsyPath = 'libraries.chatsy.config';
1545
-
1546
- // Immediately hide the fake button
1547
- select('#prechat-btn').hide();
1548
-
1549
- // Load the script
1550
- loadScript({
1551
- src: 'https://app.chatsy.ai/resources/script.js',
1552
- // src: 'http://localhost:4001/resources/script.js',
1553
- attributes: [
1554
- {name: 'data-account-id', value: utilities.get(options, chatsyPath + '.accountId', '')},
1555
- {name: 'data-chat-id', value: utilities.get(options, chatsyPath + '.chatId', '')},
1556
- {name: 'data-settings', value: JSON.stringify(utilities.get(options, chatsyPath + '.settings', ''))},
1557
- ],
1558
- crossorigin: true,
1559
- })
1560
- .then(function () {
1561
- // Listen for Chatsy status
1562
- chatsy.on('status', function(event, status) {
1563
- if (status === 'loaded') {
1564
- chatsy.open();
1565
- }
1566
- })
1567
-
1568
- resolve();
1569
- })
1570
-
1571
- self.properties.page._chatsyRequested = true;
1572
- });
1573
- }
1574
-
1575
- var load_sentry = function(self, options) {
1576
- return new Promise(function(resolve, reject) {
1577
- // Skip if not enabled
1578
- if (!options.libraries.sentry.enabled) {
1579
- return resolve();
1580
- }
1581
-
1582
- // Import Sentry
1583
- import('@sentry/browser')
1584
- .then(function(mod) {
1585
- // Set global
1586
- window.Sentry = mod;
1587
-
1588
- // Set config
1589
- var config = options.libraries.sentry.config;
1590
- config.release = config.release + '@' + self.properties.global.version;
1591
- config.environment = self.properties.meta.environment;
1592
- config.integrations = config.integrations || [];
1593
-
1594
- // if (self.isDevelopment()) {
1595
- // config.dsn = 'https://901db748bbb9469f860dc36fb07a4374@o1120154.ingest.sentry.io/6155285';
1596
- // }
1597
-
1598
- // Add integration: browser tracing
1599
- config.integrations.push(Sentry.browserTracingIntegration());
1600
-
1601
- // Add integration: replay
1602
- if (config.replaysSessionSampleRate > 0 || config.replaysOnErrorSampleRate > 0) {
1603
- config.integrations.push(Sentry.replayIntegration({
1604
- maskAllText: false,
1605
- blockAllMedia: false,
1606
- }));
1607
- }
1608
-
1609
- // Setup before send
1610
- config.beforeSend = function (event, hint) {
1611
- var startTime = self.properties.page.startTime;
1612
- var hoursSinceStart = (new Date() - startTime) / (1000 * 3600);
1613
-
1614
- // Setup tags
1615
- event.tags = event.tags || {};
1616
- event.tags['process.type'] = event.tags['process.type'] || 'browser';
1617
- // event.tags['usage.total.opens'] = parseInt(usage.total.opens);
1618
- // event.tags['usage.total.hours'] = usage.total.hours;
1619
- event.tags['usage.session.hours'] = hoursSinceStart.toFixed(2);
1620
- // event.tags['store'] = self.properties().isStore();
1621
-
1622
- // Setup user
1623
- event.user = event.user || {};
1624
- event.user.email = storage.get('user.auth.email', '')
1625
- event.user.uid = storage.get('user.auth.uid', '');
1626
- // event.user.ip = storage.get('user.ip', '');
1627
-
1628
- // Log to console
1629
- console.error('[SENTRY] Caught error', event, hint);
1630
-
1631
- // Skip processing the event
1632
- if (self.isDevelopment()) {
1633
- return null;
1634
- }
1635
-
1636
- // Process the event
1637
- return event;
1638
- }
1639
-
1640
- // Initialize
1641
- Sentry.init(config);
1642
-
1643
- // Resolve
1644
- resolve();
1645
- })
1646
- .catch(reject);
1647
- });
1648
- }
1649
-
1650
- Manager.prototype.log = function() {
1651
- var self = this;
1652
-
1653
- if (self.isDevelopment()) {
1654
- // 1. Convert args to a normal array
1655
- var args = Array.prototype.slice.call(arguments);
1656
-
1657
- // 2. Prepend log prefix log string
1658
- args.unshift('[DEV @ ' + new Date().toLocaleTimeString() + ']');
1659
-
1660
- // 3. Pass along arguments to console.log
1661
- if (args[1] === 'error') {
1662
- args.splice(1,1);
1663
- console.error.apply(console, args);
1664
- } else if (args[1] === 'warn') {
1665
- args.splice(1,1);
1666
- console.warn.apply(console, args);
1667
- } else if (args[1] === 'log') {
1668
- args.splice(1,1);
1669
- console.log.apply(console, args);
1670
- } else {
1671
- console.log.apply(console, args);
1672
- }
1673
- }
1674
- }
1675
-
1676
- function init_loadPolyfills(self, configuration, cb) {
1677
- // https://github.com/jquintozamora/polyfill-io-feature-detection/blob/master/index.js
1678
- var featuresPass = (
1679
- typeof Symbol !== 'undefined'
1680
- );
1681
-
1682
- // Process
1683
- if (featuresPass) {
1684
- cb();
1685
- } else {
1686
- loadScript({src: 'https://cdnjs.cloudflare.com/polyfill/v3/polyfill.min.js?flags=always%2Cgated&features=default%2Ces5%2Ces6%2Ces7%2CPromise.prototype.finally%2C%7Ehtml5-elements%2ClocalStorage%2Cfetch%2CURLSearchParams'})
1687
- .then(function() {
1688
- cb();
1689
- })
1690
- }
1691
- }
1692
-
1693
- /**
1694
- * UTILITIES
1695
- */
1696
- Manager.prototype.utilities = function() {
1697
- return utilities;
1698
- }
1699
-
1700
- /**
1701
- * STORAGE
1702
- */
1703
- Manager.prototype.storage = function() {
1704
- return storage;
1705
- }
1706
-
1707
- /**
1708
- * QUERIES
1709
- */
1710
- // Manager.prototype.query = function() {
1711
- // return query;
1712
- // }
1713
-
1714
- /**
1715
- * DOM OPERATIONS
1716
- */
1717
- Manager.prototype.dom = function() {
1718
- return dom;
1719
- }
1720
-
1721
- /**
1722
- * ACCOUNT
1723
- */
1724
- // Manager.prototype.account = function() {
1725
- // var self = this;
1726
- // return {
1727
- // resolve: function (options) {
1728
- // return import('./lib/account.js')
1729
- // .then(function(mod) {
1730
- // self.account = function () { return mod.default }
1731
- // return self.account().resolve(options);
1732
- // })
1733
- // }
1734
- // }
1735
- // }
1736
-
1737
- Manager.prototype.account = function() {
1738
- var self = this;
1739
-
1740
- return {
1741
- import: function () {
1742
- return import('./lib/account.js')
1743
- .then(function(mod) {
1744
- self.account = function () { return mod.default }
1745
- mod.default.prototype.Manager = self;
1746
- return self.account();
1747
- })
1748
- }
1749
- }
1750
- }
1751
-
1752
- // Manager.prototype.fetch = function(url, options) {
1753
- // var response = {
1754
- // status: 500,
1755
- // };
1756
- // return new Promise(function(resolve, reject) {
1757
- // fetch(url, options)
1758
- // .then(function (res) {
1759
- // response = res;
1760
- // if (res.status >= 200 && res.status < 300) {
1761
- // return resolve({response: res});
1762
- // } else {
1763
- // return res.text()
1764
- // .then(function (data) {
1765
- // throw new Error(data || res.statusTest || 'Unknown error.')
1766
- // })
1767
- // }
1768
- // })
1769
- // .catch(function (e) {
1770
- // return reject({response: response, error: e});
1771
- // });
1772
- // });
1773
- // }
1774
-
1775
- // Manager.prototype.ajax = function() {
1776
- // return ajax;
1777
- // }
1778
-
1779
- /**
1780
- * OTHER
1781
- */
1782
- // Manager.prototype.performance = function() {
1783
- // var supported = ('performance' in window);
1784
- // return {
1785
- // mark: function(mark) {
1786
- // if (!supported) {return};
1787
- // window.performance.mark(mark);
1788
- // }
1789
- // }
1790
- // }
1791
- Manager.prototype.performance = function () {
1792
- return {
1793
- mark: function(mark) {
1794
- try {
1795
- window.performance.mark(mark);
1796
- } catch (e) {
1797
- }
1798
- }
1799
- }
1800
- }
1801
-
1802
- Manager.prototype.isValidRedirectUrl = function (url) {
1803
- var self = this;
1804
-
1805
- var returnUrlObject = new URL(decodeURIComponent(url));
1806
- var currentUrlObject = new URL(window.location.href);
1807
-
1808
- return returnUrlObject.host === currentUrlObject.host
1809
- || returnUrlObject.protocol === this.properties.global.app + ':'
1810
- || self.properties.global.validRedirectHosts.includes(returnUrlObject.host)
1811
- }
1812
-
1813
- Manager.prototype.isDevelopment = function () {
1814
- var self = this;
1815
-
1816
- return self.properties.meta.environment === 'development';
1817
- }
1818
-
1819
- // Manager.prototype.performance = function() {
1820
- // var self = this;
1821
- //
1822
- // return {
1823
- // mark2: function () {
1824
- // return firebaseActive ? !!firebase.auth().currentUser : false;
1825
- // },
1826
- //
1827
- // }
1828
- // }
1829
-
1830
- function getApiUrl(url) {
1831
- // Set API url
1832
- var globalUrl = new URL(url);
1833
- var hostnameParts = globalUrl.hostname.split('.');
1834
-
1835
- // Check if subdomain exists
1836
- if (hostnameParts.length > 2) {
1837
- hostnameParts[0] = 'api';
1838
- } else {
1839
- hostnameParts.unshift('api');
1840
- }
1841
-
1842
- // Set hostname
1843
- globalUrl.hostname = hostnameParts.join('.');
1844
-
1845
- // Return new URL
1846
- return globalUrl.toString();
1847
- }
1848
-
1849
-
1850
- /**
1851
- * HELPERS
1852
- */
1853
-
1854
- module.exports = Manager;