@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.
- package/build/clarity.visualize.js +52 -11
- package/build/clarity.visualize.min.js +1 -1
- package/build/clarity.visualize.module.js +52 -11
- package/package.json +2 -2
- package/src/heatmap.ts +34 -4
- package/src/visualizer.ts +3 -3
|
@@ -104,8 +104,9 @@ var selectorMap = {};
|
|
|
104
104
|
function reset$8() {
|
|
105
105
|
selectorMap = {};
|
|
106
106
|
}
|
|
107
|
-
function
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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(
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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(
|
|
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
|
|
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.
|
|
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.
|
|
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.
|
|
161
|
+
helper.selector.config(options.excludeClassNames);
|
|
162
162
|
}
|
|
163
163
|
// Infer options
|
|
164
164
|
options.pointer = "pointer" in options ? options.pointer : true;
|