@gemx-dev/clarity-visualize 3.5.2 → 3.5.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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @gemx-dev/clarity-visualize
2
2
 
3
+ ## 3.5.4
4
+
5
+ ### Patch Changes
6
+
7
+ - [#34](https://github.com/ducky0209/gemx-sdk/pull/34) [`ee65886`](https://github.com/ducky0209/gemx-sdk/commit/ee6588699a5be630fe8b688806f51c8417b73c4c) Thanks [@ducky0209](https://github.com/ducky0209)! - Update logic show heatmap
8
+
9
+ ## 3.5.3
10
+
11
+ ### Patch Changes
12
+
13
+ - [`5e9d540`](https://github.com/ducky0209/gemx-sdk/commit/5e9d5401afda160251a62c6e0116e91d63f08ab9) Thanks [@ducky0209](https://github.com/ducky0209)! - Update contend readme
14
+
3
15
  ## 3.5.2
4
16
 
5
17
  ### Patch Changes
package/README.md CHANGED
@@ -1,26 +1 @@
1
- # Clarity
2
- Clarity is an open-source behavioral analytics library written in typescript, with two key goals: privacy & performance.
3
-
4
- It helps you understand how users view and use your website across all modern devices and browsers. Understanding how users navigate, interact and browse your website can provide new insights about your users. Empathizing with your users and seeing where features fail or succeed can help improve your product, grow revenue and improve user retention.
5
-
6
- This package takes the decoded data from [clarity-decode](https://github.com/microsoft/clarity/tree/master/packages/clarity-decode) and turns it into pixel-perfect session replay, exactly how the user saw it.
7
-
8
- We encourage the community to join us in building the best behavioral analytics library, that puts privacy first and prioritizes performance.
9
-
10
- ## Examples
11
- Here are some example sessions on popular websites visualized to demonstrate the telemetry captured:
12
- 1. CNN (Web)
13
- </br><a href="https://thumbs.gfycat.com/AggressiveLankyAbyssiniangroundhornbill-size_restricted.gif"><img src="https://thumbs.gfycat.com/AggressiveLankyAbyssiniangroundhornbill-size_restricted.gif" title="Clarity - CNN Example"/></a>
14
-
15
- 2. Cook with Manali (Mobile)
16
- </br><a href="https://thumbs.gfycat.com/CoolDependableAdamsstaghornedbeetle-size_restricted.gif"><img src="https://thumbs.gfycat.com/CoolDependableAdamsstaghornedbeetle-size_restricted.gif" title="Clarity - Cook With Manali Example"/></a>
17
-
18
- ## Privacy Notice
19
- Clarity handles sensitive data with care. By default sensitive content on the page is masked before uploading to the server.
20
-
21
- ## Improving Clarity
22
- If you haven't already done so, start contributing by following instructions **[here](https://github.com/microsoft/clarity/blob/master/CONTRIBUTING.md)**.
23
-
24
- This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
25
-
26
- Happy coding!
1
+ ## GemX Heatmap Visualize — `@gemx-dev/clarity-visualize`
package/package.json CHANGED
@@ -1,31 +1,12 @@
1
1
  {
2
2
  "name": "@gemx-dev/clarity-visualize",
3
- "version": "3.5.2",
4
- "description": "An analytics library that uses web page interactions to generate aggregated insights",
5
- "author": "Microsoft Corp.",
3
+ "version": "3.5.4",
4
+ "description": "GemX Heatmap Visualize (Clarity) fork",
6
5
  "license": "MIT",
7
6
  "main": "build/clarity.visualize.js",
8
7
  "module": "build/clarity.visualize.module.js",
9
8
  "unpkg": "build/clarity.visualize.min.js",
10
9
  "types": "types/index.d.ts",
11
- "keywords": [
12
- "clarity",
13
- "Microsoft",
14
- "interactions",
15
- "cursor",
16
- "pointer",
17
- "instrumentation",
18
- "analytics",
19
- "visualization"
20
- ],
21
- "repository": {
22
- "type": "git",
23
- "url": "https://github.com/microsoft/clarity.git",
24
- "directory": "packages/clarity-visualize"
25
- },
26
- "bugs": {
27
- "url": "https://github.com/Microsoft/clarity/issues"
28
- },
29
10
  "dependencies": {
30
11
  "clarity-decode": "^0.8.38"
31
12
  },
@@ -46,6 +27,7 @@
46
27
  "scripts": {
47
28
  "build": "yarn build:clean && yarn build:main",
48
29
  "build:main": "rollup -c rollup.config.ts --configPlugin @rollup/plugin-typescript",
30
+ "build:main:watch": "rollup -c rollup.config.ts --configPlugin @rollup/plugin-typescript --watch",
49
31
  "build:clean": "del-cli build/*",
50
32
  "tslint": "tslint --project ./",
51
33
  "tslint:fix": "tslint --fix --project ./ --force",
package/src/heatmap.ts CHANGED
@@ -1,16 +1,9 @@
1
- import {
2
- Activity,
3
- Constant,
4
- Heatmap,
5
- Setting,
6
- ScrollMapInfo,
7
- PlaybackState,
8
- } from '@clarity-types/visualize';
9
- import { Data } from 'clarity-js';
10
- import { LayoutHelper } from './layout';
1
+ import { Activity, Constant, Heatmap, Setting, ScrollMapInfo, PlaybackState } from "@clarity-types/visualize";
2
+ import { Data } from "clarity-js";
3
+ import { LayoutHelper } from "./layout";
11
4
 
12
5
  export class HeatmapHelper {
13
- static COLORS = ['blue', 'cyan', 'lime', 'yellow', 'red'];
6
+ static COLORS = ["blue", "cyan", "lime", "yellow", "red"];
14
7
  data: Activity = null;
15
8
  scrollData: ScrollMapInfo[] = null;
16
9
  max: number = null;
@@ -45,8 +38,8 @@ export class HeatmapHelper {
45
38
  // Remove scroll and resize event listeners
46
39
  if (this.state && this.state.window) {
47
40
  let win = this.state.window;
48
- win.removeEventListener('scroll', this.redraw, true);
49
- win.removeEventListener('resize', this.redraw, true);
41
+ win.removeEventListener("scroll", this.redraw, true);
42
+ win.removeEventListener("resize", this.redraw, true);
50
43
  }
51
44
  };
52
45
 
@@ -75,23 +68,18 @@ export class HeatmapHelper {
75
68
  let doc = this.state.window.document;
76
69
  var body = doc.body;
77
70
  var de = doc.documentElement;
78
- var height = Math.max(
79
- body.scrollHeight,
80
- body.offsetHeight,
81
- de.clientHeight,
82
- de.scrollHeight,
83
- de.offsetHeight,
84
- );
71
+ var height = Math.max(body.scrollHeight, body.offsetHeight, de.clientHeight, de.scrollHeight, de.offsetHeight);
85
72
  canvas.height = Math.min(height, Setting.ScrollCanvasMaxHeight);
86
73
  canvas.style.top = 0 + Constant.Pixel;
87
74
  if (canvas.width > 0 && canvas.height > 0) {
88
75
  if (this.scrollData) {
89
76
  const grd = context.createLinearGradient(0, 0, 0, canvas.height);
90
77
  for (const currentCombination of this.scrollData) {
91
- const huePercentView =
92
- 1 - currentCombination.cumulativeSum / this.scrollData[0].cumulativeSum;
78
+ const huePercentView = 1 - currentCombination.cumulativeSum / this.scrollData[0].cumulativeSum;
79
+ console.log(`🚀 🐥 ~ HeatmapHelper ~ huePercentView:`, huePercentView);
93
80
  const percentView = (currentCombination.scrollReachY / 100) * (height / canvas.height);
94
81
  const hue = huePercentView * Setting.MaxHue;
82
+ console.log(`🚀 🐥 ~ HeatmapHelper ~ hue:`, hue);
95
83
  if (percentView <= 1) {
96
84
  grd.addColorStop(percentView, `hsla(${hue}, 100%, 50%, 0.6)`);
97
85
  }
@@ -101,52 +89,27 @@ export class HeatmapHelper {
101
89
  context.fillStyle = grd;
102
90
  context.fillRect(0, 0, canvas.width, canvas.height);
103
91
  if (this.addScrollMakers) {
104
- this.addInfoMarkers(
105
- context,
106
- this.scrollData,
107
- canvas.width,
108
- canvas.height,
109
- this.scrollAvgFold,
110
- );
92
+ this.addInfoMarkers(context, this.scrollData, canvas.width, canvas.height, this.scrollAvgFold);
111
93
  }
112
94
  }
113
95
  }
114
96
  };
115
97
 
116
- private addInfoMarkers = (
117
- context: CanvasRenderingContext2D,
118
- scrollMapInfo: ScrollMapInfo[],
119
- width: number,
120
- height: number,
121
- avgFold: number,
122
- ): void => {
98
+ private addInfoMarkers = (context: CanvasRenderingContext2D, scrollMapInfo: ScrollMapInfo[], width: number, height: number, avgFold: number): void => {
123
99
  this.addMarker(context, width, Constant.AverageFold, avgFold, Setting.MarkerMediumWidth);
124
100
  const markers = [75, 50, 25];
125
101
  for (const marker of markers) {
126
- const closest = scrollMapInfo.reduce(
127
- (prev: ScrollMapInfo, curr: ScrollMapInfo): ScrollMapInfo => {
128
- return Math.abs(curr.percUsers - marker) < Math.abs(prev.percUsers - marker)
129
- ? curr
130
- : prev;
131
- },
132
- );
133
- if (
134
- closest.percUsers >= marker - Setting.MarkerRange &&
135
- closest.percUsers <= marker + Setting.MarkerRange
136
- ) {
102
+ const closest = scrollMapInfo.reduce((prev: ScrollMapInfo, curr: ScrollMapInfo): ScrollMapInfo => {
103
+ return Math.abs(curr.percUsers - marker) < Math.abs(prev.percUsers - marker) ? curr : prev;
104
+ });
105
+ if (closest.percUsers >= marker - Setting.MarkerRange && closest.percUsers <= marker + Setting.MarkerRange) {
137
106
  const markerLine = (closest.scrollReachY / 100) * height;
138
107
  this.addMarker(context, width, `${marker}%`, markerLine, Setting.MarkerSmallWidth);
139
108
  }
140
109
  }
141
110
  };
142
111
 
143
- private addMarker = (
144
- context: CanvasRenderingContext2D,
145
- heatmapWidth: number,
146
- label: string,
147
- markerY: number,
148
- markerWidth: number,
149
- ): void => {
112
+ private addMarker = (context: CanvasRenderingContext2D, heatmapWidth: number, label: string, markerY: number, markerWidth: number): void => {
150
113
  context.beginPath();
151
114
  context.moveTo(0, markerY);
152
115
  context.lineTo(heatmapWidth, markerY);
@@ -213,9 +176,9 @@ export class HeatmapHelper {
213
176
  canvas.style.position = Constant.Absolute;
214
177
  canvas.style.zIndex = `${Setting.ZIndex}`;
215
178
  de.appendChild(canvas);
216
- win.addEventListener('scroll', this.redraw, true);
217
- win.addEventListener('resize', this.redraw, true);
218
- this.observer = this.state.window['ResizeObserver'] ? new ResizeObserver(this.redraw) : null;
179
+ win.addEventListener("scroll", this.redraw, true);
180
+ win.addEventListener("resize", this.redraw, true);
181
+ this.observer = this.state.window["ResizeObserver"] ? new ResizeObserver(this.redraw) : null;
219
182
 
220
183
  if (this.observer) {
221
184
  this.observer.observe(doc.body);
@@ -276,7 +239,7 @@ export class HeatmapHelper {
276
239
  }
277
240
  this.timeout = setTimeout(this.click, Setting.Interval);
278
241
  } else if (this.scrollData) {
279
- if (event.type != 'scroll') {
242
+ if (event.type != "scroll") {
280
243
  if (this.timeout) {
281
244
  clearTimeout(this.timeout);
282
245
  }
@@ -289,15 +252,12 @@ export class HeatmapHelper {
289
252
  let output: Heatmap[] = [];
290
253
  let points: { [key: string]: number } = {};
291
254
  let localMax = 0;
292
- let height =
293
- this.state.window && this.state.window.document
294
- ? this.state.window.document.documentElement.clientHeight
295
- : 0;
255
+ let height = this.state.window && this.state.window.document ? this.state.window.document.documentElement.clientHeight : 0;
296
256
 
297
257
  for (let element of this.data) {
298
258
  let el = this.layout.get(element.hash) as HTMLElement;
299
259
  el && console.log(`🚀 🐥 ~ HeatmapHelper ~ el:`, el);
300
- if (el && typeof el.getBoundingClientRect === 'function') {
260
+ if (el && typeof el.getBoundingClientRect === "function") {
301
261
  let r = el.getBoundingClientRect();
302
262
  let v = this.visible(el, r, height);
303
263
  // Process clicks for only visible elements
@@ -320,7 +280,7 @@ export class HeatmapHelper {
320
280
  for (let coordinates of Object.keys(points)) {
321
281
  let parts = coordinates.split(Constant.Separator);
322
282
  let alpha = Math.min(points[coordinates] / this.max + Setting.AlphaBoost, 1);
323
- if (parts[2] === '1') {
283
+ if (parts[2] === "1") {
324
284
  output.push({ x: parseInt(parts[0], 10), y: parseInt(parts[1], 10), a: alpha });
325
285
  }
326
286
  }
@@ -337,10 +297,7 @@ export class HeatmapHelper {
337
297
  let elements = doc.elementsFromPoint(r.left + r.width / 2, r.top + r.height / 2);
338
298
  for (let e of elements) {
339
299
  // Ignore if top element ends up being the canvas element we added for heatmap visualization
340
- if (
341
- e.tagName === Constant.Canvas ||
342
- (e.id && e.id.indexOf(Constant.ClarityPrefix) === 0)
343
- ) {
300
+ if (e.tagName === Constant.Canvas || (e.id && e.id.indexOf(Constant.ClarityPrefix) === 0)) {
344
301
  continue;
345
302
  }
346
303
  visibility = e === el;
package/src/layout.ts CHANGED
@@ -1,114 +1,107 @@
1
- import { Data, Layout } from 'clarity-js';
2
- import type { Layout as DecodedLayout } from 'clarity-decode';
3
- import {
4
- Asset,
5
- Constant,
6
- type LinkHandler,
7
- NodeType,
8
- type PlaybackState,
9
- Setting,
10
- } from '@clarity-types/visualize';
11
- import { StyleSheetOperation } from 'clarity-js/types/layout';
12
- import { AnimationOperation } from 'clarity-js/types/layout';
13
- import { Constant as LayoutConstants } from 'clarity-js/types/layout';
14
- import sharedStyle from './styles/shared.css';
1
+ import { Data, Layout } from "clarity-js";
2
+ import type { Layout as DecodedLayout } from "clarity-decode";
3
+ import { Asset, Constant, type LinkHandler, NodeType, type PlaybackState, Setting } from "@clarity-types/visualize";
4
+ import { StyleSheetOperation } from "clarity-js/types/layout";
5
+ import { AnimationOperation } from "clarity-js/types/layout";
6
+ import { Constant as LayoutConstants } from "clarity-js/types/layout";
7
+ import sharedStyle from "./styles/shared.css";
15
8
 
16
9
  /* BEGIN blobUnavailableSvgs */
17
- import blobUnavailableSvgEnglish from './styles/blobUnavailable/english.svg';
18
- import blobUnavailableSvgSmall from './styles/blobUnavailable/iconOnly.svg';
19
- import blobUnavailableSvgChineseSimplified from './styles/blobUnavailable/chineseSimplified.svg';
20
- import blobUnavailableSvgChineseTraditional from './styles/blobUnavailable/chineseTraditional.svg';
21
- import blobUnavailableSvgJapanese from './styles/blobUnavailable/japanese.svg';
22
- import blobUnavailableSvgKorean from './styles/blobUnavailable/korean.svg';
23
- import blobUnavailableSvgRussian from './styles/blobUnavailable/russian.svg';
24
- import blobUnavailableSvgSpanish from './styles/blobUnavailable/spanish.svg';
25
- import blobUnavailableSvgTurkish from './styles/blobUnavailable/turkish.svg';
26
- import blobUnavailableSvgDutch from './styles/blobUnavailable/dutch.svg';
27
- import blobUnavailableSvgFrench from './styles/blobUnavailable/french.svg';
28
- import blobUnavailableSvgGerman from './styles/blobUnavailable/german.svg';
29
- import blobUnavailableSvgItalian from './styles/blobUnavailable/italian.svg';
30
- import blobUnavailableSvgPortuguese from './styles/blobUnavailable/portuguese.svg';
10
+ import blobUnavailableSvgEnglish from "./styles/blobUnavailable/english.svg";
11
+ import blobUnavailableSvgSmall from "./styles/blobUnavailable/iconOnly.svg";
12
+ import blobUnavailableSvgChineseSimplified from "./styles/blobUnavailable/chineseSimplified.svg";
13
+ import blobUnavailableSvgChineseTraditional from "./styles/blobUnavailable/chineseTraditional.svg";
14
+ import blobUnavailableSvgJapanese from "./styles/blobUnavailable/japanese.svg";
15
+ import blobUnavailableSvgKorean from "./styles/blobUnavailable/korean.svg";
16
+ import blobUnavailableSvgRussian from "./styles/blobUnavailable/russian.svg";
17
+ import blobUnavailableSvgSpanish from "./styles/blobUnavailable/spanish.svg";
18
+ import blobUnavailableSvgTurkish from "./styles/blobUnavailable/turkish.svg";
19
+ import blobUnavailableSvgDutch from "./styles/blobUnavailable/dutch.svg";
20
+ import blobUnavailableSvgFrench from "./styles/blobUnavailable/french.svg";
21
+ import blobUnavailableSvgGerman from "./styles/blobUnavailable/german.svg";
22
+ import blobUnavailableSvgItalian from "./styles/blobUnavailable/italian.svg";
23
+ import blobUnavailableSvgPortuguese from "./styles/blobUnavailable/portuguese.svg";
31
24
  const blobUnavailableSvg = {
32
- 'de-de': blobUnavailableSvgGerman,
33
- 'en-gb': blobUnavailableSvgEnglish,
34
- 'en-us': blobUnavailableSvgEnglish,
35
- 'es-es': blobUnavailableSvgSpanish,
36
- 'fr-fr': blobUnavailableSvgFrench,
37
- 'it-it': blobUnavailableSvgItalian,
38
- 'ja-jp': blobUnavailableSvgJapanese,
39
- 'ko-kr': blobUnavailableSvgKorean,
40
- 'nl-nl': blobUnavailableSvgDutch,
41
- 'pt-br': blobUnavailableSvgPortuguese,
42
- 'ru-ru': blobUnavailableSvgRussian,
43
- 'tr-tr': blobUnavailableSvgTurkish,
44
- 'zh-hans': blobUnavailableSvgChineseSimplified,
45
- 'zh-hant': blobUnavailableSvgChineseTraditional,
25
+ "de-de": blobUnavailableSvgGerman,
26
+ "en-gb": blobUnavailableSvgEnglish,
27
+ "en-us": blobUnavailableSvgEnglish,
28
+ "es-es": blobUnavailableSvgSpanish,
29
+ "fr-fr": blobUnavailableSvgFrench,
30
+ "it-it": blobUnavailableSvgItalian,
31
+ "ja-jp": blobUnavailableSvgJapanese,
32
+ "ko-kr": blobUnavailableSvgKorean,
33
+ "nl-nl": blobUnavailableSvgDutch,
34
+ "pt-br": blobUnavailableSvgPortuguese,
35
+ "ru-ru": blobUnavailableSvgRussian,
36
+ "tr-tr": blobUnavailableSvgTurkish,
37
+ "zh-hans": blobUnavailableSvgChineseSimplified,
38
+ "zh-hant": blobUnavailableSvgChineseTraditional,
46
39
  };
47
40
  /* END blobUnavailableSvgs */
48
41
 
49
42
  /* BEGIN iframeUnavailableSvgs */
50
- import iframeUnavailableSvgEnglish from './styles/iframeUnavailable/english.svg';
51
- import iframeUnavailableSvgSmall from './styles/iframeUnavailable/iconOnly.svg';
52
- import iframeUnavailableSvgChineseSimplified from './styles/iframeUnavailable/chineseSimplified.svg';
53
- import iframeUnavailableSvgChineseTraditional from './styles/iframeUnavailable/chineseTraditional.svg';
54
- import iframeUnavailableSvgJapanese from './styles/iframeUnavailable/japanese.svg';
55
- import iframeUnavailableSvgKorean from './styles/iframeUnavailable/korean.svg';
56
- import iframeUnavailableSvgRussian from './styles/iframeUnavailable/russian.svg';
57
- import iframeUnavailableSvgSpanish from './styles/iframeUnavailable/spanish.svg';
58
- import iframeUnavailableSvgTurkish from './styles/iframeUnavailable/turkish.svg';
59
- import iframeUnavailableSvgDutch from './styles/iframeUnavailable/dutch.svg';
60
- import iframeUnavailableSvgFrench from './styles/iframeUnavailable/french.svg';
61
- import iframeUnavailableSvgGerman from './styles/iframeUnavailable/german.svg';
62
- import iframeUnavailableSvgItalian from './styles/iframeUnavailable/italian.svg';
63
- import iframeUnavailableSvgPortuguese from './styles/iframeUnavailable/portuguese.svg';
43
+ import iframeUnavailableSvgEnglish from "./styles/iframeUnavailable/english.svg";
44
+ import iframeUnavailableSvgSmall from "./styles/iframeUnavailable/iconOnly.svg";
45
+ import iframeUnavailableSvgChineseSimplified from "./styles/iframeUnavailable/chineseSimplified.svg";
46
+ import iframeUnavailableSvgChineseTraditional from "./styles/iframeUnavailable/chineseTraditional.svg";
47
+ import iframeUnavailableSvgJapanese from "./styles/iframeUnavailable/japanese.svg";
48
+ import iframeUnavailableSvgKorean from "./styles/iframeUnavailable/korean.svg";
49
+ import iframeUnavailableSvgRussian from "./styles/iframeUnavailable/russian.svg";
50
+ import iframeUnavailableSvgSpanish from "./styles/iframeUnavailable/spanish.svg";
51
+ import iframeUnavailableSvgTurkish from "./styles/iframeUnavailable/turkish.svg";
52
+ import iframeUnavailableSvgDutch from "./styles/iframeUnavailable/dutch.svg";
53
+ import iframeUnavailableSvgFrench from "./styles/iframeUnavailable/french.svg";
54
+ import iframeUnavailableSvgGerman from "./styles/iframeUnavailable/german.svg";
55
+ import iframeUnavailableSvgItalian from "./styles/iframeUnavailable/italian.svg";
56
+ import iframeUnavailableSvgPortuguese from "./styles/iframeUnavailable/portuguese.svg";
64
57
  const iframeUnavailableSvg = {
65
- 'de-de': iframeUnavailableSvgGerman,
66
- 'en-gb': iframeUnavailableSvgEnglish,
67
- 'en-us': iframeUnavailableSvgEnglish,
68
- 'es-es': iframeUnavailableSvgSpanish,
69
- 'fr-fr': iframeUnavailableSvgFrench,
70
- 'it-it': iframeUnavailableSvgItalian,
71
- 'ja-jp': iframeUnavailableSvgJapanese,
72
- 'ko-kr': iframeUnavailableSvgKorean,
73
- 'nl-nl': iframeUnavailableSvgDutch,
74
- 'pt-br': iframeUnavailableSvgPortuguese,
75
- 'ru-ru': iframeUnavailableSvgRussian,
76
- 'tr-tr': iframeUnavailableSvgTurkish,
77
- 'zh-hans': iframeUnavailableSvgChineseSimplified,
78
- 'zh-hant': iframeUnavailableSvgChineseTraditional,
58
+ "de-de": iframeUnavailableSvgGerman,
59
+ "en-gb": iframeUnavailableSvgEnglish,
60
+ "en-us": iframeUnavailableSvgEnglish,
61
+ "es-es": iframeUnavailableSvgSpanish,
62
+ "fr-fr": iframeUnavailableSvgFrench,
63
+ "it-it": iframeUnavailableSvgItalian,
64
+ "ja-jp": iframeUnavailableSvgJapanese,
65
+ "ko-kr": iframeUnavailableSvgKorean,
66
+ "nl-nl": iframeUnavailableSvgDutch,
67
+ "pt-br": iframeUnavailableSvgPortuguese,
68
+ "ru-ru": iframeUnavailableSvgRussian,
69
+ "tr-tr": iframeUnavailableSvgTurkish,
70
+ "zh-hans": iframeUnavailableSvgChineseSimplified,
71
+ "zh-hant": iframeUnavailableSvgChineseTraditional,
79
72
  };
80
73
  /* END iframeUnavailableSvgs */
81
74
 
82
75
  /* BEGIN imageMaskedSvgs */
83
- import imageMaskedSvgEnglish from './styles/imageMasked/english.svg';
84
- import imageMaskedSvgSmall from './styles/imageMasked/iconOnly.svg';
85
- import imageMaskedSvgChineseSimplified from './styles/imageMasked/chineseSimplified.svg';
86
- import imageMaskedSvgChineseTraditional from './styles/imageMasked/chineseTraditional.svg';
87
- import imageMaskedSvgJapanese from './styles/imageMasked/japanese.svg';
88
- import imageMaskedSvgKorean from './styles/imageMasked/korean.svg';
89
- import imageMaskedSvgRussian from './styles/imageMasked/russian.svg';
90
- import imageMaskedSvgSpanish from './styles/imageMasked/spanish.svg';
91
- import imageMaskedSvgTurkish from './styles/imageMasked/turkish.svg';
92
- import imageMaskedSvgDutch from './styles/imageMasked/dutch.svg';
93
- import imageMaskedSvgFrench from './styles/imageMasked/french.svg';
94
- import imageMaskedSvgGerman from './styles/imageMasked/german.svg';
95
- import imageMaskedSvgItalian from './styles/imageMasked/italian.svg';
96
- import imageMaskedSvgPortuguese from './styles/imageMasked/portuguese.svg';
76
+ import imageMaskedSvgEnglish from "./styles/imageMasked/english.svg";
77
+ import imageMaskedSvgSmall from "./styles/imageMasked/iconOnly.svg";
78
+ import imageMaskedSvgChineseSimplified from "./styles/imageMasked/chineseSimplified.svg";
79
+ import imageMaskedSvgChineseTraditional from "./styles/imageMasked/chineseTraditional.svg";
80
+ import imageMaskedSvgJapanese from "./styles/imageMasked/japanese.svg";
81
+ import imageMaskedSvgKorean from "./styles/imageMasked/korean.svg";
82
+ import imageMaskedSvgRussian from "./styles/imageMasked/russian.svg";
83
+ import imageMaskedSvgSpanish from "./styles/imageMasked/spanish.svg";
84
+ import imageMaskedSvgTurkish from "./styles/imageMasked/turkish.svg";
85
+ import imageMaskedSvgDutch from "./styles/imageMasked/dutch.svg";
86
+ import imageMaskedSvgFrench from "./styles/imageMasked/french.svg";
87
+ import imageMaskedSvgGerman from "./styles/imageMasked/german.svg";
88
+ import imageMaskedSvgItalian from "./styles/imageMasked/italian.svg";
89
+ import imageMaskedSvgPortuguese from "./styles/imageMasked/portuguese.svg";
97
90
  const imageMaskedSvg = {
98
- 'de-de': imageMaskedSvgGerman,
99
- 'en-gb': imageMaskedSvgEnglish,
100
- 'en-us': imageMaskedSvgEnglish,
101
- 'es-es': imageMaskedSvgSpanish,
102
- 'fr-fr': imageMaskedSvgFrench,
103
- 'it-it': imageMaskedSvgItalian,
104
- 'ja-jp': imageMaskedSvgJapanese,
105
- 'ko-kr': imageMaskedSvgKorean,
106
- 'nl-nl': imageMaskedSvgDutch,
107
- 'pt-br': imageMaskedSvgPortuguese,
108
- 'ru-ru': imageMaskedSvgRussian,
109
- 'tr-tr': imageMaskedSvgTurkish,
110
- 'zh-hans': imageMaskedSvgChineseSimplified,
111
- 'zh-hant': imageMaskedSvgChineseTraditional,
91
+ "de-de": imageMaskedSvgGerman,
92
+ "en-gb": imageMaskedSvgEnglish,
93
+ "en-us": imageMaskedSvgEnglish,
94
+ "es-es": imageMaskedSvgSpanish,
95
+ "fr-fr": imageMaskedSvgFrench,
96
+ "it-it": imageMaskedSvgItalian,
97
+ "ja-jp": imageMaskedSvgJapanese,
98
+ "ko-kr": imageMaskedSvgKorean,
99
+ "nl-nl": imageMaskedSvgDutch,
100
+ "pt-br": imageMaskedSvgPortuguese,
101
+ "ru-ru": imageMaskedSvgRussian,
102
+ "tr-tr": imageMaskedSvgTurkish,
103
+ "zh-hans": imageMaskedSvgChineseSimplified,
104
+ "zh-hant": imageMaskedSvgChineseTraditional,
112
105
  };
113
106
  /* END imageMaskedSvgs */
114
107
 
@@ -127,23 +120,12 @@ export class LayoutHelper {
127
120
  animations = {};
128
121
  state: PlaybackState = null;
129
122
  stylesToApply: { [id: string]: string[] } = {};
130
- BackgroundImageEligibleElements = [
131
- 'DIV',
132
- 'SECTION',
133
- 'ARTICLE',
134
- 'HEADER',
135
- 'FOOTER',
136
- 'ASIDE',
137
- 'NAV',
138
- 'SPAN',
139
- 'P',
140
- 'MAIN',
141
- ];
123
+ BackgroundImageEligibleElements = ["DIV", "SECTION", "ARTICLE", "HEADER", "FOOTER", "ASIDE", "NAV", "SPAN", "P", "MAIN"];
142
124
  MaskedBackgroundImageStyle = `#CCC no-repeat center url("${Asset.Hide}")`;
143
125
  vNext: boolean;
144
126
  locale: string;
145
127
 
146
- constructor(state: PlaybackState, isMobile = false, vNext = false, locale = 'en-us') {
128
+ constructor(state: PlaybackState, isMobile = false, vNext = false, locale = "en-us") {
147
129
  this.state = state;
148
130
  this.isMobile = isMobile;
149
131
  this.vNext = vNext;
@@ -199,10 +181,7 @@ export class LayoutHelper {
199
181
  let target = this.element(event.data.targetId);
200
182
  // only create the animation if we successfully found the target, an animation without a target will throw an error
201
183
  if (target) {
202
- this.animations[event.data.id] = (target as HTMLElement).animate(
203
- JSON.parse(event.data.keyFrames),
204
- JSON.parse(event.data.timing),
205
- );
184
+ this.animations[event.data.id] = (target as HTMLElement).animate(JSON.parse(event.data.keyFrames), JSON.parse(event.data.timing));
206
185
  }
207
186
  break;
208
187
  case AnimationOperation.Cancel:
@@ -267,16 +246,12 @@ export class LayoutHelper {
267
246
 
268
247
  public customElement = (event: DecodedLayout.CustomElementEvent): void => {
269
248
  if (!this.state.window.customElements.get(event.data.name)) {
270
- this.state.window.customElements.define(
271
- event.data.name,
272
- class extends (this.state.window as typeof window).HTMLElement {},
273
- );
249
+ this.state.window.customElements.define(event.data.name, class extends (this.state.window as typeof window).HTMLElement {});
274
250
  }
275
251
  };
276
252
 
277
253
  private setDocumentStyles(documentId: number, styleIds: string[]) {
278
- let targetDocument =
279
- documentId === -1 ? this.state.window.document : (this.element(documentId) as Document);
254
+ let targetDocument = documentId === -1 ? this.state.window.document : (this.element(documentId) as Document);
280
255
 
281
256
  if (!targetDocument) {
282
257
  if (!this.stylesToApply[documentId]) {
@@ -325,7 +300,7 @@ export class LayoutHelper {
325
300
  if (tag && tag.indexOf(Layout.Constant.IFramePrefix) === 0) {
326
301
  tag = node.tag.substr(Layout.Constant.IFramePrefix.length);
327
302
  }
328
- if (parent === null && node.parent !== null && node.parent > -1 && tag !== 'HTML') {
303
+ if (parent === null && node.parent !== null && node.parent > -1 && tag !== "HTML") {
329
304
  // We are referencing a parent for this node that hasn't been created yet. Push it to a list of nodes to
330
305
  // try once we are finished with other nodes within this event. Though we don't require HTML tags to
331
306
  // have a parent as they are typically the root.
@@ -334,26 +309,13 @@ export class LayoutHelper {
334
309
  }
335
310
  switch (tag) {
336
311
  case Layout.Constant.DocumentTag:
337
- let tagDoc =
338
- tag !== node.tag
339
- ? parent
340
- ? (parent as HTMLIFrameElement).contentDocument
341
- : null
342
- : doc;
312
+ let tagDoc = tag !== node.tag ? (parent ? (parent as HTMLIFrameElement).contentDocument : null) : doc;
343
313
  if (tagDoc && tagDoc === doc && type === Data.Event.Discover) {
344
314
  this.reset();
345
315
  }
346
- if (typeof XMLSerializer !== 'undefined' && tagDoc) {
316
+ if (typeof XMLSerializer !== "undefined" && tagDoc) {
347
317
  tagDoc.open();
348
- tagDoc.write(
349
- new XMLSerializer().serializeToString(
350
- tagDoc.implementation.createDocumentType(
351
- node.attributes['name'],
352
- node.attributes['publicId'],
353
- node.attributes['systemId'],
354
- ),
355
- ),
356
- );
318
+ tagDoc.write(new XMLSerializer().serializeToString(tagDoc.implementation.createDocumentType(node.attributes["name"], node.attributes["publicId"], node.attributes["systemId"])));
357
319
  tagDoc.close();
358
320
  }
359
321
  break;
@@ -366,9 +328,7 @@ export class LayoutHelper {
366
328
  case Layout.Constant.ShadowDomTag:
367
329
  if (parent) {
368
330
  let shadowRoot = this.element(node.id);
369
- shadowRoot = shadowRoot
370
- ? shadowRoot
371
- : (parent as HTMLElement).attachShadow({ mode: 'open' });
331
+ shadowRoot = shadowRoot ? shadowRoot : (parent as HTMLElement).attachShadow({ mode: "open" });
372
332
  this.nodes[node.id] = shadowRoot;
373
333
  this.addToHashMap(node, shadowRoot);
374
334
  this.addStyles(node.id);
@@ -386,7 +346,7 @@ export class LayoutHelper {
386
346
  (suspendedElement as HTMLElement).setAttribute(Constant.Suspend, Layout.Constant.Empty);
387
347
  }
388
348
  break;
389
- case 'HTML':
349
+ case "HTML":
390
350
  if (this.primaryHtmlNodeId === null) {
391
351
  this.primaryHtmlNodeId = node.id;
392
352
  }
@@ -398,11 +358,7 @@ export class LayoutHelper {
398
358
  this.insertDefaultElement(node, parent, pivot, doc, insert);
399
359
  break;
400
360
  }
401
- let htmlDoc = isIframe
402
- ? parent
403
- ? (parent as HTMLIFrameElement).contentDocument
404
- : null
405
- : doc;
361
+ let htmlDoc = isIframe ? (parent ? (parent as HTMLIFrameElement).contentDocument : null) : doc;
406
362
  if (htmlDoc !== null) {
407
363
  let docElement = this.element(node.id) as HTMLElement;
408
364
  if (docElement === null) {
@@ -421,75 +377,60 @@ export class LayoutHelper {
421
377
  // If we are still processing discover events, keep the markup hidden until we are done
422
378
  if (type === Data.Event.Discover && !parent) {
423
379
  htmlDoc.documentElement.style.visibility = Constant.Hidden;
380
+ htmlDoc.documentElement.style.opacity = `${Constant.VisibleOpacity} !important`;
424
381
  }
425
382
  this.nodes[node.id] = htmlDoc.documentElement;
426
383
  this.addToHashMap(node, htmlDoc.documentElement);
427
384
  }
428
385
  break;
429
- case 'HEAD':
386
+ case "HEAD":
430
387
  let headElement = this.element(node.id);
431
388
  if (headElement === null) {
432
389
  headElement = doc.createElement(node.tag);
433
390
  if (node.attributes && Layout.Constant.Base in node.attributes) {
434
- let base = doc.createElement('base');
391
+ let base = doc.createElement("base");
435
392
  base.href = node.attributes[Layout.Constant.Base];
436
393
  headElement.appendChild(base);
437
394
  }
438
395
 
439
396
  // Add custom styles to assist with visualization
440
- let custom = doc.createElement('style');
441
- custom.setAttribute(Constant.CustomStyleTag, 'true');
397
+ let custom = doc.createElement("style");
398
+ custom.setAttribute(Constant.CustomStyleTag, "true");
442
399
  custom.innerText = this.getCustomStyle();
443
400
  headElement.appendChild(custom);
444
401
  }
445
402
  this.setAttributes(headElement as HTMLElement, node);
446
403
  insert(node, parent, headElement, pivot);
447
404
  break;
448
- case 'LINK':
405
+ case "LINK":
449
406
  let linkElement = this.element(node.id) as HTMLLinkElement;
450
- linkElement = linkElement
451
- ? linkElement
452
- : (this.createElement(doc, node.tag) as HTMLLinkElement);
407
+ linkElement = linkElement ? linkElement : (this.createElement(doc, node.tag) as HTMLLinkElement);
453
408
  if (!node.attributes) {
454
409
  node.attributes = {};
455
410
  }
456
411
  this.setAttributes(linkElement, node);
457
- if ('rel' in node.attributes) {
458
- if (node.attributes['rel'] === Constant.StyleSheet) {
412
+ if ("rel" in node.attributes) {
413
+ if (node.attributes["rel"] === Constant.StyleSheet) {
459
414
  this.stylesheets.push(
460
415
  new Promise((resolve: () => void): void => {
461
416
  const proxy = useproxy ?? this.state.options.useproxy;
462
417
  if (proxy) {
463
418
  if (linkElement.integrity) {
464
- linkElement.removeAttribute('integrity');
419
+ linkElement.removeAttribute("integrity");
465
420
  }
466
421
 
467
422
  linkElement.href = proxy(linkElement.href, linkElement.id, Constant.StyleSheet);
468
423
  }
469
- linkElement.onload = linkElement.onerror = this.style.bind(
470
- this,
471
- linkElement,
472
- resolve,
473
- );
424
+ linkElement.onload = linkElement.onerror = this.style.bind(this, linkElement, resolve);
474
425
  setTimeout(resolve, LayoutHelper.TIMEOUT);
475
426
  }),
476
427
  );
477
- } else if (
478
- (node.attributes['rel'].includes('preload') ||
479
- node.attributes['rel'].includes('preconnect')) &&
480
- (node.attributes?.as === 'style' || node.attributes?.as === 'font')
481
- ) {
428
+ } else if ((node.attributes["rel"].includes("preload") || node.attributes["rel"].includes("preconnect")) && (node.attributes?.as === "style" || node.attributes?.as === "font")) {
482
429
  this.fonts.push(
483
430
  new Promise((resolve: () => void): void => {
484
431
  const proxy = useproxy ?? this.state.options.useproxy;
485
- linkElement.href = proxy
486
- ? proxy(linkElement.href, linkElement.id, node.attributes.as)
487
- : linkElement.href;
488
- linkElement.onload = linkElement.onerror = this.style.bind(
489
- this,
490
- linkElement,
491
- resolve,
492
- );
432
+ linkElement.href = proxy ? proxy(linkElement.href, linkElement.id, node.attributes.as) : linkElement.href;
433
+ linkElement.onload = linkElement.onerror = this.style.bind(this, linkElement, resolve);
493
434
  setTimeout(resolve, LayoutHelper.TIMEOUT);
494
435
  }),
495
436
  );
@@ -498,35 +439,25 @@ export class LayoutHelper {
498
439
  insert(node, parent, linkElement, pivot);
499
440
  break;
500
441
  case Layout.Constant.ImageTag:
501
- let imgElement =
502
- (this.element(node.id) as HTMLImageElement) ??
503
- (this.createElement(doc, node.tag) as HTMLImageElement);
442
+ let imgElement = (this.element(node.id) as HTMLImageElement) ?? (this.createElement(doc, node.tag) as HTMLImageElement);
504
443
  const proxy = useproxy ?? this.state.options.useproxy;
505
444
  if (proxy && !!node.attributes?.src) {
506
- node.attributes.src = proxy(
507
- node.attributes.src,
508
- node.attributes.id,
509
- Layout.Constant.ImageTag,
510
- );
445
+ node.attributes.src = proxy(node.attributes.src, node.attributes.id, Layout.Constant.ImageTag);
511
446
  }
512
447
  this.setAttributes(imgElement, node);
513
448
  this.resize(imgElement, node.width, node.height);
514
449
  insert(node, parent, imgElement, pivot);
515
450
  break;
516
- case 'STYLE':
517
- let styleElement =
518
- (this.element(node.id) as HTMLStyleElement) ??
519
- (doc.createElement(node.tag) as HTMLStyleElement);
451
+ case "STYLE":
452
+ let styleElement = (this.element(node.id) as HTMLStyleElement) ?? (doc.createElement(node.tag) as HTMLStyleElement);
520
453
  this.setAttributes(styleElement, node);
521
454
  styleElement.textContent = node.value;
522
455
  insert(node, parent, styleElement, pivot);
523
456
  this.style(styleElement);
524
457
  break;
525
- case 'IFRAME':
458
+ case "IFRAME":
526
459
  let iframeElement = this.element(node.id) as HTMLIFrameElement;
527
- iframeElement = iframeElement
528
- ? iframeElement
529
- : (this.createElement(doc, node.tag) as HTMLIFrameElement);
460
+ iframeElement = iframeElement ? iframeElement : (this.createElement(doc, node.tag) as HTMLIFrameElement);
530
461
  if (!node.attributes) {
531
462
  node.attributes = {};
532
463
  }
@@ -549,13 +480,7 @@ export class LayoutHelper {
549
480
  }
550
481
  };
551
482
 
552
- private insertDefaultElement = (
553
- node: DecodedLayout.DomData,
554
- parent: Node,
555
- pivot: Node,
556
- doc: Document,
557
- insert: (data: DecodedLayout.DomData, parent: Node, node: Node, previous: Node) => void,
558
- ): void => {
483
+ private insertDefaultElement = (node: DecodedLayout.DomData, parent: Node, pivot: Node, doc: Document, insert: (data: DecodedLayout.DomData, parent: Node, node: Node, previous: Node) => void): void => {
559
484
  let domElement = this.element(node.id) as HTMLElement;
560
485
  domElement = domElement ? domElement : this.createElement(doc, node.tag);
561
486
  this.setAttributes(domElement as HTMLElement, node);
@@ -596,10 +521,7 @@ export class LayoutHelper {
596
521
 
597
522
  private createElement = (doc: Document, tag: string): HTMLElement => {
598
523
  if (tag && tag.indexOf(Layout.Constant.SvgPrefix) === 0) {
599
- return doc.createElementNS(
600
- Layout.Constant.SvgNamespace as string,
601
- tag.substr(Layout.Constant.SvgPrefix.length),
602
- ) as HTMLElement;
524
+ return doc.createElementNS(Layout.Constant.SvgNamespace as string, tag.substr(Layout.Constant.SvgPrefix.length)) as HTMLElement;
603
525
  }
604
526
  try {
605
527
  return doc.createElement(tag);
@@ -610,26 +532,14 @@ export class LayoutHelper {
610
532
  }
611
533
  };
612
534
 
613
- private insertAfter = (
614
- data: DecodedLayout.DomData,
615
- parent: Node,
616
- node: Node,
617
- previous: Node,
618
- ): void => {
535
+ private insertAfter = (data: DecodedLayout.DomData, parent: Node, node: Node, previous: Node): void => {
619
536
  // Skip over no-op changes where parent and previous element is still the same
620
537
  // 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
621
- if (
622
- this.events[data.id] &&
623
- this.events[data.id].parent === data.parent &&
624
- this.events[data.id].previous === data.previous
625
- ) {
538
+ if (this.events[data.id] && this.events[data.id].parent === data.parent && this.events[data.id].previous === data.previous) {
626
539
  return;
627
540
  }
628
541
  // In case parent is a Shadow DOM, previous.parentElement will return null but previous.parentNode will return a valid node
629
- let next =
630
- previous && (previous.parentElement === parent || previous.parentNode === parent)
631
- ? previous.nextSibling
632
- : null;
542
+ let next = previous && (previous.parentElement === parent || previous.parentNode === parent) ? previous.nextSibling : null;
633
543
  next = previous === null && parent ? this.firstChild(parent) : next;
634
544
  this.insertBefore(data, parent, node, next);
635
545
  };
@@ -637,12 +547,8 @@ export class LayoutHelper {
637
547
  private firstChild = (node: Node): ChildNode => {
638
548
  let child = node.firstChild;
639
549
  // BASE tag should always be the first child to ensure resources with relative URLs are loaded correctly
640
- if (
641
- child &&
642
- child.nodeType === NodeType.ELEMENT_NODE &&
643
- (child as HTMLElement).tagName === Layout.Constant.BaseTag
644
- ) {
645
- if ((child.nextSibling as HTMLElement)?.hasAttribute('clarity-custom-styles')) {
550
+ if (child && child.nodeType === NodeType.ELEMENT_NODE && (child as HTMLElement).tagName === Layout.Constant.BaseTag) {
551
+ if ((child.nextSibling as HTMLElement)?.hasAttribute("clarity-custom-styles")) {
646
552
  // Keep the custom style tag on top of the head to let client tags override its values.
647
553
  return child.nextSibling.nextSibling;
648
554
  }
@@ -653,17 +559,10 @@ export class LayoutHelper {
653
559
 
654
560
  // Mask images within a masked ancestor element in the node has a background image.
655
561
  private mask = (node: HTMLElement) => {
656
- if (
657
- node &&
658
- this.BackgroundImageEligibleElements.includes(node.nodeName) &&
659
- 'getComputedStyle' in window &&
660
- 'closest' in node
661
- ) {
562
+ if (node && this.BackgroundImageEligibleElements.includes(node.nodeName) && "getComputedStyle" in window && "closest" in node) {
662
563
  const urlPattern = /url\(['"]?([^'")]+)['"]?\)/;
663
564
  const computedStyles = window.getComputedStyle(node);
664
- const hasBackgroundImage =
665
- computedStyles.backgroundImage?.match(urlPattern) ||
666
- computedStyles.background?.match(urlPattern);
565
+ const hasBackgroundImage = computedStyles.backgroundImage?.match(urlPattern) || computedStyles.background?.match(urlPattern);
667
566
  const masked = node.closest?.(`[${LayoutConstants.MaskData}]`);
668
567
 
669
568
  if (hasBackgroundImage && masked) {
@@ -672,12 +571,7 @@ export class LayoutHelper {
672
571
  }
673
572
  };
674
573
 
675
- private insertBefore = (
676
- data: DecodedLayout.DomData,
677
- parent: Node,
678
- node: Node,
679
- next: Node,
680
- ): void => {
574
+ private insertBefore = (data: DecodedLayout.DomData, parent: Node, node: Node, next: Node): void => {
681
575
  if (parent !== null) {
682
576
  // Compare against both parentNode and parentElement to ensure visualization works correctly for shadow DOMs
683
577
  next = next && next.parentElement !== parent && next.parentNode !== parent ? null : next;
@@ -685,8 +579,8 @@ export class LayoutHelper {
685
579
  parent.insertBefore(node, next);
686
580
  this.mask(node as HTMLElement);
687
581
  } catch (ex) {
688
- console.warn('Node: ' + node + ' | Parent: ' + parent + ' | Data: ' + JSON.stringify(data));
689
- console.warn('Exception encountered while inserting node: ' + ex);
582
+ console.warn("Node: " + node + " | Parent: " + parent + " | Data: " + JSON.stringify(data));
583
+ console.warn("Exception encountered while inserting node: " + ex);
690
584
  }
691
585
  } else if (parent === null && node.parentElement !== null) {
692
586
  node.parentElement.removeChild(node);
@@ -725,25 +619,17 @@ export class LayoutHelper {
725
619
  if (attributes[attribute] !== undefined) {
726
620
  try {
727
621
  let v = attributes[attribute];
728
- if (attribute.indexOf('xlink:') === 0) {
729
- node.setAttributeNS('http://www.w3.org/1999/xlink', attribute, v);
622
+ if (attribute.indexOf("xlink:") === 0) {
623
+ node.setAttributeNS("http://www.w3.org/1999/xlink", attribute, v);
730
624
  } else if (attribute.indexOf(Layout.Constant.SameOrigin) === 0) {
731
625
  sameorigin = true;
732
- } else if (attribute.indexOf('*') === 0) {
626
+ } else if (attribute.indexOf("*") === 0) {
733
627
  // Do nothing if we encounter internal Clarity attributes
734
- } else if (
735
- (tag === Constant.IFrameTag &&
736
- (attribute.indexOf('src') === 0 || attribute.indexOf('allow') === 0)) ||
737
- attribute === 'sandbox'
738
- ) {
628
+ } else if ((tag === Constant.IFrameTag && (attribute.indexOf("src") === 0 || attribute.indexOf("allow") === 0)) || attribute === "sandbox") {
739
629
  node.setAttribute(`data-clarity-${attribute}`, v);
740
- } else if (
741
- tag === Constant.ImageTag &&
742
- attribute.indexOf('src') === 0 &&
743
- (v === null || v.length === 0 || v?.startsWith('blob:'))
744
- ) {
630
+ } else if (tag === Constant.ImageTag && attribute.indexOf("src") === 0 && (v === null || v.length === 0 || v?.startsWith("blob:"))) {
745
631
  if (this.vNext) {
746
- if (v.startsWith('blob:')) {
632
+ if (v.startsWith("blob:")) {
747
633
  if (data.width >= Setting.LargeSvg && data.height >= Setting.LargeSvg) {
748
634
  node.setAttribute(Constant.BlobUnavailable, `${Constant.Large}${Constant.Beta}`);
749
635
  } else {
@@ -760,12 +646,7 @@ export class LayoutHelper {
760
646
  node.setAttribute(attribute, Asset.Transparent);
761
647
  let size = Constant.Large;
762
648
  if (data.width) {
763
- size =
764
- data.width <= Setting.Medium
765
- ? Constant.Medium
766
- : data.width <= Setting.Small
767
- ? Constant.Small
768
- : size;
649
+ size = data.width <= Setting.Medium ? Constant.Medium : data.width <= Setting.Small ? Constant.Small : size;
769
650
  }
770
651
  node.setAttribute(Constant.Hide, size);
771
652
  }
@@ -773,17 +654,13 @@ export class LayoutHelper {
773
654
  node.setAttribute(attribute, v);
774
655
  }
775
656
  } catch (ex) {
776
- console.warn('Node: ' + node + ' | ' + JSON.stringify(attributes));
777
- console.warn('Exception encountered while adding attributes: ' + ex);
657
+ console.warn("Node: " + node + " | " + JSON.stringify(attributes));
658
+ console.warn("Exception encountered while adding attributes: " + ex);
778
659
  }
779
660
  }
780
661
  }
781
662
 
782
- if (
783
- sameorigin === false &&
784
- tag === Constant.IFrameTag &&
785
- typeof node.setAttribute === Constant.Function
786
- ) {
663
+ if (sameorigin === false && tag === Constant.IFrameTag && typeof node.setAttribute === Constant.Function) {
787
664
  if (this.svgFitsText(node)) {
788
665
  node.setAttribute(Constant.Unavailable, Layout.Constant.Empty);
789
666
  } else {
@@ -810,7 +687,7 @@ export class LayoutHelper {
810
687
  return `*{scrollbar-width: none; scrollbar-gutter: unset;};`;
811
688
  }
812
689
 
813
- return '';
690
+ return "";
814
691
  };
815
692
 
816
693
  private getCustomStyle = (): string => {
@@ -835,10 +712,7 @@ export class LayoutHelper {
835
712
 
836
713
  private getIframeUnavailableCss = (): string => {
837
714
  if (this.vNext) {
838
- return (
839
- `${Constant.IFrameTag}[${Constant.UnavailableSmall}] { ${iframeUnavailableSvgSmall} }` +
840
- `${Constant.IFrameTag}[${Constant.Unavailable}] { ${iframeUnavailableSvg[this.locale]} }`
841
- );
715
+ return `${Constant.IFrameTag}[${Constant.UnavailableSmall}] { ${iframeUnavailableSvgSmall} }` + `${Constant.IFrameTag}[${Constant.Unavailable}] { ${iframeUnavailableSvg[this.locale]} }`;
842
716
  } else {
843
717
  return `${Constant.IFrameTag}[${Constant.Unavailable}] { background: url(${Asset.Unavailable}) no-repeat center center, url('${Asset.Cross}'); }`;
844
718
  }
@@ -846,20 +720,14 @@ export class LayoutHelper {
846
720
 
847
721
  private getBlobUnavailableCss = (): string => {
848
722
  if (this.vNext) {
849
- return (
850
- `${Constant.ImageTag}[${Constant.BlobUnavailable}=${Constant.Small}${Constant.Beta}] { ${blobUnavailableSvgSmall} }` +
851
- `${Constant.ImageTag}[${Constant.BlobUnavailable}=${Constant.Large}${Constant.Beta}] { ${blobUnavailableSvg[this.locale]} }`
852
- );
723
+ return `${Constant.ImageTag}[${Constant.BlobUnavailable}=${Constant.Small}${Constant.Beta}] { ${blobUnavailableSvgSmall} }` + `${Constant.ImageTag}[${Constant.BlobUnavailable}=${Constant.Large}${Constant.Beta}] { ${blobUnavailableSvg[this.locale]} }`;
853
724
  }
854
- return '';
725
+ return "";
855
726
  };
856
727
 
857
728
  private getImageHiddenCss = (): string => {
858
729
  if (this.vNext) {
859
- return (
860
- `${Constant.ImageTag}[${Constant.Hide}=${Constant.Small}${Constant.Beta}] { ${imageMaskedSvgSmall} }` +
861
- `${Constant.ImageTag}[${Constant.Hide}=${Constant.Large}${Constant.Beta}] { ${imageMaskedSvg[this.locale]} }`
862
- );
730
+ return `${Constant.ImageTag}[${Constant.Hide}=${Constant.Small}${Constant.Beta}] { ${imageMaskedSvgSmall} }` + `${Constant.ImageTag}[${Constant.Hide}=${Constant.Large}${Constant.Beta}] { ${imageMaskedSvg[this.locale]} }`;
863
731
  } else {
864
732
  return (
865
733
  `${Constant.ImageTag}[${Constant.Hide}] { background-color: #CCC; background-image: url(${Asset.Hide}); background-repeat:no-repeat; background-position: center; }` +
@@ -874,6 +742,6 @@ export class LayoutHelper {
874
742
  if (this.vNext) {
875
743
  return sharedStyle;
876
744
  }
877
- return '';
745
+ return "";
878
746
  };
879
747
  }
package/src/visualizer.ts CHANGED
@@ -1,24 +1,12 @@
1
- import {
2
- Activity,
3
- Constant,
4
- ErrorLogger,
5
- LinkHandler,
6
- MergedPayload,
7
- Options,
8
- PlaybackState,
9
- ScrollMapInfo,
10
- Setting,
11
- ShortCircuitStrategy,
12
- Visualizer as VisualizerType,
13
- } from '@clarity-types/visualize';
14
- import { Data } from 'clarity-js';
15
- import type { Data as DecodedData, Interaction, Layout } from 'clarity-decode';
16
- import { DataHelper } from './data';
17
- import { EnrichHelper } from './enrich';
18
- import { HeatmapHelper } from './heatmap';
19
- import { InteractionHelper } from './interaction';
20
- import { LayoutHelper } from './layout';
21
- import { Dimension } from 'clarity-js/types/data';
1
+ import { Activity, Constant, ErrorLogger, LinkHandler, MergedPayload, Options, PlaybackState, ScrollMapInfo, Setting, ShortCircuitStrategy, Visualizer as VisualizerType } from "@clarity-types/visualize";
2
+ import { Data } from "clarity-js";
3
+ import type { Data as DecodedData, Interaction, Layout } from "clarity-decode";
4
+ import { DataHelper } from "./data";
5
+ import { EnrichHelper } from "./enrich";
6
+ import { HeatmapHelper } from "./heatmap";
7
+ import { InteractionHelper } from "./interaction";
8
+ import { LayoutHelper } from "./layout";
9
+ import { Dimension } from "clarity-js/types/data";
22
10
 
23
11
  export class Visualizer implements VisualizerType {
24
12
  _state: PlaybackState = null;
@@ -43,11 +31,7 @@ export class Visualizer implements VisualizerType {
43
31
  return this.layout?.get(hash);
44
32
  };
45
33
 
46
- private shortCircuitRendering = (
47
- strategy: ShortCircuitStrategy,
48
- domEvent: Layout.DomEvent,
49
- hash: string,
50
- ) => {
34
+ private shortCircuitRendering = (strategy: ShortCircuitStrategy, domEvent: Layout.DomEvent, hash: string) => {
51
35
  switch (strategy) {
52
36
  case ShortCircuitStrategy.HashFirstTimestamp:
53
37
  return this.layout.exists(hash);
@@ -55,10 +39,7 @@ export class Visualizer implements VisualizerType {
55
39
  if (this.hashFoundTime === -1 && this.layout.exists(hash)) {
56
40
  this.hashFoundTime = domEvent.time;
57
41
  }
58
- return (
59
- this.hashFoundTime > -1 &&
60
- domEvent.time > this.hashFoundTime + Setting.VisualizationSettleBuffer
61
- );
42
+ return this.hashFoundTime > -1 && domEvent.time > this.hashFoundTime + Setting.VisualizationSettleBuffer;
62
43
  case ShortCircuitStrategy.HashBeforeDeleted:
63
44
  for (let node of domEvent.data) {
64
45
  if ((node.hashAlpha === hash || node.hashBeta === hash) && node.parent === null) {
@@ -72,14 +53,7 @@ export class Visualizer implements VisualizerType {
72
53
  }
73
54
  };
74
55
 
75
- public html = async (
76
- decoded: DecodedData.DecodedPayload[],
77
- target: Window,
78
- hash: string = null,
79
- useproxy?: LinkHandler,
80
- logerror?: ErrorLogger,
81
- shortCircuitStrategy: ShortCircuitStrategy = ShortCircuitStrategy.None,
82
- ): Promise<Visualizer> => {
56
+ public html = async (decoded: DecodedData.DecodedPayload[], target: Window, hash: string = null, useproxy?: LinkHandler, logerror?: ErrorLogger, shortCircuitStrategy: ShortCircuitStrategy = ShortCircuitStrategy.None): Promise<Visualizer> => {
83
57
  if (decoded && decoded.length > 0 && target) {
84
58
  try {
85
59
  // Flatten the payload and parse all events out of them, sorted by time
@@ -132,6 +106,7 @@ export class Visualizer implements VisualizerType {
132
106
  };
133
107
 
134
108
  public clearmap = (): void => {
109
+ console.log(`🚀 🐥 ~ Visualizer ~ this.state:`, this.state);
135
110
  if (this.state === null) {
136
111
  throw new Error(`Initialize heatmap by calling "html" or "setup" prior to making this call.`);
137
112
  }
@@ -185,8 +160,8 @@ export class Visualizer implements VisualizerType {
185
160
  public setup = async (target: Window, options: Options): Promise<Visualizer> => {
186
161
  this.reset();
187
162
  // Infer options
188
- options.canvas = 'canvas' in options ? options.canvas : true;
189
- options.keyframes = 'keyframes' in options ? options.keyframes : false;
163
+ options.canvas = "canvas" in options ? options.canvas : true;
164
+ options.keyframes = "keyframes" in options ? options.keyframes : false;
190
165
 
191
166
  // Set visualization state
192
167
  this._state = { window: target, options };