Dev aleksk (#795)
*feat(tracker;backend;frontend/player): focus in elem *feat(tracker;frontend/player): FontFace load
This commit is contained in:
parent
d8774122b7
commit
822ca53980
28 changed files with 3070 additions and 2713 deletions
|
|
@ -10,5 +10,5 @@ func IsIOSType(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 || 37 == id || 38 == id || 49 == id || 54 == id || 55 == id || 59 == id || 60 == id || 61 == id || 67 == id || 69 == id || 70 == id || 71 == id || 72 == id || 73 == id || 74 == id || 75 == id || 76 == id || 77 == id || 90 == id || 93 == id || 96 == id || 100 == id || 102 == id || 103 == id || 105 == 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 || 37 == id || 38 == id || 49 == id || 54 == id || 55 == id || 57 == id || 58 == id || 59 == id || 60 == id || 61 == id || 67 == id || 69 == id || 70 == id || 71 == id || 72 == id || 73 == id || 74 == id || 75 == id || 76 == id || 77 == id || 90 == id || 93 == id || 96 == id || 100 == id || 102 == id || 103 == id || 105 == id
|
||||
}
|
||||
|
|
@ -4,7 +4,6 @@ package messages
|
|||
import "encoding/binary"
|
||||
|
||||
const (
|
||||
|
||||
MsgBatchMeta = 80
|
||||
|
||||
MsgBatchMetadata = 81
|
||||
|
|
@ -119,6 +118,10 @@ const (
|
|||
|
||||
MsgPerformanceTrackAggr = 56
|
||||
|
||||
MsgLoadFontFace = 57
|
||||
|
||||
MsgSetNodeFocus = 58
|
||||
|
||||
MsgLongTask = 59
|
||||
|
||||
MsgSetNodeAttributeURLBased = 60
|
||||
|
|
@ -198,10 +201,8 @@ const (
|
|||
MsgIOSPerformanceAggregated = 110
|
||||
|
||||
MsgIOSIssueEvent = 111
|
||||
|
||||
)
|
||||
|
||||
|
||||
type BatchMeta struct {
|
||||
message
|
||||
PageNo uint64
|
||||
|
|
@ -544,7 +545,6 @@ func (msg *SetViewportScroll) TypeID() int {
|
|||
|
||||
type CreateDocument struct {
|
||||
message
|
||||
|
||||
}
|
||||
|
||||
func (msg *CreateDocument) Encode() []byte {
|
||||
|
|
@ -2352,6 +2352,76 @@ func (msg *PerformanceTrackAggr) TypeID() int {
|
|||
return 56
|
||||
}
|
||||
|
||||
type LoadFontFace struct {
|
||||
message
|
||||
ParentID uint64
|
||||
Family string
|
||||
Source string
|
||||
Descriptors string
|
||||
}
|
||||
|
||||
func (msg *LoadFontFace) Encode() []byte {
|
||||
buf := make([]byte, 41+len(msg.Family)+len(msg.Source)+len(msg.Descriptors))
|
||||
buf[0] = 57
|
||||
p := 1
|
||||
p = WriteUint(msg.ParentID, buf, p)
|
||||
p = WriteString(msg.Family, buf, p)
|
||||
p = WriteString(msg.Source, buf, p)
|
||||
p = WriteString(msg.Descriptors, buf, p)
|
||||
return buf[:p]
|
||||
}
|
||||
|
||||
func (msg *LoadFontFace) EncodeWithIndex() []byte {
|
||||
encoded := msg.Encode()
|
||||
if IsIOSType(msg.TypeID()) {
|
||||
return encoded
|
||||
}
|
||||
data := make([]byte, len(encoded)+8)
|
||||
copy(data[8:], encoded[:])
|
||||
binary.LittleEndian.PutUint64(data[0:], msg.Meta().Index)
|
||||
return data
|
||||
}
|
||||
|
||||
func (msg *LoadFontFace) Decode() Message {
|
||||
return msg
|
||||
}
|
||||
|
||||
func (msg *LoadFontFace) TypeID() int {
|
||||
return 57
|
||||
}
|
||||
|
||||
type SetNodeFocus struct {
|
||||
message
|
||||
ID int64
|
||||
}
|
||||
|
||||
func (msg *SetNodeFocus) Encode() []byte {
|
||||
buf := make([]byte, 11)
|
||||
buf[0] = 58
|
||||
p := 1
|
||||
p = WriteInt(msg.ID, buf, p)
|
||||
return buf[:p]
|
||||
}
|
||||
|
||||
func (msg *SetNodeFocus) EncodeWithIndex() []byte {
|
||||
encoded := msg.Encode()
|
||||
if IsIOSType(msg.TypeID()) {
|
||||
return encoded
|
||||
}
|
||||
data := make([]byte, len(encoded)+8)
|
||||
copy(data[8:], encoded[:])
|
||||
binary.LittleEndian.PutUint64(data[0:], msg.Meta().Index)
|
||||
return data
|
||||
}
|
||||
|
||||
func (msg *SetNodeFocus) Decode() Message {
|
||||
return msg
|
||||
}
|
||||
|
||||
func (msg *SetNodeFocus) TypeID() int {
|
||||
return 58
|
||||
}
|
||||
|
||||
type LongTask struct {
|
||||
message
|
||||
Timestamp uint64
|
||||
|
|
@ -3869,4 +3939,3 @@ func (msg *IOSIssueEvent) Decode() Message {
|
|||
func (msg *IOSIssueEvent) TypeID() int {
|
||||
return 111
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import (
|
|||
"io"
|
||||
)
|
||||
|
||||
|
||||
func DecodeBatchMeta(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &BatchMeta{}
|
||||
|
|
@ -22,7 +21,6 @@ func DecodeBatchMeta(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeBatchMetadata(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &BatchMetadata{}
|
||||
|
|
@ -44,7 +42,6 @@ func DecodeBatchMetadata(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodePartitionedMessage(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &PartitionedMessage{}
|
||||
|
|
@ -57,7 +54,6 @@ func DecodePartitionedMessage(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeTimestamp(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &Timestamp{}
|
||||
|
|
@ -67,7 +63,6 @@ func DecodeTimestamp(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeSessionStart(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &SessionStart{}
|
||||
|
|
@ -122,7 +117,6 @@ func DecodeSessionStart(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeSessionEndDeprecated(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &SessionEndDeprecated{}
|
||||
|
|
@ -132,7 +126,6 @@ func DecodeSessionEndDeprecated(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeSetPageLocation(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &SetPageLocation{}
|
||||
|
|
@ -148,7 +141,6 @@ func DecodeSetPageLocation(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeSetViewportSize(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &SetViewportSize{}
|
||||
|
|
@ -161,7 +153,6 @@ func DecodeSetViewportSize(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeSetViewportScroll(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &SetViewportScroll{}
|
||||
|
|
@ -174,7 +165,6 @@ func DecodeSetViewportScroll(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeCreateDocument(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &CreateDocument{}
|
||||
|
|
@ -182,7 +172,6 @@ func DecodeCreateDocument(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeCreateElementNode(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &CreateElementNode{}
|
||||
|
|
@ -204,7 +193,6 @@ func DecodeCreateElementNode(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeCreateTextNode(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &CreateTextNode{}
|
||||
|
|
@ -220,7 +208,6 @@ func DecodeCreateTextNode(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeMoveNode(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &MoveNode{}
|
||||
|
|
@ -236,7 +223,6 @@ func DecodeMoveNode(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeRemoveNode(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &RemoveNode{}
|
||||
|
|
@ -246,7 +232,6 @@ func DecodeRemoveNode(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeSetNodeAttribute(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &SetNodeAttribute{}
|
||||
|
|
@ -262,7 +247,6 @@ func DecodeSetNodeAttribute(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeRemoveNodeAttribute(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &RemoveNodeAttribute{}
|
||||
|
|
@ -275,7 +259,6 @@ func DecodeRemoveNodeAttribute(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeSetNodeData(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &SetNodeData{}
|
||||
|
|
@ -288,7 +271,6 @@ func DecodeSetNodeData(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeSetCSSData(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &SetCSSData{}
|
||||
|
|
@ -301,7 +283,6 @@ func DecodeSetCSSData(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeSetNodeScroll(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &SetNodeScroll{}
|
||||
|
|
@ -317,7 +298,6 @@ func DecodeSetNodeScroll(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeSetInputTarget(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &SetInputTarget{}
|
||||
|
|
@ -330,7 +310,6 @@ func DecodeSetInputTarget(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeSetInputValue(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &SetInputValue{}
|
||||
|
|
@ -346,7 +325,6 @@ func DecodeSetInputValue(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeSetInputChecked(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &SetInputChecked{}
|
||||
|
|
@ -359,7 +337,6 @@ func DecodeSetInputChecked(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeMouseMove(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &MouseMove{}
|
||||
|
|
@ -372,7 +349,6 @@ func DecodeMouseMove(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeConsoleLog(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &ConsoleLog{}
|
||||
|
|
@ -385,7 +361,6 @@ func DecodeConsoleLog(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodePageLoadTiming(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &PageLoadTiming{}
|
||||
|
|
@ -419,7 +394,6 @@ func DecodePageLoadTiming(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodePageRenderTiming(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &PageRenderTiming{}
|
||||
|
|
@ -435,7 +409,6 @@ func DecodePageRenderTiming(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeJSExceptionDeprecated(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &JSExceptionDeprecated{}
|
||||
|
|
@ -451,7 +424,6 @@ func DecodeJSExceptionDeprecated(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeIntegrationEvent(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &IntegrationEvent{}
|
||||
|
|
@ -473,7 +445,6 @@ func DecodeIntegrationEvent(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeRawCustomEvent(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &RawCustomEvent{}
|
||||
|
|
@ -486,7 +457,6 @@ func DecodeRawCustomEvent(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeUserID(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &UserID{}
|
||||
|
|
@ -496,7 +466,6 @@ func DecodeUserID(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeUserAnonymousID(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &UserAnonymousID{}
|
||||
|
|
@ -506,7 +475,6 @@ func DecodeUserAnonymousID(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeMetadata(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &Metadata{}
|
||||
|
|
@ -519,7 +487,6 @@ func DecodeMetadata(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodePageEvent(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &PageEvent{}
|
||||
|
|
@ -577,7 +544,6 @@ func DecodePageEvent(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeInputEvent(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &InputEvent{}
|
||||
|
|
@ -599,7 +565,6 @@ func DecodeInputEvent(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeClickEvent(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &ClickEvent{}
|
||||
|
|
@ -621,7 +586,6 @@ func DecodeClickEvent(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeResourceEvent(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &ResourceEvent{}
|
||||
|
|
@ -664,7 +628,6 @@ func DecodeResourceEvent(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeCustomEvent(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &CustomEvent{}
|
||||
|
|
@ -683,7 +646,6 @@ func DecodeCustomEvent(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeCSSInsertRule(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &CSSInsertRule{}
|
||||
|
|
@ -699,7 +661,6 @@ func DecodeCSSInsertRule(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeCSSDeleteRule(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &CSSDeleteRule{}
|
||||
|
|
@ -712,7 +673,6 @@ func DecodeCSSDeleteRule(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeFetch(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &Fetch{}
|
||||
|
|
@ -740,7 +700,6 @@ func DecodeFetch(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeProfiler(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &Profiler{}
|
||||
|
|
@ -759,7 +718,6 @@ func DecodeProfiler(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeOTable(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &OTable{}
|
||||
|
|
@ -772,7 +730,6 @@ func DecodeOTable(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeStateAction(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &StateAction{}
|
||||
|
|
@ -782,7 +739,6 @@ func DecodeStateAction(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeStateActionEvent(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &StateActionEvent{}
|
||||
|
|
@ -798,7 +754,6 @@ func DecodeStateActionEvent(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeRedux(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &Redux{}
|
||||
|
|
@ -814,7 +769,6 @@ func DecodeRedux(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeVuex(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &Vuex{}
|
||||
|
|
@ -827,7 +781,6 @@ func DecodeVuex(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeMobX(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &MobX{}
|
||||
|
|
@ -840,7 +793,6 @@ func DecodeMobX(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeNgRx(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &NgRx{}
|
||||
|
|
@ -856,7 +808,6 @@ func DecodeNgRx(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeGraphQL(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &GraphQL{}
|
||||
|
|
@ -875,7 +826,6 @@ func DecodeGraphQL(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodePerformanceTrack(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &PerformanceTrack{}
|
||||
|
|
@ -894,7 +844,6 @@ func DecodePerformanceTrack(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeGraphQLEvent(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &GraphQLEvent{}
|
||||
|
|
@ -919,7 +868,6 @@ func DecodeGraphQLEvent(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeFetchEvent(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &FetchEvent{}
|
||||
|
|
@ -950,7 +898,6 @@ func DecodeFetchEvent(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeDOMDrop(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &DOMDrop{}
|
||||
|
|
@ -960,7 +907,6 @@ func DecodeDOMDrop(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeResourceTiming(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &ResourceTiming{}
|
||||
|
|
@ -991,7 +937,6 @@ func DecodeResourceTiming(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeConnectionInformation(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &ConnectionInformation{}
|
||||
|
|
@ -1004,7 +949,6 @@ func DecodeConnectionInformation(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeSetPageVisibility(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &SetPageVisibility{}
|
||||
|
|
@ -1014,7 +958,6 @@ func DecodeSetPageVisibility(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodePerformanceTrackAggr(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &PerformanceTrackAggr{}
|
||||
|
|
@ -1063,6 +1006,32 @@ func DecodePerformanceTrackAggr(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
func DecodeLoadFontFace(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &LoadFontFace{}
|
||||
if msg.ParentID, err = ReadUint(reader); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if msg.Family, err = ReadString(reader); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if msg.Source, err = ReadString(reader); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if msg.Descriptors, err = ReadString(reader); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return msg, err
|
||||
}
|
||||
|
||||
func DecodeSetNodeFocus(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &SetNodeFocus{}
|
||||
if msg.ID, err = ReadInt(reader); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return msg, err
|
||||
}
|
||||
|
||||
func DecodeLongTask(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
|
|
@ -1091,7 +1060,6 @@ func DecodeLongTask(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeSetNodeAttributeURLBased(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &SetNodeAttributeURLBased{}
|
||||
|
|
@ -1110,7 +1078,6 @@ func DecodeSetNodeAttributeURLBased(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeSetCSSDataURLBased(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &SetCSSDataURLBased{}
|
||||
|
|
@ -1126,7 +1093,6 @@ func DecodeSetCSSDataURLBased(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeIssueEvent(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &IssueEvent{}
|
||||
|
|
@ -1151,7 +1117,6 @@ func DecodeIssueEvent(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeTechnicalInfo(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &TechnicalInfo{}
|
||||
|
|
@ -1164,7 +1129,6 @@ func DecodeTechnicalInfo(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeCustomIssue(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &CustomIssue{}
|
||||
|
|
@ -1177,7 +1141,6 @@ func DecodeCustomIssue(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeAssetCache(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &AssetCache{}
|
||||
|
|
@ -1187,7 +1150,6 @@ func DecodeAssetCache(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeCSSInsertRuleURLBased(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &CSSInsertRuleURLBased{}
|
||||
|
|
@ -1206,7 +1168,6 @@ func DecodeCSSInsertRuleURLBased(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeMouseClick(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &MouseClick{}
|
||||
|
|
@ -1225,7 +1186,6 @@ func DecodeMouseClick(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeCreateIFrameDocument(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &CreateIFrameDocument{}
|
||||
|
|
@ -1238,7 +1198,6 @@ func DecodeCreateIFrameDocument(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeAdoptedSSReplaceURLBased(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &AdoptedSSReplaceURLBased{}
|
||||
|
|
@ -1254,7 +1213,6 @@ func DecodeAdoptedSSReplaceURLBased(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeAdoptedSSReplace(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &AdoptedSSReplace{}
|
||||
|
|
@ -1267,7 +1225,6 @@ func DecodeAdoptedSSReplace(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeAdoptedSSInsertRuleURLBased(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &AdoptedSSInsertRuleURLBased{}
|
||||
|
|
@ -1286,7 +1243,6 @@ func DecodeAdoptedSSInsertRuleURLBased(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeAdoptedSSInsertRule(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &AdoptedSSInsertRule{}
|
||||
|
|
@ -1302,7 +1258,6 @@ func DecodeAdoptedSSInsertRule(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeAdoptedSSDeleteRule(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &AdoptedSSDeleteRule{}
|
||||
|
|
@ -1315,7 +1270,6 @@ func DecodeAdoptedSSDeleteRule(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeAdoptedSSAddOwner(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &AdoptedSSAddOwner{}
|
||||
|
|
@ -1328,7 +1282,6 @@ func DecodeAdoptedSSAddOwner(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeAdoptedSSRemoveOwner(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &AdoptedSSRemoveOwner{}
|
||||
|
|
@ -1341,7 +1294,6 @@ func DecodeAdoptedSSRemoveOwner(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeZustand(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &Zustand{}
|
||||
|
|
@ -1354,7 +1306,6 @@ func DecodeZustand(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeJSException(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &JSException{}
|
||||
|
|
@ -1373,7 +1324,6 @@ func DecodeJSException(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeSessionEnd(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &SessionEnd{}
|
||||
|
|
@ -1386,7 +1336,6 @@ func DecodeSessionEnd(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeSessionSearch(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &SessionSearch{}
|
||||
|
|
@ -1399,7 +1348,6 @@ func DecodeSessionSearch(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeIOSBatchMeta(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &IOSBatchMeta{}
|
||||
|
|
@ -1415,7 +1363,6 @@ func DecodeIOSBatchMeta(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeIOSSessionStart(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &IOSSessionStart{}
|
||||
|
|
@ -1452,7 +1399,6 @@ func DecodeIOSSessionStart(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeIOSSessionEnd(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &IOSSessionEnd{}
|
||||
|
|
@ -1462,7 +1408,6 @@ func DecodeIOSSessionEnd(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeIOSMetadata(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &IOSMetadata{}
|
||||
|
|
@ -1481,7 +1426,6 @@ func DecodeIOSMetadata(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeIOSCustomEvent(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &IOSCustomEvent{}
|
||||
|
|
@ -1500,7 +1444,6 @@ func DecodeIOSCustomEvent(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeIOSUserID(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &IOSUserID{}
|
||||
|
|
@ -1516,7 +1459,6 @@ func DecodeIOSUserID(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeIOSUserAnonymousID(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &IOSUserAnonymousID{}
|
||||
|
|
@ -1532,7 +1474,6 @@ func DecodeIOSUserAnonymousID(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeIOSScreenChanges(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &IOSScreenChanges{}
|
||||
|
|
@ -1557,7 +1498,6 @@ func DecodeIOSScreenChanges(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeIOSCrash(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &IOSCrash{}
|
||||
|
|
@ -1579,7 +1519,6 @@ func DecodeIOSCrash(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeIOSScreenEnter(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &IOSScreenEnter{}
|
||||
|
|
@ -1598,7 +1537,6 @@ func DecodeIOSScreenEnter(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeIOSScreenLeave(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &IOSScreenLeave{}
|
||||
|
|
@ -1617,7 +1555,6 @@ func DecodeIOSScreenLeave(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeIOSClickEvent(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &IOSClickEvent{}
|
||||
|
|
@ -1639,7 +1576,6 @@ func DecodeIOSClickEvent(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeIOSInputEvent(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &IOSInputEvent{}
|
||||
|
|
@ -1661,7 +1597,6 @@ func DecodeIOSInputEvent(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeIOSPerformanceEvent(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &IOSPerformanceEvent{}
|
||||
|
|
@ -1680,7 +1615,6 @@ func DecodeIOSPerformanceEvent(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeIOSLog(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &IOSLog{}
|
||||
|
|
@ -1699,7 +1633,6 @@ func DecodeIOSLog(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeIOSInternalError(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &IOSInternalError{}
|
||||
|
|
@ -1715,7 +1648,6 @@ func DecodeIOSInternalError(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeIOSNetworkCall(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &IOSNetworkCall{}
|
||||
|
|
@ -1749,7 +1681,6 @@ func DecodeIOSNetworkCall(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeIOSPerformanceAggregated(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &IOSPerformanceAggregated{}
|
||||
|
|
@ -1798,7 +1729,6 @@ func DecodeIOSPerformanceAggregated(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
func DecodeIOSIssueEvent(reader io.Reader) (Message, error) {
|
||||
var err error = nil
|
||||
msg := &IOSIssueEvent{}
|
||||
|
|
@ -1820,8 +1750,6 @@ func DecodeIOSIssueEvent(reader io.Reader) (Message, error) {
|
|||
return msg, err
|
||||
}
|
||||
|
||||
|
||||
|
||||
func ReadMessage(t uint64, reader io.Reader) (Message, error) {
|
||||
switch t {
|
||||
|
||||
|
|
@ -1996,6 +1924,12 @@ func ReadMessage(t uint64, reader io.Reader) (Message, error) {
|
|||
case 56:
|
||||
return DecodePerformanceTrackAggr(reader)
|
||||
|
||||
case 57:
|
||||
return DecodeLoadFontFace(reader)
|
||||
|
||||
case 58:
|
||||
return DecodeSetNodeFocus(reader)
|
||||
|
||||
case 59:
|
||||
return DecodeLongTask(reader)
|
||||
|
||||
|
|
|
|||
|
|
@ -66,12 +66,18 @@ func ResolveCSS(baseURL string, css string) string {
|
|||
css = rewriteLinks(css, func(rawurl string) string {
|
||||
return ResolveURL(baseURL, rawurl)
|
||||
})
|
||||
return strings.Replace(css, ":hover", ".-openreplay-hover", -1)
|
||||
return rewritePseudoclasses(css)
|
||||
}
|
||||
|
||||
func (r *Rewriter) RewriteCSS(sessionID uint64, baseurl string, css string) string {
|
||||
css = rewriteLinks(css, func(rawurl string) string {
|
||||
return r.RewriteURL(sessionID, baseurl, rawurl)
|
||||
})
|
||||
return strings.Replace(css, ":hover", ".-openreplay-hover", -1)
|
||||
return rewritePseudoclasses(css)
|
||||
}
|
||||
|
||||
func rewritePseudoclasses(css string) string {
|
||||
css = strings.Replace(css, ":hover", ".-openreplay-hover", -1)
|
||||
css = strings.Replace(css, ":focus", ".-openreplay-focus", -1)
|
||||
return css
|
||||
}
|
||||
|
|
|
|||
|
|
@ -568,6 +568,23 @@ class PerformanceTrackAggr(Message):
|
|||
self.max_used_js_heap_size = max_used_js_heap_size
|
||||
|
||||
|
||||
class LoadFontFace(Message):
|
||||
__id__ = 57
|
||||
|
||||
def __init__(self, parent_id, family, source, descriptors):
|
||||
self.parent_id = parent_id
|
||||
self.family = family
|
||||
self.source = source
|
||||
self.descriptors = descriptors
|
||||
|
||||
|
||||
class SetNodeFocus(Message):
|
||||
__id__ = 58
|
||||
|
||||
def __init__(self, id):
|
||||
self.id = id
|
||||
|
||||
|
||||
class LongTask(Message):
|
||||
__id__ = 59
|
||||
|
||||
|
|
|
|||
|
|
@ -524,6 +524,19 @@ class MessageCodec(Codec):
|
|||
max_used_js_heap_size=self.read_uint(reader)
|
||||
)
|
||||
|
||||
if message_id == 57:
|
||||
return LoadFontFace(
|
||||
parent_id=self.read_uint(reader),
|
||||
family=self.read_string(reader),
|
||||
source=self.read_string(reader),
|
||||
descriptors=self.read_string(reader)
|
||||
)
|
||||
|
||||
if message_id == 58:
|
||||
return SetNodeFocus(
|
||||
id=self.read_int(reader)
|
||||
)
|
||||
|
||||
if message_id == 59:
|
||||
return LongTask(
|
||||
timestamp=self.read_uint(reader),
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import type { Message, SetNodeScroll, CreateElementNode } from '../../messages';
|
|||
|
||||
import ListWalker from '../ListWalker';
|
||||
import StylesManager, { rewriteNodeStyleSheet } from './StylesManager';
|
||||
import FocusManager from './FocusManager';
|
||||
import {
|
||||
VElement,
|
||||
VText,
|
||||
|
|
@ -35,9 +36,9 @@ const ATTR_NAME_REGEXP = /([^\t\n\f \/>"'=]+)/; // regexp costs ~
|
|||
|
||||
|
||||
export default class DOMManager extends ListWalker<Message> {
|
||||
private vTexts: Map<number, VText> = new Map() // map vs object here?
|
||||
private vElements: Map<number, VElement> = new Map()
|
||||
private vRoots: Map<number, VShadowRoot | VDocument> = new Map()
|
||||
private readonly vTexts: Map<number, VText> = new Map() // map vs object here?
|
||||
private readonly vElements: Map<number, VElement> = new Map()
|
||||
private readonly vRoots: Map<number, VShadowRoot | VDocument> = new Map()
|
||||
private activeIframeRoots: Map<number, number> = new Map()
|
||||
private styleSheets: Map<number, CSSStyleSheet> = new Map()
|
||||
private ppStyleSheets: Map<number, PostponedStyleSheet> = new Map()
|
||||
|
|
@ -46,6 +47,7 @@ export default class DOMManager extends ListWalker<Message> {
|
|||
private upperBodyId: number = -1;
|
||||
private nodeScrollManagers: Map<number, ListWalker<SetNodeScroll>> = new Map()
|
||||
private stylesManager: StylesManager
|
||||
private focusManager: FocusManager = new FocusManager(this.vElements)
|
||||
|
||||
|
||||
constructor(
|
||||
|
|
@ -67,6 +69,10 @@ export default class DOMManager extends ListWalker<Message> {
|
|||
scrollManager.append(m)
|
||||
return
|
||||
}
|
||||
if (m.tp === "set_node_focus") {
|
||||
this.focusManager.append(m)
|
||||
return
|
||||
}
|
||||
if (m.tp === "create_element_node") {
|
||||
if(m.tag === "BODY" && this.upperBodyId === -1) {
|
||||
this.upperBodyId = m.id
|
||||
|
|
@ -126,7 +132,7 @@ export default class DOMManager extends ListWalker<Message> {
|
|||
parent.insertChildAt(child, index)
|
||||
}
|
||||
|
||||
private applyMessage = (msg: Message): void => {
|
||||
private applyMessage = (msg: Message): Promise<any> | undefined => {
|
||||
let node: Node | undefined
|
||||
let vn: VNode | undefined
|
||||
let doc: Document | null
|
||||
|
|
@ -145,12 +151,15 @@ export default class DOMManager extends ListWalker<Message> {
|
|||
fRoot.innerText = '';
|
||||
|
||||
vn = new VElement(fRoot)
|
||||
this.vElements = new Map([[0, vn]])
|
||||
this.vElements.clear()
|
||||
this.vElements.set(0, vn)
|
||||
const vDoc = new VDocument(doc)
|
||||
vDoc.insertChildAt(vn, 0)
|
||||
this.vRoots = new Map([[0, vDoc]]) // watchout: id==0 for both Document and documentElement
|
||||
this.vRoots.clear()
|
||||
this.vRoots.set(0, vDoc) // watchout: id==0 for both Document and documentElement
|
||||
// this is done for the AdoptedCSS logic
|
||||
// todo: start from 0 (sync logic with tracker)
|
||||
this.vTexts.clear()
|
||||
this.stylesManager.reset()
|
||||
this.activeIframeRoots.clear()
|
||||
return
|
||||
|
|
@ -371,20 +380,37 @@ export default class DOMManager extends ListWalker<Message> {
|
|||
//@ts-ignore
|
||||
vn.node.adoptedStyleSheets = [...vn.node.adoptedStyleSheets].filter(s => s !== styleSheet)
|
||||
return
|
||||
case "load_font_face":
|
||||
vn = this.vRoots.get(msg.parentID)
|
||||
if (!vn) { logger.error("Node not found", msg); return }
|
||||
if (vn instanceof VShadowRoot) { logger.error(`Node ${vn} expected to be a Document`, msg); return }
|
||||
let descr: Object
|
||||
try {
|
||||
descr = JSON.parse(msg.descriptors)
|
||||
descr = typeof descr === 'object' ? descr : undefined
|
||||
} catch {
|
||||
logger.warn("Can't parse font-face descriptors: ", msg)
|
||||
}
|
||||
const ff = new FontFace(msg.family, msg.source, descr)
|
||||
vn.node.fonts.add(ff)
|
||||
return ff.load()
|
||||
}
|
||||
}
|
||||
|
||||
moveReady(t: number): Promise<void> {
|
||||
async moveReady(t: number): Promise<void> {
|
||||
// MBTODO (back jump optimisation):
|
||||
// - store intemediate virtual dom state
|
||||
// - cancel previous moveReady tasks (is it possible?) if new timestamp is less
|
||||
this.moveApply(t, this.applyMessage) // This function autoresets pointer if necessary (better name?)
|
||||
// This function autoresets pointer if necessary (better name?)
|
||||
|
||||
await this.moveWait(t, this.applyMessage)
|
||||
this.vRoots.forEach(rt => rt.applyChanges()) // MBTODO (optimisation): affected set
|
||||
|
||||
// Thinkabout (read): css preload
|
||||
// What if we go back before it is ready? We'll have two handlres?
|
||||
return this.stylesManager.moveReady(t).then(() => {
|
||||
// Apply focus
|
||||
this.focusManager.move(t)
|
||||
// Apply all scrolls after the styles got applied
|
||||
this.nodeScrollManagers.forEach(manager => {
|
||||
const msg = manager.moveGetLast(t)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
import logger from 'App/logger';
|
||||
import type { SetNodeFocus } from '../../messages';
|
||||
import type { VElement } from './VirtualDOM';
|
||||
import ListWalker from '../ListWalker';
|
||||
|
||||
|
||||
const FOCUS_CLASS = "-openreplay-focus"
|
||||
|
||||
export default class FocusManager extends ListWalker<SetNodeFocus> {
|
||||
constructor(private readonly vElements: Map<number, VElement>) {super()}
|
||||
private focused: Element | null = null
|
||||
move(t: number) {
|
||||
const msg = this.moveGetLast(t)
|
||||
if (!msg) {return}
|
||||
this.focused?.classList.remove(FOCUS_CLASS)
|
||||
if (msg.id === -1) {
|
||||
this.focused = null
|
||||
return
|
||||
}
|
||||
const vn = this.vElements.get(msg.id)
|
||||
if (!vn) { logger.error("Node not found", msg); return }
|
||||
this.focused = vn.node
|
||||
this.focused.classList.add(FOCUS_CLASS)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@ export default class ListWalker<T extends Timed> {
|
|||
console.error("Trying to append message with the less time then the list tail: ", m)
|
||||
return
|
||||
}
|
||||
this._list.push(m);
|
||||
this.list.push(m);
|
||||
}
|
||||
|
||||
reset(): void {
|
||||
|
|
@ -18,53 +18,53 @@ export default class ListWalker<T extends Timed> {
|
|||
|
||||
sort(comparator: (a: T, b: T) => number): void {
|
||||
// @ts-ignore
|
||||
this._list.sort((m1,m2) => comparator(m1,m2) || (m1._index - m2._index) ); // indexes for sort stability (TODO: fix types???)
|
||||
this.list.sort((m1,m2) => comparator(m1,m2) || (m1._index - m2._index) ); // indexes for sort stability (TODO: fix types???)
|
||||
}
|
||||
|
||||
forEach(f: (item: T) => void):void {
|
||||
this._list.forEach(f);
|
||||
this.list.forEach(f);
|
||||
}
|
||||
|
||||
get last(): T | null {
|
||||
if (this._list.length === 0) {
|
||||
if (this.list.length === 0) {
|
||||
return null;
|
||||
}
|
||||
return this._list[ this._list.length - 1 ];
|
||||
return this.list[ this.list.length - 1 ];
|
||||
}
|
||||
|
||||
get current(): T | null {
|
||||
if (this.p === 0) {
|
||||
return null;
|
||||
}
|
||||
return this._list[ this.p - 1 ];
|
||||
return this.list[ this.p - 1 ];
|
||||
}
|
||||
|
||||
get timeNow(): number {
|
||||
if (this.p === 0) {
|
||||
return 0;
|
||||
}
|
||||
return this._list[ this.p - 1 ].time;
|
||||
return this.list[ this.p - 1 ].time;
|
||||
}
|
||||
|
||||
get length(): number {
|
||||
return this._list.length;
|
||||
return this.list.length;
|
||||
}
|
||||
|
||||
get maxTime(): number {
|
||||
if (this.length === 0) {
|
||||
return 0;
|
||||
}
|
||||
return this._list[ this.length - 1 ].time;
|
||||
return this.list[ this.length - 1 ].time;
|
||||
}
|
||||
get minTime(): number {
|
||||
if (this.length === 0) {
|
||||
return 0;
|
||||
}
|
||||
return this._list[ 0 ].time;
|
||||
return this.list[ 0 ].time;
|
||||
}
|
||||
|
||||
get listNow(): Array<T> {
|
||||
return this._list.slice(0, this.p);
|
||||
return this.list.slice(0, this.p);
|
||||
}
|
||||
|
||||
get list(): Array<T> {
|
||||
|
|
@ -93,28 +93,42 @@ export default class ListWalker<T extends Timed> {
|
|||
}
|
||||
|
||||
let changed = false;
|
||||
while (this.p < this.length && this._list[this.p][key] <= val) {
|
||||
while (this.p < this.length && this.list[this.p][key] <= val) {
|
||||
this.p++;
|
||||
changed = true;
|
||||
}
|
||||
while (this.p > 0 && this._list[ this.p - 1 ][key] > val) {
|
||||
while (this.p > 0 && this.list[ this.p - 1 ][key] > val) {
|
||||
this.p--;
|
||||
changed = true;
|
||||
}
|
||||
return changed ? this._list[ this.p - 1 ] : null;
|
||||
return changed ? this.list[ this.p - 1 ] : null;
|
||||
}
|
||||
|
||||
moveApply(t: number, fn: (T) => void, fnBack?: (T) => void): void {
|
||||
moveApply(t: number, fn: (msg: T) => void, fnBack?: (msg: T) => void): void {
|
||||
// Applying only in increment order for now
|
||||
if (t < this.timeNow) {
|
||||
this.reset();
|
||||
}
|
||||
|
||||
while (!!this._list[this.p] && this._list[this.p].time <= t) {
|
||||
fn(this._list[ this.p++ ]);
|
||||
const list = this.list
|
||||
while (list[this.p] && list[this.p].time <= t) {
|
||||
fn(list[ this.p++ ]);
|
||||
}
|
||||
while (fnBack && this.p > 0 && this._list[ this.p - 1 ].time > t) {
|
||||
fnBack(this._list[ --this.p ]);
|
||||
while (fnBack && this.p > 0 && list[ this.p - 1 ].time > t) {
|
||||
fnBack(list[ --this.p ]);
|
||||
}
|
||||
}
|
||||
|
||||
async moveWait(t: number, fn: (msg: T) => Promise<any> | undefined): Promise<void> {
|
||||
// Applying only in increment order for now
|
||||
if (t < this.timeNow) {
|
||||
this.reset();
|
||||
}
|
||||
|
||||
const list = this.list
|
||||
while (list[this.p] && list[this.p].time <= t) {
|
||||
const ret = fn(this.list[ this.p++ ]);
|
||||
if (ret) { await ret }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -366,6 +366,28 @@ export default class RawMessageReader extends PrimitiveReader {
|
|||
};
|
||||
}
|
||||
|
||||
case 57: {
|
||||
const parentID = this.readUint(); if (parentID === null) { return resetPointer() }
|
||||
const family = this.readString(); if (family === null) { return resetPointer() }
|
||||
const source = this.readString(); if (source === null) { return resetPointer() }
|
||||
const descriptors = this.readString(); if (descriptors === null) { return resetPointer() }
|
||||
return {
|
||||
tp: "load_font_face",
|
||||
parentID,
|
||||
family,
|
||||
source,
|
||||
descriptors,
|
||||
};
|
||||
}
|
||||
|
||||
case 58: {
|
||||
const id = this.readInt(); if (id === null) { return resetPointer() }
|
||||
return {
|
||||
tp: "set_node_focus",
|
||||
id,
|
||||
};
|
||||
}
|
||||
|
||||
case 59: {
|
||||
const timestamp = this.readUint(); if (timestamp === null) { return resetPointer() }
|
||||
const duration = this.readUint(); if (duration === null) { return resetPointer() }
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@ import type {
|
|||
RawPerformanceTrack,
|
||||
RawConnectionInformation,
|
||||
RawSetPageVisibility,
|
||||
RawLoadFontFace,
|
||||
RawSetNodeFocus,
|
||||
RawLongTask,
|
||||
RawSetNodeAttributeURLBased,
|
||||
RawSetCssDataURLBased,
|
||||
|
|
@ -123,6 +125,10 @@ export type ConnectionInformation = RawConnectionInformation & Timed
|
|||
|
||||
export type SetPageVisibility = RawSetPageVisibility & Timed
|
||||
|
||||
export type LoadFontFace = RawLoadFontFace & Timed
|
||||
|
||||
export type SetNodeFocus = RawSetNodeFocus & Timed
|
||||
|
||||
export type LongTask = RawLongTask & Timed
|
||||
|
||||
export type SetNodeAttributeURLBased = RawSetNodeAttributeURLBased & Timed
|
||||
|
|
|
|||
|
|
@ -207,6 +207,19 @@ export interface RawSetPageVisibility {
|
|||
hidden: boolean,
|
||||
}
|
||||
|
||||
export interface RawLoadFontFace {
|
||||
tp: "load_font_face",
|
||||
parentID: number,
|
||||
family: string,
|
||||
source: string,
|
||||
descriptors: string,
|
||||
}
|
||||
|
||||
export interface RawSetNodeFocus {
|
||||
tp: "set_node_focus",
|
||||
id: number,
|
||||
}
|
||||
|
||||
export interface RawLongTask {
|
||||
tp: "long_task",
|
||||
timestamp: number,
|
||||
|
|
@ -378,4 +391,4 @@ export interface RawIosNetworkCall {
|
|||
}
|
||||
|
||||
|
||||
export type RawMessage = RawTimestamp | RawSetPageLocation | RawSetViewportSize | RawSetViewportScroll | RawCreateDocument | RawCreateElementNode | RawCreateTextNode | RawMoveNode | RawRemoveNode | RawSetNodeAttribute | RawRemoveNodeAttribute | RawSetNodeData | RawSetCssData | RawSetNodeScroll | RawSetInputValue | RawSetInputChecked | RawMouseMove | RawConsoleLog | RawCssInsertRule | RawCssDeleteRule | RawFetch | RawProfiler | RawOTable | RawRedux | RawVuex | RawMobX | RawNgRx | RawGraphQl | RawPerformanceTrack | RawConnectionInformation | RawSetPageVisibility | RawLongTask | RawSetNodeAttributeURLBased | RawSetCssDataURLBased | RawCssInsertRuleURLBased | RawMouseClick | RawCreateIFrameDocument | RawAdoptedSsReplaceURLBased | RawAdoptedSsReplace | RawAdoptedSsInsertRuleURLBased | RawAdoptedSsInsertRule | RawAdoptedSsDeleteRule | RawAdoptedSsAddOwner | RawAdoptedSsRemoveOwner | RawZustand | RawIosSessionStart | RawIosCustomEvent | RawIosScreenChanges | RawIosClickEvent | RawIosPerformanceEvent | RawIosLog | RawIosNetworkCall;
|
||||
export type RawMessage = RawTimestamp | RawSetPageLocation | RawSetViewportSize | RawSetViewportScroll | RawCreateDocument | RawCreateElementNode | RawCreateTextNode | RawMoveNode | RawRemoveNode | RawSetNodeAttribute | RawRemoveNodeAttribute | RawSetNodeData | RawSetCssData | RawSetNodeScroll | RawSetInputValue | RawSetInputChecked | RawMouseMove | RawConsoleLog | RawCssInsertRule | RawCssDeleteRule | RawFetch | RawProfiler | RawOTable | RawRedux | RawVuex | RawMobX | RawNgRx | RawGraphQl | RawPerformanceTrack | RawConnectionInformation | RawSetPageVisibility | RawLoadFontFace | RawSetNodeFocus | RawLongTask | RawSetNodeAttributeURLBased | RawSetCssDataURLBased | RawCssInsertRuleURLBased | RawMouseClick | RawCreateIFrameDocument | RawAdoptedSsReplaceURLBased | RawAdoptedSsReplace | RawAdoptedSsInsertRuleURLBased | RawAdoptedSsInsertRule | RawAdoptedSsDeleteRule | RawAdoptedSsAddOwner | RawAdoptedSsRemoveOwner | RawZustand | RawIosSessionStart | RawIosCustomEvent | RawIosScreenChanges | RawIosClickEvent | RawIosPerformanceEvent | RawIosLog | RawIosNetworkCall;
|
||||
|
|
|
|||
|
|
@ -46,6 +46,8 @@ export const TP_MAP = {
|
|||
53: "resource_timing",
|
||||
54: "connection_information",
|
||||
55: "set_page_visibility",
|
||||
57: "load_font_face",
|
||||
58: "set_node_focus",
|
||||
59: "long_task",
|
||||
60: "set_node_attribute_url_based",
|
||||
61: "set_css_data_url_based",
|
||||
|
|
|
|||
|
|
@ -290,6 +290,19 @@ type TrSetPageVisibility = [
|
|||
hidden: boolean,
|
||||
]
|
||||
|
||||
type TrLoadFontFace = [
|
||||
type: 57,
|
||||
parentID: number,
|
||||
family: string,
|
||||
source: string,
|
||||
descriptors: string,
|
||||
]
|
||||
|
||||
type TrSetNodeFocus = [
|
||||
type: 58,
|
||||
id: number,
|
||||
]
|
||||
|
||||
type TrLongTask = [
|
||||
type: 59,
|
||||
timestamp: number,
|
||||
|
|
@ -398,7 +411,7 @@ type TrJSException = [
|
|||
]
|
||||
|
||||
|
||||
export type TrackerMessage = TrBatchMetadata | TrPartitionedMessage | TrTimestamp | TrSetPageLocation | TrSetViewportSize | TrSetViewportScroll | TrCreateDocument | TrCreateElementNode | TrCreateTextNode | TrMoveNode | TrRemoveNode | TrSetNodeAttribute | TrRemoveNodeAttribute | TrSetNodeData | TrSetNodeScroll | TrSetInputTarget | TrSetInputValue | TrSetInputChecked | TrMouseMove | TrConsoleLog | TrPageLoadTiming | TrPageRenderTiming | TrJSExceptionDeprecated | TrRawCustomEvent | TrUserID | TrUserAnonymousID | TrMetadata | TrCSSInsertRule | TrCSSDeleteRule | TrFetch | TrProfiler | TrOTable | TrStateAction | TrRedux | TrVuex | TrMobX | TrNgRx | TrGraphQL | TrPerformanceTrack | TrResourceTiming | TrConnectionInformation | TrSetPageVisibility | TrLongTask | TrSetNodeAttributeURLBased | TrSetCSSDataURLBased | TrTechnicalInfo | TrCustomIssue | TrCSSInsertRuleURLBased | TrMouseClick | TrCreateIFrameDocument | TrAdoptedSSReplaceURLBased | TrAdoptedSSInsertRuleURLBased | TrAdoptedSSDeleteRule | TrAdoptedSSAddOwner | TrAdoptedSSRemoveOwner | TrZustand | TrJSException
|
||||
export type TrackerMessage = TrBatchMetadata | TrPartitionedMessage | TrTimestamp | TrSetPageLocation | TrSetViewportSize | TrSetViewportScroll | TrCreateDocument | TrCreateElementNode | TrCreateTextNode | TrMoveNode | TrRemoveNode | TrSetNodeAttribute | TrRemoveNodeAttribute | TrSetNodeData | TrSetNodeScroll | TrSetInputTarget | TrSetInputValue | TrSetInputChecked | TrMouseMove | TrConsoleLog | TrPageLoadTiming | TrPageRenderTiming | TrJSExceptionDeprecated | TrRawCustomEvent | TrUserID | TrUserAnonymousID | TrMetadata | TrCSSInsertRule | TrCSSDeleteRule | TrFetch | TrProfiler | TrOTable | TrStateAction | TrRedux | TrVuex | TrMobX | TrNgRx | TrGraphQL | TrPerformanceTrack | TrResourceTiming | TrConnectionInformation | TrSetPageVisibility | TrLoadFontFace | TrSetNodeFocus | TrLongTask | TrSetNodeAttributeURLBased | TrSetCSSDataURLBased | TrTechnicalInfo | TrCustomIssue | TrCSSInsertRuleURLBased | TrMouseClick | TrCreateIFrameDocument | TrAdoptedSSReplaceURLBased | TrAdoptedSSInsertRuleURLBased | TrAdoptedSSDeleteRule | TrAdoptedSSAddOwner | TrAdoptedSSRemoveOwner | TrZustand | TrJSException
|
||||
|
||||
export default function translate(tMsg: TrackerMessage): RawMessage | null {
|
||||
switch(tMsg[0]) {
|
||||
|
|
@ -662,6 +675,23 @@ export default function translate(tMsg: TrackerMessage): RawMessage | null {
|
|||
}
|
||||
}
|
||||
|
||||
case 57: {
|
||||
return {
|
||||
tp: "load_font_face",
|
||||
parentID: tMsg[1],
|
||||
family: tMsg[2],
|
||||
source: tMsg[3],
|
||||
descriptors: tMsg[4],
|
||||
}
|
||||
}
|
||||
|
||||
case 58: {
|
||||
return {
|
||||
tp: "set_node_focus",
|
||||
id: tMsg[1],
|
||||
}
|
||||
}
|
||||
|
||||
case 59: {
|
||||
return {
|
||||
tp: "long_task",
|
||||
|
|
|
|||
|
|
@ -50,6 +50,14 @@ function rewriteCSSLinks(css: string, rewriter: (rawurl: string) => string): str
|
|||
return css
|
||||
}
|
||||
|
||||
export function resolveCSS(baseURL: string, css: string): string {
|
||||
return rewriteCSSLinks(css, rawurl => resolveURL(baseURL, rawurl));
|
||||
function rewritePseudoclasses(css: string): string {
|
||||
return css
|
||||
.replace(/:hover/g, ".-openreplay-hover")
|
||||
.replace(/:focus/g, ".-openreplay-focus")
|
||||
}
|
||||
|
||||
export function resolveCSS(baseURL: string, css: string): string {
|
||||
return rewritePseudoclasses(
|
||||
rewriteCSSLinks(css, rawurl => resolveURL(baseURL, rawurl))
|
||||
);
|
||||
}
|
||||
|
|
@ -4,11 +4,5 @@
|
|||
To generate all necessary files for the project:
|
||||
|
||||
```sh
|
||||
ruby run.rb
|
||||
sh generate.sh
|
||||
```
|
||||
|
||||
In order format generated files run:
|
||||
```sh
|
||||
sh format.sh
|
||||
```
|
||||
(Otherwise there will be changes in stage)
|
||||
|
|
|
|||
|
|
@ -1 +1,2 @@
|
|||
ruby run.rb
|
||||
gofmt -w ../backend/pkg/messages
|
||||
|
|
@ -359,7 +359,19 @@ message 56, 'PerformanceTrackAggr', :tracker => false, :replayer => false do
|
|||
uint 'AvgUsedJSHeapSize'
|
||||
uint 'MaxUsedJSHeapSize'
|
||||
end
|
||||
## 57 58
|
||||
|
||||
# Since 4.1.7 / 1.9.0
|
||||
message 57, 'LoadFontFace' do
|
||||
uint 'ParentID'
|
||||
string 'Family'
|
||||
string 'Source'
|
||||
string 'Descriptors'
|
||||
end
|
||||
# Since 4.1.7 / 1.9.0
|
||||
message 58, 'SetNodeFocus' do
|
||||
int 'ID'
|
||||
end
|
||||
|
||||
#Depricated (since 3.0.?)
|
||||
message 59, 'LongTask' do
|
||||
uint 'Timestamp'
|
||||
|
|
@ -466,6 +478,8 @@ message 78, 'JSException', :replayer => false do
|
|||
string 'Payload'
|
||||
string 'Metadata'
|
||||
end
|
||||
|
||||
|
||||
message 126, 'SessionEnd', :tracker => false, :replayer => false do
|
||||
uint 'Timestamp'
|
||||
string 'EncryptionKey'
|
||||
|
|
|
|||
|
|
@ -44,6 +44,8 @@ export declare const enum Type {
|
|||
ResourceTiming = 53,
|
||||
ConnectionInformation = 54,
|
||||
SetPageVisibility = 55,
|
||||
LoadFontFace = 57,
|
||||
SetNodeFocus = 58,
|
||||
LongTask = 59,
|
||||
SetNodeAttributeURLBased = 60,
|
||||
SetCSSDataURLBased = 61,
|
||||
|
|
@ -348,6 +350,19 @@ export type SetPageVisibility = [
|
|||
/*hidden:*/ boolean,
|
||||
]
|
||||
|
||||
export type LoadFontFace = [
|
||||
/*type:*/ Type.LoadFontFace,
|
||||
/*parentID:*/ number,
|
||||
/*family:*/ string,
|
||||
/*source:*/ string,
|
||||
/*descriptors:*/ string,
|
||||
]
|
||||
|
||||
export type SetNodeFocus = [
|
||||
/*type:*/ Type.SetNodeFocus,
|
||||
/*id:*/ number,
|
||||
]
|
||||
|
||||
export type LongTask = [
|
||||
/*type:*/ Type.LongTask,
|
||||
/*timestamp:*/ number,
|
||||
|
|
@ -456,5 +471,5 @@ export type JSException = [
|
|||
]
|
||||
|
||||
|
||||
type Message = BatchMetadata | PartitionedMessage | Timestamp | SetPageLocation | SetViewportSize | SetViewportScroll | CreateDocument | CreateElementNode | CreateTextNode | MoveNode | RemoveNode | SetNodeAttribute | RemoveNodeAttribute | SetNodeData | SetNodeScroll | SetInputTarget | SetInputValue | SetInputChecked | MouseMove | ConsoleLog | PageLoadTiming | PageRenderTiming | JSExceptionDeprecated | RawCustomEvent | UserID | UserAnonymousID | Metadata | CSSInsertRule | CSSDeleteRule | Fetch | Profiler | OTable | StateAction | Redux | Vuex | MobX | NgRx | GraphQL | PerformanceTrack | ResourceTiming | ConnectionInformation | SetPageVisibility | LongTask | SetNodeAttributeURLBased | SetCSSDataURLBased | TechnicalInfo | CustomIssue | CSSInsertRuleURLBased | MouseClick | CreateIFrameDocument | AdoptedSSReplaceURLBased | AdoptedSSInsertRuleURLBased | AdoptedSSDeleteRule | AdoptedSSAddOwner | AdoptedSSRemoveOwner | Zustand | JSException
|
||||
type Message = BatchMetadata | PartitionedMessage | Timestamp | SetPageLocation | SetViewportSize | SetViewportScroll | CreateDocument | CreateElementNode | CreateTextNode | MoveNode | RemoveNode | SetNodeAttribute | RemoveNodeAttribute | SetNodeData | SetNodeScroll | SetInputTarget | SetInputValue | SetInputChecked | MouseMove | ConsoleLog | PageLoadTiming | PageRenderTiming | JSExceptionDeprecated | RawCustomEvent | UserID | UserAnonymousID | Metadata | CSSInsertRule | CSSDeleteRule | Fetch | Profiler | OTable | StateAction | Redux | Vuex | MobX | NgRx | GraphQL | PerformanceTrack | ResourceTiming | ConnectionInformation | SetPageVisibility | LoadFontFace | SetNodeFocus | LongTask | SetNodeAttributeURLBased | SetCSSDataURLBased | TechnicalInfo | CustomIssue | CSSInsertRuleURLBased | MouseClick | CreateIFrameDocument | AdoptedSSReplaceURLBased | AdoptedSSInsertRuleURLBased | AdoptedSSDeleteRule | AdoptedSSAddOwner | AdoptedSSRemoveOwner | Zustand | JSException
|
||||
export default Message
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ export function isRootNode(node: Node): node is Document | DocumentFragment {
|
|||
|
||||
type TagTypeMap = {
|
||||
HTML: HTMLHtmlElement
|
||||
BODY: HTMLBodyElement
|
||||
IMG: HTMLImageElement
|
||||
INPUT: HTMLInputElement
|
||||
TEXTAREA: HTMLTextAreaElement
|
||||
|
|
|
|||
|
|
@ -480,7 +480,8 @@ export default class App {
|
|||
|
||||
const onStartInfo = { sessionToken: token, userUUID, sessionID }
|
||||
|
||||
this.startCallbacks.forEach((cb) => cb(onStartInfo)) // TODO: start as early as possible (before receiving the token)
|
||||
// TODO: start as early as possible (before receiving the token)
|
||||
this.startCallbacks.forEach((cb) => cb(onStartInfo)) // MBTODO: callbacks after DOM "mounted" (observed)
|
||||
this.observer.observe()
|
||||
this.ticker.start()
|
||||
this.activityState = ActivityState.Active
|
||||
|
|
|
|||
|
|
@ -535,6 +535,30 @@ export function SetPageVisibility(
|
|||
]
|
||||
}
|
||||
|
||||
export function LoadFontFace(
|
||||
parentID: number,
|
||||
family: string,
|
||||
source: string,
|
||||
descriptors: string,
|
||||
): Messages.LoadFontFace {
|
||||
return [
|
||||
Messages.Type.LoadFontFace,
|
||||
parentID,
|
||||
family,
|
||||
source,
|
||||
descriptors,
|
||||
]
|
||||
}
|
||||
|
||||
export function SetNodeFocus(
|
||||
id: number,
|
||||
): Messages.SetNodeFocus {
|
||||
return [
|
||||
Messages.Type.SetNodeFocus,
|
||||
id,
|
||||
]
|
||||
}
|
||||
|
||||
export function LongTask(
|
||||
timestamp: number,
|
||||
duration: number,
|
||||
|
|
|
|||
|
|
@ -129,6 +129,8 @@ export default class TopObserver extends Observer {
|
|||
window.document,
|
||||
() => {
|
||||
this.app.send(CreateDocument())
|
||||
// it has no node_id here
|
||||
this.app.nodes.callNodeCallbacks(document, true)
|
||||
},
|
||||
window.document.documentElement,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ import Performance from './modules/performance.js'
|
|||
import Scroll from './modules/scroll.js'
|
||||
import Viewport from './modules/viewport.js'
|
||||
import CSSRules from './modules/cssrules.js'
|
||||
import Focus from './modules/focus.js'
|
||||
import Fonts from './modules/fonts.js'
|
||||
import ConstructedStyleSheets from './modules/constructedStyleSheets.js'
|
||||
import { IN_BROWSER, deprecationWarn, DOCS_HOST } from './utils.js'
|
||||
|
||||
|
|
@ -123,6 +125,8 @@ export default class API {
|
|||
Timing(app, options)
|
||||
Performance(app, options)
|
||||
Scroll(app)
|
||||
Focus(app)
|
||||
Fonts(app)
|
||||
;(window as any).__OPENREPLAY__ = this
|
||||
|
||||
if (options.autoResetOnWindowOpen) {
|
||||
|
|
|
|||
|
|
@ -31,10 +31,6 @@ export default function (app: App | null) {
|
|||
return
|
||||
}
|
||||
if (!hasAdoptedSS(document)) {
|
||||
app.attachStartCallback(() => {
|
||||
// MBTODO: pre-start sendQueue app
|
||||
app.send(TechnicalInfo('no_adopted_stylesheets', ''))
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
45
tracker/tracker/src/main/modules/focus.ts
Normal file
45
tracker/tracker/src/main/modules/focus.ts
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
import type App from '../app/index.js'
|
||||
import { isNode, hasTag } from '../app/guards.js'
|
||||
import { SetNodeFocus } from '../app/messages.gen.js'
|
||||
|
||||
export default function (app: App): void {
|
||||
function sendSetNodeFocus(n: Node) {
|
||||
const id = app.nodes.getID(n)
|
||||
if (id !== undefined) {
|
||||
app.send(SetNodeFocus(id))
|
||||
}
|
||||
}
|
||||
|
||||
let blurred = false
|
||||
app.nodes.attachNodeCallback((node) => {
|
||||
if (!hasTag(node, 'BODY')) {
|
||||
return
|
||||
}
|
||||
app.nodes.attachNodeListener(node, 'focus', (e: FocusEvent): void => {
|
||||
if (!isNode(e.target)) {
|
||||
return
|
||||
}
|
||||
sendSetNodeFocus(e.target)
|
||||
blurred = false
|
||||
})
|
||||
app.nodes.attachNodeListener(node, 'blur', (e: FocusEvent): void => {
|
||||
if (e.relatedTarget === null) {
|
||||
blurred = true
|
||||
setTimeout(() => {
|
||||
if (blurred) {
|
||||
app.send(SetNodeFocus(-1))
|
||||
}
|
||||
}, 0)
|
||||
}
|
||||
})
|
||||
})
|
||||
app.attachStartCallback(() => {
|
||||
let elem = document.activeElement
|
||||
while (elem && hasTag(elem, 'IFRAME') && elem.contentDocument) {
|
||||
elem = elem.contentDocument.activeElement
|
||||
}
|
||||
if (elem && elem !== elem.ownerDocument.body) {
|
||||
sendSetNodeFocus(elem)
|
||||
}
|
||||
}, true)
|
||||
}
|
||||
66
tracker/tracker/src/main/modules/fonts.ts
Normal file
66
tracker/tracker/src/main/modules/fonts.ts
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
import type App from '../app/index.js'
|
||||
import { isDocument } from '../app/guards.js'
|
||||
import { LoadFontFace } from '../app/messages.gen.js'
|
||||
|
||||
type FFData = [string, string, string]
|
||||
|
||||
export default function (app: App) {
|
||||
if (!window.FontFace) {
|
||||
return
|
||||
}
|
||||
|
||||
const docFonts: Map<Document, FFData[]> = new Map()
|
||||
|
||||
const patchWindow = (wnd: typeof globalThis) => {
|
||||
class FontFaceInterceptor extends wnd.FontFace {
|
||||
constructor(...args: ConstructorParameters<typeof FontFace>) {
|
||||
//maybe do this on load(). In this case check if the document.fonts.load(...) function calls the font's load()
|
||||
if (typeof args[1] === 'string') {
|
||||
let desc = ''
|
||||
if (args[2]) {
|
||||
app.safe(() => {
|
||||
desc = JSON.stringify(args[2])
|
||||
})
|
||||
}
|
||||
|
||||
const ffData: FFData = [args[0], args[1], desc]
|
||||
const ffDataArr = docFonts.get(wnd.document) || []
|
||||
ffDataArr.push(ffData)
|
||||
docFonts.set(wnd.document, ffDataArr)
|
||||
|
||||
const parentID = wnd === window ? 0 : app.nodes.getID(wnd.document)
|
||||
if (parentID === undefined) {
|
||||
return
|
||||
}
|
||||
|
||||
if (app.active()) {
|
||||
app.send(LoadFontFace(parentID, ...ffData))
|
||||
}
|
||||
}
|
||||
super(...args)
|
||||
}
|
||||
}
|
||||
wnd.FontFace = FontFaceInterceptor
|
||||
}
|
||||
app.observer.attachContextCallback(patchWindow)
|
||||
patchWindow(window)
|
||||
|
||||
app.nodes.attachNodeCallback((node) => {
|
||||
if (!isDocument(node)) {
|
||||
return
|
||||
}
|
||||
const ffDataArr = docFonts.get(node)
|
||||
if (!ffDataArr) {
|
||||
return
|
||||
}
|
||||
|
||||
const parentID = node.defaultView === window ? 0 : app.nodes.getID(node)
|
||||
if (parentID === undefined) {
|
||||
return
|
||||
}
|
||||
|
||||
ffDataArr.forEach((ffData) => {
|
||||
app.send(LoadFontFace(parentID, ...ffData))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
@ -178,6 +178,14 @@ export default class MessageEncoder extends PrimitiveEncoder {
|
|||
return this.boolean(msg[1])
|
||||
break
|
||||
|
||||
case Messages.Type.LoadFontFace:
|
||||
return this.uint(msg[1]) && this.string(msg[2]) && this.string(msg[3]) && this.string(msg[4])
|
||||
break
|
||||
|
||||
case Messages.Type.SetNodeFocus:
|
||||
return this.int(msg[1])
|
||||
break
|
||||
|
||||
case Messages.Type.LongTask:
|
||||
return this.uint(msg[1]) && this.uint(msg[2]) && this.uint(msg[3]) && this.uint(msg[4]) && this.string(msg[5]) && this.string(msg[6]) && this.string(msg[7])
|
||||
break
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue