forked from snowplow/snowplow-javascript-tracker
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbrowser_props.ts
More file actions
142 lines (128 loc) · 4.04 KB
/
Copy pathbrowser_props.ts
File metadata and controls
142 lines (128 loc) · 4.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
interface BrowserProperties {
viewport?: string | null;
documentSize?: string | null;
resolution?: string | null;
colorDepth: number;
devicePixelRatio: number;
cookiesEnabled: boolean;
online: boolean;
browserLanguage: string;
documentLanguage: string;
webdriver: boolean;
deviceMemory?: number; // Optional because it's not supported in all browsers
hardwareConcurrency?: number;
}
function useResizeObserver(): boolean {
return 'ResizeObserver' in window;
}
let resizeObserverInitialized = false;
function initializeResizeObserver() {
if (resizeObserverInitialized) {
return;
}
if(!document || !document.body || !document.documentElement) {
return;
}
resizeObserverInitialized = true;
const resizeObserver = new ResizeObserver((entries) => {
for (let entry of entries) {
if (entry.target === document.body || entry.target === document.documentElement) {
cachedProperties = readBrowserProperties();
}
}
});
resizeObserver.observe(document.body);
resizeObserver.observe(document.documentElement);
}
let cachedProperties: BrowserProperties;
/* Separator used for dimension values e.g. widthxheight */
const DIMENSION_SEPARATOR = 'x';
/**
* Gets various browser properties (that are expensive to read!)
* - Will use a "ResizeObserver" approach in modern browsers to update cached properties only on change
* - Will fallback to a direct read approach without cache in old browsers
*
* @returns BrowserProperties
*/
export function getBrowserProperties() {
if (!useResizeObserver()) {
return readBrowserProperties();
}
if (!cachedProperties) {
cachedProperties = readBrowserProperties();
}
initializeResizeObserver();
return cachedProperties;
}
/**
* Reads the browser properties - expensive call!
*
* @returns BrowserProperties
*/
function readBrowserProperties(): BrowserProperties {
return {
viewport: floorDimensionFields(detectViewport()),
documentSize: floorDimensionFields(detectDocumentSize()),
resolution: floorDimensionFields(detectScreenResolution()),
colorDepth: screen.colorDepth,
devicePixelRatio: window.devicePixelRatio,
cookiesEnabled: window.navigator.cookieEnabled,
online: window.navigator.onLine,
browserLanguage: window.navigator.language || (window.navigator as any).userLanguage,
documentLanguage: document.documentElement.lang,
webdriver: window.navigator.webdriver,
deviceMemory: (window.navigator as any).deviceMemory,
hardwareConcurrency: (window.navigator as any).hardwareConcurrency,
};
}
/**
* Gets the current viewport.
*
* Code based on:
* - http://andylangton.co.uk/articles/javascript/get-viewport-size-javascript/
* - http://responsejs.com/labs/dimensions/
*/
function detectViewport() {
var width, height;
if ('innerWidth' in window) {
width = window['innerWidth'];
height = window['innerHeight'];
} else {
const e = document.documentElement || document.body;
width = e['clientWidth'];
height = e['clientHeight'];
}
if (width >= 0 && height >= 0) {
return width + DIMENSION_SEPARATOR + height;
} else {
return null;
}
}
/**
* Gets the dimensions of the current
* document.
*
* Code based on:
* - http://andylangton.co.uk/articles/javascript/get-viewport-size-javascript/
*/
function detectDocumentSize() {
var de = document.documentElement, // Alias
be = document.body,
// document.body may not have rendered, so check whether be.offsetHeight is null
bodyHeight = be ? Math.max(be.offsetHeight, be.scrollHeight) : 0;
var w = Math.max(de.clientWidth, de.offsetWidth, de.scrollWidth);
var h = Math.max(de.clientHeight, de.offsetHeight, de.scrollHeight, bodyHeight);
return isNaN(w) || isNaN(h) ? '' : w + DIMENSION_SEPARATOR + h;
}
function detectScreenResolution() {
return screen.width + DIMENSION_SEPARATOR + screen.height;
}
export function floorDimensionFields(field?: string | null) {
return (
field &&
field
.split(DIMENSION_SEPARATOR)
.map((dimension) => Math.floor(Number(dimension)))
.join(DIMENSION_SEPARATOR)
);
}