From d047570eb936c29f0820ded4177bd8ac94f6a1ea Mon Sep 17 00:00:00 2001 From: nick-delirium Date: Wed, 8 Mar 2023 12:49:32 +0100 Subject: [PATCH 1/4] fix(player): fix clickmap session size? --- .../app/components/Session/Player/ClickMapRenderer/Renderer.tsx | 1 - frontend/app/player/web/Screen/Screen.ts | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/frontend/app/components/Session/Player/ClickMapRenderer/Renderer.tsx b/frontend/app/components/Session/Player/ClickMapRenderer/Renderer.tsx index 8a51717e5..29da5800c 100644 --- a/frontend/app/components/Session/Player/ClickMapRenderer/Renderer.tsx +++ b/frontend/app/components/Session/Player/ClickMapRenderer/Renderer.tsx @@ -16,7 +16,6 @@ function Player() { } }, []); - if (!playerContext.player) return null; return ( diff --git a/frontend/app/player/web/Screen/Screen.ts b/frontend/app/player/web/Screen/Screen.ts index cca56d402..377f704ed 100644 --- a/frontend/app/player/web/Screen/Screen.ts +++ b/frontend/app/player/web/Screen/Screen.ts @@ -218,7 +218,7 @@ export default class Screen { case ScaleMode.AdjustParentHeight: this.scaleRatio = offsetWidth / width translate = "translate(-50%, 0)" - posStyles = { top: 0, height: this.document!.documentElement.getBoundingClientRect().height + 'px', } + posStyles = { top: 0, height: height + 'px', } break; } From 022928d082ae0233189b1e164380df40f6f0cf72 Mon Sep 17 00:00:00 2001 From: nick-delirium Date: Wed, 8 Mar 2023 15:30:22 +0100 Subject: [PATCH 2/4] fix(player): fix clickmap url filtering, fix clickmap highliter --- .../CustomMetricsWidgets/ClickMapCard/ClickMapCard.tsx | 8 +++----- frontend/app/player/web/addons/TargetMarker.ts | 2 +- frontend/app/player/web/addons/clickmapStyles.ts | 6 +++--- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/frontend/app/components/Dashboard/Widgets/CustomMetricsWidgets/ClickMapCard/ClickMapCard.tsx b/frontend/app/components/Dashboard/Widgets/CustomMetricsWidgets/ClickMapCard/ClickMapCard.tsx index e8ff709c9..c77dbcd95 100644 --- a/frontend/app/components/Dashboard/Widgets/CustomMetricsWidgets/ClickMapCard/ClickMapCard.tsx +++ b/frontend/app/components/Dashboard/Widgets/CustomMetricsWidgets/ClickMapCard/ClickMapCard.tsx @@ -20,6 +20,7 @@ function ClickMapCard({ const onMarkerClick = (s: string, innerText: string) => { metricStore.changeClickMapSearch(s, innerText) } + const mapUrl = metricStore.instance.series[0].filter.filters[0].value[0] React.useEffect(() => { return () => clearCurrentSession() @@ -32,12 +33,10 @@ function ClickMapCard({ React.useEffect(() => { if (visitedEvents.length) { - const urlOptions = visitedEvents.map(({ url, host }: any) => ({ label: url, value: url, host })) - const url = insightsFilters.url ? insightsFilters.url : host + urlOptions[0].value; const rangeValue = dashboardStore.drillDownPeriod.rangeValue const startDate = dashboardStore.drillDownPeriod.start const endDate = dashboardStore.drillDownPeriod.end - fetchInsights({ ...insightsFilters, url, startDate, endDate, rangeValue, clickRage: metricStore.clickMapFilter }) + fetchInsights({ ...insightsFilters, url: mapUrl || '/', startDate, endDate, rangeValue, clickRage: metricStore.clickMapFilter }) } }, [visitedEvents, metricStore.clickMapFilter]) @@ -62,9 +61,8 @@ function ClickMapCard({ return
Loading session
} - const searchUrl = metricStore.instance.series[0].filter.filters[0].value[0] const jumpToEvent = metricStore.instance.data.events.find((evt: Record) => { - if (searchUrl) return evt.path.includes(searchUrl) + if (mapUrl) return evt.path.includes(mapUrl) return evt }) || { timestamp: metricStore.instance.data.startTs } diff --git a/frontend/app/player/web/addons/TargetMarker.ts b/frontend/app/player/web/addons/TargetMarker.ts index 6629ceaec..452ddd00f 100644 --- a/frontend/app/player/web/addons/TargetMarker.ts +++ b/frontend/app/player/web/addons/TargetMarker.ts @@ -240,7 +240,7 @@ export default class TargetMarker { }) } - Object.assign(smallClicksBubble.style, clickmapStyles.clicks({ top, height, isRage: s.clickRage })) + Object.assign(smallClicksBubble.style, clickmapStyles.clicks({ top, height, isRage: s.clickRage, left })) border.appendChild(smallClicksBubble) overlay.appendChild(bubbleContainer) diff --git a/frontend/app/player/web/addons/clickmapStyles.ts b/frontend/app/player/web/addons/clickmapStyles.ts index 0ab795ea0..f0dc65a9c 100644 --- a/frontend/app/player/web/addons/clickmapStyles.ts +++ b/frontend/app/player/web/addons/clickmapStyles.ts @@ -16,7 +16,7 @@ export const clickmapStyles = { }, bubbleContainer: ({ top, left, height }: { top: number; left: number, height: number }) => ({ position: 'absolute', - top: top > 20 ? top + 'px' : height + 2 + 'px', + top: top > 75 ? top + 'px' : height+75 + 'px', width: '250px', left: `${left}px`, padding: '10px', @@ -51,9 +51,9 @@ export const clickmapStyles = { position: 'absolute', zIndex, }), - clicks: ({ top, height, isRage }: { top: number; height: number, isRage?: boolean }) => ({ + clicks: ({ top, height, isRage, left }: { top: number; height: number, isRage?: boolean, left: number }) => ({ top: top > 20 ? 0 : `${height}px`, - left: 0, + left: left < 5 ? '100%' : 0, position: 'absolute', borderRadius: '999px', padding: '6px', From 604b095b63c55d65ba73f205d0e0919fb9c56327 Mon Sep 17 00:00:00 2001 From: nick-delirium Date: Wed, 8 Mar 2023 16:13:56 +0100 Subject: [PATCH 3/4] 986b5a8802ec953f9035b16e87b47425bb6249f9 resolved conflicts --- frontend/app/player/web/Screen/Screen.ts | 3 +-- tracker/tracker/CHANGELOG.md | 5 ++++- tracker/tracker/package.json | 3 ++- tracker/tracker/src/main/modules/mouse.ts | 27 ++++++++--------------- 4 files changed, 16 insertions(+), 22 deletions(-) diff --git a/frontend/app/player/web/Screen/Screen.ts b/frontend/app/player/web/Screen/Screen.ts index 377f704ed..f27a251f1 100644 --- a/frontend/app/player/web/Screen/Screen.ts +++ b/frontend/app/player/web/Screen/Screen.ts @@ -3,7 +3,6 @@ import Cursor from './Cursor' import type { Point, Dimensions } from './types'; - export type State = Dimensions export const INITIAL_STATE: State = { @@ -182,7 +181,7 @@ export default class Screen { getElementBySelector(selector: string) { if (!selector) return null; try { - const safeSelector = selector.replace(/:/g, '\\\\3A ').replace(/\//g, '\\/'); + const safeSelector = selector.replace(/\//g, '\\/'); return this.document?.querySelector(safeSelector) || null; } catch (e) { console.error("Can not select element. ", e) diff --git a/tracker/tracker/CHANGELOG.md b/tracker/tracker/CHANGELOG.md index 559e4e865..e3a4c3d78 100644 --- a/tracker/tracker/CHANGELOG.md +++ b/tracker/tracker/CHANGELOG.md @@ -1,4 +1,7 @@ -## 5.0.0 +## 5.0.1 + +- Default text input mode is now Obscured +- Use `@medv/finder` instead of our own implementation of `getSelector` for better clickmaps experience - Added "tel" to supported input types - Added `{ withCurrentTime: true }` to `tracker.getSessionURL` method which will return sessionURL with current session's timestamp diff --git a/tracker/tracker/package.json b/tracker/tracker/package.json index c45c15e4a..326b45575 100644 --- a/tracker/tracker/package.json +++ b/tracker/tracker/package.json @@ -1,7 +1,7 @@ { "name": "@openreplay/tracker", "description": "The OpenReplay tracker main package", - "version": "5.0.0", + "version": "5.0.1-beta.1", "keywords": [ "logging", "replay" @@ -47,6 +47,7 @@ "typescript": "^4.9.4" }, "dependencies": { + "@medv/finder": "^3.0.0", "error-stack-parser": "^2.0.6" }, "engines": { diff --git a/tracker/tracker/src/main/modules/mouse.ts b/tracker/tracker/src/main/modules/mouse.ts index b00d6d304..2b32a99d7 100644 --- a/tracker/tracker/src/main/modules/mouse.ts +++ b/tracker/tracker/src/main/modules/mouse.ts @@ -3,26 +3,17 @@ import { hasTag, isSVGElement, isDocument } from '../app/guards.js' import { normSpaces, hasOpenreplayAttribute, getLabelAttribute } from '../utils.js' import { MouseMove, MouseClick } from '../app/messages.gen.js' import { getInputLabel } from './input.js' +import { finder } from '@medv/finder' function _getSelector(target: Element, document: Document): string { - let el: Element | null = target - let selector: string | null = null - do { - if (el.id) { - return `#${el.id}` + (selector ? ` > ${selector}` : '') - } - selector = - el.className - .split(' ') - .map((cn) => cn.trim()) - .filter((cn) => cn !== '') - .reduce((sel, cn) => `${sel}.${cn}`, el.tagName.toLowerCase()) + - (selector ? ` > ${selector}` : '') - if (el === document.body) { - return selector - } - el = el.parentElement - } while (el !== document.body && el !== null) + const selector = finder(target, { + root: document.body, + seedMinLength: 3, + optimizedMinLength: 2, + threshold: 1000, + maxNumberOfTries: 10_000, + }) + return selector } From 8c14743425dbb45b8089b37aae4bdbc3caf7b6a9 Mon Sep 17 00:00:00 2001 From: nick-delirium Date: Wed, 8 Mar 2023 16:41:49 +0100 Subject: [PATCH 4/4] fix(player): track tr th clicks for map --- third-party.md | 2 +- tracker/tracker/package.json | 2 +- tracker/tracker/src/main/modules/mouse.ts | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/third-party.md b/third-party.md index e0b68d9f6..0cfe2cac2 100644 --- a/third-party.md +++ b/third-party.md @@ -115,4 +115,4 @@ Below is the list of dependencies used in OpenReplay software. Licenses may chan | yq | MIT | Infrastructure | | html2canvas | MIT | JavaScript | | eget | MIT | Infrastructure | - +| @medv/finder | MIT | JavaScript | diff --git a/tracker/tracker/package.json b/tracker/tracker/package.json index 326b45575..a67073cc9 100644 --- a/tracker/tracker/package.json +++ b/tracker/tracker/package.json @@ -1,7 +1,7 @@ { "name": "@openreplay/tracker", "description": "The OpenReplay tracker main package", - "version": "5.0.1-beta.1", + "version": "5.0.1-beta.2", "keywords": [ "logging", "replay" diff --git a/tracker/tracker/src/main/modules/mouse.ts b/tracker/tracker/src/main/modules/mouse.ts index 2b32a99d7..155a14a8d 100644 --- a/tracker/tracker/src/main/modules/mouse.ts +++ b/tracker/tracker/src/main/modules/mouse.ts @@ -24,6 +24,8 @@ function isClickable(element: Element): boolean { tag === 'A' || tag === 'LI' || tag === 'SELECT' || + tag === 'TR' || + tag === 'TH' || (element as HTMLElement).onclick != null || element.getAttribute('role') === 'button' )