fix(tracker): some events changes...

This commit is contained in:
nick-delirium 2023-02-09 16:38:13 +01:00
parent f5f7f37260
commit 3266f46440
14 changed files with 133 additions and 56 deletions

View file

@ -2,7 +2,7 @@
package messages
func IsReplayerType(id int) bool {
return 1 != id && 3 != id && 17 != id && 23 != id && 24 != id && 25 != id && 26 != id && 27 != id && 28 != id && 29 != id && 30 != id && 31 != id && 32 != id && 33 != id && 35 != id && 42 != id && 52 != id && 56 != id && 62 != id && 63 != id && 64 != id && 66 != id && 78 != id && 80 != id && 81 != id && 82 != id && 125 != id && 126 != id && 127 != id && 107 != id && 91 != id && 92 != id && 94 != id && 95 != id && 97 != id && 98 != id && 99 != id && 101 != id && 104 != id && 110 != id && 111 != id
return 1 != id && 3 != id && 17 != id && 23 != id && 24 != id && 25 != id && 26 != id && 27 != id && 28 != id && 29 != id && 30 != id && 31 != id && 32 != id && 33 != id && 35 != id && 42 != id && 52 != id && 56 != id && 62 != id && 63 != id && 64 != id && 66 != id && 78 != id && 80 != id && 81 != id && 82 != id && 83 != id && 125 != id && 126 != id && 127 != id && 107 != id && 91 != id && 92 != id && 94 != id && 95 != id && 97 != id && 98 != id && 99 != id && 101 != id && 104 != id && 110 != id && 111 != id
}
func IsIOSType(id int) bool {

View file

@ -79,6 +79,7 @@ const (
MsgBatchMeta = 80
MsgBatchMetadata = 81
MsgPartitionedMessage = 82
MsgInputChange = 83
MsgIssueEvent = 125
MsgSessionEnd = 126
MsgSessionSearch = 127
@ -531,19 +532,17 @@ func (msg *SetInputTarget) TypeID() int {
type SetInputValue struct {
message
ID uint64
Value string
HesitationTime int64
Mask int64
ID uint64
Value string
Mask int64
}
func (msg *SetInputValue) Encode() []byte {
buf := make([]byte, 41+len(msg.Value))
buf := make([]byte, 31+len(msg.Value))
buf[0] = 18
p := 1
p = WriteUint(msg.ID, buf, p)
p = WriteString(msg.Value, buf, p)
p = WriteInt(msg.HesitationTime, buf, p)
p = WriteInt(msg.Mask, buf, p)
return buf[:p]
}
@ -2119,6 +2118,31 @@ func (msg *PartitionedMessage) TypeID() int {
return 82
}
type InputChange struct {
message
ID uint64
Label string
HesitationTime int64
}
func (msg *InputChange) Encode() []byte {
buf := make([]byte, 31+len(msg.Label))
buf[0] = 83
p := 1
p = WriteUint(msg.ID, buf, p)
p = WriteString(msg.Label, buf, p)
p = WriteInt(msg.HesitationTime, buf, p)
return buf[:p]
}
func (msg *InputChange) Decode() Message {
return msg
}
func (msg *InputChange) TypeID() int {
return 83
}
type IssueEvent struct {
message
MessageID uint64

View file

@ -270,9 +270,6 @@ func DecodeSetInputValue(reader BytesReader) (Message, error) {
if msg.Value, err = reader.ReadString(); err != nil {
return nil, err
}
if msg.HesitationTime, err = reader.ReadInt(); err != nil {
return nil, err
}
if msg.Mask, err = reader.ReadInt(); err != nil {
return nil, err
}
@ -1296,6 +1293,21 @@ func DecodePartitionedMessage(reader BytesReader) (Message, error) {
return msg, err
}
func DecodeInputChange(reader BytesReader) (Message, error) {
var err error = nil
msg := &InputChange{}
if msg.ID, err = reader.ReadUint(); err != nil {
return nil, err
}
if msg.Label, err = reader.ReadString(); err != nil {
return nil, err
}
if msg.HesitationTime, err = reader.ReadInt(); err != nil {
return nil, err
}
return msg, err
}
func DecodeIssueEvent(reader BytesReader) (Message, error) {
var err error = nil
msg := &IssueEvent{}
@ -1905,6 +1917,8 @@ func ReadMessage(t uint64, reader BytesReader) (Message, error) {
return DecodeBatchMetadata(reader)
case 82:
return DecodePartitionedMessage(reader)
case 83:
return DecodeInputChange(reader)
case 125:
return DecodeIssueEvent(reader)
case 126:

View file

@ -163,10 +163,9 @@ class SetInputTarget(Message):
class SetInputValue(Message):
__id__ = 18
def __init__(self, id, value, hesitation_time, mask):
def __init__(self, id, value, mask):
self.id = id
self.value = value
self.hesitation_time = hesitation_time
self.mask = mask
@ -745,6 +744,15 @@ class PartitionedMessage(Message):
self.part_total = part_total
class InputChange(Message):
__id__ = 83
def __init__(self, id, label, hesitation_time):
self.id = id
self.label = label
self.hesitation_time = hesitation_time
class IssueEvent(Message):
__id__ = 125

View file

@ -200,7 +200,6 @@ class MessageCodec(Codec):
return SetInputValue(
id=self.read_uint(reader),
value=self.read_string(reader),
hesitation_time=self.read_int(reader),
mask=self.read_int(reader)
)
@ -661,6 +660,13 @@ class MessageCodec(Codec):
part_total=self.read_uint(reader)
)
if message_id == 83:
return InputChange(
id=self.read_uint(reader),
label=self.read_string(reader),
hesitation_time=self.read_int(reader)
)
if message_id == 125:
return IssueEvent(
message_id=self.read_uint(reader),

View file

@ -172,13 +172,11 @@ export default class RawMessageReader extends PrimitiveReader {
case 18: {
const id = this.readUint(); if (id === null) { return resetPointer() }
const value = this.readString(); if (value === null) { return resetPointer() }
const hesitationTime = this.readInt(); if (hesitationTime === null) { return resetPointer() }
const mask = this.readInt(); if (mask === null) { return resetPointer() }
return {
tp: MType.SetInputValue,
id,
value,
hesitationTime,
mask,
};
}

View file

@ -156,7 +156,6 @@ export interface RawSetInputValue {
tp: MType.SetInputValue,
id: number,
value: string,
hesitationTime: number,
mask: number,
}

View file

@ -98,7 +98,6 @@ type TrSetInputValue = [
type: 18,
id: number,
value: string,
hesitationTime: number,
mask: number,
]
@ -430,8 +429,15 @@ type TrPartitionedMessage = [
partTotal: number,
]
type TrInputChange = [
type: 83,
id: number,
label: string,
hesitationTime: number,
]
export type TrackerMessage = TrTimestamp | TrSetPageLocation | TrSetViewportSize | TrSetViewportScroll | TrCreateDocument | TrCreateElementNode | TrCreateTextNode | TrMoveNode | TrRemoveNode | TrSetNodeAttribute | TrRemoveNodeAttribute | TrSetNodeData | TrSetNodeScroll | TrSetInputTarget | TrSetInputValue | TrSetInputChecked | TrMouseMove | TrNetworkRequest | TrConsoleLog | TrPageLoadTiming | TrPageRenderTiming | TrCustomEvent | TrUserID | TrUserAnonymousID | TrMetadata | TrCSSInsertRule | TrCSSDeleteRule | TrFetch | TrProfiler | TrOTable | TrStateAction | TrRedux | TrVuex | TrMobX | TrNgRx | TrGraphQL | TrPerformanceTrack | TrStringDict | TrSetNodeAttributeDict | TrResourceTiming | TrConnectionInformation | TrSetPageVisibility | TrLoadFontFace | TrSetNodeFocus | TrLongTask | TrSetNodeAttributeURLBased | TrSetCSSDataURLBased | TrTechnicalInfo | TrCustomIssue | TrCSSInsertRuleURLBased | TrMouseClick | TrCreateIFrameDocument | TrAdoptedSSReplaceURLBased | TrAdoptedSSInsertRuleURLBased | TrAdoptedSSDeleteRule | TrAdoptedSSAddOwner | TrAdoptedSSRemoveOwner | TrJSException | TrZustand | TrBatchMetadata | TrPartitionedMessage
export type TrackerMessage = TrTimestamp | TrSetPageLocation | TrSetViewportSize | TrSetViewportScroll | TrCreateDocument | TrCreateElementNode | TrCreateTextNode | TrMoveNode | TrRemoveNode | TrSetNodeAttribute | TrRemoveNodeAttribute | TrSetNodeData | TrSetNodeScroll | TrSetInputTarget | TrSetInputValue | TrSetInputChecked | TrMouseMove | TrNetworkRequest | TrConsoleLog | TrPageLoadTiming | TrPageRenderTiming | TrCustomEvent | TrUserID | TrUserAnonymousID | TrMetadata | TrCSSInsertRule | TrCSSDeleteRule | TrFetch | TrProfiler | TrOTable | TrStateAction | TrRedux | TrVuex | TrMobX | TrNgRx | TrGraphQL | TrPerformanceTrack | TrStringDict | TrSetNodeAttributeDict | TrResourceTiming | TrConnectionInformation | TrSetPageVisibility | TrLoadFontFace | TrSetNodeFocus | TrLongTask | TrSetNodeAttributeURLBased | TrSetCSSDataURLBased | TrTechnicalInfo | TrCustomIssue | TrCSSInsertRuleURLBased | TrMouseClick | TrCreateIFrameDocument | TrAdoptedSSReplaceURLBased | TrAdoptedSSInsertRuleURLBased | TrAdoptedSSDeleteRule | TrAdoptedSSAddOwner | TrAdoptedSSRemoveOwner | TrJSException | TrZustand | TrBatchMetadata | TrPartitionedMessage | TrInputChange
export default function translate(tMsg: TrackerMessage): RawMessage | null {
switch(tMsg[0]) {
@ -550,8 +556,7 @@ export default function translate(tMsg: TrackerMessage): RawMessage | null {
tp: MType.SetInputValue,
id: tMsg[1],
value: tMsg[2],
hesitationTime: tMsg[3],
mask: tMsg[4],
mask: tMsg[3],
}
}

View file

@ -94,7 +94,6 @@ end
message 18, 'SetInputValue' do
uint 'ID'
string 'Value'
int 'HesitationTime'
int 'Mask'
end
message 19, 'SetInputChecked' do
@ -476,6 +475,11 @@ message 82, 'PartitionedMessage', :replayer => false do
uint 'PartTotal'
end
message 83, 'InputChange', :replayer => false do
uint 'ID'
string 'Label'
int 'HesitationTime'
end
## Backend-only
message 125, 'IssueEvent', :replayer => false, :tracker => false do

View file

@ -63,6 +63,7 @@ export declare const enum Type {
Zustand = 79,
BatchMetadata = 81,
PartitionedMessage = 82,
InputChange = 83,
}
@ -159,7 +160,6 @@ export type SetInputValue = [
/*type:*/ Type.SetInputValue,
/*id:*/ number,
/*value:*/ string,
/*hesitationTime:*/ number,
/*mask:*/ number,
]
@ -491,6 +491,13 @@ export type PartitionedMessage = [
/*partTotal:*/ number,
]
export type InputChange = [
/*type:*/ Type.InputChange,
/*id:*/ number,
/*label:*/ string,
/*hesitationTime:*/ number,
]
type Message = Timestamp | SetPageLocation | SetViewportSize | SetViewportScroll | CreateDocument | CreateElementNode | CreateTextNode | MoveNode | RemoveNode | SetNodeAttribute | RemoveNodeAttribute | SetNodeData | SetNodeScroll | SetInputTarget | SetInputValue | SetInputChecked | MouseMove | NetworkRequest | ConsoleLog | PageLoadTiming | PageRenderTiming | CustomEvent | UserID | UserAnonymousID | Metadata | CSSInsertRule | CSSDeleteRule | Fetch | Profiler | OTable | StateAction | Redux | Vuex | MobX | NgRx | GraphQL | PerformanceTrack | StringDict | SetNodeAttributeDict | ResourceTiming | ConnectionInformation | SetPageVisibility | LoadFontFace | SetNodeFocus | LongTask | SetNodeAttributeURLBased | SetCSSDataURLBased | TechnicalInfo | CustomIssue | CSSInsertRuleURLBased | MouseClick | CreateIFrameDocument | AdoptedSSReplaceURLBased | AdoptedSSInsertRuleURLBased | AdoptedSSDeleteRule | AdoptedSSAddOwner | AdoptedSSRemoveOwner | JSException | Zustand | BatchMetadata | PartitionedMessage
type Message = Timestamp | SetPageLocation | SetViewportSize | SetViewportScroll | CreateDocument | CreateElementNode | CreateTextNode | MoveNode | RemoveNode | SetNodeAttribute | RemoveNodeAttribute | SetNodeData | SetNodeScroll | SetInputTarget | SetInputValue | SetInputChecked | MouseMove | NetworkRequest | ConsoleLog | PageLoadTiming | PageRenderTiming | CustomEvent | UserID | UserAnonymousID | Metadata | CSSInsertRule | CSSDeleteRule | Fetch | Profiler | OTable | StateAction | Redux | Vuex | MobX | NgRx | GraphQL | PerformanceTrack | StringDict | SetNodeAttributeDict | ResourceTiming | ConnectionInformation | SetPageVisibility | LoadFontFace | SetNodeFocus | LongTask | SetNodeAttributeURLBased | SetCSSDataURLBased | TechnicalInfo | CustomIssue | CSSInsertRuleURLBased | MouseClick | CreateIFrameDocument | AdoptedSSReplaceURLBased | AdoptedSSInsertRuleURLBased | AdoptedSSDeleteRule | AdoptedSSAddOwner | AdoptedSSRemoveOwner | JSException | Zustand | BatchMetadata | PartitionedMessage | InputChange
export default Message

View file

@ -278,14 +278,11 @@ export default class App {
listener: EventListener,
useSafe = true,
useCapture = true,
onlyStop = false,
): void {
if (useSafe) {
listener = this.safe(listener)
}
if (!onlyStop) {
this.attachStartCallback(() => target?.addEventListener(type, listener, useCapture), useSafe)
}
this.attachStartCallback(() => target?.addEventListener(type, listener, useCapture), useSafe)
this.attachStopCallback(() => target?.removeEventListener(type, listener, useCapture), useSafe)
}

View file

@ -172,14 +172,12 @@ export function SetInputTarget(
export function SetInputValue(
id: number,
value: string,
hesitationTime: number,
mask: number,
): Messages.SetInputValue {
return [
Messages.Type.SetInputValue,
id,
value,
hesitationTime,
mask,
]
}
@ -794,3 +792,16 @@ export function PartitionedMessage(
]
}
export function InputChange(
id: number,
label: string,
hesitationTime: number,
): Messages.InputChange {
return [
Messages.Type.InputChange,
id,
label,
hesitationTime,
]
}

View file

@ -1,7 +1,7 @@
import type App from '../app/index.js'
import { normSpaces, IN_BROWSER, getLabelAttribute, debounce } from '../utils.js'
import { hasTag } from '../app/guards.js'
import { SetInputTarget, SetInputValue, SetInputChecked } from '../app/messages.gen.js'
import { InputChange, SetInputValue, SetInputChecked } from '../app/messages.gen.js'
const INPUT_TYPES = ['text', 'password', 'email', 'search', 'number', 'range', 'date', 'tel']
@ -86,6 +86,7 @@ export interface Options {
}
export default function (app: App, opts: Partial<Options>): void {
const inputHesitationMap: Map<number, { hesitation: number; focusEv: number }> = new Map()
const options: Options = Object.assign(
{
obscureInputNumbers: true,
@ -96,10 +97,12 @@ export default function (app: App, opts: Partial<Options>): void {
opts,
)
function sendInputTarget(id: number, node: TextEditableElement): void {
function sendInputChange(id: number, node: TextEditableElement): void {
const label = getInputLabel(node)
// @ts-ignore maybe if hesitationTime > 150 ?
const { hesitation } = inputHesitationMap.get(id)
if (label !== '') {
app.send(SetInputTarget(id, label))
app.send(InputChange(id, label, hesitation))
}
}
@ -130,9 +133,7 @@ export default function (app: App, opts: Partial<Options>): void {
break
}
// @ts-ignore maybe if hesitationTime > 150 ?
const hesitationTime = node.or_inputHesitation || 0
app.send(SetInputValue(id, value, hesitationTime, mask))
app.send(SetInputValue(id, value, mask))
}
const inputValues: Map<number, string> = new Map()
@ -144,10 +145,14 @@ export default function (app: App, opts: Partial<Options>): void {
})
const debouncedUpdate = debounce((id: number, node: TextEditableElement) => {
sendInputTarget(id, node)
sendInputChange(id, node)
sendInputValue(id, node)
}, 125)
const debouncedTyping = debounce((id: number, node: TextEditableElement) => {
sendInputValue(id, node)
}, 60)
app.nodes.attachNodeCallback(
app.safe((node: Node): void => {
const id = app.nodes.getID(node)
@ -160,26 +165,27 @@ export default function (app: App, opts: Partial<Options>): void {
const handler = () => {
sendInputValue(id, node)
}
node.addEventListener('change', handler)
app.attachEventListener(node, 'change', handler, false, true, true)
app.nodes.attachNodeListener(node, 'change', handler)
}
if (isTextEditable(node)) {
inputValues.set(id, node.value)
inputHesitationMap.set(id, { hesitation: 0, focusEv: 0 })
sendInputValue(id, node)
const setFocus = () => {
Object.assign(node, { or_focusStart: +new Date() })
inputHesitationMap.set(id, { hesitation: 0, focusEv: +new Date() })
}
const inputEvent = (e: InputEvent) => {
const value = (e.target as HTMLInputElement).value
if (inputValues.get(id) === '' && value !== '') {
const inputTime = +new Date()
const { focusEv } = inputHesitationMap.get(id)!
// @ts-ignore
const hesitationTime = inputTime - node.or_focusStart
Object.assign(node, { or_inputHesitation: hesitationTime })
const hesitationTime = inputTime - focusEv
inputHesitationMap.set(id, { hesitation: hesitationTime, focusEv })
}
inputValues.set(id, value)
debouncedUpdate(id, node)
debouncedTyping(id, node)
}
const changeEvent = (e: InputEvent) => {
const value = (e.target as HTMLInputElement).value
@ -187,14 +193,11 @@ export default function (app: App, opts: Partial<Options>): void {
inputValues.set(id, value)
debouncedUpdate(id, node)
}
Object.assign(node, { or_inputHesitation: undefined, or_focusStart: undefined })
inputHesitationMap.set(id, { hesitation: 0, focusEv: 0 })
}
node.addEventListener('focus', setFocus)
node.addEventListener('input', inputEvent)
node.addEventListener('change', changeEvent)
app.attachEventListener(node, 'focus', setFocus, false, true, true)
app.attachEventListener(node, 'input', inputEvent, false, true, true)
app.attachEventListener(node, 'change', changeEvent, false, true, true)
app.nodes.attachNodeListener(node, 'focus', setFocus)
app.nodes.attachNodeListener(node, 'input', inputEvent)
app.nodes.attachNodeListener(node, 'change', changeEvent)
return
}
@ -203,13 +206,10 @@ export default function (app: App, opts: Partial<Options>): void {
app.send(SetInputChecked(id, node.checked))
const checkboxChange = (e: InputEvent) => {
const value = (e.target as HTMLInputElement).checked
if (checkboxValues.get(id) !== value) {
checkboxValues.set(id, value)
app.send(SetInputChecked(id, value))
}
checkboxValues.set(id, value)
app.send(SetInputChecked(id, value))
}
node.addEventListener('change', checkboxChange)
app.attachEventListener(node, 'change', checkboxChange, false, true, true)
app.nodes.attachNodeListener(node, 'change', checkboxChange)
return
}

View file

@ -67,7 +67,7 @@ export default class MessageEncoder extends PrimitiveEncoder {
break
case Messages.Type.SetInputValue:
return this.uint(msg[1]) && this.string(msg[2]) && this.int(msg[3]) && this.int(msg[4])
return this.uint(msg[1]) && this.string(msg[2]) && this.int(msg[3])
break
case Messages.Type.SetInputChecked:
@ -254,6 +254,10 @@ export default class MessageEncoder extends PrimitiveEncoder {
return this.uint(msg[1]) && this.uint(msg[2])
break
case Messages.Type.InputChange:
return this.uint(msg[1]) && this.string(msg[2]) && this.int(msg[3])
break
}
}