@gemx-dev/clarity-visualize 0.8.63 → 0.8.65

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.
@@ -104,8 +104,9 @@ var selectorMap = {};
104
104
  function reset$8() {
105
105
  selectorMap = {};
106
106
  }
107
- function configure(classNames) {
107
+ function config$2(classNames) {
108
108
  extraExcludeClassNames = classNames || [];
109
+ console.log("[Selector] config called \u2014 extraExcludeClassNames set to: [".concat(extraExcludeClassNames.join(', '), "]"));
109
110
  }
110
111
  function get$1(input, type) {
111
112
  var a = input.attributes;
@@ -129,7 +130,13 @@ function get$1(input, type) {
129
130
  input.tag = input.tag.indexOf("svg:" /* Constant.SvgPrefix */) === 0 ? input.tag.substr("svg:" /* Constant.SvgPrefix */.length) : input.tag;
130
131
  var selector = "".concat(prefix).concat(input.tag).concat(suffix);
131
132
  var id = "id" /* Constant.Id */ in a && a["id" /* Constant.Id */].length > 0 ? a["id" /* Constant.Id */] : null;
132
- var classes = input.tag !== "BODY" /* Constant.BodyTag */ && "class" /* Constant.Class */ in a && a["class" /* Constant.Class */].length > 0 ? a["class" /* Constant.Class */].trim().split(/\s+/).filter(function (c) { return filter(c); }).join("." /* Constant.Period */) : null;
133
+ var rawClasses = "class" /* Constant.Class */ in a ? a["class" /* Constant.Class */].trim().split(/\s+/) : [];
134
+ var filteredClasses = rawClasses.filter(function (c) { return filter(c); });
135
+ var removedClasses = rawClasses.filter(function (c) { return !filter(c); });
136
+ if (removedClasses.length > 0) {
137
+ console.log("[Selector] tag=\"".concat(input.tag, "\" id=\"").concat(input.id, "\" \u2014 removed classes: [").concat(removedClasses.join(', '), "] | kept: [").concat(filteredClasses.join(', '), "] | extraExclude: [").concat(extraExcludeClassNames.join(', '), "]"));
138
+ }
139
+ var classes = input.tag !== "BODY" /* Constant.BodyTag */ && filteredClasses.length > 0 ? filteredClasses.join("." /* Constant.Period */) : null;
133
140
  if (classes && classes.length > 0) {
134
141
  if (type === 0 /* Selector.Alpha */) {
135
142
  // In Alpha mode, update selector to use class names, with relative positioning within the parent id container.
@@ -142,16 +149,19 @@ function get$1(input, type) {
142
149
  selectorMap[key].push(input.id);
143
150
  }
144
151
  selector = "".concat(key).concat("~" /* Constant.Tilde */).concat(selectorMap[key].indexOf(input.id));
152
+ console.log("\uD83D\uDE80 \uD83D\uDC25 ~ get ~ selector:", selector);
145
153
  }
146
154
  else {
147
155
  // In Beta mode, we continue to look at query selectors in context of the full page
148
156
  selector = "".concat(prefix).concat(input.tag, ".").concat(classes).concat(suffix);
157
+ console.log("\uD83D\uDE80 \uD83D\uDC25 ~ get ~ selector:", selector);
149
158
  }
150
159
  }
151
160
  // Update selector to use "id" field when available. There are two exceptions:
152
161
  // (1) if "id" appears to be an auto generated string token, e.g. guid or a random id containing digits
153
162
  // (2) if "id" appears inside a shadow DOM, in which case we continue to prefix up to shadow DOM to prevent conflicts
154
163
  selector = id && filter(id) ? "".concat(getDomPrefix(prefix)).concat("#" /* Constant.Hash */).concat(id) : selector;
164
+ console.log("\uD83D\uDE80 \uD83D\uDC25 ~ get ~ selector:", selector);
155
165
  return selector;
156
166
  }
157
167
  }
@@ -178,7 +188,9 @@ function filter(value) {
178
188
  if (!value) {
179
189
  return false;
180
190
  } // Do not process empty strings
181
- if (getExcludeClassNames().some(function (x) { return value.toLowerCase().indexOf(x) >= 0; })) {
191
+ var excludeClassNames = getExcludeClassNames();
192
+ console.log("\uD83D\uDE80 \uD83D\uDC25 ~ filter ~ excludeClassNames:", excludeClassNames);
193
+ if (excludeClassNames.some(function (x) { return value.toLowerCase().indexOf(x) >= 0; })) {
182
194
  return false;
183
195
  }
184
196
  for (var i = 0; i < value.length; i++) {
@@ -190,12 +202,14 @@ function filter(value) {
190
202
  return true;
191
203
  }
192
204
  function getExcludeClassNames() {
205
+ console.log("\uD83D\uDE80 \uD83D\uDC25 ~ getExcludeClassNames ~ extraExcludeClassNames:", extraExcludeClassNames);
206
+ console.log("\uD83D\uDE80 \uD83D\uDC25 ~ getExcludeClassNames ~ excludeClassNames:", excludeClassNames);
193
207
  return __spreadArray(__spreadArray([], excludeClassNames, true), extraExcludeClassNames, true);
194
208
  }
195
209
 
196
210
  var selector = /*#__PURE__*/Object.freeze({
197
211
  __proto__: null,
198
- configure: configure,
212
+ config: config$2,
199
213
  get: get$1,
200
214
  reset: reset$8
201
215
  });
@@ -914,7 +928,8 @@ var HeatmapHelper = /** @class */ (function () {
914
928
  continue;
915
929
  }
916
930
  var r = el.getBoundingClientRect();
917
- var v = _this.visible(el, r, height);
931
+ var isDebugHash = element.hash === "270qs0pw7";
932
+ var v = _this.visible(el, r, height, isDebugHash ? element.hash : undefined);
918
933
  if (!v && _this.max !== null) {
919
934
  console.warn("[Heatmap] SKIP hash=\"".concat(element.hash, "\" \u2014 not visible on re-render"), { rect: { top: r.top, left: r.left, width: r.width, height: r.height }, maxIsSet: _this.max !== null });
920
935
  continue;
@@ -953,13 +968,28 @@ var HeatmapHelper = /** @class */ (function () {
953
968
  console.groupEnd();
954
969
  return output;
955
970
  };
956
- this.visible = function (el, r, height) {
971
+ this.visible = function (el, r, height, debugHash) {
957
972
  var doc = _this.state.window.document;
958
973
  var visibility = r.height > height ? true : false;
974
+ if (debugHash) {
975
+ console.group("[Heatmap visible] hash=".concat(debugHash, " tag=").concat(el === null || el === void 0 ? void 0 : el.tagName));
976
+ console.log(" rect: top=".concat(r.top.toFixed(1), " bottom=").concat(r.bottom.toFixed(1), " left=").concat(r.left.toFixed(1), " width=").concat(r.width.toFixed(1), " height=").concat(r.height.toFixed(1)));
977
+ console.log(" viewport height=".concat(height, " | r.height > height? ").concat(r.height > height));
978
+ }
959
979
  if (visibility === false && r.width > 0 && r.height > 0) {
980
+ var checkX = r.left + (r.width / 2);
981
+ var checkY = r.top + (r.height / 2);
982
+ if (debugHash) {
983
+ console.log(" elementsFromPoint(".concat(checkX.toFixed(1), ", ").concat(checkY.toFixed(1), ")"));
984
+ }
960
985
  while (!visibility && doc) {
961
986
  var shadowElement = null;
962
- var elements = doc.elementsFromPoint(r.left + (r.width / 2), r.top + (r.height / 2));
987
+ var elements = doc.elementsFromPoint(checkX, checkY);
988
+ if (debugHash) {
989
+ var topElements = elements.slice(0, 5).map(function (e) { return "".concat(e.tagName).concat(e.id ? '#' + e.id : '').concat(e.className ? '.' + String(e.className).trim().split(/\s+/).slice(0, 2).join('.') : ''); });
990
+ console.log(" top elements at center: [".concat(topElements.join(', '), "]"));
991
+ console.log(" is el in top elements? ".concat(elements.includes(el), " | el matches first non-canvas? ").concat(elements.find(function (e) { return !(e.tagName === "CANVAS" /* Constant.Canvas */ || (e.id && e.id.indexOf("clarity-" /* Constant.ClarityPrefix */) === 0)); }) === el));
992
+ }
963
993
  for (var _i = 0, elements_1 = elements; _i < elements_1.length; _i++) {
964
994
  var e = elements_1[_i];
965
995
  // Ignore if top element ends up being the canvas element we added for heatmap visualization
@@ -973,7 +1003,18 @@ var HeatmapHelper = /** @class */ (function () {
973
1003
  doc = shadowElement;
974
1004
  }
975
1005
  }
976
- return visibility && r.bottom >= 0 && r.top <= height;
1006
+ else if (debugHash) {
1007
+ if (r.width === 0 || r.height === 0) {
1008
+ console.log(" SKIP elementsFromPoint \u2014 zero dimension: width=".concat(r.width, " height=").concat(r.height));
1009
+ }
1010
+ }
1011
+ var result = visibility && r.bottom >= 0 && r.top <= height;
1012
+ if (debugHash) {
1013
+ console.log(" visibility=".concat(visibility, " | r.bottom(").concat(r.bottom.toFixed(1), ") >= 0? ").concat(r.bottom >= 0, " | r.top(").concat(r.top.toFixed(1), ") <= height(").concat(height, ")? ").concat(r.top <= height));
1014
+ console.log(" => final result: ".concat(result));
1015
+ console.groupEnd();
1016
+ }
1017
+ return result;
977
1018
  };
978
1019
  this.waitForDialogs = function () { return __awaiter(_this, void 0, void 0, function () {
979
1020
  var isPortalCanvas;
@@ -2353,7 +2394,7 @@ var Visualizer = /** @class */ (function () {
2353
2394
  this._excludeClassNames = [];
2354
2395
  this.configure = function (opts) {
2355
2396
  _this._excludeClassNames = opts.excludeClassNames || [];
2356
- helper.selector.configure(_this._excludeClassNames);
2397
+ helper.selector.config(_this._excludeClassNames);
2357
2398
  };
2358
2399
  this.dom = function (event) { return __awaiter(_this, void 0, void 0, function () {
2359
2400
  return __generator(this, function (_a) {
@@ -2475,7 +2516,7 @@ var Visualizer = /** @class */ (function () {
2475
2516
  decoded = decoded.sort(_this.sortPayloads);
2476
2517
  // Re-initialize enrich class if someone ends up calling merge function directly
2477
2518
  _this.enrich = _this.enrich || new EnrichHelper();
2478
- helper.selector.configure(_this._excludeClassNames);
2519
+ helper.selector.config(_this._excludeClassNames);
2479
2520
  _this.enrich.reset();
2480
2521
  // Walk through payloads and generate merged payload from an array of decoded payloads
2481
2522
  for (var _i = 0, decoded_1 = decoded; _i < decoded_1.length; _i++) {
@@ -2516,7 +2557,7 @@ var Visualizer = /** @class */ (function () {
2516
2557
  this.reset();
2517
2558
  if (options.excludeClassNames) {
2518
2559
  this._excludeClassNames = options.excludeClassNames;
2519
- helper.selector.configure(options.excludeClassNames);
2560
+ helper.selector.config(options.excludeClassNames);
2520
2561
  }
2521
2562
  // Infer options
2522
2563
  options.pointer = "pointer" in options ? options.pointer : true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gemx-dev/clarity-visualize",
3
- "version": "0.8.63",
3
+ "version": "0.8.65",
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.63"
12
+ "@gemx-dev/clarity-decode": "^0.8.65"
13
13
  },
14
14
  "devDependencies": {
15
15
  "@rollup/plugin-commonjs": "^24.0.0",
package/src/heatmap.ts CHANGED
@@ -292,7 +292,8 @@ export class HeatmapHelper {
292
292
  }
293
293
 
294
294
  let r = el.getBoundingClientRect();
295
- let v = this.visible(el, r, height);
295
+ const isDebugHash = element.hash === "270qs0pw7";
296
+ let v = this.visible(el, r, height, isDebugHash ? element.hash : undefined);
296
297
 
297
298
  if (!v && this.max !== null) {
298
299
  console.warn(`[Heatmap] SKIP hash="${element.hash}" — not visible on re-render`, { rect: { top: r.top, left: r.left, width: r.width, height: r.height }, maxIsSet: this.max !== null });
@@ -336,14 +337,32 @@ export class HeatmapHelper {
336
337
  return output;
337
338
  }
338
339
 
339
- private visible = (el: HTMLElement, r: DOMRect, height: number): boolean => {
340
+ private visible = (el: HTMLElement, r: DOMRect, height: number, debugHash?: string): boolean => {
340
341
  let doc: Document | ShadowRoot = this.state.window.document;
341
342
  let visibility = r.height > height ? true : false;
343
+
344
+ if (debugHash) {
345
+ console.group(`[Heatmap visible] hash=${debugHash} tag=${el?.tagName}`);
346
+ console.log(` rect: top=${r.top.toFixed(1)} bottom=${r.bottom.toFixed(1)} left=${r.left.toFixed(1)} width=${r.width.toFixed(1)} height=${r.height.toFixed(1)}`);
347
+ console.log(` viewport height=${height} | r.height > height? ${r.height > height}`);
348
+ }
349
+
342
350
  if (visibility === false && r.width > 0 && r.height > 0) {
351
+ const checkX = r.left + (r.width / 2);
352
+ const checkY = r.top + (r.height / 2);
353
+ if (debugHash) { console.log(` elementsFromPoint(${checkX.toFixed(1)}, ${checkY.toFixed(1)})`); }
354
+
343
355
  while (!visibility && doc)
344
356
  {
345
357
  let shadowElement = null;
346
- let elements = doc.elementsFromPoint(r.left + (r.width / 2), r.top + (r.height / 2));
358
+ let elements = doc.elementsFromPoint(checkX, checkY);
359
+
360
+ if (debugHash) {
361
+ const topElements = elements.slice(0, 5).map(e => `${e.tagName}${e.id ? '#' + e.id : ''}${e.className ? '.' + String(e.className).trim().split(/\s+/).slice(0, 2).join('.') : ''}`);
362
+ console.log(` top elements at center: [${topElements.join(', ')}]`);
363
+ console.log(` is el in top elements? ${elements.includes(el)} | el matches first non-canvas? ${elements.find(e => !(e.tagName === Constant.Canvas || (e.id && e.id.indexOf(Constant.ClarityPrefix) === 0))) === el}`);
364
+ }
365
+
347
366
  for (let e of elements) {
348
367
  // Ignore if top element ends up being the canvas element we added for heatmap visualization
349
368
  if (e.tagName === Constant.Canvas || (e.id && e.id.indexOf(Constant.ClarityPrefix) === 0)) { continue; }
@@ -353,8 +372,19 @@ export class HeatmapHelper {
353
372
  }
354
373
  doc = shadowElement;
355
374
  }
375
+ } else if (debugHash) {
376
+ if (r.width === 0 || r.height === 0) {
377
+ console.log(` SKIP elementsFromPoint — zero dimension: width=${r.width} height=${r.height}`);
378
+ }
379
+ }
380
+
381
+ const result = visibility && r.bottom >= 0 && r.top <= height;
382
+ if (debugHash) {
383
+ console.log(` visibility=${visibility} | r.bottom(${r.bottom.toFixed(1)}) >= 0? ${r.bottom >= 0} | r.top(${r.top.toFixed(1)}) <= height(${height})? ${r.top <= height}`);
384
+ console.log(` => final result: ${result}`);
385
+ console.groupEnd();
356
386
  }
357
- return visibility && r.bottom >= 0 && r.top <= height;
387
+ return result;
358
388
  }
359
389
 
360
390
  private waitForDialogs = async (): Promise<void> => {
package/src/visualizer.ts CHANGED
@@ -27,7 +27,7 @@ export class Visualizer implements VisualizerType {
27
27
 
28
28
  public configure = (opts: { excludeClassNames?: string[] }): void => {
29
29
  this._excludeClassNames = opts.excludeClassNames || [];
30
- helper.selector.configure(this._excludeClassNames);
30
+ helper.selector.config(this._excludeClassNames);
31
31
  }
32
32
 
33
33
  public dom = async (event: Layout.DomEvent): Promise<void> => {
@@ -123,7 +123,7 @@ export class Visualizer implements VisualizerType {
123
123
  decoded = decoded.sort(this.sortPayloads);
124
124
  // Re-initialize enrich class if someone ends up calling merge function directly
125
125
  this.enrich = this.enrich || new EnrichHelper();
126
- helper.selector.configure(this._excludeClassNames);
126
+ helper.selector.config(this._excludeClassNames);
127
127
  this.enrich.reset();
128
128
  // Walk through payloads and generate merged payload from an array of decoded payloads
129
129
  for (let payload of decoded) {
@@ -158,7 +158,7 @@ export class Visualizer implements VisualizerType {
158
158
  this.reset();
159
159
  if (options.excludeClassNames) {
160
160
  this._excludeClassNames = options.excludeClassNames;
161
- helper.selector.configure(options.excludeClassNames);
161
+ helper.selector.config(options.excludeClassNames);
162
162
  }
163
163
  // Infer options
164
164
  options.pointer = "pointer" in options ? options.pointer : true;