From 345d099d8cd791a2ebcb96a3f21ebc7c2902ee35 Mon Sep 17 00:00:00 2001 From: nick-delirium Date: Fri, 6 Jun 2025 15:26:49 +0200 Subject: [PATCH] testing WAP support --- backend/pkg/messages/filters.go | 2 +- backend/pkg/messages/messages.go | 24 +++++++ backend/pkg/messages/read-message.go | 14 ++++ ee/connectors/msgcodec/messages.py | 8 +++ ee/connectors/msgcodec/messages.pyx | 11 +++ ee/connectors/msgcodec/msgcodec.py | 6 ++ ee/connectors/msgcodec/msgcodec.pyx | 6 ++ .../web/messages/RawMessageReader.gen.ts | 10 +++ .../app/player/web/messages/filters.gen.ts | 2 +- .../app/player/web/messages/message.gen.ts | 3 + frontend/app/player/web/messages/raw.gen.ts | 9 ++- .../player/web/messages/tracker-legacy.gen.ts | 1 + .../app/player/web/messages/tracker.gen.ts | 16 ++++- mobs/messages.rb | 7 +- tracker/tracker/package.json | 2 +- tracker/tracker/src/common/messages.gen.ts | 9 ++- tracker/tracker/src/main/app/messages.gen.ts | 11 +++ tracker/tracker/src/main/index.ts | 7 +- .../tracker/src/main/modules/webAnimations.ts | 69 +++++++++++++++++++ .../src/webworker/MessageEncoder.gen.ts | 4 ++ 20 files changed, 213 insertions(+), 8 deletions(-) create mode 100644 tracker/tracker/src/main/modules/webAnimations.ts diff --git a/backend/pkg/messages/filters.go b/backend/pkg/messages/filters.go index 090f0e00d..fc0471290 100644 --- a/backend/pkg/messages/filters.go +++ b/backend/pkg/messages/filters.go @@ -10,5 +10,5 @@ func IsMobileType(id int) bool { } func IsDOMType(id int) bool { - return 0 == id || 4 == id || 5 == id || 6 == id || 7 == id || 8 == id || 9 == id || 10 == id || 11 == id || 12 == id || 13 == id || 14 == id || 15 == id || 16 == id || 18 == id || 19 == id || 20 == id || 34 == id || 35 == id || 37 == id || 38 == id || 49 == id || 50 == id || 51 == id || 43 == id || 52 == id || 54 == id || 55 == id || 57 == id || 58 == id || 59 == id || 60 == id || 61 == id || 65 == id || 67 == id || 68 == id || 69 == id || 70 == id || 71 == id || 72 == id || 73 == id || 74 == id || 75 == id || 76 == id || 77 == id || 113 == id || 114 == id || 117 == id || 118 == id || 119 == id || 122 == id || 93 == id || 96 == id || 100 == id || 101 == id || 102 == id || 103 == id || 104 == id || 105 == id || 106 == id || 111 == id + return 0 == id || 4 == id || 5 == id || 6 == id || 7 == id || 8 == id || 9 == id || 10 == id || 11 == id || 12 == id || 13 == id || 14 == id || 15 == id || 16 == id || 18 == id || 19 == id || 20 == id || 34 == id || 35 == id || 36 == id || 37 == id || 38 == id || 49 == id || 50 == id || 51 == id || 43 == id || 52 == id || 54 == id || 55 == id || 57 == id || 58 == id || 59 == id || 60 == id || 61 == id || 65 == id || 67 == id || 68 == id || 69 == id || 70 == id || 71 == id || 72 == id || 73 == id || 74 == id || 75 == id || 76 == id || 77 == id || 113 == id || 114 == id || 117 == id || 118 == id || 119 == id || 122 == id || 93 == id || 96 == id || 100 == id || 101 == id || 102 == id || 103 == id || 104 == id || 105 == id || 106 == id || 111 == id } diff --git a/backend/pkg/messages/messages.go b/backend/pkg/messages/messages.go index 787754816..2a514fbba 100644 --- a/backend/pkg/messages/messages.go +++ b/backend/pkg/messages/messages.go @@ -37,6 +37,7 @@ const ( MsgPageEvent = 33 MsgStringDictGlobal = 34 MsgSetNodeAttributeDictGlobal = 35 + MsgNodeAnimationResult = 36 MsgCSSInsertRule = 37 MsgCSSDeleteRule = 38 MsgFetch = 39 @@ -1069,6 +1070,29 @@ func (msg *SetNodeAttributeDictGlobal) TypeID() int { return 35 } +type NodeAnimationResult struct { + message + ID uint64 + Styles string +} + +func (msg *NodeAnimationResult) Encode() []byte { + buf := make([]byte, 21+len(msg.Styles)) + buf[0] = 36 + p := 1 + p = WriteUint(msg.ID, buf, p) + p = WriteString(msg.Styles, buf, p) + return buf[:p] +} + +func (msg *NodeAnimationResult) Decode() Message { + return msg +} + +func (msg *NodeAnimationResult) TypeID() int { + return 36 +} + type CSSInsertRule struct { message ID uint64 diff --git a/backend/pkg/messages/read-message.go b/backend/pkg/messages/read-message.go index 856dc6d50..6abe41ba6 100644 --- a/backend/pkg/messages/read-message.go +++ b/backend/pkg/messages/read-message.go @@ -633,6 +633,18 @@ func DecodeSetNodeAttributeDictGlobal(reader BytesReader) (Message, error) { return msg, err } +func DecodeNodeAnimationResult(reader BytesReader) (Message, error) { + var err error = nil + msg := &NodeAnimationResult{} + if msg.ID, err = reader.ReadUint(); err != nil { + return nil, err + } + if msg.Styles, err = reader.ReadString(); err != nil { + return nil, err + } + return msg, err +} + func DecodeCSSInsertRule(reader BytesReader) (Message, error) { var err error = nil msg := &CSSInsertRule{} @@ -2262,6 +2274,8 @@ func ReadMessage(t uint64, reader BytesReader) (Message, error) { return DecodeStringDictGlobal(reader) case 35: return DecodeSetNodeAttributeDictGlobal(reader) + case 36: + return DecodeNodeAnimationResult(reader) case 37: return DecodeCSSInsertRule(reader) case 38: diff --git a/ee/connectors/msgcodec/messages.py b/ee/connectors/msgcodec/messages.py index c1cc7f0de..c6423e96c 100644 --- a/ee/connectors/msgcodec/messages.py +++ b/ee/connectors/msgcodec/messages.py @@ -356,6 +356,14 @@ class SetNodeAttributeDictGlobal(Message): self.value = value +class NodeAnimationResult(Message): + __id__ = 36 + + def __init__(self, id, styles): + self.id = id + self.styles = styles + + class CSSInsertRule(Message): __id__ = 37 diff --git a/ee/connectors/msgcodec/messages.pyx b/ee/connectors/msgcodec/messages.pyx index 14e171463..01f88fed5 100644 --- a/ee/connectors/msgcodec/messages.pyx +++ b/ee/connectors/msgcodec/messages.pyx @@ -535,6 +535,17 @@ cdef class SetNodeAttributeDictGlobal(PyMessage): self.value = value +cdef class NodeAnimationResult(PyMessage): + cdef public int __id__ + cdef public unsigned long id + cdef public str styles + + def __init__(self, unsigned long id, str styles): + self.__id__ = 36 + self.id = id + self.styles = styles + + cdef class CSSInsertRule(PyMessage): cdef public int __id__ cdef public unsigned long id diff --git a/ee/connectors/msgcodec/msgcodec.py b/ee/connectors/msgcodec/msgcodec.py index 0b422d808..a48230af6 100644 --- a/ee/connectors/msgcodec/msgcodec.py +++ b/ee/connectors/msgcodec/msgcodec.py @@ -373,6 +373,12 @@ class MessageCodec(Codec): value=self.read_uint(reader) ) + if message_id == 36: + return NodeAnimationResult( + id=self.read_uint(reader), + styles=self.read_string(reader) + ) + if message_id == 37: return CSSInsertRule( id=self.read_uint(reader), diff --git a/ee/connectors/msgcodec/msgcodec.pyx b/ee/connectors/msgcodec/msgcodec.pyx index 29a03472b..81bf056c8 100644 --- a/ee/connectors/msgcodec/msgcodec.pyx +++ b/ee/connectors/msgcodec/msgcodec.pyx @@ -471,6 +471,12 @@ cdef class MessageCodec: value=self.read_uint(reader) ) + if message_id == 36: + return NodeAnimationResult( + id=self.read_uint(reader), + styles=self.read_string(reader) + ) + if message_id == 37: return CSSInsertRule( id=self.read_uint(reader), diff --git a/frontend/app/player/web/messages/RawMessageReader.gen.ts b/frontend/app/player/web/messages/RawMessageReader.gen.ts index 2b9cb1f7f..1e3623f01 100644 --- a/frontend/app/player/web/messages/RawMessageReader.gen.ts +++ b/frontend/app/player/web/messages/RawMessageReader.gen.ts @@ -255,6 +255,16 @@ export default class RawMessageReader extends PrimitiveReader { }; } + case 36: { + const id = this.readUint(); if (id === null) { return resetPointer() } + const styles = this.readString(); if (styles === null) { return resetPointer() } + return { + tp: MType.NodeAnimationResult, + id, + styles, + }; + } + case 37: { const id = this.readUint(); if (id === null) { return resetPointer() } const rule = this.readString(); if (rule === null) { return resetPointer() } diff --git a/frontend/app/player/web/messages/filters.gen.ts b/frontend/app/player/web/messages/filters.gen.ts index 5aaac8102..d213f8d3b 100644 --- a/frontend/app/player/web/messages/filters.gen.ts +++ b/frontend/app/player/web/messages/filters.gen.ts @@ -4,7 +4,7 @@ import { MType } from './raw.gen' const IOS_TYPES = [90,91,92,93,94,95,96,97,98,100,101,102,103,104,105,106,107,110,111] -const DOM_TYPES = [0,4,5,6,7,8,9,10,11,12,13,14,15,16,18,19,20,34,35,37,38,49,50,51,43,52,54,55,57,58,59,60,61,65,67,68,69,70,71,72,73,74,75,76,77,113,114,117,118,119,122] +const DOM_TYPES = [0,4,5,6,7,8,9,10,11,12,13,14,15,16,18,19,20,34,35,36,37,38,49,50,51,43,52,54,55,57,58,59,60,61,65,67,68,69,70,71,72,73,74,75,76,77,113,114,117,118,119,122] export function isDOMType(t: MType) { return DOM_TYPES.includes(t) } \ No newline at end of file diff --git a/frontend/app/player/web/messages/message.gen.ts b/frontend/app/player/web/messages/message.gen.ts index 2196249a2..423724608 100644 --- a/frontend/app/player/web/messages/message.gen.ts +++ b/frontend/app/player/web/messages/message.gen.ts @@ -25,6 +25,7 @@ import type { RawConsoleLog, RawStringDictGlobal, RawSetNodeAttributeDictGlobal, + RawNodeAnimationResult, RawCssInsertRule, RawCssDeleteRule, RawFetch, @@ -133,6 +134,8 @@ export type StringDictGlobal = RawStringDictGlobal & Timed export type SetNodeAttributeDictGlobal = RawSetNodeAttributeDictGlobal & Timed +export type NodeAnimationResult = RawNodeAnimationResult & Timed + export type CssInsertRule = RawCssInsertRule & Timed export type CssDeleteRule = RawCssDeleteRule & Timed diff --git a/frontend/app/player/web/messages/raw.gen.ts b/frontend/app/player/web/messages/raw.gen.ts index 5f16303da..2d60cb59a 100644 --- a/frontend/app/player/web/messages/raw.gen.ts +++ b/frontend/app/player/web/messages/raw.gen.ts @@ -23,6 +23,7 @@ export const enum MType { ConsoleLog = 22, StringDictGlobal = 34, SetNodeAttributeDictGlobal = 35, + NodeAnimationResult = 36, CssInsertRule = 37, CssDeleteRule = 38, Fetch = 39, @@ -226,6 +227,12 @@ export interface RawSetNodeAttributeDictGlobal { value: number, } +export interface RawNodeAnimationResult { + tp: MType.NodeAnimationResult, + id: number, + styles: string, +} + export interface RawCssInsertRule { tp: MType.CssInsertRule, id: number, @@ -710,4 +717,4 @@ export interface RawMobileIssueEvent { } -export type RawMessage = RawTimestamp | RawSetPageLocationDeprecated | RawSetViewportSize | RawSetViewportScroll | RawCreateDocument | RawCreateElementNode | RawCreateTextNode | RawMoveNode | RawRemoveNode | RawSetNodeAttribute | RawRemoveNodeAttribute | RawSetNodeData | RawSetCssData | RawSetNodeScroll | RawSetInputValue | RawSetInputChecked | RawMouseMove | RawNetworkRequestDeprecated | RawConsoleLog | RawStringDictGlobal | RawSetNodeAttributeDictGlobal | RawCssInsertRule | RawCssDeleteRule | RawFetch | RawProfiler | RawOTable | RawReduxDeprecated | RawVuex | RawMobX | RawNgRx | RawGraphQlDeprecated | RawPerformanceTrack | RawStringDictDeprecated | RawSetNodeAttributeDictDeprecated | RawStringDict | RawSetNodeAttributeDict | RawResourceTimingDeprecatedDeprecated | RawConnectionInformation | RawSetPageVisibility | RawLoadFontFace | RawSetNodeFocus | RawLongTask | RawSetNodeAttributeURLBased | RawSetCssDataURLBased | RawSetNodeSlot | RawCssInsertRuleURLBased | RawMouseClick | RawMouseClickDeprecated | RawCreateIFrameDocument | RawAdoptedSsReplaceURLBased | RawAdoptedSsReplace | RawAdoptedSsInsertRuleURLBased | RawAdoptedSsInsertRule | RawAdoptedSsDeleteRule | RawAdoptedSsAddOwner | RawAdoptedSsRemoveOwner | RawZustand | RawNetworkRequest | RawWsChannel | RawResourceTiming | RawIncident | RawLongAnimationTask | RawSelectionChange | RawMouseThrashing | RawResourceTimingDeprecated | RawTabChange | RawTabData | RawCanvasNode | RawTagTrigger | RawRedux | RawSetPageLocation | RawGraphQl | RawMobileEvent | RawMobileScreenChanges | RawMobileClickEvent | RawMobileInputEvent | RawMobilePerformanceEvent | RawMobileLog | RawMobileInternalError | RawMobileNetworkCall | RawMobileSwipeEvent | RawMobileIssueEvent; +export type RawMessage = RawTimestamp | RawSetPageLocationDeprecated | RawSetViewportSize | RawSetViewportScroll | RawCreateDocument | RawCreateElementNode | RawCreateTextNode | RawMoveNode | RawRemoveNode | RawSetNodeAttribute | RawRemoveNodeAttribute | RawSetNodeData | RawSetCssData | RawSetNodeScroll | RawSetInputValue | RawSetInputChecked | RawMouseMove | RawNetworkRequestDeprecated | RawConsoleLog | RawStringDictGlobal | RawSetNodeAttributeDictGlobal | RawNodeAnimationResult | RawCssInsertRule | RawCssDeleteRule | RawFetch | RawProfiler | RawOTable | RawReduxDeprecated | RawVuex | RawMobX | RawNgRx | RawGraphQlDeprecated | RawPerformanceTrack | RawStringDictDeprecated | RawSetNodeAttributeDictDeprecated | RawStringDict | RawSetNodeAttributeDict | RawResourceTimingDeprecatedDeprecated | RawConnectionInformation | RawSetPageVisibility | RawLoadFontFace | RawSetNodeFocus | RawLongTask | RawSetNodeAttributeURLBased | RawSetCssDataURLBased | RawSetNodeSlot | RawCssInsertRuleURLBased | RawMouseClick | RawMouseClickDeprecated | RawCreateIFrameDocument | RawAdoptedSsReplaceURLBased | RawAdoptedSsReplace | RawAdoptedSsInsertRuleURLBased | RawAdoptedSsInsertRule | RawAdoptedSsDeleteRule | RawAdoptedSsAddOwner | RawAdoptedSsRemoveOwner | RawZustand | RawNetworkRequest | RawWsChannel | RawResourceTiming | RawIncident | RawLongAnimationTask | RawSelectionChange | RawMouseThrashing | RawResourceTimingDeprecated | RawTabChange | RawTabData | RawCanvasNode | RawTagTrigger | RawRedux | RawSetPageLocation | RawGraphQl | RawMobileEvent | RawMobileScreenChanges | RawMobileClickEvent | RawMobileInputEvent | RawMobilePerformanceEvent | RawMobileLog | RawMobileInternalError | RawMobileNetworkCall | RawMobileSwipeEvent | RawMobileIssueEvent; diff --git a/frontend/app/player/web/messages/tracker-legacy.gen.ts b/frontend/app/player/web/messages/tracker-legacy.gen.ts index 901b369bd..8d6bcad72 100644 --- a/frontend/app/player/web/messages/tracker-legacy.gen.ts +++ b/frontend/app/player/web/messages/tracker-legacy.gen.ts @@ -24,6 +24,7 @@ export const TP_MAP = { 22: MType.ConsoleLog, 34: MType.StringDictGlobal, 35: MType.SetNodeAttributeDictGlobal, + 36: MType.NodeAnimationResult, 37: MType.CssInsertRule, 38: MType.CssDeleteRule, 39: MType.Fetch, diff --git a/frontend/app/player/web/messages/tracker.gen.ts b/frontend/app/player/web/messages/tracker.gen.ts index 0174794f7..b4411072d 100644 --- a/frontend/app/player/web/messages/tracker.gen.ts +++ b/frontend/app/player/web/messages/tracker.gen.ts @@ -186,6 +186,12 @@ type TrSetNodeAttributeDictGlobal = [ value: number, ] +type TrNodeAnimationResult = [ + type: 36, + id: number, + styles: string, +] + type TrCSSInsertRule = [ type: 37, id: number, @@ -627,7 +633,7 @@ type TrWebVitals = [ ] -export type TrackerMessage = TrTimestamp | TrSetPageLocationDeprecated | TrSetViewportSize | TrSetViewportScroll | TrCreateDocument | TrCreateElementNode | TrCreateTextNode | TrMoveNode | TrRemoveNode | TrSetNodeAttribute | TrRemoveNodeAttribute | TrSetNodeData | TrSetNodeScroll | TrSetInputTarget | TrSetInputValue | TrSetInputChecked | TrMouseMove | TrNetworkRequestDeprecated | TrConsoleLog | TrPageLoadTiming | TrPageRenderTiming | TrCustomEvent | TrUserID | TrUserAnonymousID | TrMetadata | TrStringDictGlobal | TrSetNodeAttributeDictGlobal | TrCSSInsertRule | TrCSSDeleteRule | TrFetch | TrProfiler | TrOTable | TrStateAction | TrReduxDeprecated | TrVuex | TrMobX | TrNgRx | TrGraphQLDeprecated | TrPerformanceTrack | TrStringDictDeprecated | TrSetNodeAttributeDictDeprecated | TrStringDict | TrSetNodeAttributeDict | TrResourceTimingDeprecatedDeprecated | TrConnectionInformation | TrSetPageVisibility | TrLoadFontFace | TrSetNodeFocus | TrLongTask | TrSetNodeAttributeURLBased | TrSetCSSDataURLBased | TrTechnicalInfo | TrCustomIssue | TrSetNodeSlot | TrCSSInsertRuleURLBased | TrMouseClick | TrMouseClickDeprecated | TrCreateIFrameDocument | TrAdoptedSSReplaceURLBased | TrAdoptedSSInsertRuleURLBased | TrAdoptedSSDeleteRule | TrAdoptedSSAddOwner | TrAdoptedSSRemoveOwner | TrJSException | TrZustand | TrBatchMetadata | TrPartitionedMessage | TrNetworkRequest | TrWSChannel | TrResourceTiming | TrIncident | TrLongAnimationTask | TrInputChange | TrSelectionChange | TrMouseThrashing | TrUnbindNodes | TrResourceTimingDeprecated | TrTabChange | TrTabData | TrCanvasNode | TrTagTrigger | TrRedux | TrSetPageLocation | TrGraphQL | TrWebVitals +export type TrackerMessage = TrTimestamp | TrSetPageLocationDeprecated | TrSetViewportSize | TrSetViewportScroll | TrCreateDocument | TrCreateElementNode | TrCreateTextNode | TrMoveNode | TrRemoveNode | TrSetNodeAttribute | TrRemoveNodeAttribute | TrSetNodeData | TrSetNodeScroll | TrSetInputTarget | TrSetInputValue | TrSetInputChecked | TrMouseMove | TrNetworkRequestDeprecated | TrConsoleLog | TrPageLoadTiming | TrPageRenderTiming | TrCustomEvent | TrUserID | TrUserAnonymousID | TrMetadata | TrStringDictGlobal | TrSetNodeAttributeDictGlobal | TrNodeAnimationResult | TrCSSInsertRule | TrCSSDeleteRule | TrFetch | TrProfiler | TrOTable | TrStateAction | TrReduxDeprecated | TrVuex | TrMobX | TrNgRx | TrGraphQLDeprecated | TrPerformanceTrack | TrStringDictDeprecated | TrSetNodeAttributeDictDeprecated | TrStringDict | TrSetNodeAttributeDict | TrResourceTimingDeprecatedDeprecated | TrConnectionInformation | TrSetPageVisibility | TrLoadFontFace | TrSetNodeFocus | TrLongTask | TrSetNodeAttributeURLBased | TrSetCSSDataURLBased | TrTechnicalInfo | TrCustomIssue | TrSetNodeSlot | TrCSSInsertRuleURLBased | TrMouseClick | TrMouseClickDeprecated | TrCreateIFrameDocument | TrAdoptedSSReplaceURLBased | TrAdoptedSSInsertRuleURLBased | TrAdoptedSSDeleteRule | TrAdoptedSSAddOwner | TrAdoptedSSRemoveOwner | TrJSException | TrZustand | TrBatchMetadata | TrPartitionedMessage | TrNetworkRequest | TrWSChannel | TrResourceTiming | TrIncident | TrLongAnimationTask | TrInputChange | TrSelectionChange | TrMouseThrashing | TrUnbindNodes | TrResourceTimingDeprecated | TrTabChange | TrTabData | TrCanvasNode | TrTagTrigger | TrRedux | TrSetPageLocation | TrGraphQL | TrWebVitals export default function translate(tMsg: TrackerMessage): RawMessage | null { switch(tMsg[0]) { @@ -805,6 +811,14 @@ export default function translate(tMsg: TrackerMessage): RawMessage | null { } } + case 36: { + return { + tp: MType.NodeAnimationResult, + id: tMsg[1], + styles: tMsg[2], + } + } + case 37: { return { tp: MType.CssInsertRule, diff --git a/mobs/messages.rb b/mobs/messages.rb index 341aff236..353c58a89 100644 --- a/mobs/messages.rb +++ b/mobs/messages.rb @@ -220,6 +220,11 @@ message 35, 'SetNodeAttributeDictGlobal' do uint 'Value' end +message 36, 'NodeAnimationResult' do + uint 'ID' + string 'Styles' +end + # DEPRECATED since 4.0.2 in favor of AdoptedSSInsertRule + AdoptedSSAddOwner message 37, 'CSSInsertRule' do uint 'ID' @@ -662,4 +667,4 @@ message 127, 'SessionSearch', :tracker => false, :replayer => false do uint 'Partition' end -# FREE 2, 35, 36, 87, 88, 89 +# FREE 2, 87, 88, 89 diff --git a/tracker/tracker/package.json b/tracker/tracker/package.json index e125fcf9e..ac34a7992 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": "17.1.0", + "version": "17.1.0-beta.11", "keywords": [ "logging", "replay" diff --git a/tracker/tracker/src/common/messages.gen.ts b/tracker/tracker/src/common/messages.gen.ts index 8d10b5a53..cf4e502c0 100644 --- a/tracker/tracker/src/common/messages.gen.ts +++ b/tracker/tracker/src/common/messages.gen.ts @@ -29,6 +29,7 @@ export declare const enum Type { Metadata = 30, StringDictGlobal = 34, SetNodeAttributeDictGlobal = 35, + NodeAnimationResult = 36, CSSInsertRule = 37, CSSDeleteRule = 38, Fetch = 39, @@ -271,6 +272,12 @@ export type SetNodeAttributeDictGlobal = [ /*value:*/ number, ] +export type NodeAnimationResult = [ + /*type:*/ Type.NodeAnimationResult, + /*id:*/ number, + /*styles:*/ string, +] + export type CSSInsertRule = [ /*type:*/ Type.CSSInsertRule, /*id:*/ number, @@ -712,5 +719,5 @@ export type WebVitals = [ ] -type Message = Timestamp | SetPageLocationDeprecated | SetViewportSize | SetViewportScroll | CreateDocument | CreateElementNode | CreateTextNode | MoveNode | RemoveNode | SetNodeAttribute | RemoveNodeAttribute | SetNodeData | SetNodeScroll | SetInputTarget | SetInputValue | SetInputChecked | MouseMove | NetworkRequestDeprecated | ConsoleLog | PageLoadTiming | PageRenderTiming | CustomEvent | UserID | UserAnonymousID | Metadata | StringDictGlobal | SetNodeAttributeDictGlobal | CSSInsertRule | CSSDeleteRule | Fetch | Profiler | OTable | StateAction | ReduxDeprecated | Vuex | MobX | NgRx | GraphQLDeprecated | PerformanceTrack | StringDictDeprecated | SetNodeAttributeDictDeprecated | StringDict | SetNodeAttributeDict | ResourceTimingDeprecatedDeprecated | ConnectionInformation | SetPageVisibility | LoadFontFace | SetNodeFocus | LongTask | SetNodeAttributeURLBased | SetCSSDataURLBased | TechnicalInfo | CustomIssue | SetNodeSlot | CSSInsertRuleURLBased | MouseClick | MouseClickDeprecated | CreateIFrameDocument | AdoptedSSReplaceURLBased | AdoptedSSInsertRuleURLBased | AdoptedSSDeleteRule | AdoptedSSAddOwner | AdoptedSSRemoveOwner | JSException | Zustand | BatchMetadata | PartitionedMessage | NetworkRequest | WSChannel | ResourceTiming | Incident | LongAnimationTask | InputChange | SelectionChange | MouseThrashing | UnbindNodes | ResourceTimingDeprecated | TabChange | TabData | CanvasNode | TagTrigger | Redux | SetPageLocation | GraphQL | WebVitals +type Message = Timestamp | SetPageLocationDeprecated | SetViewportSize | SetViewportScroll | CreateDocument | CreateElementNode | CreateTextNode | MoveNode | RemoveNode | SetNodeAttribute | RemoveNodeAttribute | SetNodeData | SetNodeScroll | SetInputTarget | SetInputValue | SetInputChecked | MouseMove | NetworkRequestDeprecated | ConsoleLog | PageLoadTiming | PageRenderTiming | CustomEvent | UserID | UserAnonymousID | Metadata | StringDictGlobal | SetNodeAttributeDictGlobal | NodeAnimationResult | CSSInsertRule | CSSDeleteRule | Fetch | Profiler | OTable | StateAction | ReduxDeprecated | Vuex | MobX | NgRx | GraphQLDeprecated | PerformanceTrack | StringDictDeprecated | SetNodeAttributeDictDeprecated | StringDict | SetNodeAttributeDict | ResourceTimingDeprecatedDeprecated | ConnectionInformation | SetPageVisibility | LoadFontFace | SetNodeFocus | LongTask | SetNodeAttributeURLBased | SetCSSDataURLBased | TechnicalInfo | CustomIssue | SetNodeSlot | CSSInsertRuleURLBased | MouseClick | MouseClickDeprecated | CreateIFrameDocument | AdoptedSSReplaceURLBased | AdoptedSSInsertRuleURLBased | AdoptedSSDeleteRule | AdoptedSSAddOwner | AdoptedSSRemoveOwner | JSException | Zustand | BatchMetadata | PartitionedMessage | NetworkRequest | WSChannel | ResourceTiming | Incident | LongAnimationTask | InputChange | SelectionChange | MouseThrashing | UnbindNodes | ResourceTimingDeprecated | TabChange | TabData | CanvasNode | TagTrigger | Redux | SetPageLocation | GraphQL | WebVitals export default Message diff --git a/tracker/tracker/src/main/app/messages.gen.ts b/tracker/tracker/src/main/app/messages.gen.ts index d8b5487e7..118865851 100644 --- a/tracker/tracker/src/main/app/messages.gen.ts +++ b/tracker/tracker/src/main/app/messages.gen.ts @@ -340,6 +340,17 @@ export function SetNodeAttributeDictGlobal( ] } +export function NodeAnimationResult( + id: number, + styles: string, +): Messages.NodeAnimationResult { + return [ + Messages.Type.NodeAnimationResult, + id, + styles, + ] +} + export function CSSInsertRule( id: number, rule: string, diff --git a/tracker/tracker/src/main/index.ts b/tracker/tracker/src/main/index.ts index fb7c3e72f..ff65bbadb 100644 --- a/tracker/tracker/src/main/index.ts +++ b/tracker/tracker/src/main/index.ts @@ -29,9 +29,11 @@ import ConstructedStyleSheets from './modules/constructedStyleSheets.js' import Selection from './modules/selection.js' import Tabs from './modules/tabs.js' import LongAnimationTask from "./modules/longAnimationTask.js"; +import FeatureFlags, { IFeatureFlag } from './modules/featureFlags.js' +import WebAnimations from './modules/webAnimations.js' import { IN_BROWSER, deprecationWarn, DOCS_HOST, inIframe } from './utils.js' -import FeatureFlags, { IFeatureFlag } from './modules/featureFlags.js' + import type { Options as AppOptions } from './app/index.js' import type { Options as ConsoleOptions } from './modules/console.js' import type { Options as ExceptionOptions } from './modules/exception.js' @@ -43,6 +45,7 @@ import type { MouseHandlerOptions } from './modules/mouse.js' import type { SessionInfo } from './app/session.js' import type { CssRulesOptions } from './modules/cssrules.js' import type { LATOptions } from './modules/longAnimationTask.js' +import type { Options as WapOptions } from './modules/webAnimations.js' import type { StartOptions } from './app/index.js' //TODO: unique options init @@ -71,6 +74,7 @@ export type Options = Partial< // dev only __DISABLE_SECURE_MODE?: boolean css: CssRulesOptions + webAnimations?: WapOptions } const DOCS_SETUP = '/en/sdk' @@ -217,6 +221,7 @@ export default class API { Network(app, options.network) } Selection(app) + WebAnimations(app, options.webAnimations) ;(window as any).__OPENREPLAY__ = this if (options.flags && options.flags.onFlagsLoad) { diff --git a/tracker/tracker/src/main/modules/webAnimations.ts b/tracker/tracker/src/main/modules/webAnimations.ts new file mode 100644 index 000000000..f7e9b8669 --- /dev/null +++ b/tracker/tracker/src/main/modules/webAnimations.ts @@ -0,0 +1,69 @@ +import type App from '../app/index.js' +import { NodeAnimationResult } from '../app/messages.gen.js' + +/** + * this will only work for custom elements by default (because of ionic) + */ + +export interface Options { + allElements?: boolean +} + +const toIgnore = ["composite", "computedOffset", "easing", "offset"] + +function webAnimations(app: App, options: Options = {}) { + const { allElements = false } = options + let listening = new WeakSet() + let handled = new WeakSet() + function wire(anim, el, nodeId) { + if (handled.has(anim)) return + handled.add(anim) + + anim.addEventListener( + 'finish', + () => { + const lastKF = anim.effect.getKeyframes().at(-1) + const computedStyle = getComputedStyle(el) + const keys = Object.keys(lastKF).filter((p) => !toIgnore.includes(p)) + // @ts-ignore + const finalStyle = {} + keys.forEach((key) => { + finalStyle[key] = computedStyle[key] + }) + app.send(NodeAnimationResult(nodeId, JSON.stringify(finalStyle))) + }, + { once: true }, + ) + } + + function scanElement(el, nodeId) { + el.getAnimations({ subtree: false }).forEach((anim) => wire(anim, el, nodeId)) + } + + app.nodes.attachNodeCallback((node) => { + if ((allElements || node.nodeName.includes('-')) && 'getAnimations' in node) { + const animations = (node as Element).getAnimations({ subtree: false }) + const id = app.nodes.getID(node) + if (animations.length > 0 && !listening.has(node) && id) { + listening.add(node) + scanElement(node, id) + node.addEventListener('animationstart', () => scanElement(node, id)) + } + } + }) + + const origAnimate = Element.prototype.animate + Element.prototype.animate = function (...args) { + const anim = origAnimate.apply(this, args) + wire(anim, this) + return anim + } + + app.attachStopCallback(() => { + Element.prototype.animate = origAnimate // Restore original animate method + listening = new WeakSet() + handled = new WeakSet() + }) +} + +export default webAnimations diff --git a/tracker/tracker/src/webworker/MessageEncoder.gen.ts b/tracker/tracker/src/webworker/MessageEncoder.gen.ts index 95a78da21..e00e0cc15 100644 --- a/tracker/tracker/src/webworker/MessageEncoder.gen.ts +++ b/tracker/tracker/src/webworker/MessageEncoder.gen.ts @@ -118,6 +118,10 @@ export default class MessageEncoder extends PrimitiveEncoder { return this.uint(msg[1]) && this.uint(msg[2]) && this.uint(msg[3]) break + case Messages.Type.NodeAnimationResult: + return this.uint(msg[1]) && this.string(msg[2]) + break + case Messages.Type.CSSInsertRule: return this.uint(msg[1]) && this.string(msg[2]) && this.uint(msg[3]) break