1 | import type {JsonObject, Wnd} from './types';
|
2 | import {doNotTrack, buildWarn, isBot} from './utils';
|
3 | import {version} from '../package.json';
|
4 |
|
5 | export {Wnd};
|
6 | const run = () => {
|
7 | if (!window) return;
|
8 | const isDnt = doNotTrack();
|
9 |
|
10 | const {
|
11 |
|
12 | screen: {width, height},
|
13 |
|
14 | navigator: {language, userAgent},
|
15 | location: {hostname, pathname, search, origin},
|
16 | document,
|
17 | history,
|
18 | } = window;
|
19 |
|
20 | const script = document.querySelector('script[data-site]');
|
21 | if (!script) return console.error('script.js not found');
|
22 |
|
23 |
|
24 | const url = new URL(document.currentScript.src).origin;
|
25 |
|
26 | const attr = (key: string) =>
|
27 | script && (script.getAttribute(key) || script.getAttribute(`data-${key}`));
|
28 |
|
29 | const shortcode = attr('site');
|
30 | const dnt0ff = attr('dnt-off');
|
31 | const spa = attr('spa');
|
32 | const warn = buildWarn();
|
33 | const parsedHosthName = attr('hostname') || hostname;
|
34 |
|
35 | const canonical = attr('canonical');
|
36 |
|
37 | if (!shortcode) return warn('site not found');
|
38 | if (isBot(userAgent)) return warn('bot detected');
|
39 | if (dnt0ff && isDnt) return warn('dnt-off and dnt=1');
|
40 |
|
41 | if (
|
42 | 'visibilityState' in document &&
|
43 |
|
44 | 'prerender' === document.visibilityState
|
45 | ) {
|
46 | return warn('Prerendering');
|
47 | }
|
48 |
|
49 | const historyAttached = () => {
|
50 | const pushState = history.pushState;
|
51 | if (void 0 !== history) {
|
52 | history.pushState = function () {
|
53 | var output = pushState.apply(history, arguments as any);
|
54 | return (
|
55 | window.dispatchEvent(new Event('pushstate')),
|
56 | window.dispatchEvent(new Event('prxm')),
|
57 | output
|
58 | );
|
59 | };
|
60 | window.addEventListener('popstate', function () {
|
61 | window.dispatchEvent(new Event('prxm'));
|
62 | });
|
63 | window.addEventListener('prxm', monitor);
|
64 | }
|
65 | };
|
66 |
|
67 | const hashAttached = () => {
|
68 | window.addEventListener('hashchange', monitor);
|
69 | };
|
70 |
|
71 | const init = () => {
|
72 | warn('init');
|
73 |
|
74 | if (spa) {
|
75 | switch (spa) {
|
76 | case 'history':
|
77 | historyAttached();
|
78 | break;
|
79 | case 'hash':
|
80 | hashAttached();
|
81 | break;
|
82 | default:
|
83 | void 0 !== history ? historyAttached() : hashAttached();
|
84 | }
|
85 | } else {
|
86 | window.addEventListener('load', monitor);
|
87 | }
|
88 | };
|
89 |
|
90 | const pxl = (p: string, e: JsonObject) => {
|
91 | const element = document.createElement('img') as HTMLImageElement;
|
92 | element.setAttribute('aria-hidden', 'true');
|
93 | element.setAttribute('alt', '');
|
94 | element.src = url + e.toString();
|
95 | element.style.position = 'absolute';
|
96 |
|
97 | element.src = url + p + '/pixel?' + new URLSearchParams(e).toString();
|
98 | element.addEventListener('load', function () {
|
99 | element.parentNode && element.parentNode.removeChild(element);
|
100 | });
|
101 | element.addEventListener('error', function () {
|
102 | element.parentNode && element.parentNode.removeChild(element);
|
103 | });
|
104 | document.body.appendChild(element);
|
105 | };
|
106 |
|
107 | const event = (e: JsonObject) => {};
|
108 |
|
109 | const send = (p: string, data: JsonObject) => {
|
110 | const xhr = new XMLHttpRequest();
|
111 | xhr.open('POST', url + p, true);
|
112 | xhr.setRequestHeader('Content-Type', 'text/plain');
|
113 | xhr.addEventListener('error', function () {
|
114 | pxl(p, data);
|
115 | });
|
116 | xhr.send(JSON.stringify(data));
|
117 | };
|
118 |
|
119 | const monitor = () => {
|
120 | const data = {
|
121 | p: origin + pathname + search,
|
122 | v: version,
|
123 | s: shortcode,
|
124 | h: parsedHosthName,
|
125 | r: document.referrer,
|
126 | cid: Date.now().toString(32),
|
127 |
|
128 | l: navigator.userLanguage || navigator.language || '',
|
129 |
|
130 | };
|
131 | send('/hit/torch', data);
|
132 | };
|
133 |
|
134 |
|
135 | const monitorEvent = () => {};
|
136 |
|
137 | if (!(window as Wnd).proxima) {
|
138 | const proxima = {
|
139 | monitor: monitor,
|
140 | event: monitor,
|
141 | };
|
142 | (window as Wnd).proxima = proxima;
|
143 | init();
|
144 | }
|
145 | };
|
146 | run();
|