@gemx-dev/clarity-visualize 0.8.55 → 0.8.57

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.
@@ -975,51 +975,6 @@ var HeatmapHelper = /** @class */ (function () {
975
975
  }
976
976
  return null;
977
977
  };
978
- this.visibleV2 = function (el, r, height) {
979
- var doc = _this.state.window.document;
980
- var visibility = r.height > height ? true : false;
981
- if (visibility === false && r.width > 0 && r.height > 0) {
982
- while (!visibility && doc) {
983
- var shadowElement = null;
984
- var elements = doc.elementsFromPoint(r.left + (r.width / 2), r.top + (r.height / 2));
985
- // Check if only dialog and HTML are returned (element is behind dialog)
986
- var hasOnlyDialogAndHtml = elements.length === 2 &&
987
- elements[0].tagName === 'DIALOG' &&
988
- elements[1].tagName === 'HTML';
989
- // If element is behind a dialog, assume it's visible
990
- // (we can't check through top-layer, so trust the element exists)
991
- if (hasOnlyDialogAndHtml) {
992
- visibility = true;
993
- break;
994
- }
995
- for (var _i = 0, elements_2 = elements; _i < elements_2.length; _i++) {
996
- var e = elements_2[_i];
997
- // Check if this is the target element BEFORE skipping dialogs
998
- // This handles case where target element IS a dialog
999
- if (e === el) {
1000
- visibility = true;
1001
- shadowElement = e.shadowRoot && e.shadowRoot != doc ? e.shadowRoot : null;
1002
- break;
1003
- }
1004
- // Skip dialog elements - treat as transparent for checking elements behind
1005
- if (e.tagName === 'DIALOG') {
1006
- continue;
1007
- }
1008
- // Skip canvas and clarity elements
1009
- if (e.tagName === "CANVAS" /* Constant.Canvas */ ||
1010
- (e.id && e.id.indexOf("clarity-" /* Constant.ClarityPrefix */) === 0)) {
1011
- continue;
1012
- }
1013
- // This is the first non-ignored element
1014
- visibility = e === el;
1015
- shadowElement = e.shadowRoot && e.shadowRoot != doc ? e.shadowRoot : null;
1016
- break;
1017
- }
1018
- doc = shadowElement;
1019
- }
1020
- }
1021
- return visibility && r.bottom >= 0 && r.top <= height;
1022
- };
1023
978
  this.state = state;
1024
979
  this.layout = layout;
1025
980
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gemx-dev/clarity-visualize",
3
- "version": "0.8.55",
3
+ "version": "0.8.57",
4
4
  "description": "Clarity visualize",
5
5
  "author": "Microsoft Corp.",
6
6
  "license": "MIT",
@@ -9,7 +9,7 @@
9
9
  "unpkg": "build/clarity.visualize.min.js",
10
10
  "types": "types/index.d.ts",
11
11
  "dependencies": {
12
- "@gemx-dev/clarity-decode": "^0.8.55"
12
+ "@gemx-dev/clarity-decode": "^0.8.57"
13
13
  },
14
14
  "devDependencies": {
15
15
  "@rollup/plugin-commonjs": "^24.0.0",
@@ -1,4 +1,4 @@
1
- import { Constant, Setting } from "@clarity-types/visualize";
1
+ import { Constant } from "@clarity-types/visualize";
2
2
 
3
3
  /**
4
4
  * Custom module for managing canvas layer z-index with dialog top-layer
@@ -28,12 +28,14 @@ export interface ParentCanvasInfo {
28
28
  */
29
29
  export function createParentWindowCanvas(
30
30
  iframeDoc: Document,
31
+ portalCanvasId: string
31
32
  ): ParentCanvasInfo | null {
32
33
  // Check if we're inside an iframe
33
34
  if (iframeDoc.defaultView === iframeDoc.defaultView?.top) {
34
35
  throw new Error('Not in iframe: ' + iframeDoc.defaultView);
35
36
  }
36
-
37
+
38
+
37
39
  try {
38
40
  const parentWindow = iframeDoc.defaultView?.parent;
39
41
  const parentDoc = parentWindow?.document;
@@ -47,10 +49,11 @@ export function createParentWindowCanvas(
47
49
  if (!iframeParent) throw new Error('Iframe parent not found');
48
50
 
49
51
  // Create canvas as sibling to iframe
50
- let canvas = parentDoc.getElementById(Constant.HeatmapCanvas) as HTMLCanvasElement;
52
+ const canvasId = `${Constant.HeatmapCanvas}-${portalCanvasId}`;
53
+ let canvas = parentDoc.getElementById(canvasId) as HTMLCanvasElement;
51
54
  if (canvas === null) {
52
55
  canvas = parentDoc.createElement('canvas');
53
- canvas.id = Constant.HeatmapCanvas;
56
+ canvas.id = canvasId;
54
57
  canvas.width = 0;
55
58
  canvas.height = 0;
56
59
  canvas.style.position = Constant.Absolute;
package/src/heatmap.ts CHANGED
@@ -191,7 +191,7 @@ export class HeatmapHelper {
191
191
  let win = this.state.window;
192
192
  let de = doc.documentElement;
193
193
 
194
- const isPortalCanvas = this.state.options.portalCanvas;
194
+ const isPortalCanvas = !!this.state.options.portalCanvasId;
195
195
  if (isPortalCanvas) return this.createPortalCanvas(doc, win, de);
196
196
 
197
197
  let canvas = doc.getElementById(Constant.HeatmapCanvas) as HTMLCanvasElement;
@@ -328,7 +328,7 @@ export class HeatmapHelper {
328
328
  }
329
329
 
330
330
  private waitForDialogs = async (): Promise<void> => {
331
- const isPortalCanvas = this.state.options.portalCanvas;
331
+ const isPortalCanvas = !!this.state.options.portalCanvasId;
332
332
  if (!isPortalCanvas) return ;
333
333
 
334
334
  await dialogCustom.waitForDialogsRendered();
@@ -340,7 +340,7 @@ export class HeatmapHelper {
340
340
  try {
341
341
  canvas = this.parentCanvasInfo?.canvas;
342
342
  if (!canvas) {
343
- this.parentCanvasInfo = canvasLayer.createParentWindowCanvas(doc);
343
+ this.parentCanvasInfo = canvasLayer.createParentWindowCanvas(doc, this.state.options.portalCanvasId);
344
344
  canvas = this.parentCanvasInfo.canvas;
345
345
 
346
346
  // Add event listeners only once when canvas is created
@@ -352,7 +352,7 @@ export class HeatmapHelper {
352
352
  }
353
353
 
354
354
  canvas.width = de.clientWidth;
355
- canvas.height = de.clientHeight + 4; // TODO: GEMX VERIFY
355
+ canvas.height = de.clientHeight; // TODO: GEMX VERIFY
356
356
  canvas.style.top = '0';
357
357
  canvas.style.left = '0';
358
358
  canvas.getContext(Constant.Context).clearRect(0, 0, canvas.width, canvas.height);
@@ -365,55 +365,55 @@ export class HeatmapHelper {
365
365
  return null;
366
366
  }
367
367
 
368
- private visibleV2 = (el: HTMLElement, r: DOMRect, height: number): boolean => {
369
- let doc: Document | ShadowRoot = this.state.window.document;
370
- let visibility = r.height > height ? true : false;
371
- if (visibility === false && r.width > 0 && r.height > 0) {
372
- while (!visibility && doc) {
373
- let shadowElement = null;
374
- let elements = doc.elementsFromPoint(r.left + (r.width / 2), r.top + (r.height / 2));
375
-
376
- // Check if only dialog and HTML are returned (element is behind dialog)
377
- let hasOnlyDialogAndHtml = elements.length === 2 &&
378
- elements[0].tagName === 'DIALOG' &&
379
- elements[1].tagName === 'HTML';
380
-
381
- // If element is behind a dialog, assume it's visible
382
- // (we can't check through top-layer, so trust the element exists)
383
- if (hasOnlyDialogAndHtml) {
384
- visibility = true;
385
- break;
386
- }
387
-
388
- for (let e of elements) {
389
- // Check if this is the target element BEFORE skipping dialogs
390
- // This handles case where target element IS a dialog
391
- if (e === el) {
392
- visibility = true;
393
- shadowElement = e.shadowRoot && e.shadowRoot != doc ? e.shadowRoot : null;
394
- break;
395
- }
396
-
397
- // Skip dialog elements - treat as transparent for checking elements behind
398
- if (e.tagName === 'DIALOG') {
399
- continue;
400
- }
401
-
402
- // Skip canvas and clarity elements
403
- if (e.tagName === Constant.Canvas ||
404
- (e.id && e.id.indexOf(Constant.ClarityPrefix) === 0)) {
405
- continue;
406
- }
407
-
408
- // This is the first non-ignored element
409
- visibility = e === el;
410
- shadowElement = e.shadowRoot && e.shadowRoot != doc ? e.shadowRoot : null;
411
- break;
412
- }
413
-
414
- doc = shadowElement;
415
- }
416
- }
417
- return visibility && r.bottom >= 0 && r.top <= height;
418
- }
368
+ // private _visibleV2 = (el: HTMLElement, r: DOMRect, height: number): boolean => {
369
+ // let doc: Document | ShadowRoot = this.state.window.document;
370
+ // let visibility = r.height > height ? true : false;
371
+ // if (visibility === false && r.width > 0 && r.height > 0) {
372
+ // while (!visibility && doc) {
373
+ // let shadowElement = null;
374
+ // let elements = doc.elementsFromPoint(r.left + (r.width / 2), r.top + (r.height / 2));
375
+
376
+ // // Check if only dialog and HTML are returned (element is behind dialog)
377
+ // let hasOnlyDialogAndHtml = elements.length === 2 &&
378
+ // elements[0].tagName === 'DIALOG' &&
379
+ // elements[1].tagName === 'HTML';
380
+
381
+ // // If element is behind a dialog, assume it's visible
382
+ // // (we can't check through top-layer, so trust the element exists)
383
+ // if (hasOnlyDialogAndHtml) {
384
+ // visibility = true;
385
+ // break;
386
+ // }
387
+
388
+ // for (let e of elements) {
389
+ // // Check if this is the target element BEFORE skipping dialogs
390
+ // // This handles case where target element IS a dialog
391
+ // if (e === el) {
392
+ // visibility = true;
393
+ // shadowElement = e.shadowRoot && e.shadowRoot != doc ? e.shadowRoot : null;
394
+ // break;
395
+ // }
396
+
397
+ // // Skip dialog elements - treat as transparent for checking elements behind
398
+ // if (e.tagName === 'DIALOG') {
399
+ // continue;
400
+ // }
401
+
402
+ // // Skip canvas and clarity elements
403
+ // if (e.tagName === Constant.Canvas ||
404
+ // (e.id && e.id.indexOf(Constant.ClarityPrefix) === 0)) {
405
+ // continue;
406
+ // }
407
+
408
+ // // This is the first non-ignored element
409
+ // visibility = e === el;
410
+ // shadowElement = e.shadowRoot && e.shadowRoot != doc ? e.shadowRoot : null;
411
+ // break;
412
+ // }
413
+
414
+ // doc = shadowElement;
415
+ // }
416
+ // }
417
+ // return visibility && r.bottom >= 0 && r.top <= height;
418
+ // }
419
419
  }
package/src/visualizer.ts CHANGED
@@ -53,12 +53,12 @@ export class Visualizer implements VisualizerType {
53
53
  }
54
54
  }
55
55
 
56
- public html = async (decoded: DecodedData.DecodedPayload[], target: Window, portalCanvas?: boolean, hash: string = null, useproxy?: LinkHandler, logerror?: ErrorLogger, shortCircuitStrategy: ShortCircuitStrategy = ShortCircuitStrategy.None): Promise<Visualizer> => {
56
+ public html = async (decoded: DecodedData.DecodedPayload[], target: Window, portalCanvasId?: string, hash: string = null, useproxy?: LinkHandler, logerror?: ErrorLogger, shortCircuitStrategy: ShortCircuitStrategy = ShortCircuitStrategy.None): Promise<Visualizer> => {
57
57
  if (decoded && decoded.length > 0 && target) {
58
58
  try {
59
59
  // Flatten the payload and parse all events out of them, sorted by time
60
60
  let merged = this.merge(decoded);
61
- await this.setup(target, { version: decoded[0].envelope.version, dom: merged.dom, useproxy, portalCanvas });
61
+ await this.setup(target, { version: decoded[0].envelope.version, dom: merged.dom, useproxy, portalCanvasId });
62
62
  // Render all mutations on top of the initial markup
63
63
  while (merged.events.length > 0) {
64
64
  let entry = merged.events.shift();
@@ -20,7 +20,7 @@ export interface Visualize {
20
20
  export class Visualizer {
21
21
  readonly state: PlaybackState;
22
22
  dom: (event: Layout.DomEvent) => Promise<void>;
23
- html: (decoded: Data.DecodedPayload[], target: Window, portalCanvas?: boolean, hash?: string, useproxy?: LinkHandler, logerror?: ErrorLogger, shortCircuitStrategy?: ShortCircuitStrategy) => Promise<Visualizer>;
23
+ html: (decoded: Data.DecodedPayload[], target: Window, portalCanvasId?: string, hash?: string, useproxy?: LinkHandler, logerror?: ErrorLogger, shortCircuitStrategy?: ShortCircuitStrategy) => Promise<Visualizer>;
24
24
  clickmap: (activity?: Activity) => void;
25
25
  clearmap: () => void;
26
26
  scrollmap: (data?: ScrollMapInfo[], averageFold?: number, addMarkers?: boolean) => void;
@@ -65,7 +65,7 @@ export interface Options {
65
65
  metadata?: HTMLElement;
66
66
  pointer?: boolean;
67
67
  canvas?: boolean;
68
- portalCanvas?: boolean;
68
+ portalCanvasId?: string;
69
69
  keyframes?: boolean;
70
70
  mobile?: boolean;
71
71
  vNext?: boolean;