clarity-visualize 0.6.23
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/README.md +26 -0
- package/build/clarity.visualize.js +1305 -0
- package/build/clarity.visualize.min.js +1 -0
- package/build/clarity.visualize.module.js +1301 -0
- package/package.json +62 -0
- package/rollup.config.ts +42 -0
- package/src/clarity.ts +159 -0
- package/src/data.ts +90 -0
- package/src/global.ts +9 -0
- package/src/heatmap.ts +279 -0
- package/src/index.ts +2 -0
- package/src/interaction.ts +380 -0
- package/src/layout.ts +351 -0
- package/tsconfig.json +20 -0
- package/tslint.json +33 -0
- package/types/index.d.ts +19 -0
- package/types/visualize.d.ts +154 -0
package/src/layout.ts
ADDED
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
import { Data, Layout } from "clarity-decode";
|
|
2
|
+
import { Asset, Constant, NodeType, Setting } from "@clarity-types/visualize";
|
|
3
|
+
import { state } from "./clarity";
|
|
4
|
+
|
|
5
|
+
const TIMEOUT = 3000;
|
|
6
|
+
let stylesheets: Promise<void>[] = [];
|
|
7
|
+
let nodes = {};
|
|
8
|
+
let events = {};
|
|
9
|
+
let hashMap = {};
|
|
10
|
+
|
|
11
|
+
export function reset(): void {
|
|
12
|
+
nodes = {};
|
|
13
|
+
stylesheets = [];
|
|
14
|
+
events = {};
|
|
15
|
+
hashMap = {};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function get(hash) {
|
|
19
|
+
var element = hash in hashMap ? (hashMap[hash].isConnected ? hashMap[hash] : null) : null;
|
|
20
|
+
return element;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function box(event: Layout.BoxEvent): void {
|
|
24
|
+
let data = event.data;
|
|
25
|
+
for (let b of data) {
|
|
26
|
+
let el = element(b.id) as HTMLElement;
|
|
27
|
+
resize(el, b.width, b.height);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function addToHashMap(hash, node)
|
|
32
|
+
{
|
|
33
|
+
// In case of selector collision, prefer the first inserted node
|
|
34
|
+
let element = get(hash)
|
|
35
|
+
hashMap[hash] = element ? element : node;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function resize(el: HTMLElement, width: number, height: number): void {
|
|
39
|
+
if (el && el.nodeType === NodeType.ELEMENT_NODE && width && height) {
|
|
40
|
+
el.style.width = width + Layout.Constant.Pixel;
|
|
41
|
+
el.style.height = height + Layout.Constant.Pixel;
|
|
42
|
+
el.style.boxSizing = Layout.Constant.BorderBox; // Reference: https://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function element(nodeId: number): Node {
|
|
47
|
+
return nodeId !== null && nodeId > 0 && nodeId in nodes ? nodes[nodeId] : null;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export async function dom(event: Layout.DomEvent): Promise<void> {
|
|
51
|
+
if (event) {
|
|
52
|
+
// When setting up rendering for the first time, start off with hidden target window
|
|
53
|
+
// This ensures we do not show flickers to the end user
|
|
54
|
+
let doc = state.window.document;
|
|
55
|
+
if (doc && doc.documentElement) {
|
|
56
|
+
doc.documentElement.style.visibility = Constant.Hidden;
|
|
57
|
+
// Render all DOM events to reconstruct the page
|
|
58
|
+
markup(event);
|
|
59
|
+
// Wait on all stylesheets to finish loading
|
|
60
|
+
await Promise.all(stylesheets);
|
|
61
|
+
// Toggle back the visibility of target window
|
|
62
|
+
doc.documentElement.style.visibility = Constant.Visible;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export function exists(hash: string): boolean {
|
|
68
|
+
if (hash) {
|
|
69
|
+
let match = get(hash);
|
|
70
|
+
if (match) {
|
|
71
|
+
let rectangle = match.getBoundingClientRect();
|
|
72
|
+
return rectangle && rectangle.width > 0 && rectangle.height > 0;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function markup(event: Layout.DomEvent): void {
|
|
79
|
+
let data = event.data;
|
|
80
|
+
let type = event.event;
|
|
81
|
+
let doc = state.window.document;
|
|
82
|
+
for (let node of data) {
|
|
83
|
+
let parent = element(node.parent);
|
|
84
|
+
let pivot = element(node.previous);
|
|
85
|
+
let insert = insertAfter;
|
|
86
|
+
|
|
87
|
+
let tag = node.tag;
|
|
88
|
+
if (tag && tag.indexOf(Layout.Constant.IFramePrefix) === 0) { tag = node.tag.substr(Layout.Constant.IFramePrefix.length); }
|
|
89
|
+
switch (tag) {
|
|
90
|
+
case Layout.Constant.DocumentTag:
|
|
91
|
+
let tagDoc = tag !== node.tag ? (parent ? (parent as HTMLIFrameElement).contentDocument : null): doc;
|
|
92
|
+
if (tagDoc && tagDoc === doc && type === Data.Event.Discover) { reset(); }
|
|
93
|
+
if (typeof XMLSerializer !== "undefined" && tagDoc) {
|
|
94
|
+
tagDoc.open();
|
|
95
|
+
tagDoc.write(new XMLSerializer().serializeToString(
|
|
96
|
+
tagDoc.implementation.createDocumentType(
|
|
97
|
+
node.attributes["name"],
|
|
98
|
+
node.attributes["publicId"],
|
|
99
|
+
node.attributes["systemId"]
|
|
100
|
+
)
|
|
101
|
+
));
|
|
102
|
+
tagDoc.close();
|
|
103
|
+
}
|
|
104
|
+
break;
|
|
105
|
+
case Layout.Constant.PolyfillShadowDomTag:
|
|
106
|
+
// In case of polyfill, map shadow dom to it's parent for rendering purposes
|
|
107
|
+
// All its children should be inserted as regular children to the parent node.
|
|
108
|
+
nodes[node.id] = parent;
|
|
109
|
+
addToHashMap(node.hash, parent);
|
|
110
|
+
break;
|
|
111
|
+
case Layout.Constant.ShadowDomTag:
|
|
112
|
+
if (parent) {
|
|
113
|
+
let shadowRoot = element(node.id);
|
|
114
|
+
shadowRoot = shadowRoot ? shadowRoot : (parent as HTMLElement).attachShadow({ mode: "open" });
|
|
115
|
+
if ("style" in node.attributes) {
|
|
116
|
+
let shadowStyle = doc.createElement("style");
|
|
117
|
+
// Support for adoptedStyleSheet is limited and not available in all browsers.
|
|
118
|
+
// To ensure that we can replay session in any browser, we turn adoptedStyleSheets from recording
|
|
119
|
+
// into classic style tags at the playback time.
|
|
120
|
+
if (shadowRoot.firstChild && (shadowRoot.firstChild as HTMLElement).id === Constant.AdoptedStyleSheet) {
|
|
121
|
+
shadowStyle = shadowRoot.firstChild as HTMLStyleElement;
|
|
122
|
+
}
|
|
123
|
+
shadowStyle.id = Constant.AdoptedStyleSheet;
|
|
124
|
+
shadowStyle.textContent = node.attributes["style"];
|
|
125
|
+
shadowRoot.appendChild(shadowStyle);
|
|
126
|
+
}
|
|
127
|
+
nodes[node.id] = shadowRoot;
|
|
128
|
+
addToHashMap(node.hash, shadowRoot);
|
|
129
|
+
}
|
|
130
|
+
break;
|
|
131
|
+
case Layout.Constant.TextTag:
|
|
132
|
+
let textElement = element(node.id);
|
|
133
|
+
textElement = textElement ? textElement : doc.createTextNode(null);
|
|
134
|
+
textElement.nodeValue = node.value;
|
|
135
|
+
insert(node, parent, textElement, pivot);
|
|
136
|
+
break;
|
|
137
|
+
case Layout.Constant.SuspendMutationTag:
|
|
138
|
+
let suspendedElement = element(node.id);
|
|
139
|
+
if (suspendedElement && suspendedElement.nodeType === Node.ELEMENT_NODE) {
|
|
140
|
+
(suspendedElement as HTMLElement).setAttribute(Constant.Suspend, Layout.Constant.Empty);
|
|
141
|
+
}
|
|
142
|
+
break;
|
|
143
|
+
case "HTML":
|
|
144
|
+
let htmlDoc = tag !== node.tag ? (parent ? (parent as HTMLIFrameElement).contentDocument : null): doc;
|
|
145
|
+
if (htmlDoc !== null) {
|
|
146
|
+
let docElement = element(node.id) as HTMLElement;
|
|
147
|
+
if (docElement === null) {
|
|
148
|
+
let newDoc = htmlDoc.implementation.createHTMLDocument(Layout.Constant.Empty);
|
|
149
|
+
docElement = newDoc.documentElement;
|
|
150
|
+
let p = htmlDoc.importNode(docElement, true);
|
|
151
|
+
htmlDoc.replaceChild(p, htmlDoc.documentElement);
|
|
152
|
+
if (htmlDoc.head) { htmlDoc.head.parentNode.removeChild(htmlDoc.head); }
|
|
153
|
+
if (htmlDoc.body) { htmlDoc.body.parentNode.removeChild(htmlDoc.body); }
|
|
154
|
+
}
|
|
155
|
+
setAttributes(htmlDoc.documentElement, node);
|
|
156
|
+
// If we are still processing discover events, keep the markup hidden until we are done
|
|
157
|
+
if (type === Data.Event.Discover) { htmlDoc.documentElement.style.visibility = Constant.Hidden; }
|
|
158
|
+
nodes[node.id] = htmlDoc.documentElement;
|
|
159
|
+
addToHashMap(node.hash, htmlDoc.documentElement);
|
|
160
|
+
}
|
|
161
|
+
break;
|
|
162
|
+
case "HEAD":
|
|
163
|
+
let headElement = element(node.id);
|
|
164
|
+
if (headElement === null) {
|
|
165
|
+
headElement = doc.createElement(node.tag);
|
|
166
|
+
if (node.attributes && Layout.Constant.Base in node.attributes) {
|
|
167
|
+
let base = doc.createElement("base");
|
|
168
|
+
base.href = node.attributes[Layout.Constant.Base];
|
|
169
|
+
headElement.appendChild(base);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Add custom styles to assist with visualization
|
|
173
|
+
let custom = doc.createElement("style");
|
|
174
|
+
custom.innerText = getCustomStyle();
|
|
175
|
+
headElement.appendChild(custom);
|
|
176
|
+
}
|
|
177
|
+
setAttributes(headElement as HTMLElement, node);
|
|
178
|
+
insert(node, parent, headElement, pivot);
|
|
179
|
+
break;
|
|
180
|
+
case "LINK":
|
|
181
|
+
let linkElement = element(node.id) as HTMLLinkElement;
|
|
182
|
+
linkElement = linkElement ? linkElement : createElement(doc, node.tag) as HTMLLinkElement;
|
|
183
|
+
if (!node.attributes) { node.attributes = {}; }
|
|
184
|
+
setAttributes(linkElement as HTMLElement, node);
|
|
185
|
+
if ("rel" in node.attributes && node.attributes["rel"] === "stylesheet") {
|
|
186
|
+
stylesheets.push(new Promise((resolve: () => void): void => {
|
|
187
|
+
linkElement.onload = linkElement.onerror = style.bind(this, linkElement, resolve);
|
|
188
|
+
setTimeout(resolve, TIMEOUT);
|
|
189
|
+
}));
|
|
190
|
+
}
|
|
191
|
+
insert(node, parent, linkElement, pivot);
|
|
192
|
+
break;
|
|
193
|
+
case "STYLE":
|
|
194
|
+
let styleElement = element(node.id) as HTMLStyleElement;
|
|
195
|
+
styleElement = styleElement ? styleElement : doc.createElement(node.tag) as HTMLStyleElement;
|
|
196
|
+
setAttributes(styleElement as HTMLElement, node);
|
|
197
|
+
styleElement.textContent = node.value;
|
|
198
|
+
insert(node, parent, styleElement, pivot);
|
|
199
|
+
style(styleElement);
|
|
200
|
+
break;
|
|
201
|
+
case "IFRAME":
|
|
202
|
+
let iframeElement = element(node.id) as HTMLElement;
|
|
203
|
+
iframeElement = iframeElement ? iframeElement : createElement(doc, node.tag);
|
|
204
|
+
if (!node.attributes) { node.attributes = {}; }
|
|
205
|
+
setAttributes(iframeElement as HTMLElement, node);
|
|
206
|
+
insert(node, parent, iframeElement, pivot);
|
|
207
|
+
break;
|
|
208
|
+
default:
|
|
209
|
+
let domElement = element(node.id) as HTMLElement;
|
|
210
|
+
domElement = domElement ? domElement : createElement(doc, node.tag);
|
|
211
|
+
setAttributes(domElement as HTMLElement, node);
|
|
212
|
+
resize(domElement, node.width, node.height);
|
|
213
|
+
insert(node, parent, domElement, pivot);
|
|
214
|
+
break;
|
|
215
|
+
}
|
|
216
|
+
// Track state for this node
|
|
217
|
+
if (node.id) { events[node.id] = node; }
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
function style(node: HTMLLinkElement | HTMLStyleElement, resolve: () => void = null): void {
|
|
222
|
+
// Firefox throws a SecurityError when trying to access cssRules of a stylesheet from a different domain
|
|
223
|
+
try {
|
|
224
|
+
const sheet = node.sheet as CSSStyleSheet;
|
|
225
|
+
let cssRules = sheet ? sheet.cssRules : [];
|
|
226
|
+
for (let i = 0; i < cssRules.length; i++) {
|
|
227
|
+
if (cssRules[i].cssText.indexOf(Constant.Hover) >= 0) {
|
|
228
|
+
let css = cssRules[i].cssText.replace(/:hover/g, `[${Constant.CustomHover}]`);
|
|
229
|
+
sheet.removeRule(i);
|
|
230
|
+
sheet.insertRule(css, i);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
} catch { /* do nothing */ }
|
|
234
|
+
|
|
235
|
+
if (resolve) { resolve(); }
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
function createElement(doc: Document, tag: string): HTMLElement {
|
|
239
|
+
if (tag && tag.indexOf(Layout.Constant.SvgPrefix) === 0) {
|
|
240
|
+
return doc.createElementNS(Layout.Constant.SvgNamespace as string, tag.substr(Layout.Constant.SvgPrefix.length)) as HTMLElement;
|
|
241
|
+
}
|
|
242
|
+
try { return doc.createElement(tag); } catch (ex) {
|
|
243
|
+
// We log the warning on non-standard markup but continue with the visualization
|
|
244
|
+
console.warn(`Exception encountered while creating element ${tag}: ${ex}`);
|
|
245
|
+
return doc.createElement(Constant.UnknownTag);
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
function insertAfter(data: Layout.DomData, parent: Node, node: Node, previous: Node): void {
|
|
250
|
+
// Skip over no-op changes where parent and previous element is still the same
|
|
251
|
+
// In case of IFRAME, re-adding DOM at the exact same place will lead to loss of state and the markup inside will be destroyed
|
|
252
|
+
if (events[data.id] && events[data.id].parent === data.parent && events[data.id].previous === data.previous) { return; }
|
|
253
|
+
let next = previous && previous.parentElement === parent ? previous.nextSibling : null;
|
|
254
|
+
next = previous === null && parent ? firstChild(parent) : next;
|
|
255
|
+
insertBefore(data, parent, node, next);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
function firstChild(node: Node): ChildNode {
|
|
259
|
+
let child = node.firstChild;
|
|
260
|
+
// BASE tag should always be the first child to ensure resources with relative URLs are loaded correctly
|
|
261
|
+
if (child && child.nodeType === NodeType.ELEMENT_NODE && (child as HTMLElement).tagName === Layout.Constant.BaseTag) {
|
|
262
|
+
return child.nextSibling;
|
|
263
|
+
}
|
|
264
|
+
return child;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
function insertBefore(data: Layout.DomData, parent: Node, node: Node, next: Node): void {
|
|
268
|
+
if (parent !== null) {
|
|
269
|
+
next = next && next.parentElement !== parent ? null : next;
|
|
270
|
+
try {
|
|
271
|
+
parent.insertBefore(node, next);
|
|
272
|
+
} catch (ex) {
|
|
273
|
+
console.warn("Node: " + node + " | Parent: " + parent + " | Data: " + JSON.stringify(data));
|
|
274
|
+
console.warn("Exception encountered while inserting node: " + ex);
|
|
275
|
+
}
|
|
276
|
+
} else if (parent === null && node.parentElement !== null) {
|
|
277
|
+
node.parentElement.removeChild(node);
|
|
278
|
+
}
|
|
279
|
+
nodes[data.id] = node;
|
|
280
|
+
addToHashMap(data.hash, node);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
function setAttributes(node: HTMLElement, data: Layout.DomData): void {
|
|
284
|
+
let attributes = data.attributes || {};
|
|
285
|
+
let sameorigin = false;
|
|
286
|
+
|
|
287
|
+
// Clarity attributes
|
|
288
|
+
attributes[Constant.Id] = `${data.id}`;
|
|
289
|
+
attributes[Constant.Hash] = `${data.hash}`;
|
|
290
|
+
|
|
291
|
+
let tag = node.nodeType === NodeType.ELEMENT_NODE ? node.tagName.toLowerCase() : null;
|
|
292
|
+
// First remove all its existing attributes
|
|
293
|
+
if (node.attributes) {
|
|
294
|
+
let length = node.attributes.length;
|
|
295
|
+
while (node.attributes && length > 0) {
|
|
296
|
+
// Do not remove "clarity-hover" attribute and let it be managed by interaction module
|
|
297
|
+
// This helps avoid flickers during visualization
|
|
298
|
+
if (node.attributes[0].name !== Constant.HoverAttribute) {
|
|
299
|
+
node.removeAttribute(node.attributes[0].name);
|
|
300
|
+
}
|
|
301
|
+
length--;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// Add new attributes
|
|
306
|
+
for (let attribute in attributes) {
|
|
307
|
+
if (attributes[attribute] !== undefined) {
|
|
308
|
+
try {
|
|
309
|
+
let v = attributes[attribute];
|
|
310
|
+
if (attribute.indexOf("xlink:") === 0) {
|
|
311
|
+
node.setAttributeNS("http://www.w3.org/1999/xlink", attribute, v);
|
|
312
|
+
} else if (attribute.indexOf(Layout.Constant.SameOrigin) === 0) {
|
|
313
|
+
sameorigin = true;
|
|
314
|
+
} else if (attribute.indexOf("*") === 0) {
|
|
315
|
+
// Do nothing if we encounter internal Clarity attributes
|
|
316
|
+
} else if (tag === Constant.IFrameTag && (attribute.indexOf("src") === 0 || attribute.indexOf("allow") === 0) || attribute === "sandbox") {
|
|
317
|
+
node.setAttribute(`data-clarity-${attribute}`, v);
|
|
318
|
+
} else if (tag === Constant.ImageTag && attribute.indexOf("src") === 0 && (v === null || v.length === 0)) {
|
|
319
|
+
node.setAttribute(attribute, Asset.Transparent);
|
|
320
|
+
let size = Constant.Large;
|
|
321
|
+
if (data.width) {
|
|
322
|
+
size = data.width <= Setting.Medium ? Constant.Medium : (data.width <= Setting.Small ? Constant.Small : size);
|
|
323
|
+
}
|
|
324
|
+
node.setAttribute(Constant.Hide, size);
|
|
325
|
+
} else {
|
|
326
|
+
node.setAttribute(attribute, v);
|
|
327
|
+
}
|
|
328
|
+
} catch (ex) {
|
|
329
|
+
console.warn("Node: " + node + " | " + JSON.stringify(attributes));
|
|
330
|
+
console.warn("Exception encountered while adding attributes: " + ex);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
if (sameorigin === false && tag === Constant.IFrameTag && typeof node.setAttribute == Constant.Function) {
|
|
336
|
+
node.setAttribute(Constant.Unavailable, Layout.Constant.Empty);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
// Add an empty ALT tag on all IMG elements
|
|
340
|
+
if (tag === Constant.ImageTag && !node.hasAttribute(Constant.AltAttribute)) { node.setAttribute(Constant.AltAttribute, Constant.Empty); }
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
function getCustomStyle(): string {
|
|
344
|
+
// tslint:disable-next-line: max-line-length
|
|
345
|
+
return `${Constant.ImageTag}[${Constant.Hide}] { background-color: #CCC; background-image: url(${Asset.Hide}); background-repeat:no-repeat; background-position: center; }` +
|
|
346
|
+
`${Constant.ImageTag}[${Constant.Hide}=${Constant.Small}] { background-size: 18px 18px; }` +
|
|
347
|
+
`${Constant.ImageTag}[${Constant.Hide}=${Constant.Medium}] { background-size: 24px 24px; }` +
|
|
348
|
+
`${Constant.ImageTag}[${Constant.Hide}=${Constant.Large}] { background-size: 36px 36px; }` +
|
|
349
|
+
`${Constant.IFrameTag}[${Constant.Unavailable}] { background: url(${Asset.Unavailable}) no-repeat center center, url('${Asset.Cross}'); }` +
|
|
350
|
+
`*[${Constant.Suspend}] { filter: grayscale(100%); }`;
|
|
351
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"module": "esnext",
|
|
4
|
+
"target": "es5",
|
|
5
|
+
"lib": ["es6", "dom", "es2016", "es2017"],
|
|
6
|
+
"moduleResolution": "node",
|
|
7
|
+
"forceConsistentCasingInFileNames": true,
|
|
8
|
+
"noImplicitReturns": true,
|
|
9
|
+
"noUnusedLocals": true,
|
|
10
|
+
"noUnusedParameters": true,
|
|
11
|
+
"esModuleInterop": true,
|
|
12
|
+
"baseUrl": ".",
|
|
13
|
+
"paths": {
|
|
14
|
+
"@src/*": ["src/*"],
|
|
15
|
+
"@clarity-types/*": ["types/*"]
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"include":["src/**/*.ts","types/**/*.d.ts"],
|
|
19
|
+
"exclude": ["node_modules", "build"]
|
|
20
|
+
}
|
package/tslint.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "tslint:recommended",
|
|
3
|
+
"rules": {
|
|
4
|
+
"max-line-length": [
|
|
5
|
+
true,
|
|
6
|
+
140
|
|
7
|
+
],
|
|
8
|
+
"no-console": [
|
|
9
|
+
false
|
|
10
|
+
],
|
|
11
|
+
"no-string-literal": false,
|
|
12
|
+
"prefer-const": false,
|
|
13
|
+
"prefer-for-of": false,
|
|
14
|
+
"object-literal-sort-keys": false,
|
|
15
|
+
"one-variable-per-declaration": false,
|
|
16
|
+
"trailing-comma": [
|
|
17
|
+
false
|
|
18
|
+
],
|
|
19
|
+
"variable-name": false,
|
|
20
|
+
"interface-name": false,
|
|
21
|
+
"interface-over-type-literal": false,
|
|
22
|
+
"only-arrow-functions": false,
|
|
23
|
+
"typedef": [
|
|
24
|
+
true,
|
|
25
|
+
"call-signature",
|
|
26
|
+
"parameter",
|
|
27
|
+
"property-declaration",
|
|
28
|
+
"member-variable-declaration",
|
|
29
|
+
"object-destructuring",
|
|
30
|
+
"array-destructuring"
|
|
31
|
+
]
|
|
32
|
+
}
|
|
33
|
+
}
|
package/types/index.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Activity, MergedPayload, Options, ResizeHandler, ScrollMapInfo } from "./visualize";
|
|
2
|
+
import { Data, Diagnostic, Interaction, Layout } from "clarity-decode"
|
|
3
|
+
|
|
4
|
+
export interface Visualize {
|
|
5
|
+
dom: (event: Layout.DomEvent) => Promise<void>;
|
|
6
|
+
html: (decoded: Data.DecodedPayload[], target: Window, hash?: string, time?: number) => Visualize;
|
|
7
|
+
clickmap: (activity?: Activity) => void;
|
|
8
|
+
clearmap: () => void;
|
|
9
|
+
scrollmap: (data?: ScrollMapInfo[], averageFold?: number) => void;
|
|
10
|
+
merge: (decoded: Data.DecodedPayload[]) => MergedPayload;
|
|
11
|
+
render: (events: Data.DecodedEvent[]) => void;
|
|
12
|
+
setup: (target: Window, options: Options) => Visualize;
|
|
13
|
+
time: () => number;
|
|
14
|
+
get: (hash: string) => HTMLElement;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
declare const visualize: Visualize;
|
|
18
|
+
|
|
19
|
+
export { visualize, Data, Diagnostic, Interaction, Layout, MergedPayload, ResizeHandler };
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { Data, Layout } from "clarity-decode";
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
export type ResizeHandler = (width: number, height: number) => void;
|
|
5
|
+
|
|
6
|
+
export interface MergedPayload {
|
|
7
|
+
timestamp: number;
|
|
8
|
+
envelope: Data.Envelope;
|
|
9
|
+
dom: Layout.DomEvent;
|
|
10
|
+
events: Data.DecodedEvent[];
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface Point {
|
|
14
|
+
time: number;
|
|
15
|
+
x: number;
|
|
16
|
+
y: number;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface Options {
|
|
20
|
+
version: string;
|
|
21
|
+
dom?: Layout.DomEvent;
|
|
22
|
+
onresize?: ResizeHandler;
|
|
23
|
+
metadata?: HTMLElement;
|
|
24
|
+
canvas?: boolean;
|
|
25
|
+
keyframes?: boolean;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface PlaybackState {
|
|
29
|
+
window: Window;
|
|
30
|
+
options: Options;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export type Activity = ElementData[];
|
|
34
|
+
|
|
35
|
+
export interface ScrollMapInfo {
|
|
36
|
+
scrollReachY: number;
|
|
37
|
+
cumulativeSum: number;
|
|
38
|
+
percUsers: number;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
export interface ElementData {
|
|
43
|
+
hash: string;
|
|
44
|
+
selector: string;
|
|
45
|
+
totalclicks: number;
|
|
46
|
+
x: number[];
|
|
47
|
+
y: number[];
|
|
48
|
+
clicks: number[];
|
|
49
|
+
points: number;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface Heatmap {
|
|
53
|
+
x: number; /* X Coordinate */
|
|
54
|
+
y: number; /* Y Coordinate */
|
|
55
|
+
a: number; /* Alpha */
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export const enum NodeType {
|
|
59
|
+
ELEMENT_NODE = 1,
|
|
60
|
+
ATTRIBUTE_NODE = 2,
|
|
61
|
+
TEXT_NODE = 3,
|
|
62
|
+
COMMENT_NODE = 8,
|
|
63
|
+
DOCUMENT_NODE = 9,
|
|
64
|
+
DOCUMENT_TYPE_NODE = 10
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export const enum Asset {
|
|
68
|
+
Pointer = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB0AAAAmCAYAAAA4LpBhAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAASDSURBVHgB7VdPTCNlFH8z0/+FFmRatnFNiDGR4O4mBk08smZvXjjIxRueNME9eHGNxoLxSNwr4WyigYToQRJLjXDzQtDNmnhR4kWWAJm20ymddtrx94bvI9NBWAptsod9ycvM92fe73vv/b73fUP0DIlCfRQ1AMTtjwcHB1+gPgOT67oK6+TkZBjNbxRF+X1gYCCDPpX6IKdGAaTu7++HuG9tbe1ONBr9GR7r+Xy+98DsIRuemJiIjI6OJgH+3e7urruzs+OOjIw8SiaTNwRwz8OtQWPpdHoYoKt///ar2/jxaw84k8k8gt5YWVnRqEfi90BrtVph0Uetx0V67d9fqFAo3G6324XZ2VldLK4noK4AVqvVaoh8YZTAxWLxdiwW20CoM70IdceWicfjSpCxfuBEIrGxsLCQZR7QNcQDwFaRRhRmcXCSL9S3kN8CtlP2Oqz2QoWt4Q4NDanHx8cy3HQBMIe6sLS0pF811B7I5uYmhUKh1nmAQWAOteM4xcXFxczMzEzXHp+u9PDwUBHvymWBmVzr6+t6t9tJhtPzEEYuFaoguebm5nTqJOXFoMxEVCO50tMFXBaYcwwbGwAfRagv5bEKthK2igdUr9epG/EDYw//xKGmzoLz/6BQd3t7m5i9dAUJsJoLSPZp5PIGp6amXHjsVSaEirqVALk8jy/axx2hwAcMTlcRH/Ad5LfA24kEZ4JzudbySSJzyqDnomq37pH14utH/iUrCA5HCeRwHYXc8dzNNs5jfXp6uoD+e/Pz8zzfDYIqq6urihg4NyTaK2/Rw8fNo0/euWvBWI3TwGAiHW2RnjY7LRVjX+7t7d3nSWL8FFSKIj46I0r2ZXr4R/PoQT5f1TTtU3Q5OAbbbAxtV4BwXx07wUI5raJdTaVS5vLysmYYhlyMDJBHJBoeHpbFwQ0CfmuP04P8V1VVVb9AVwXGy/xE6SyHw2FuW9Aa2jYAHVx1HAZh78bGxs44wYkm0zS9PPrC1QE4+8HcPwD8HONPYNzEkAU1UX+raFcYmPswzhu9ISLmShIdHBx0lFfVH2s+SyWR/IBofgYvnmCIPTQjkYiBk8mARwYWU4aW8F5uNpslXHkstBncxjcOeyqJ6vfUO9oQd2avlyeKJj3A9z/8yAOE7uHKUgGoiRQYMFZCdEq2bZfgpYFnmd9xzprlcrnCOdV13cbWaWKezGVnAUBOmVBpkOAlPH/AxuYJu/DoPQDcxfubeB/ncZCDL+IpaDKgiVwul8AzDo1BI3RC1HPLIg+mYPQmvPke+hdY+S68ehuevIHQvYpV5/i2KIxKg5pUUew1AaL6wM4cl4oPFJjxFMJ0H6BbIIgBwAbeLSzABLBVKpVszGvSCf27r5dCNE7h1tYWX1U0ECHUaDT+REhryKENrTFbwdLj+skRxIAeM+ka4rGV2QWv2vCIjVoAryC0Jk6MCk6fGvoY0OkFoF80UDsG8AG8j/BtD78YWRSMNNoJQbSe/1Zw0tmwBB6kE0ZG+wXI4v1ECYAIdbKzf/+povypEui6t/jnwvIf5FVJ1Cj/1+UAAAAASUVORK5CYII=",
|
|
69
|
+
Click = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB0AAAAmCAYAAAA4LpBhAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAVoSURBVHgB7VdNTCRFGP2qe6aBGRhA5mfJ7kZcV0XQTQx68MYabl44yMWbetAY3IMX12gWMCZeSLwSEi/GiAHF1SjqMAhoshuTJbg/GkM0xMQIBMj8D/Nfvq+6enZmEtFdhsSDRT66q6qnXr33varqJvoPFUHHWIw6IK6/2tbWdg8dMzBJKQXHwMCAG9UPhBDXW1tbA2gz6BhKZVAAGTs7Oy5um5+fP9fU1LQExv6xsbHGAzNDHrivr88KhUJegH+0ubkp19fXZVdX1w2v13tCAzdcbhPR3N7e3gnQuY0ry3L7nRcUcCAQuIE4MTs7a1IDi9CgXuQxCNBPNq6uyF+HWuTO5IvVjEP6uSMXlk1qYCOVSnFOgYvRLUtmVmbp9HfvUSQSebS5uXkRwIFGSF2zZFpaWoTtWEHCcgvDclPm+4/p3qvvK2CPx7M4MTERZB/QEYoCxVJxBhHsYvwn0+2WKiyLslc+pfuufSjD4fAjyG+Y03AUVyupsDRkR0eHcXBwYMuNKQi3BaYIt5uYce6Hz8XZ63MMzFKHp6am/HcrtQJZWVkhl8tVIju/KqkmgBxAdQXr3LUv6exPl5XUxWIxMjk5GRgZGbljxpWZ7u3tCX3PPCuALDEYk2Ytij9+RQ9ufFEx18LCgv9Ol5PjXsUQg9hSsXubLA3IwC7JoVgjSjfD9PDm1xVzjY6O+qnWlIeDshOxGzkzVRNgeW2mdl6FfXVkxiQsKv/8LfX9sUScY4yxCPAQpP5XjA0GwFJRTLPZrG5mUFcln6Ytc+Uq0CdcLgAvyf4/lxUw1vA3LDVVpexQedfW1ojdW2m1N4cKM8PllqLKUMI0SRhCsuVKtyLUv7XsuJo3kOA/mUt1Dg4OsqRqZ4JUPJZtIttAaqMAMzQarH8NCzwqSzcjghlrcynGh63jGinwA5VP9efIaBr2vqgBnGeltH+nJonCjPts4HPIb5iXE2nP1IPyXssniZNTBhVq0RhC3p6QTd/oHxLpk4/t356yelQawijrecnek6fKOI/9w8PDYQw1ND4+zs/LelAxNzcndIdRLRwzs5kIYT7wJL17q7D/2tPn0+jIcDunRDMt6/SUmbQT6Htra2vrAj+k+yugFRT9I6qVEGxCZwCY3784dillmubr6CqWSqUyD4a61CDclsVKSGM7TaGe8vl8yenpaTMajTqTqeSUjUSdnZ3O5iCrYUXwDM1ke+ni2NspwzAuoTGBweN8xdYZd7vdXE8jMqjnAFjEq06RQZhdT08P1RdONCWTSaEFdeSyqQfvFzO5XnrupdHfAfgm+rcxeBJdaUQS+28K9QQDcxv6eaHntWLSMdHu7q6zxWorVGnNZ6nQVmVJmSEDovoGWGyjixkmLcuK4mSKglEUk4kjYriPFwqFGF550qgzeA6/KTJTx6jVTNXRBt3ZvSpP1OSlmYNeev7lVxQgYqtcLicAmkQKohgsBnViuVwuBpZRXON8j3M2GY/HE5xTv9+fw9Ip4DknlzXAnFM2VDtMcBrXz7Cw+YFNMHoWAOdx/wTue7kf5uAXcR/CWxee7u5uD64tiGaERbZR/3Zb5E4fBj0FNpcRv8GVz4DVU2DyOKR7CLPu5rdFPagzoOmE3uxNDWJUgYl6UFEFCswWH2S6ANBVGCQKwDzu05hAEsDpWCyWw3MFsu0v6S6LySlcXV3lVxUTRnDl8/lfIGkGOcwhMuxWuPQgax9BDKicSUcoyq3sLrAqgxEPmgZ4AtImcWIkcPpk0MaAxUYAVhcT1m4GeCvuu/htD58YQWwY7ah7tNEa/lnBSeeBHeA2sh3ZdFyAXNRHlAawqNadx/edqrc/wwE66lv8/4XLX3gjac6XP/Y1AAAAAElFTkSuQmCC",
|
|
70
|
+
Sound = "data:video/webm;base64,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",
|
|
71
|
+
Transparent = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=",
|
|
72
|
+
Hide = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAYAAADhAJiYAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAANvSURBVHgB7Ve9VhpREJ5dU6BNVqt0wS6dpEuX9QmiTyA+gfgE4BOgZSrJE4hlKvEJxDKVa2caoaSSfB87F4Z7dtmFhFTMOfcMe52Z+935u6PIhjb0dxTIihRFUQ2M6z0/dXuI9ay8PwTJklQaEADw0JMgCI4USFSkMx6Pe2BdrFtgS6QEFQICjirYGYDUc0AMcXCCvw8XAVVwHQD7IasAokfCMGzB0NmCA1o44N7T+wpwlwouT+80z2NbOWAaMHqDn7FuJcorapRATkej0bOvyz2s7zs7O2L0GbYXrCrscjUqlUoAuZ6vH3hAIr3diW4xHC3wW+w/KZhLgDmXEgRzbR6udvbBD/DdITB3UewfWm+FRpnIHwyYLo1A+Aq/vzkDWFdSni4krTjm1RnDOxgM9nFOS//OM++0YmeAFMydQw4gDSgeu7LVyprE3489je3u7t5waQFMifrQ6ehn7PZfX18v6BkFOwcq9MDQQKxeseRu0PXARJprBHxED2t7sPSol6p5YHs467OkXo8cqBA/rmXmmVO/atzZzk4G0Kond+DJJJLmStc3Sm+rpxLVbYcEoRu8xbWNp9U1B1rqyzzIRNQj5tAe84ZVKVmGZ6BoK5Vh2JADT1hjLny3rBL27nS/7RtUXZdDmb1H5Ug1rDgjrFMKrGGb2CzPt7e3C95gb2+vqeU/1Mor/UZpg21og50CsfYzATllsLY+E6TE60OTPoUqOV8EQNKKmuTTgifHAmO4GOokyDFah2BTTAOTNFcmIQFI3qyVoxurp+dIL3ZF72bYdzL1zKcDLb2P1n4rqUfcg/nB3Cre3t6uQeY3ZBOri72q87B7ULHY035CdmTs85H9BVlR23yWumVf+6YJo0/MK7qcI8al9RCqq9R4w4ICq9JDYZEwk44ly2TWFtGT+VKnF2PwB6cis8sUzkw+vSsrqNXQ0eUmxo+S5gEPfvQBSTpNLjU1rjzCLiKEYAAWMQRFA5m2GzdJxIUhW5H6yutFguhRToapcb8WQGwL5MwtDnt5cvQOZJuq0yHfkjUQWwHbAn5+AqgvKHGW/IsPRquR+ZdgcQIdrStkYh5tN1ocZYCpSto2Dqezl6yRMga/yQSpXToyYFzOrReQAcUhzp8E+E4eWzD/lTgxuPFGR5Wlm+Y/J3qL/7fJhja0RvoDR4Tn4Lo/zi8AAAAASUVORK5CYII=",
|
|
73
|
+
Unavailable = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC4AAAAiCAYAAAAge+tMAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAU6SURBVHgBzVg7TyNJEG6bh5AIjpOQeCXj7LL18pDIdpztRYuzy7CjCzG/ADu8CO8vwEQXrgkvws6QeNiEFzEk4GznIFnxvO/zVntrhx6/kLxb0mh6uqurvq6urqqehHklra+ve3d3dx8SiUT6+fk5ja4ZtGf4tjzoD9AXoBmiXUsmk+cnJyc18wpKmCFodXXVx8t/enraBCDPDEchniqeg9PT06oZkAYCTsCw2A6afjc+8IQCjGR3oBtxR/bHx8crR0dHgemD+gIugPfQ9OJ4BGwF72qj0ajrsTQI7rEFcDnTndoLeHh4KDebzdAMC5z+e39/T8B+Nz6AbcJtslAWdOMDfg8LONTuJf7vRVgDPEW40H6crLG4AVi58Pj4+Deav0WUFIjBfDt8NYD+HaBbpge1Wq1wbm5uH+DXjewe5IXQ85buxAMurJS9sbi46IG/jnlforKS0Q7f92dWVlYOAXLXgqMb4CmcnZ2l8E5YpVwIlGZ7basm8nIO50qXNzY29g6y8+hP0RCKPYexBne+K3Ay3N7eNoxyDViziicFwR+la8uOwULFQUBr8LB6XgOU/gDukcGittUY3bUBY25oGR0fX1tbSwPgoVFWxquoAFufv5DxgDvgAsZdu7m52WR7cnLyIC5SAMxnqw+6PRzqSzvmOg9coPX7ZAzoAN9vNWgSQKfVpzP2yq5dQGGZD61F+S5e6KnYNkD6eozWBwZav6m6K1hs2yBJB2hGiIwrQmDsjfp8MS6L2zMqa7INebvGTedKthcdtODN90Yi+I2kCO0owsq3e4U1EqOBq98FwNWnxgKCgd66a5znAe6RjYDfGsdJzmtfgqBPWFE+Jg2HSmFcNuS8QqSv5mLkwQewiumDBKcn87JJ5UuB8BDQJ8TxYnQyFnep2ukYMCXzvXUY57ddvIOGUeIUNw47UQWneEYsrwFVJiYmSjYqkAdx9bOMMR6n4pSTF7J+0ZHCRVKwfaA7SXUZ0g3xNJn+j4+Pm655L1L+8vLyrmRHS4FR6ZfJyUichyKGy5IZgvot2EA1GC8fDanOWgXgCwBPodqPqxCwjQKIljmUPiaSTJxVuoAuCui+CXhKqOGLne84xpgEQKqoSwMpwIIy/ZajUdBytspSVV6KblaT79AsaP0afM+yFtbP4bXT48LAWqYEtymbHrIgZy/SnYurAsV4O7ocRjvD21Nf9bgIYMbK9VgAq8f2rYYHbHp6OqjVau3DK+UCXcw1P9ethI2cO9YzqYFuQLIA3/TegTYxpbPqE+UdazM7o82suWn6AC8Rr2F10upjZgBiPX19fd3E83F+fr5mviakKQiad/FDWfHq6upftlFbM0N7AvwP1kHoY5Fmzwrr7wCyzx16vywsLBDwe9s31GU5ShKz30gOmLGWQZwv2fIBYfRZ2JnCf7Vz0V8xyvIsaV1nReeQ9oXGjIDoYlB6IZ811tx6PAo+Gvoswd0urFGS5icgLCSHV8e/GS5dJYemUQHXxZnnYugFXtzRzg1HApz1jC3iqFzqkxfUDTxcTc9pDhRVXkOICrSYb78RPQ5cfOivRqKNv7S0lMAi/lTRqziSw0mSqMADauufbLdfb45ir032rjsyi0ssnlJWfw/Ltlxxm4T+fyR2+7qfi+GckQEXMHWA9c3XRDRl5KcPXOE/JKrA8vEvwezsLH8a5YwqEWDtMqz9F9sjcxVL4jJM/RuRoVB+iZjob2qSgO7cpEYO3BJrfry2etU8XAx4XtyBfxhwki3aAGyT9b39HS3/KJsoGSr4rLuuh/8DlPszm7LNbUUAAAAASUVORK5CYII=",
|
|
74
|
+
Cross = 'data:image/svg+xml,<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100%" height="100%"><rect width="100%" height="100%" style="fill:rgb(204,204,204)"/><line stroke-dasharray="5, 5" x1="0" y1="100%" x2="100%" y2="0" style="stroke:rgb(119,119,119);stroke-width:1"/><line stroke-dasharray="5, 5" x1="0" y1="0" x2="100%" y2="100%" style="stroke:rgb(119,119,119);stroke-width:1"/><circle cx="50%" cy="50%" r="40" fill="rgb(204,204,204)"/></svg>',
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export const enum Constant {
|
|
78
|
+
ClarityPrefix = "clarity-",
|
|
79
|
+
Canvas = "CANVAS",
|
|
80
|
+
HeatmapCanvas = "clarity-heatmap-canvas",
|
|
81
|
+
InteractionCanvas = "clarity-interaction-canvas",
|
|
82
|
+
UnknownTag = "clarity-unknown",
|
|
83
|
+
ImageTag = "img",
|
|
84
|
+
IFrameTag = "iframe",
|
|
85
|
+
AltAttribute = "alt",
|
|
86
|
+
Hover = ":hover",
|
|
87
|
+
CustomHover = "clarity-hover",
|
|
88
|
+
Region = "clarity-region",
|
|
89
|
+
AdoptedStyleSheet = "clarity-adopted-style",
|
|
90
|
+
Id = "data-clarity-id",
|
|
91
|
+
Hash = "data-clarity-hash",
|
|
92
|
+
Hide = "data-clarity-hide",
|
|
93
|
+
Unavailable = "data-clarity-unavailable",
|
|
94
|
+
Suspend = "data-clarity-suspend",
|
|
95
|
+
Hidden = "hidden",
|
|
96
|
+
Visible = "visible",
|
|
97
|
+
None = "none",
|
|
98
|
+
Small = "s",
|
|
99
|
+
Medium = "m",
|
|
100
|
+
Large = "l",
|
|
101
|
+
Dom = "dom",
|
|
102
|
+
Context = "2d",
|
|
103
|
+
Pixel = "px",
|
|
104
|
+
Separator = "X",
|
|
105
|
+
Absolute = "absolute",
|
|
106
|
+
Black = "black",
|
|
107
|
+
Transparent = "transparent",
|
|
108
|
+
HiddenOpacity = "0.4",
|
|
109
|
+
VisibleOpacity = "1",
|
|
110
|
+
ClickLayer = "clarity-click",
|
|
111
|
+
PointerLayer = "clarity-pointer",
|
|
112
|
+
TouchLayer = "clarity-touch",
|
|
113
|
+
HoverAttribute = "clarity-hover",
|
|
114
|
+
PointerClickLayer = "clarity-pointer-click",
|
|
115
|
+
PointerNone = "clarity-pointer-none",
|
|
116
|
+
PointerMove = "clarity-pointer-move",
|
|
117
|
+
ClickRing = "clarity-click-ring",
|
|
118
|
+
TouchRing = "clarity-touch-ring",
|
|
119
|
+
Title = "title",
|
|
120
|
+
Round = "round",
|
|
121
|
+
AverageFold = "Average Fold",
|
|
122
|
+
Empty = "",
|
|
123
|
+
Undefined = "undefined",
|
|
124
|
+
Function = "function"
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export const enum Setting {
|
|
128
|
+
Medium = 200,
|
|
129
|
+
Small = 75,
|
|
130
|
+
Radius = 20,
|
|
131
|
+
AlphaBoost = 0.15,
|
|
132
|
+
Colors = 256,
|
|
133
|
+
Interval = 30,
|
|
134
|
+
ZIndex = 2147483647, // Max integer value
|
|
135
|
+
PointerWidth = 29,
|
|
136
|
+
PointerHeight = 38,
|
|
137
|
+
PointerOffset = 4,
|
|
138
|
+
ClickRadius = 22,
|
|
139
|
+
PixelLife = 3000,
|
|
140
|
+
TrailWidth = 6,
|
|
141
|
+
MaxTrailPoints = 75,
|
|
142
|
+
HoverDepth = 7,
|
|
143
|
+
MaxHue = 240,
|
|
144
|
+
MarkerLineHeight = 1,
|
|
145
|
+
MarkerHeight = 32,
|
|
146
|
+
MarkerMediumWidth = 84,
|
|
147
|
+
MarkerRange = 2,
|
|
148
|
+
MarkerSmallWidth = 35,
|
|
149
|
+
MarkerPadding = 5,
|
|
150
|
+
MarkerColor = "white",
|
|
151
|
+
CanvasTextColor = "#323130",
|
|
152
|
+
CanvasTextFont = "500 12px Segoe UI",
|
|
153
|
+
ScrollCanvasMaxHeight = 40000
|
|
154
|
+
}
|