mirror of
https://github.com/chenasraf/clarity.git
synced 2026-05-17 17:48:05 +00:00
Merge pull request #604 from microsoft/samart/styleSharedState
breaking out the style states into 2 fields and ensuring we dont rese…
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
"packages": [
|
||||
"packages/*"
|
||||
],
|
||||
"version": "0.7.34",
|
||||
"version": "0.7.35",
|
||||
"npmClient": "yarn",
|
||||
"useWorkspaces": true
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "clarity-decode",
|
||||
"version": "0.7.34",
|
||||
"version": "0.7.35",
|
||||
"description": "An analytics library that uses web page interactions to generate aggregated insights",
|
||||
"author": "Microsoft Corp.",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "clarity-devtools",
|
||||
"version": "0.7.34",
|
||||
"version": "0.7.35",
|
||||
"private": true,
|
||||
"description": "Adds Clarity debugging support to browser devtools",
|
||||
"author": "Microsoft Corp.",
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
"manifest_version": 2,
|
||||
"name": "Microsoft Clarity Developer Tools",
|
||||
"description": "Clarity helps you understand how users are interacting with your website.",
|
||||
"version": "0.7.34",
|
||||
"version_name": "0.7.34",
|
||||
"version": "0.7.35",
|
||||
"version_name": "0.7.35",
|
||||
"minimum_chrome_version": "50",
|
||||
"devtools_page": "devtools.html",
|
||||
"icons": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "clarity-js",
|
||||
"version": "0.7.34",
|
||||
"version": "0.7.35",
|
||||
"description": "An analytics library that uses web page interactions to generate aggregated insights",
|
||||
"author": "Microsoft Corp.",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
let version = "0.7.34";
|
||||
let version = "0.7.35";
|
||||
export default version;
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
export let state = [];
|
||||
export let sheetAdoptionState = [];
|
||||
export let sheetUpdateState = [];
|
||||
export let data = null;
|
||||
|
||||
/* Intentionally blank module with empty code */
|
||||
|
||||
@@ -3,13 +3,12 @@ import { StyleSheetState } from "@clarity-types/layout";
|
||||
import * as core from "@src/core";
|
||||
import * as metric from "@src/data/metric";
|
||||
|
||||
export let state: StyleSheetState[] = [];
|
||||
export let sheetAdoptionState: StyleSheetState[] = [];
|
||||
export let sheetUpdateState: StyleSheetState[] = [];
|
||||
let replace: (text?: string) => Promise<CSSStyleSheet> = null;
|
||||
let replaceSync: (text?: string) => void = null;
|
||||
|
||||
export function start(): void {
|
||||
reset();
|
||||
|
||||
if (replace === null) {
|
||||
replace = CSSStyleSheet.prototype.replace;
|
||||
CSSStyleSheet.prototype.replace = function(): Promise<CSSStyleSheet> {
|
||||
@@ -44,7 +43,8 @@ export function compute(): void {
|
||||
}
|
||||
|
||||
export function reset(): void {
|
||||
state = [];
|
||||
sheetAdoptionState = [];
|
||||
sheetUpdateState = [];
|
||||
}
|
||||
|
||||
export function stop(): void {
|
||||
|
||||
@@ -38,17 +38,15 @@ export default async function (type: Event, timer: Timer = null, ts: number = nu
|
||||
region.reset();
|
||||
break;
|
||||
case Event.StyleSheetAdoption:
|
||||
for (let entry of style.state) {
|
||||
case Event.StyleSheetUpdate:
|
||||
for (let entry of style.sheetAdoptionState) {
|
||||
tokens = [entry.time, entry.event];
|
||||
tokens.push(entry.data.id);
|
||||
tokens.push(entry.data.operation);
|
||||
tokens.push(entry.data.newIds);
|
||||
queue(tokens);
|
||||
}
|
||||
style.reset();
|
||||
break;
|
||||
case Event.StyleSheetUpdate:
|
||||
for (let entry of style.state) {
|
||||
for (let entry of style.sheetUpdateState) {
|
||||
tokens = [entry.time, entry.event];
|
||||
tokens.push(entry.data.id);
|
||||
tokens.push(entry.data.operation);
|
||||
@@ -56,6 +54,7 @@ export default async function (type: Event, timer: Timer = null, ts: number = nu
|
||||
queue(tokens);
|
||||
}
|
||||
style.reset();
|
||||
break;
|
||||
case Event.Animation:
|
||||
for (let entry of animation.state) {
|
||||
tokens = [entry.time, entry.event];
|
||||
|
||||
@@ -3,29 +3,33 @@ import { StyleSheetOperation, StyleSheetState } from "@clarity-types/layout";
|
||||
import { time } from "@src/core/time";
|
||||
import { shortid, data as metadataFields } from "@src/data/metadata";
|
||||
import encode from "@src/layout/encode";
|
||||
import { getId, getNode } from "@src/layout/dom";
|
||||
import { getId } from "@src/layout/dom";
|
||||
import * as core from "@src/core";
|
||||
import { getCssRules } from "./node";
|
||||
import * as metric from "@src/data/metric";
|
||||
|
||||
export let state: StyleSheetState[] = [];
|
||||
export let sheetUpdateState: StyleSheetState[] = [];
|
||||
export let sheetAdoptionState: StyleSheetState[] = [];
|
||||
let replace: (text?: string) => Promise<CSSStyleSheet> = null;
|
||||
let replaceSync: (text?: string) => void = null;
|
||||
const styleSheetId = 'claritySheetId';
|
||||
const styleSheetPageNum = 'claritySheetNum';
|
||||
let styleSheetMap = {};
|
||||
let styleTimeMap: {[key: string]: number} = {};
|
||||
let documentNodes = [];
|
||||
|
||||
export function start(): void {
|
||||
reset();
|
||||
|
||||
if (replace === null) {
|
||||
replace = CSSStyleSheet.prototype.replace;
|
||||
CSSStyleSheet.prototype.replace = function(): Promise<CSSStyleSheet> {
|
||||
if (core.active()) {
|
||||
metric.max(Metric.ConstructedStyles, 1);
|
||||
bootStrapStyleSheet(this);
|
||||
trackStyleChange(time(), this[styleSheetId], StyleSheetOperation.Replace, arguments[0]);
|
||||
// if we haven't seen this stylesheet on this page yet, wait until the checkDocumentStyles has found it
|
||||
// and attached the sheet to a document. This way the timestamp of the style sheet creation will align
|
||||
// to when it is used in the document rather than potentially being misaligned during the traverse process.
|
||||
if (this[styleSheetPageNum] === metadataFields.pageNum) {
|
||||
trackStyleChange(time(), this[styleSheetId], StyleSheetOperation.Replace, arguments[0]);
|
||||
}
|
||||
}
|
||||
return replace.apply(this, arguments);
|
||||
};
|
||||
@@ -36,28 +40,22 @@ export function start(): void {
|
||||
CSSStyleSheet.prototype.replaceSync = function(): void {
|
||||
if (core.active()) {
|
||||
metric.max(Metric.ConstructedStyles, 1);
|
||||
bootStrapStyleSheet(this);
|
||||
trackStyleChange(time(), this[styleSheetId], StyleSheetOperation.ReplaceSync, arguments[0]);
|
||||
// if we haven't seen this stylesheet on this page yet, wait until the checkDocumentStyles has found it
|
||||
// and attached the sheet to a document. This way the timestamp of the style sheet creation will align
|
||||
// to when it is used in the document rather than potentially being misaligned during the traverse process.
|
||||
if (this[styleSheetPageNum] === metadataFields.pageNum) {
|
||||
trackStyleChange(time(), this[styleSheetId], StyleSheetOperation.ReplaceSync, arguments[0]);
|
||||
}
|
||||
}
|
||||
return replaceSync.apply(this, arguments);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function bootStrapStyleSheet(styleSheet: CSSStyleSheet): void {
|
||||
// If we haven't seen this style sheet on this page yet, we create a reference to it for the visualizer.
|
||||
// For SPA or times in which Clarity restarts on a given page, our visualizer would lose context
|
||||
// on the previously created style sheet for page N-1.
|
||||
const pageNum = metadataFields.pageNum;
|
||||
if (styleSheet[styleSheetPageNum] !== pageNum) {
|
||||
styleSheet[styleSheetPageNum] = pageNum;
|
||||
styleSheet[styleSheetId] = shortid();
|
||||
// need to pass a create style sheet event (don't add it to any nodes, but do create it)
|
||||
trackStyleChange(time(), styleSheet[styleSheetId], StyleSheetOperation.Create);
|
||||
}
|
||||
}
|
||||
|
||||
export function checkDocumentStyles(documentNode: Document, timestamp: number): void {
|
||||
if (documentNodes.indexOf(documentNode) === -1) {
|
||||
documentNodes.push(documentNode);
|
||||
}
|
||||
timestamp = timestamp || time();
|
||||
if (!documentNode?.adoptedStyleSheets) {
|
||||
// if we don't have adoptedStyledSheets on the Node passed to us, we can short circuit.
|
||||
@@ -67,7 +65,10 @@ export function checkDocumentStyles(documentNode: Document, timestamp: number):
|
||||
let currentStyleSheets: string[] = [];
|
||||
for (var styleSheet of documentNode.adoptedStyleSheets) {
|
||||
const pageNum = metadataFields.pageNum;
|
||||
// if we haven't seen this style sheet, create it and call replaceSync with its contents to bootstrap it
|
||||
// If we haven't seen this style sheet on this page yet, we create a reference to it for the visualizer.
|
||||
// For SPA or times in which Clarity restarts on a given page, our visualizer would lose context
|
||||
// on the previously created style sheet for page N-1.
|
||||
// Then we synthetically call replaceSync with its contents to bootstrap it
|
||||
if (styleSheet[styleSheetPageNum] !== pageNum) {
|
||||
styleSheet[styleSheetPageNum] = pageNum;
|
||||
styleSheet[styleSheetId] = shortid();
|
||||
@@ -90,23 +91,27 @@ export function checkDocumentStyles(documentNode: Document, timestamp: number):
|
||||
}
|
||||
|
||||
export function compute(): void {
|
||||
let ts = -1 in styleTimeMap ? styleTimeMap[-1] : null;
|
||||
checkDocumentStyles(document, ts);
|
||||
Object.keys(styleSheetMap).forEach((x) => checkDocumentStyles(getNode(parseInt(x, 10)) as Document, styleTimeMap[x]));
|
||||
for (var documentNode of documentNodes) {
|
||||
var docId = documentNode == document ? -1 : getId(documentNode);
|
||||
let ts = docId in styleTimeMap ? styleTimeMap[docId] : null;
|
||||
checkDocumentStyles(document, ts);
|
||||
}
|
||||
}
|
||||
|
||||
export function reset(): void {
|
||||
state = [];
|
||||
sheetAdoptionState = [];
|
||||
sheetUpdateState = [];
|
||||
}
|
||||
|
||||
export function stop(): void {
|
||||
styleSheetMap = {};
|
||||
styleTimeMap = {};
|
||||
documentNodes = [];
|
||||
reset();
|
||||
}
|
||||
|
||||
function trackStyleChange(time: number, id: string, operation: StyleSheetOperation, cssRules?: string): void {
|
||||
state.push({
|
||||
sheetUpdateState.push({
|
||||
time,
|
||||
event: Event.StyleSheetUpdate,
|
||||
data: {
|
||||
@@ -120,7 +125,7 @@ function trackStyleChange(time: number, id: string, operation: StyleSheetOperati
|
||||
}
|
||||
|
||||
function trackStyleAdoption(time: number, id: number, operation: StyleSheetOperation, newIds: string[]): void {
|
||||
state.push({
|
||||
sheetAdoptionState.push({
|
||||
time,
|
||||
event: Event.StyleSheetAdoption,
|
||||
data: {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "clarity-visualize",
|
||||
"version": "0.7.34",
|
||||
"version": "0.7.35",
|
||||
"description": "An analytics library that uses web page interactions to generate aggregated insights",
|
||||
"author": "Microsoft Corp.",
|
||||
"license": "MIT",
|
||||
|
||||
Reference in New Issue
Block a user