@gemx-dev/clarity-visualize 0.8.63 → 0.8.64
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 +81 -18
- package/build/clarity.visualize.min.js +1 -1
- package/build/clarity.visualize.module.js +81 -18
- package/package.json +2 -2
- package/src/heatmap.ts +34 -4
|
@@ -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
|
});
|
|
@@ -374,6 +388,10 @@ var EnrichHelper = /** @class */ (function () {
|
|
|
374
388
|
var selectorBeta = helper.selector.get(input, 1 /* Layout.Selector.Beta */);
|
|
375
389
|
d.selectorBeta = selectorBeta.length > 0 ? selectorBeta : null;
|
|
376
390
|
d.hashBeta = selectorBeta.length > 0 ? helper.hash(d.selectorBeta) : null;
|
|
391
|
+
var rawClass = (d.attributes || {})['class'] || '';
|
|
392
|
+
if (rawClass.includes('gp_ls-is-cached')) {
|
|
393
|
+
console.log("[Enrich] id=".concat(d.id, " tag=").concat(d.tag, " | class=\"").concat(rawClass, "\" | selectorBeta=\"").concat(selectorBeta, "\" | hashBeta=").concat(d.hashBeta));
|
|
394
|
+
}
|
|
377
395
|
/* Track state for future reference */
|
|
378
396
|
node.alpha = selectorAlpha;
|
|
379
397
|
node.beta = selectorBeta;
|
|
@@ -914,7 +932,8 @@ var HeatmapHelper = /** @class */ (function () {
|
|
|
914
932
|
continue;
|
|
915
933
|
}
|
|
916
934
|
var r = el.getBoundingClientRect();
|
|
917
|
-
var
|
|
935
|
+
var isDebugHash = element.hash === "270qs0pw7";
|
|
936
|
+
var v = _this.visible(el, r, height, isDebugHash ? element.hash : undefined);
|
|
918
937
|
if (!v && _this.max !== null) {
|
|
919
938
|
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
939
|
continue;
|
|
@@ -953,13 +972,28 @@ var HeatmapHelper = /** @class */ (function () {
|
|
|
953
972
|
console.groupEnd();
|
|
954
973
|
return output;
|
|
955
974
|
};
|
|
956
|
-
this.visible = function (el, r, height) {
|
|
975
|
+
this.visible = function (el, r, height, debugHash) {
|
|
957
976
|
var doc = _this.state.window.document;
|
|
958
977
|
var visibility = r.height > height ? true : false;
|
|
978
|
+
if (debugHash) {
|
|
979
|
+
console.group("[Heatmap visible] hash=".concat(debugHash, " tag=").concat(el === null || el === void 0 ? void 0 : el.tagName));
|
|
980
|
+
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)));
|
|
981
|
+
console.log(" viewport height=".concat(height, " | r.height > height? ").concat(r.height > height));
|
|
982
|
+
}
|
|
959
983
|
if (visibility === false && r.width > 0 && r.height > 0) {
|
|
984
|
+
var checkX = r.left + (r.width / 2);
|
|
985
|
+
var checkY = r.top + (r.height / 2);
|
|
986
|
+
if (debugHash) {
|
|
987
|
+
console.log(" elementsFromPoint(".concat(checkX.toFixed(1), ", ").concat(checkY.toFixed(1), ")"));
|
|
988
|
+
}
|
|
960
989
|
while (!visibility && doc) {
|
|
961
990
|
var shadowElement = null;
|
|
962
|
-
var elements = doc.elementsFromPoint(
|
|
991
|
+
var elements = doc.elementsFromPoint(checkX, checkY);
|
|
992
|
+
if (debugHash) {
|
|
993
|
+
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('.') : ''); });
|
|
994
|
+
console.log(" top elements at center: [".concat(topElements.join(', '), "]"));
|
|
995
|
+
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));
|
|
996
|
+
}
|
|
963
997
|
for (var _i = 0, elements_1 = elements; _i < elements_1.length; _i++) {
|
|
964
998
|
var e = elements_1[_i];
|
|
965
999
|
// Ignore if top element ends up being the canvas element we added for heatmap visualization
|
|
@@ -973,7 +1007,18 @@ var HeatmapHelper = /** @class */ (function () {
|
|
|
973
1007
|
doc = shadowElement;
|
|
974
1008
|
}
|
|
975
1009
|
}
|
|
976
|
-
|
|
1010
|
+
else if (debugHash) {
|
|
1011
|
+
if (r.width === 0 || r.height === 0) {
|
|
1012
|
+
console.log(" SKIP elementsFromPoint \u2014 zero dimension: width=".concat(r.width, " height=").concat(r.height));
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
var result = visibility && r.bottom >= 0 && r.top <= height;
|
|
1016
|
+
if (debugHash) {
|
|
1017
|
+
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));
|
|
1018
|
+
console.log(" => final result: ".concat(result));
|
|
1019
|
+
console.groupEnd();
|
|
1020
|
+
}
|
|
1021
|
+
return result;
|
|
977
1022
|
};
|
|
978
1023
|
this.waitForDialogs = function () { return __awaiter(_this, void 0, void 0, function () {
|
|
979
1024
|
var isPortalCanvas;
|
|
@@ -1722,6 +1767,9 @@ var LayoutHelper = /** @class */ (function () {
|
|
|
1722
1767
|
// In case of selector collision, prefer the first inserted node
|
|
1723
1768
|
_this.hashMapAlpha[data.hashAlpha] = _this.get(data.hashAlpha) || parent;
|
|
1724
1769
|
_this.hashMapBeta[data.hashBeta] = _this.get(data.hashBeta) || parent;
|
|
1770
|
+
if (data.hashBeta === '2e36mrf7c' || data.hashBeta === '19lq10ve5') {
|
|
1771
|
+
console.log("[Layout] addToHashMap hashBeta=".concat(data.hashBeta, " | hashAlpha=").concat(data.hashAlpha, " | tag=").concat(parent === null || parent === void 0 ? void 0 : parent.tagName));
|
|
1772
|
+
}
|
|
1725
1773
|
};
|
|
1726
1774
|
this.resize = function (el, width, height) {
|
|
1727
1775
|
if (el && el.nodeType === 1 /* NodeType.ELEMENT_NODE */ && width && height) {
|
|
@@ -2391,25 +2439,33 @@ var Visualizer = /** @class */ (function () {
|
|
|
2391
2439
|
return false;
|
|
2392
2440
|
}
|
|
2393
2441
|
};
|
|
2394
|
-
this.html = function (decoded, target, portalCanvasId, hash, useproxy, logerror, shortCircuitStrategy) {
|
|
2442
|
+
this.html = function (decoded, target, portalCanvasId, hash, useproxy, logerror, shortCircuitStrategy, signal) {
|
|
2395
2443
|
if (hash === void 0) { hash = null; }
|
|
2396
2444
|
if (shortCircuitStrategy === void 0) { shortCircuitStrategy = 0 /* ShortCircuitStrategy.None */; }
|
|
2397
2445
|
return __awaiter(_this, void 0, void 0, function () {
|
|
2398
|
-
var merged, entry, _a, domEvent, e_1;
|
|
2446
|
+
var merged, CHUNK_BUDGET_MS, chunkStart, entry, _a, domEvent, e_1;
|
|
2399
2447
|
return __generator(this, function (_b) {
|
|
2400
2448
|
switch (_b.label) {
|
|
2401
2449
|
case 0:
|
|
2402
|
-
if (!(decoded && decoded.length > 0 && target)) return [3 /*break*/,
|
|
2450
|
+
if (!(decoded && decoded.length > 0 && target)) return [3 /*break*/, 13];
|
|
2403
2451
|
_b.label = 1;
|
|
2404
2452
|
case 1:
|
|
2405
|
-
_b.trys.push([1,
|
|
2453
|
+
_b.trys.push([1, 12, , 13]);
|
|
2406
2454
|
merged = this.merge(decoded);
|
|
2455
|
+
if (signal === null || signal === void 0 ? void 0 : signal.aborted)
|
|
2456
|
+
return [2 /*return*/, this];
|
|
2407
2457
|
return [4 /*yield*/, this.setup(target, { version: decoded[0].envelope.version, dom: merged.dom, useproxy: useproxy, portalCanvasId: portalCanvasId })];
|
|
2408
2458
|
case 2:
|
|
2409
2459
|
_b.sent();
|
|
2460
|
+
if (signal === null || signal === void 0 ? void 0 : signal.aborted)
|
|
2461
|
+
return [2 /*return*/, this];
|
|
2462
|
+
CHUNK_BUDGET_MS = 8;
|
|
2463
|
+
chunkStart = performance.now();
|
|
2410
2464
|
_b.label = 3;
|
|
2411
2465
|
case 3:
|
|
2412
|
-
if (!(merged.events.length > 0)) return [3 /*break*/,
|
|
2466
|
+
if (!(merged.events.length > 0)) return [3 /*break*/, 11];
|
|
2467
|
+
if (signal === null || signal === void 0 ? void 0 : signal.aborted)
|
|
2468
|
+
return [2 /*return*/, this];
|
|
2413
2469
|
entry = merged.events.shift();
|
|
2414
2470
|
_a = entry.event;
|
|
2415
2471
|
switch (_a) {
|
|
@@ -2435,15 +2491,22 @@ var Visualizer = /** @class */ (function () {
|
|
|
2435
2491
|
case 7:
|
|
2436
2492
|
_b.sent();
|
|
2437
2493
|
return [3 /*break*/, 8];
|
|
2438
|
-
case 8:
|
|
2439
|
-
|
|
2440
|
-
|
|
2494
|
+
case 8:
|
|
2495
|
+
if (!(performance.now() - chunkStart >= CHUNK_BUDGET_MS)) return [3 /*break*/, 10];
|
|
2496
|
+
return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 0); })];
|
|
2497
|
+
case 9:
|
|
2498
|
+
_b.sent();
|
|
2499
|
+
chunkStart = performance.now();
|
|
2500
|
+
_b.label = 10;
|
|
2501
|
+
case 10: return [3 /*break*/, 3];
|
|
2502
|
+
case 11: return [3 /*break*/, 13];
|
|
2503
|
+
case 12:
|
|
2441
2504
|
e_1 = _b.sent();
|
|
2442
2505
|
if (logerror) {
|
|
2443
2506
|
logerror(e_1);
|
|
2444
2507
|
}
|
|
2445
|
-
return [3 /*break*/,
|
|
2446
|
-
case
|
|
2508
|
+
return [3 /*break*/, 13];
|
|
2509
|
+
case 13: return [2 /*return*/, this];
|
|
2447
2510
|
}
|
|
2448
2511
|
});
|
|
2449
2512
|
});
|
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.64",
|
|
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.64"
|
|
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> => {
|