· 5 years ago · Jul 22, 2020, 11:52 AM
1import CookieService from './CookieService';
2
3export default function createAnalytics() {
4 (function(win, doc) {
5 var Util = {
6 isArray: function(a) {
7 return 'function' === typeof Array.isArray
8 ? Array.isArray(a)
9 : '[object Array]' === Object.prototype.toString.call(a);
10 },
11 isString: function(a) {
12 return '[object String]' === Object.prototype.toString.call(a);
13 },
14 random: function(a, b) {
15 2 > arguments.length && ((b = a), (a = 0));
16 1 > arguments.length && (b = 1073741824);
17 return Math.floor(Math.random() * (b - a)) + a;
18 },
19 mergeObjects: function(obj, src) {
20 for (var key in src) {
21 if (src.hasOwnProperty(key)) obj[key] = src[key];
22 }
23 return obj;
24 },
25 };
26 var Browser = {
27 pageLoadTime: function() {
28 if ('object' === typeof window.chrome && window.chrome.loadTimes) {
29 var a = window.chrome.loadTimes();
30 if (a.requestTime && a.firstPaintTime && window.performance && window.performance.timing)
31 return Math.round(1e3 * a.firstPaintTime - window.performance.timing.navigationStart);
32 } else if (
33 window.performance &&
34 window.performance.timing &&
35 ((a = window.performance.timing), a.navigationStart && a.msFirstPaint)
36 )
37 return a.msFirstPaint - a.navigationStart;
38 return null;
39 },
40 netType: function() {
41 var a = (navigator.connection || { type: '' }).type;
42 return a === undefined ? '' : a;
43 },
44 getLanguage: function() {
45 var a = (win.navigator
46 ? navigator.language ||
47 navigator.userLanguage ||
48 navigator.browserLanguage ||
49 navigator.systemLanguage
50 : ''
51 ).toLowerCase();
52 return Util.isString(a) ? a : '';
53 },
54 getJavaEnabled: function() {
55 try {
56 return navigator.javaEnabled();
57 } catch (a) {
58 return !1;
59 }
60 },
61 getNotificationPermission: function() {
62 try {
63 var a = Notification.permission;
64 } catch (b) {}
65 switch (a) {
66 case 'denied':
67 return 0;
68 case 'granted':
69 return 1;
70 }
71 },
72 isIframe: function() {
73 try {
74 return win.top !== win.self;
75 } catch (a) {
76 return !1;
77 }
78 },
79 };
80
81 var Time = {
82 getSeconds: function() {
83 return Math.round(+new Date() / 1e3);
84 },
85 getTimezone: function() {
86 return -new Date().getTimezoneOffset();
87 },
88 };
89
90 var Cookies = {
91 getVid: function() {
92 var generateNew = Document.isFromAd();
93 var vid = generateNew ? 0 : this.readM('vid');
94
95 if (!vid) {
96 vid = Time.getSeconds() + '' + Util.random();
97 }
98 this.create('vid', vid, 30);
99
100 return vid;
101 },
102 getUid: function() {
103 this.globalDomain();
104 var uid = this.readM('uid');
105
106 if (!uid) {
107 uid = Time.getSeconds() + '' + Util.random();
108 this.create('uid', uid, 1036800);
109 }
110
111 return uid;
112 },
113 create: function(name, value, minutes) {
114 CookieService.set(this._prepareName(name), value, 6e4 * minutes);
115 },
116 // globalDomain: function () {
117 // var a;
118 // var b = win.location.host.split(".");
119 // for (a = 2; ;)
120 // if (a <= b.length) {
121 // if (this._domain = "." + b.slice(-a).join("."),
122 // a++)
123 // break
124 // } else {
125 // this._domain = null;
126 // break
127 // }
128
129 // return this._domain
130 // },
131 globalDomain: function() {
132 this._domain = Document.extractHostname(win.location.host);
133 return this._domain;
134 },
135 readM: function(name) {
136 name = this._prepareName(name);
137 return this.read(name);
138 },
139 read: function(name) {
140 return CookieService.get(name);
141 },
142 erase: function(name) {
143 this.create(name, '', -1);
144 },
145 _prepareName: function(name) {
146 return '_mm_' + name + (Config.counterId ? '_' + Config.counterId : '');
147 },
148 };
149
150 var Document = {
151 getDocumentCharset: function() {
152 return ('' + (doc.characterSet || doc.charset || '')).toLowerCase();
153 },
154 getRootElement: function() {
155 var a = doc.documentElement;
156 return 'CSS1Compat' === doc.compatMode ? a : doc.body || a;
157 },
158 getViewportSize: function() {
159 var a = this.getRootElement();
160 return [a.clientWidth || win.innerWidth, a.clientHeight || win.innerHeight];
161 },
162 getDocumentTitle: function() {
163 var a = doc.title;
164 'string' !== typeof a &&
165 (a = (a = doc.getElementsByTagName('title')) && a.length ? a[0].innerHTML : '');
166 return a;
167 },
168 isFromAd: function() {
169 if (!doc.referrer) {
170 return false;
171 }
172 // var url = document.createElement('a');
173 // url.href = doc.referrer;
174 //
175 // if (url.hostname === win.location.hostname) {
176 // return false;
177 // }
178
179 var adSystemSources = [
180 'adfox',
181 'admitad',
182 'adnews',
183 'adnous',
184 'adriver',
185 'advmaker',
186 'aport',
187 'aport.ru',
188 'AvitoPromo',
189 'AvitoContext',
190 'begun',
191 'bing',
192 'B2BContext',
193 'criteo',
194 'directadvert',
195 'directadvert.ru',
196 'drivenetwork',
197 'facebook',
198 'fb',
199 'facebook.com',
200 'fb.com',
201 'giraffio',
202 'google',
203 'adwords',
204 'adsense',
205 'instagram',
206 'kavanga',
207 'ladycenter',
208 'link',
209 'magna',
210 'marketgid',
211 'medialand',
212 'merchant',
213 'moimir',
214 'nnn',
215 'nnn.ru',
216 'odnoklassniki',
217 'price',
218 'price.ru',
219 'prre',
220 'mytarget',
221 'targetmailru',
222 'taboola',
223 'torg.mail.ru',
224 'trorer',
225 'rorer',
226 'Ttarget',
227 'ubn.ua',
228 'banner.ua',
229 'videonow',
230 'vkontakte',
231 'vk',
232 'vk.com',
233 'whisla',
234 'youtube',
235 ];
236 var adSystemMediums = [
237 'cpc',
238 'ppc',
239 'paidsearch',
240 'cpv',
241 'cpa',
242 'cpp',
243 'display',
244 'cpm',
245 'banner',
246 ];
247
248 var queryParams = win.location.search.replace('?', '').split('&');
249 var hashParams = win.location.hash.replace('#', '').split('&');
250 var params = hashParams.concat(queryParams);
251
252 var isAd = false;
253 params.forEach(function(item) {
254 var p = item.split('=');
255 if (p[0] === 'utm_source' && p[1] && adSystemSources.indexOf(p[1])) {
256 return (isAd = true);
257 }
258 if (p[0] === 'utm_medium' && p[1] && adSystemMediums.indexOf(p[1])) {
259 return (isAd = true);
260 }
261 });
262
263 return isAd;
264 },
265 extractHostname: function(url) {
266 if (url === undefined) {
267 return '';
268 }
269 var hostname;
270 //find & remove protocol (http, ftp, etc.) and get hostname
271
272 if (url.indexOf('://') > -1) {
273 hostname = url.split('/')[2];
274 } else {
275 hostname = url.split('/')[0];
276 }
277
278 //find & remove port number
279 hostname = hostname.split(':')[0];
280 //find & remove "?"
281 hostname = hostname.split('?')[0];
282 hostname = hostname.replace(/^www\./, '');
283 hostname = hostname.replace('#', '');
284
285 return hostname;
286 },
287 isExternal: function(linkUrl) {
288 var hostname = this.extractHostname(linkUrl);
289 if (Array.isArray(Config.siteDomains)) {
290 if (Config.siteDomains.indexOf(hostname) > -1 || hostname === '') {
291 return false;
292 }
293 } else {
294 return !(this.extractHostname(win.location.hostname) === hostname || hostname === '');
295 // var pos = linkUrl.indexOf(win.location.hostname);
296 // return !(pos !== -1 && pos < 8);
297 }
298 return true;
299 },
300 };
301
302 var Request = {
303 send: function(data) {
304 var url = Config.server;
305 data.ident = this.prepareBrowserInfo();
306 if (data.hasOwnProperty('url') && typeof data.url === 'string') {
307 data.url = data.url.toLowerCase();
308 }
309 var body = JSON.stringify(data);
310 if (!this.sendBeacon(url, body)) {
311 this.sendXHR(url, body);
312 }
313 },
314 sendBeacon: function(url, body) {
315 if ('function' === typeof navigator.sendBeacon && navigator.onLine) {
316 navigator.sendBeacon(url, body);
317 return true;
318 }
319 return false;
320 },
321 sendXHR: function(url, body) {
322 if (win.XMLHttpRequest) {
323 var xhr = new XMLHttpRequest();
324 try {
325 xhr.open('POST', url, true);
326 } catch (e) {
327 return false;
328 }
329 xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
330 xhr.send(body);
331 xhr.onreadystatechange = function() {
332 return 4 === xhr.readyState && 200 === xhr.status;
333 };
334 return true;
335 }
336
337 return false;
338 },
339 prepareBrowserInfo: function() {
340 var p = {};
341 var screen = win.screen;
342
343 var ntf = Browser.getNotificationPermission();
344 ntf !== '' && (p.ntf = ntf);
345 var net = Browser.netType();
346 net !== '' && (p.net = net);
347
348 p.t = Document.getDocumentTitle();
349 p.pc = Document.getDocumentCharset();
350 p.tz = Time.getTimezone();
351
352 var vs = Document.getViewportSize();
353 p.wcw = vs[0];
354 p.wch = vs[1];
355
356 p.plt = Browser.pageLoadTime();
357 p.la = Browser.getLanguage();
358 p.j = Browser.getJavaEnabled() ? 1 : 0;
359
360 p.clid = Config.clientId;
361 p.cid = Config.counterId;
362 p.vid = Config.visitId;
363 p.c = navigator.cookieEnabled ? 1 : 0;
364 p.sw = screen.width;
365 p.sh = screen.height;
366 p.sc = screen.colorDepth || screen.pixelDepth;
367 Browser.isIframe() && (p.ifr = 1);
368
369 var yid = Cookies.read('_ym_uid');
370 if (yid) {
371 p.yid = yid;
372 }
373 try {
374 var ga = Cookies.read('_ga');
375 if (ga.length > 0) {
376 ga = ga.split('.');
377 p.gaid = ga[2] + '.' + ga[3];
378 }
379 } catch (e) {}
380 var pv = Cookies.read('paystation_visit');
381 if (pv) {
382 p.pv = pv;
383 }
384 // if (Config.userIdQuerySelector !== "") {
385 // try {
386 // p.eid = doc.querySelector(Config.userIdQuerySelector).innerHTML
387 // }
388 // catch (e) {
389 // }
390 // }
391 return p;
392 },
393 };
394
395 var Events = {
396 setHandlers: function() {
397 this.documentReadyEvent(this.onDocumentReady);
398 this.documentReadyEvent(this.clickEvent);
399 this.documentReadyEvent(this.selectorEvent);
400 this.documentReadyEvent(this.scrollEvent);
401 },
402 documentReadyEvent: function(func) {
403 if (
404 document.attachEvent
405 ? document.readyState === 'complete'
406 : document.readyState !== 'loading'
407 ) {
408 func();
409 } else {
410 document.addEventListener('DOMContentLoaded', func);
411 }
412 },
413 clickEvent: function() {
414 var Anchors = doc.getElementsByTagName('a');
415 for (var i = 0; i < Anchors.length; i++) {
416 Events.setEvents(Anchors[i], 'click', Events.onClick);
417 }
418 },
419 setEvents: function(el, eventType, func) {
420 el.addEventListener
421 ? el.addEventListener(eventType, func)
422 : el.attachEvent && el.attachEvent('on' + eventType, func);
423 },
424 onDocumentReady: function() {
425 var data = {
426 et: 1,
427 url: win.location.href,
428 eid: Config.merchantId,
429 };
430
431 // не нужно отправлять редирект с дефолтным merchant_id
432 if (data.eid && data.eid === 2340) {
433 return;
434 }
435
436 if (doc.referrer) {
437 data.referer = doc.referrer;
438 if (!Document.isExternal(data.referer)) {
439 data.ss = 1;
440 }
441 }
442 Request.send(data);
443 },
444 onClick: function() {
445 if (Document.isExternal(this.href)) {
446 Request.send({
447 et: 2,
448 referer: win.location.href,
449 url: this.href,
450 eid: Config.merchantId,
451 });
452 }
453 },
454 selectorEvent: function() {
455 var Anchors = document.querySelectorAll('[data-analytics]');
456 for (var i = 0; i < Anchors.length; i++) {
457 Events.setEvents(Anchors[i], 'click', Events.onSelectorClick);
458 }
459 },
460 onSelectorClick: function() {
461 Request.send({
462 et: 3,
463 en: this.dataset.analytics,
464 url: win.location.href,
465 eid: Config.merchantId,
466 });
467 },
468 scrollEvent: function() {
469 Events.setEvents(win, 'scroll', Events.onScroll);
470 },
471 onScroll: function() {
472 if (ScrollTimer !== null) {
473 clearTimeout(ScrollTimer);
474 }
475 ScrollTimer = setTimeout(function() {
476 // отправляем скролл только если страница не помещается в экран
477 let scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
478 let scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight;
479 if (!ScrollFirst && scrollTop > 0) {
480 ScrollFirst = true;
481 Request.send({
482 et: 10,
483 url: win.location.href,
484 eid: Config.merchantId,
485 });
486 }
487 if (
488 !ScrollMiddle &&
489 2 * scrollTop > scrollHeight - document.documentElement.clientHeight
490 ) {
491 ScrollMiddle = true;
492 Request.send({
493 et: 11,
494 url: win.location.href,
495 eid: Config.merchantId,
496 });
497 }
498 if (
499 !ScrollBottom &&
500 scrollTop >= (scrollHeight - document.documentElement.clientHeight) * 0.9
501 ) {
502 ScrollBottom = true;
503 Request.send({
504 et: 12,
505 url: win.location.href,
506 eid: Config.merchantId,
507 });
508 }
509 }, 150);
510 },
511 onFormSubmit: function() {},
512 };
513 let ScrollTimer = null;
514 let ScrollFirst = false;
515 let ScrollMiddle = false;
516 let ScrollBottom = false;
517
518 var Config = {
519 counterId: 0,
520 clientId: 0,
521 siteDomains: null,
522 server: '',
523 merchantId: null,
524 };
525
526 var Api = {
527 hit: function(url, obj) {
528 ScrollFirst = false;
529 ScrollMiddle = false;
530 ScrollBottom = false;
531 var refererUrl = obj && obj.referer ? obj.referer : win.location.href;
532 var merchantId = obj && obj.eid ? obj.eid : Config.merchantId;
533 var data = {
534 et: 1,
535 referer: refererUrl,
536 url: url,
537 eid: merchantId,
538 };
539 if (typeof obj != 'object') {
540 obj = {};
541 }
542
543 if (!Document.isExternal(data.referer)) {
544 data.ss = 1;
545 }
546
547 obj = Util.mergeObjects(obj, data);
548 Request.send(obj);
549 },
550 externalLink: function(url, obj) {
551 var merchantId = obj && obj.eid ? obj.eid : Config.merchantId;
552 var data = {
553 et: 2,
554 referer: win.location.href,
555 url: url,
556 eid: merchantId,
557 };
558 if (typeof obj != 'object') {
559 obj = {};
560 }
561
562 obj = Util.mergeObjects(obj, data);
563 Request.send(obj);
564 },
565
566 elementClick: function(name, obj) {
567 ScrollFirst = false;
568 ScrollMiddle = false;
569 ScrollBottom = false;
570 var merchantId = obj && obj.eid ? obj.eid : Config.merchantId;
571 var data = {
572 et: 3,
573 en: name,
574 url: win.location.href,
575 eid: merchantId,
576 };
577 if (typeof obj != 'object') {
578 obj = {};
579 }
580 obj = Util.mergeObjects(obj, data);
581 Request.send(obj);
582 },
583
584 formData: function(name, formData, obj) {
585 ScrollFirst = false;
586 ScrollMiddle = false;
587 ScrollBottom = false;
588 var merchantId = obj && obj.eid ? obj.eid : Config.merchantId;
589 var exv = obj && obj.exv ? JSON.stringify(obj.exv) : '';
590 var formDataStr = formData ? JSON.stringify(formData) : '';
591 var data = {
592 et: 4,
593 en: name,
594 url: win.location.href,
595 eid: merchantId,
596 form: formDataStr,
597 };
598 if (exv) {
599 data.exv = exv;
600 }
601 if (typeof obj != 'object') {
602 obj = {};
603 }
604 obj = Util.mergeObjects(obj, data);
605 Request.send(obj);
606 },
607 };
608
609 win.XsollaAnalytics = function(params) {
610 Config.counterId = params.id;
611 Config.server = params.server;
612 Config.merchantId = params.merchantId;
613 Config.clientId = Cookies.getUid();
614 Config.visitId = Cookies.getVid();
615 Events.setHandlers();
616 return Api;
617 };
618 })(window, window.document);
619
620 try {
621 let counterId = 1002;
622 let siteDomains = null;
623
624 const xsollaDomains = [
625 'xsolla.com',
626 'www.xsolla.com',
627 'h.xsolla.com',
628 'help.xsolla.com',
629 'developers.xsolla.com',
630 'support.xsolla.com',
631 'origin-blog.xsolla.com',
632 ];
633 const publisherDomains = ['publisher.xsolla.com'];
634
635 if (xsollaDomains.indexOf(location.hostname) > -1) {
636 counterId = 1003;
637 siteDomains = xsollaDomains;
638 } else if (publisherDomains.indexOf(location.hostname) > -1) {
639 counterId = 1004;
640 siteDomains = publisherDomains;
641 }
642
643 return new XsollaAnalytics({
644 id: counterId,
645 server: 'https://datagather.xsolla.com/hit',
646 siteDomains: siteDomains,
647 });
648 } catch (e) {}
649}