diff --git a/backend/pkg/messages/filters.go b/backend/pkg/messages/filters.go index e79d1d987..35fc3ff36 100644 --- a/backend/pkg/messages/filters.go +++ b/backend/pkg/messages/filters.go @@ -2,7 +2,7 @@ package messages func IsReplayerType(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 || 22 == id || 37 == id || 38 == id || 39 == id || 40 == id || 41 == id || 44 == id || 45 == id || 46 == id || 47 == id || 48 == 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 || 79 == 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 || 22 == id || 37 == id || 38 == id || 39 == id || 40 == id || 41 == id || 44 == id || 45 == id || 46 == id || 47 == id || 48 == 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 || 79 == id || 83 == id || 90 == id || 93 == id || 96 == id || 100 == id || 102 == id || 103 == id || 105 == id } func IsIOSType(id int) bool { diff --git a/backend/pkg/messages/messages.go b/backend/pkg/messages/messages.go index 8cdb95722..a239b776a 100644 --- a/backend/pkg/messages/messages.go +++ b/backend/pkg/messages/messages.go @@ -158,6 +158,8 @@ const ( MsgZustand = 79 + MsgReplaceVCSS = 83 + MsgIOSBatchMeta = 107 MsgIOSSessionStart = 90 @@ -3066,6 +3068,36 @@ func (msg *Zustand) EncodeWithIndex() []byte { return data } +type ReplaceVCSS struct { + message + ID uint64 + Styles string + SheetID string + BaseURL string +} + +func (msg *ReplaceVCSS) Encode() []byte { + buf := make([]byte, 41+len(msg.Styles)+len(msg.SheetID)+len(msg.BaseURL)) + buf[0] = 83 + p := 1 + p = WriteUint(msg.ID, buf, p) + p = WriteString(msg.Styles, buf, p) + p = WriteString(msg.SheetID, buf, p) + p = WriteString(msg.BaseURL, buf, p) + return buf[:p] +} + +func (msg *ReplaceVCSS) 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 *Zustand) Decode() Message { return msg } @@ -3074,6 +3106,14 @@ func (msg *Zustand) TypeID() int { return 79 } +func (msg *ReplaceVCSS) Decode() Message { + return msg +} + +func (msg *ReplaceVCSS) TypeID() int { + return 83 +} + type IOSBatchMeta struct { message Timestamp uint64 diff --git a/backend/pkg/messages/read-message.go b/backend/pkg/messages/read-message.go index 1b0f579af..ff49009d8 100644 --- a/backend/pkg/messages/read-message.go +++ b/backend/pkg/messages/read-message.go @@ -1318,6 +1318,24 @@ func DecodeZustand(reader io.Reader) (Message, error) { return msg, err } +func DecodeReplaceVCSS(reader io.Reader) (Message, error) { + var err error = nil + msg := &ReplaceVCSS{} + if msg.ID, err = ReadUint(reader); err != nil { + return nil, err + } + if msg.Styles, err = ReadString(reader); err != nil { + return nil, err + } + if msg.SheetID, err = ReadString(reader); err != nil { + return nil, err + } + if msg.BaseURL, err = ReadString(reader); err != nil { + return nil, err + } + return msg, err +} + func DecodeIOSBatchMeta(reader io.Reader) (Message, error) { var err error = nil msg := &IOSBatchMeta{} @@ -1954,6 +1972,9 @@ func ReadMessage(t uint64, reader io.Reader) (Message, error) { case 79: return DecodeZustand(reader) + case 83: + return DecodeReplaceVCSS(reader) + case 107: return DecodeIOSBatchMeta(reader) diff --git a/ee/connectors/msgcodec/messages.py b/ee/connectors/msgcodec/messages.py index e1fe393a4..203a9987a 100644 --- a/ee/connectors/msgcodec/messages.py +++ b/ee/connectors/msgcodec/messages.py @@ -99,7 +99,7 @@ class CreateDocument(Message): __id__ = 7 def __init__(self, ): - + class CreateElementNode(Message): @@ -752,6 +752,16 @@ class Zustand(Message): self.state = state +class ReplaceVCSS(Message): + __id__ = 83 + + def __init__(self, id, styles, sheet_id, base_url): + self.id = id + self.styles = styles + self.sheet_id = sheet_id + self.base_url = base_url + + class IOSBatchMeta(Message): __id__ = 107 @@ -960,5 +970,3 @@ class IOSIssueEvent(Message): self.context_string = context_string self.context = context self.payload = payload - - diff --git a/ee/connectors/msgcodec/msgcodec.py b/ee/connectors/msgcodec/msgcodec.py index d53c3e75d..4e2ad02be 100644 --- a/ee/connectors/msgcodec/msgcodec.py +++ b/ee/connectors/msgcodec/msgcodec.py @@ -149,7 +149,7 @@ class MessageCodec(Codec): if message_id == 7: return CreateDocument( - + ) if message_id == 8: @@ -668,6 +668,14 @@ class MessageCodec(Codec): state=self.read_string(reader) ) + if message_id == 83: + return ReplaceVCSS( + id=self.read_uint(reader), + styles=self.read_string(reader), + sheet_id=self.read_string(reader), + base_url=self.read_string(reader) + ) + if message_id == 107: return IOSBatchMeta( timestamp=self.read_uint(reader), @@ -839,4 +847,3 @@ class MessageCodec(Codec): context=self.read_string(reader), payload=self.read_string(reader) ) - diff --git a/frontend/app/player/MessageDistributor/messages/RawMessageReader.ts b/frontend/app/player/MessageDistributor/messages/RawMessageReader.ts index d925d8bcc..ddeecbb2d 100644 --- a/frontend/app/player/MessageDistributor/messages/RawMessageReader.ts +++ b/frontend/app/player/MessageDistributor/messages/RawMessageReader.ts @@ -16,221 +16,221 @@ export default class RawMessageReader extends PrimitiveReader { if (tp === null) { return resetPointer() } switch (tp) { - + case 0: { - const timestamp = this.readUint(); if (timestamp === null) { return resetPointer() } + const timestamp = this.readUint(); if (timestamp === null) { return resetPointer() } return { - tp: "timestamp", - timestamp, + tp: "timestamp", + timestamp, }; } - + case 4: { const url = this.readString(); if (url === null) { return resetPointer() } const referrer = this.readString(); if (referrer === null) { return resetPointer() } - const navigationStart = this.readUint(); if (navigationStart === null) { return resetPointer() } + const navigationStart = this.readUint(); if (navigationStart === null) { return resetPointer() } return { - tp: "set_page_location", + tp: "set_page_location", url, referrer, - navigationStart, + navigationStart, }; } - + case 5: { const width = this.readUint(); if (width === null) { return resetPointer() } - const height = this.readUint(); if (height === null) { return resetPointer() } + const height = this.readUint(); if (height === null) { return resetPointer() } return { - tp: "set_viewport_size", + tp: "set_viewport_size", width, - height, + height, }; } - + case 6: { const x = this.readInt(); if (x === null) { return resetPointer() } - const y = this.readInt(); if (y === null) { return resetPointer() } + const y = this.readInt(); if (y === null) { return resetPointer() } return { - tp: "set_viewport_scroll", + tp: "set_viewport_scroll", x, - y, + y, }; } - + case 7: { - + return { - tp: "create_document", - + tp: "create_document", + }; } - + case 8: { const id = this.readUint(); if (id === null) { return resetPointer() } const parentID = this.readUint(); if (parentID === null) { return resetPointer() } const index = this.readUint(); if (index === null) { return resetPointer() } const tag = this.readString(); if (tag === null) { return resetPointer() } - const svg = this.readBoolean(); if (svg === null) { return resetPointer() } + const svg = this.readBoolean(); if (svg === null) { return resetPointer() } return { - tp: "create_element_node", + tp: "create_element_node", id, parentID, index, tag, - svg, + svg, }; } - + case 9: { const id = this.readUint(); if (id === null) { return resetPointer() } const parentID = this.readUint(); if (parentID === null) { return resetPointer() } - const index = this.readUint(); if (index === null) { return resetPointer() } + const index = this.readUint(); if (index === null) { return resetPointer() } return { - tp: "create_text_node", + tp: "create_text_node", id, parentID, - index, + index, }; } - + case 10: { const id = this.readUint(); if (id === null) { return resetPointer() } const parentID = this.readUint(); if (parentID === null) { return resetPointer() } - const index = this.readUint(); if (index === null) { return resetPointer() } + const index = this.readUint(); if (index === null) { return resetPointer() } return { - tp: "move_node", + tp: "move_node", id, parentID, - index, + index, }; } - + case 11: { - const id = this.readUint(); if (id === null) { return resetPointer() } + const id = this.readUint(); if (id === null) { return resetPointer() } return { - tp: "remove_node", - id, + tp: "remove_node", + id, }; } - + case 12: { const id = this.readUint(); if (id === null) { return resetPointer() } const name = this.readString(); if (name === null) { return resetPointer() } - const value = this.readString(); if (value === null) { return resetPointer() } + const value = this.readString(); if (value === null) { return resetPointer() } return { - tp: "set_node_attribute", + tp: "set_node_attribute", id, name, - value, + value, }; } - + case 13: { const id = this.readUint(); if (id === null) { return resetPointer() } - const name = this.readString(); if (name === null) { return resetPointer() } + const name = this.readString(); if (name === null) { return resetPointer() } return { - tp: "remove_node_attribute", + tp: "remove_node_attribute", id, - name, + name, }; } - + case 14: { const id = this.readUint(); if (id === null) { return resetPointer() } - const data = this.readString(); if (data === null) { return resetPointer() } + const data = this.readString(); if (data === null) { return resetPointer() } return { - tp: "set_node_data", + tp: "set_node_data", id, - data, + data, }; } - + case 15: { const id = this.readUint(); if (id === null) { return resetPointer() } - const data = this.readString(); if (data === null) { return resetPointer() } + const data = this.readString(); if (data === null) { return resetPointer() } return { - tp: "set_css_data", + tp: "set_css_data", id, - data, + data, }; } - + case 16: { const id = this.readUint(); if (id === null) { return resetPointer() } const x = this.readInt(); if (x === null) { return resetPointer() } - const y = this.readInt(); if (y === null) { return resetPointer() } + const y = this.readInt(); if (y === null) { return resetPointer() } return { - tp: "set_node_scroll", + tp: "set_node_scroll", id, x, - y, + y, }; } - + case 18: { const id = this.readUint(); if (id === null) { return resetPointer() } const value = this.readString(); if (value === null) { return resetPointer() } - const mask = this.readInt(); if (mask === null) { return resetPointer() } + const mask = this.readInt(); if (mask === null) { return resetPointer() } return { - tp: "set_input_value", + tp: "set_input_value", id, value, - mask, + mask, }; } - + case 19: { const id = this.readUint(); if (id === null) { return resetPointer() } - const checked = this.readBoolean(); if (checked === null) { return resetPointer() } + const checked = this.readBoolean(); if (checked === null) { return resetPointer() } return { - tp: "set_input_checked", + tp: "set_input_checked", id, - checked, + checked, }; } - + case 20: { const x = this.readUint(); if (x === null) { return resetPointer() } - const y = this.readUint(); if (y === null) { return resetPointer() } + const y = this.readUint(); if (y === null) { return resetPointer() } return { - tp: "mouse_move", + tp: "mouse_move", x, - y, + y, }; } - + case 22: { const level = this.readString(); if (level === null) { return resetPointer() } - const value = this.readString(); if (value === null) { return resetPointer() } + const value = this.readString(); if (value === null) { return resetPointer() } return { - tp: "console_log", + tp: "console_log", level, - value, + value, }; } - + case 37: { const id = this.readUint(); if (id === null) { return resetPointer() } const rule = this.readString(); if (rule === null) { return resetPointer() } - const index = this.readUint(); if (index === null) { return resetPointer() } + const index = this.readUint(); if (index === null) { return resetPointer() } return { - tp: "css_insert_rule", + tp: "css_insert_rule", id, rule, - index, + index, }; } - + case 38: { const id = this.readUint(); if (id === null) { return resetPointer() } - const index = this.readUint(); if (index === null) { return resetPointer() } + const index = this.readUint(); if (index === null) { return resetPointer() } return { - tp: "css_delete_rule", + tp: "css_delete_rule", id, - index, + index, }; } - + case 39: { const method = this.readString(); if (method === null) { return resetPointer() } const url = this.readString(); if (url === null) { return resetPointer() } @@ -238,133 +238,133 @@ export default class RawMessageReader extends PrimitiveReader { const response = this.readString(); if (response === null) { return resetPointer() } const status = this.readUint(); if (status === null) { return resetPointer() } const timestamp = this.readUint(); if (timestamp === null) { return resetPointer() } - const duration = this.readUint(); if (duration === null) { return resetPointer() } + const duration = this.readUint(); if (duration === null) { return resetPointer() } return { - tp: "fetch", + tp: "fetch", method, url, request, response, status, timestamp, - duration, + duration, }; } - + case 40: { const name = this.readString(); if (name === null) { return resetPointer() } const duration = this.readUint(); if (duration === null) { return resetPointer() } const args = this.readString(); if (args === null) { return resetPointer() } - const result = this.readString(); if (result === null) { return resetPointer() } + const result = this.readString(); if (result === null) { return resetPointer() } return { - tp: "profiler", + tp: "profiler", name, duration, args, - result, + result, }; } - + case 41: { const key = this.readString(); if (key === null) { return resetPointer() } - const value = this.readString(); if (value === null) { return resetPointer() } + const value = this.readString(); if (value === null) { return resetPointer() } return { - tp: "o_table", + tp: "o_table", key, - value, + value, }; } - + case 44: { const action = this.readString(); if (action === null) { return resetPointer() } const state = this.readString(); if (state === null) { return resetPointer() } - const duration = this.readUint(); if (duration === null) { return resetPointer() } + const duration = this.readUint(); if (duration === null) { return resetPointer() } return { - tp: "redux", + tp: "redux", action, state, - duration, + duration, }; } - + case 45: { const mutation = this.readString(); if (mutation === null) { return resetPointer() } - const state = this.readString(); if (state === null) { return resetPointer() } + const state = this.readString(); if (state === null) { return resetPointer() } return { - tp: "vuex", + tp: "vuex", mutation, - state, + state, }; } - + case 46: { const type = this.readString(); if (type === null) { return resetPointer() } - const payload = this.readString(); if (payload === null) { return resetPointer() } + const payload = this.readString(); if (payload === null) { return resetPointer() } return { - tp: "mob_x", + tp: "mob_x", type, - payload, + payload, }; } - + case 47: { const action = this.readString(); if (action === null) { return resetPointer() } const state = this.readString(); if (state === null) { return resetPointer() } - const duration = this.readUint(); if (duration === null) { return resetPointer() } + const duration = this.readUint(); if (duration === null) { return resetPointer() } return { - tp: "ng_rx", + tp: "ng_rx", action, state, - duration, + duration, }; } - + case 48: { const operationKind = this.readString(); if (operationKind === null) { return resetPointer() } const operationName = this.readString(); if (operationName === null) { return resetPointer() } const variables = this.readString(); if (variables === null) { return resetPointer() } - const response = this.readString(); if (response === null) { return resetPointer() } + const response = this.readString(); if (response === null) { return resetPointer() } return { - tp: "graph_ql", + tp: "graph_ql", operationKind, operationName, variables, - response, + response, }; } - + case 49: { const frames = this.readInt(); if (frames === null) { return resetPointer() } const ticks = this.readInt(); if (ticks === null) { return resetPointer() } const totalJSHeapSize = this.readUint(); if (totalJSHeapSize === null) { return resetPointer() } - const usedJSHeapSize = this.readUint(); if (usedJSHeapSize === null) { return resetPointer() } + const usedJSHeapSize = this.readUint(); if (usedJSHeapSize === null) { return resetPointer() } return { - tp: "performance_track", + tp: "performance_track", frames, ticks, totalJSHeapSize, - usedJSHeapSize, + usedJSHeapSize, }; } - + case 54: { const downlink = this.readUint(); if (downlink === null) { return resetPointer() } - const type = this.readString(); if (type === null) { return resetPointer() } + const type = this.readString(); if (type === null) { return resetPointer() } return { - tp: "connection_information", + tp: "connection_information", downlink, - type, + type, }; } - + case 55: { - const hidden = this.readBoolean(); if (hidden === null) { return resetPointer() } + const hidden = this.readBoolean(); if (hidden === null) { return resetPointer() } return { - tp: "set_page_visibility", - hidden, + tp: "set_page_visibility", + hidden, }; } - + case 59: { const timestamp = this.readUint(); if (timestamp === null) { return resetPointer() } const duration = this.readUint(); if (duration === null) { return resetPointer() } @@ -372,171 +372,185 @@ export default class RawMessageReader extends PrimitiveReader { const containerType = this.readUint(); if (containerType === null) { return resetPointer() } const containerSrc = this.readString(); if (containerSrc === null) { return resetPointer() } const containerId = this.readString(); if (containerId === null) { return resetPointer() } - const containerName = this.readString(); if (containerName === null) { return resetPointer() } + const containerName = this.readString(); if (containerName === null) { return resetPointer() } return { - tp: "long_task", + tp: "long_task", timestamp, duration, context, containerType, containerSrc, containerId, - containerName, + containerName, }; } - + case 60: { const id = this.readUint(); if (id === null) { return resetPointer() } const name = this.readString(); if (name === null) { return resetPointer() } const value = this.readString(); if (value === null) { return resetPointer() } - const baseURL = this.readString(); if (baseURL === null) { return resetPointer() } + const baseURL = this.readString(); if (baseURL === null) { return resetPointer() } return { - tp: "set_node_attribute_url_based", + tp: "set_node_attribute_url_based", id, name, value, - baseURL, + baseURL, }; } - + case 61: { const id = this.readUint(); if (id === null) { return resetPointer() } const data = this.readString(); if (data === null) { return resetPointer() } - const baseURL = this.readString(); if (baseURL === null) { return resetPointer() } + const baseURL = this.readString(); if (baseURL === null) { return resetPointer() } return { - tp: "set_css_data_url_based", + tp: "set_css_data_url_based", id, data, - baseURL, + baseURL, }; } - + case 67: { const id = this.readUint(); if (id === null) { return resetPointer() } const rule = this.readString(); if (rule === null) { return resetPointer() } const index = this.readUint(); if (index === null) { return resetPointer() } - const baseURL = this.readString(); if (baseURL === null) { return resetPointer() } + const baseURL = this.readString(); if (baseURL === null) { return resetPointer() } return { - tp: "css_insert_rule_url_based", + tp: "css_insert_rule_url_based", id, rule, index, - baseURL, + baseURL, }; } - + case 69: { const id = this.readUint(); if (id === null) { return resetPointer() } const hesitationTime = this.readUint(); if (hesitationTime === null) { return resetPointer() } const label = this.readString(); if (label === null) { return resetPointer() } - const selector = this.readString(); if (selector === null) { return resetPointer() } + const selector = this.readString(); if (selector === null) { return resetPointer() } return { - tp: "mouse_click", + tp: "mouse_click", id, hesitationTime, label, - selector, + selector, }; } - + case 70: { const frameID = this.readUint(); if (frameID === null) { return resetPointer() } - const id = this.readUint(); if (id === null) { return resetPointer() } + const id = this.readUint(); if (id === null) { return resetPointer() } return { - tp: "create_i_frame_document", + tp: "create_i_frame_document", frameID, - id, + id, }; } - + case 71: { const sheetID = this.readUint(); if (sheetID === null) { return resetPointer() } const text = this.readString(); if (text === null) { return resetPointer() } - const baseURL = this.readString(); if (baseURL === null) { return resetPointer() } + const baseURL = this.readString(); if (baseURL === null) { return resetPointer() } return { - tp: "adopted_ss_replace_url_based", + tp: "adopted_ss_replace_url_based", sheetID, text, - baseURL, + baseURL, }; } - + case 72: { const sheetID = this.readUint(); if (sheetID === null) { return resetPointer() } - const text = this.readString(); if (text === null) { return resetPointer() } + const text = this.readString(); if (text === null) { return resetPointer() } return { - tp: "adopted_ss_replace", + tp: "adopted_ss_replace", sheetID, - text, + text, }; } - + case 73: { const sheetID = this.readUint(); if (sheetID === null) { return resetPointer() } const rule = this.readString(); if (rule === null) { return resetPointer() } const index = this.readUint(); if (index === null) { return resetPointer() } - const baseURL = this.readString(); if (baseURL === null) { return resetPointer() } + const baseURL = this.readString(); if (baseURL === null) { return resetPointer() } return { - tp: "adopted_ss_insert_rule_url_based", + tp: "adopted_ss_insert_rule_url_based", sheetID, rule, index, - baseURL, + baseURL, }; } - + case 74: { const sheetID = this.readUint(); if (sheetID === null) { return resetPointer() } const rule = this.readString(); if (rule === null) { return resetPointer() } - const index = this.readUint(); if (index === null) { return resetPointer() } + const index = this.readUint(); if (index === null) { return resetPointer() } return { - tp: "adopted_ss_insert_rule", + tp: "adopted_ss_insert_rule", sheetID, rule, - index, + index, }; } - + case 75: { const sheetID = this.readUint(); if (sheetID === null) { return resetPointer() } - const index = this.readUint(); if (index === null) { return resetPointer() } + const index = this.readUint(); if (index === null) { return resetPointer() } return { - tp: "adopted_ss_delete_rule", + tp: "adopted_ss_delete_rule", sheetID, - index, + index, }; } - + case 76: { const sheetID = this.readUint(); if (sheetID === null) { return resetPointer() } - const id = this.readUint(); if (id === null) { return resetPointer() } + const id = this.readUint(); if (id === null) { return resetPointer() } return { - tp: "adopted_ss_add_owner", + tp: "adopted_ss_add_owner", sheetID, - id, + id, }; } - + case 77: { const sheetID = this.readUint(); if (sheetID === null) { return resetPointer() } - const id = this.readUint(); if (id === null) { return resetPointer() } + const id = this.readUint(); if (id === null) { return resetPointer() } return { - tp: "adopted_ss_remove_owner", + tp: "adopted_ss_remove_owner", sheetID, - id, + id, }; } - + case 79: { const mutation = this.readString(); if (mutation === null) { return resetPointer() } - const state = this.readString(); if (state === null) { return resetPointer() } + const state = this.readString(); if (state === null) { return resetPointer() } return { - tp: "zustand", + tp: "zustand", mutation, - state, + state, }; } - + + case 83: { + const id = this.readUint(); if (id === null) { return resetPointer() } + const styles = this.readString(); if (styles === null) { return resetPointer() } + const sheetID = this.readString(); if (sheetID === null) { return resetPointer() } + const baseURL = this.readString(); if (baseURL === null) { return resetPointer() } + return { + tp: "replace_vcss", + id, + styles, + sheetID, + baseURL, + }; + } + case 90: { const timestamp = this.readUint(); if (timestamp === null) { return resetPointer() } const projectID = this.readUint(); if (projectID === null) { return resetPointer() } @@ -547,9 +561,9 @@ export default class RawMessageReader extends PrimitiveReader { const userOSVersion = this.readString(); if (userOSVersion === null) { return resetPointer() } const userDevice = this.readString(); if (userDevice === null) { return resetPointer() } const userDeviceType = this.readString(); if (userDeviceType === null) { return resetPointer() } - const userCountry = this.readString(); if (userCountry === null) { return resetPointer() } + const userCountry = this.readString(); if (userCountry === null) { return resetPointer() } return { - tp: "ios_session_start", + tp: "ios_session_start", timestamp, projectID, trackerVersion, @@ -559,86 +573,86 @@ export default class RawMessageReader extends PrimitiveReader { userOSVersion, userDevice, userDeviceType, - userCountry, + userCountry, }; } - + case 93: { const timestamp = this.readUint(); if (timestamp === null) { return resetPointer() } const length = this.readUint(); if (length === null) { return resetPointer() } const name = this.readString(); if (name === null) { return resetPointer() } - const payload = this.readString(); if (payload === null) { return resetPointer() } + const payload = this.readString(); if (payload === null) { return resetPointer() } return { - tp: "ios_custom_event", + tp: "ios_custom_event", timestamp, length, name, - payload, + payload, }; } - + case 96: { const timestamp = this.readUint(); if (timestamp === null) { return resetPointer() } const length = this.readUint(); if (length === null) { return resetPointer() } const x = this.readUint(); if (x === null) { return resetPointer() } const y = this.readUint(); if (y === null) { return resetPointer() } const width = this.readUint(); if (width === null) { return resetPointer() } - const height = this.readUint(); if (height === null) { return resetPointer() } + const height = this.readUint(); if (height === null) { return resetPointer() } return { - tp: "ios_screen_changes", + tp: "ios_screen_changes", timestamp, length, x, y, width, - height, + height, }; } - + case 100: { const timestamp = this.readUint(); if (timestamp === null) { return resetPointer() } const length = this.readUint(); if (length === null) { return resetPointer() } const label = this.readString(); if (label === null) { return resetPointer() } const x = this.readUint(); if (x === null) { return resetPointer() } - const y = this.readUint(); if (y === null) { return resetPointer() } + const y = this.readUint(); if (y === null) { return resetPointer() } return { - tp: "ios_click_event", + tp: "ios_click_event", timestamp, length, label, x, - y, + y, }; } - + case 102: { const timestamp = this.readUint(); if (timestamp === null) { return resetPointer() } const length = this.readUint(); if (length === null) { return resetPointer() } const name = this.readString(); if (name === null) { return resetPointer() } - const value = this.readUint(); if (value === null) { return resetPointer() } + const value = this.readUint(); if (value === null) { return resetPointer() } return { - tp: "ios_performance_event", + tp: "ios_performance_event", timestamp, length, name, - value, + value, }; } - + case 103: { const timestamp = this.readUint(); if (timestamp === null) { return resetPointer() } const length = this.readUint(); if (length === null) { return resetPointer() } const severity = this.readString(); if (severity === null) { return resetPointer() } - const content = this.readString(); if (content === null) { return resetPointer() } + const content = this.readString(); if (content === null) { return resetPointer() } return { - tp: "ios_log", + tp: "ios_log", timestamp, length, severity, - content, + content, }; } - + case 105: { const timestamp = this.readUint(); if (timestamp === null) { return resetPointer() } const length = this.readUint(); if (length === null) { return resetPointer() } @@ -648,9 +662,9 @@ export default class RawMessageReader extends PrimitiveReader { const url = this.readString(); if (url === null) { return resetPointer() } const success = this.readBoolean(); if (success === null) { return resetPointer() } const method = this.readString(); if (method === null) { return resetPointer() } - const status = this.readUint(); if (status === null) { return resetPointer() } + const status = this.readUint(); if (status === null) { return resetPointer() } return { - tp: "ios_network_call", + tp: "ios_network_call", timestamp, length, duration, @@ -659,10 +673,10 @@ export default class RawMessageReader extends PrimitiveReader { url, success, method, - status, + status, }; } - + default: throw new Error(`Unrecognizable message type: ${ tp }; Pointer at the position ${this.p} of ${this.buf.length}`) return null; diff --git a/frontend/app/player/MessageDistributor/messages/message.ts b/frontend/app/player/MessageDistributor/messages/message.ts index 397bbfaa4..7a602c9fd 100644 --- a/frontend/app/player/MessageDistributor/messages/message.ts +++ b/frontend/app/player/MessageDistributor/messages/message.ts @@ -2,7 +2,7 @@ import type { Timed } from './timed' import type { RawMessage } from './raw' -import type { +import type { RawTimestamp, RawSetPageLocation, RawSetViewportSize, @@ -48,6 +48,7 @@ import type { RawAdoptedSsAddOwner, RawAdoptedSsRemoveOwner, RawZustand, + RawReplaceVcss, RawIosSessionStart, RawIosCustomEvent, RawIosScreenChanges, @@ -150,6 +151,8 @@ export type AdoptedSsRemoveOwner = RawAdoptedSsRemoveOwner & Timed export type Zustand = RawZustand & Timed +export type ReplaceVcss = RawReplaceVcss & Timed + export type IosSessionStart = RawIosSessionStart & Timed export type IosCustomEvent = RawIosCustomEvent & Timed diff --git a/frontend/app/player/MessageDistributor/messages/raw.ts b/frontend/app/player/MessageDistributor/messages/raw.ts index c7a133440..d3deb234d 100644 --- a/frontend/app/player/MessageDistributor/messages/raw.ts +++ b/frontend/app/player/MessageDistributor/messages/raw.ts @@ -306,6 +306,14 @@ export interface RawZustand { state: string, } +export interface RawReplaceVcss { + tp: "replace_vcss", + id: number, + styles: string, + sheetID: string, + baseURL: string, +} + export interface RawIosSessionStart { tp: "ios_session_start", timestamp: number, @@ -377,4 +385,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 | RawLongTask | RawSetNodeAttributeURLBased | RawSetCssDataURLBased | RawCssInsertRuleURLBased | RawMouseClick | RawCreateIFrameDocument | RawAdoptedSsReplaceURLBased | RawAdoptedSsReplace | RawAdoptedSsInsertRuleURLBased | RawAdoptedSsInsertRule | RawAdoptedSsDeleteRule | RawAdoptedSsAddOwner | RawAdoptedSsRemoveOwner | RawZustand | RawReplaceVcss | RawIosSessionStart | RawIosCustomEvent | RawIosScreenChanges | RawIosClickEvent | RawIosPerformanceEvent | RawIosLog | RawIosNetworkCall; diff --git a/frontend/app/player/MessageDistributor/messages/tracker-legacy.ts b/frontend/app/player/MessageDistributor/messages/tracker-legacy.ts index 088731bbc..0b849eadb 100644 --- a/frontend/app/player/MessageDistributor/messages/tracker-legacy.ts +++ b/frontend/app/player/MessageDistributor/messages/tracker-legacy.ts @@ -61,6 +61,7 @@ export const TP_MAP = { 76: "adopted_ss_add_owner", 77: "adopted_ss_remove_owner", 79: "zustand", + 83: "replace_vcss", 90: "ios_session_start", 93: "ios_custom_event", 96: "ios_screen_changes", @@ -69,5 +70,3 @@ export const TP_MAP = { 103: "ios_log", 105: "ios_network_call", } as const - - diff --git a/frontend/app/player/MessageDistributor/messages/tracker.ts b/frontend/app/player/MessageDistributor/messages/tracker.ts index 865b0ce11..7a668b113 100644 --- a/frontend/app/player/MessageDistributor/messages/tracker.ts +++ b/frontend/app/player/MessageDistributor/messages/tracker.ts @@ -1,6 +1,6 @@ // Auto-generated, do not edit -import type { RawMessage } from './raw' +import type { RawMessage } from './raw' type TrBatchMetadata = [ @@ -44,7 +44,7 @@ type TrSetViewportScroll = [ type TrCreateDocument = [ type: 7, - + ] type TrCreateElementNode = [ @@ -388,54 +388,61 @@ type TrZustand = [ state: string, ] +type TrReplaceVCSS = [ + type: 83, + id: number, + styles: string, + sheetID: string, + baseURL: string, +] -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 | TrJSException | 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 +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 | TrJSException | 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 | TrReplaceVCSS export default function translate(tMsg: TrackerMessage): RawMessage | null { switch(tMsg[0]) { - + case 0: { return { - tp: "timestamp", + tp: "timestamp", timestamp: tMsg[1], } } - + case 4: { return { - tp: "set_page_location", + tp: "set_page_location", url: tMsg[1], referrer: tMsg[2], navigationStart: tMsg[3], } } - + case 5: { return { - tp: "set_viewport_size", + tp: "set_viewport_size", width: tMsg[1], height: tMsg[2], } } - + case 6: { return { - tp: "set_viewport_scroll", + tp: "set_viewport_scroll", x: tMsg[1], y: tMsg[2], } } - + case 7: { return { - tp: "create_document", - + tp: "create_document", + } } - + case 8: { return { - tp: "create_element_node", + tp: "create_element_node", id: tMsg[1], parentID: tMsg[2], index: tMsg[3], @@ -443,119 +450,119 @@ export default function translate(tMsg: TrackerMessage): RawMessage | null { svg: tMsg[5], } } - + case 9: { return { - tp: "create_text_node", + tp: "create_text_node", id: tMsg[1], parentID: tMsg[2], index: tMsg[3], } } - + case 10: { return { - tp: "move_node", + tp: "move_node", id: tMsg[1], parentID: tMsg[2], index: tMsg[3], } } - + case 11: { return { - tp: "remove_node", + tp: "remove_node", id: tMsg[1], } } - + case 12: { return { - tp: "set_node_attribute", + tp: "set_node_attribute", id: tMsg[1], name: tMsg[2], value: tMsg[3], } } - + case 13: { return { - tp: "remove_node_attribute", + tp: "remove_node_attribute", id: tMsg[1], name: tMsg[2], } } - + case 14: { return { - tp: "set_node_data", + tp: "set_node_data", id: tMsg[1], data: tMsg[2], } } - + case 16: { return { - tp: "set_node_scroll", + tp: "set_node_scroll", id: tMsg[1], x: tMsg[2], y: tMsg[3], } } - + case 18: { return { - tp: "set_input_value", + tp: "set_input_value", id: tMsg[1], value: tMsg[2], mask: tMsg[3], } } - + case 19: { return { - tp: "set_input_checked", + tp: "set_input_checked", id: tMsg[1], checked: tMsg[2], } } - + case 20: { return { - tp: "mouse_move", + tp: "mouse_move", x: tMsg[1], y: tMsg[2], } } - + case 22: { return { - tp: "console_log", + tp: "console_log", level: tMsg[1], value: tMsg[2], } } - + case 37: { return { - tp: "css_insert_rule", + tp: "css_insert_rule", id: tMsg[1], rule: tMsg[2], index: tMsg[3], } } - + case 38: { return { - tp: "css_delete_rule", + tp: "css_delete_rule", id: tMsg[1], index: tMsg[2], } } - + case 39: { return { - tp: "fetch", + tp: "fetch", method: tMsg[1], url: tMsg[2], request: tMsg[3], @@ -565,97 +572,97 @@ export default function translate(tMsg: TrackerMessage): RawMessage | null { duration: tMsg[7], } } - + case 40: { return { - tp: "profiler", + tp: "profiler", name: tMsg[1], duration: tMsg[2], args: tMsg[3], result: tMsg[4], } } - + case 41: { return { - tp: "o_table", + tp: "o_table", key: tMsg[1], value: tMsg[2], } } - + case 44: { return { - tp: "redux", + tp: "redux", action: tMsg[1], state: tMsg[2], duration: tMsg[3], } } - + case 45: { return { - tp: "vuex", + tp: "vuex", mutation: tMsg[1], state: tMsg[2], } } - + case 46: { return { - tp: "mob_x", + tp: "mob_x", type: tMsg[1], payload: tMsg[2], } } - + case 47: { return { - tp: "ng_rx", + tp: "ng_rx", action: tMsg[1], state: tMsg[2], duration: tMsg[3], } } - + case 48: { return { - tp: "graph_ql", + tp: "graph_ql", operationKind: tMsg[1], operationName: tMsg[2], variables: tMsg[3], response: tMsg[4], } } - + case 49: { return { - tp: "performance_track", + tp: "performance_track", frames: tMsg[1], ticks: tMsg[2], totalJSHeapSize: tMsg[3], usedJSHeapSize: tMsg[4], } } - + case 54: { return { - tp: "connection_information", + tp: "connection_information", downlink: tMsg[1], type: tMsg[2], } } - + case 55: { return { - tp: "set_page_visibility", + tp: "set_page_visibility", hidden: tMsg[1], } } - + case 59: { return { - tp: "long_task", + tp: "long_task", timestamp: tMsg[1], duration: tMsg[2], context: tMsg[3], @@ -665,107 +672,117 @@ export default function translate(tMsg: TrackerMessage): RawMessage | null { containerName: tMsg[7], } } - + case 60: { return { - tp: "set_node_attribute_url_based", + tp: "set_node_attribute_url_based", id: tMsg[1], name: tMsg[2], value: tMsg[3], baseURL: tMsg[4], } } - + case 61: { return { - tp: "set_css_data_url_based", + tp: "set_css_data_url_based", id: tMsg[1], data: tMsg[2], baseURL: tMsg[3], } } - + case 67: { return { - tp: "css_insert_rule_url_based", + tp: "css_insert_rule_url_based", id: tMsg[1], rule: tMsg[2], index: tMsg[3], baseURL: tMsg[4], } } - + case 69: { return { - tp: "mouse_click", + tp: "mouse_click", id: tMsg[1], hesitationTime: tMsg[2], label: tMsg[3], selector: tMsg[4], } } - + case 70: { return { - tp: "create_i_frame_document", + tp: "create_i_frame_document", frameID: tMsg[1], id: tMsg[2], } } - + case 71: { return { - tp: "adopted_ss_replace_url_based", + tp: "adopted_ss_replace_url_based", sheetID: tMsg[1], text: tMsg[2], baseURL: tMsg[3], } } - + case 73: { return { - tp: "adopted_ss_insert_rule_url_based", + tp: "adopted_ss_insert_rule_url_based", sheetID: tMsg[1], rule: tMsg[2], index: tMsg[3], baseURL: tMsg[4], } } - + case 75: { return { - tp: "adopted_ss_delete_rule", + tp: "adopted_ss_delete_rule", sheetID: tMsg[1], index: tMsg[2], } } - + case 76: { return { - tp: "adopted_ss_add_owner", + tp: "adopted_ss_add_owner", sheetID: tMsg[1], id: tMsg[2], } } - + case 77: { return { - tp: "adopted_ss_remove_owner", + tp: "adopted_ss_remove_owner", sheetID: tMsg[1], id: tMsg[2], } } - + case 79: { return { - tp: "zustand", + tp: "zustand", mutation: tMsg[1], state: tMsg[2], } } - + + case 83: { + return { + tp: "replace_vcss", + id: tMsg[1], + styles: tMsg[2], + sheetID: tMsg[3], + baseURL: tMsg[4], + } + } + default: return null } -} \ No newline at end of file +} diff --git a/mobs/messages.rb b/mobs/messages.rb index 09acdb6f2..fd9ed762b 100644 --- a/mobs/messages.rb +++ b/mobs/messages.rb @@ -460,3 +460,10 @@ message 79, 'Zustand' do string 'Mutation' string 'State' end + +message 83, 'ReplaceVCSS' do + uint 'ID' + string 'Styles' + string 'SheetID' + string 'BaseURL' +end diff --git a/tracker/tracker-zustand/cjs/index.js b/tracker/tracker-zustand/cjs/index.js new file mode 100644 index 000000000..b1fe7d7c6 --- /dev/null +++ b/tracker/tracker-zustand/cjs/index.js @@ -0,0 +1,42 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const tracker_1 = require("@openreplay/tracker/cjs"); +const index_js_1 = require("./syncod/index.js"); +function processMutationAndState(app, options, encoder, mutation, state) { + if (options.filter(mutation, state)) { + try { + const _mutation = encoder.encode(options.mutationTransformer(mutation)); + const _state = encoder.encode(options.transformer(state)); + const _table = encoder.commit(); + for (let key in _table) + app.send(tracker_1.Messages.OTable(key, _table[key])); + app.send(tracker_1.Messages.Zustand(_mutation, _state)); + } + catch (e) { + encoder.clear(); + app.debug.error(e); + } + } +} +function default_1(opts = {}) { + const options = Object.assign({ + filter: () => true, + transformer: state => state, + mutationTransformer: mutation => mutation, + }, opts); + return (app) => { + if (app === null) { + return Function.prototype; + } + const encoder = new index_js_1.Encoder(index_js_1.sha1, 50); + const state = {}; + return (storeName = Math.random().toString(36).substring(2, 9)) => (config) => (set, get, api) => config((...args) => { + set(...args); + const newState = get(); + state[storeName] = newState; + const triggeredActions = args.map(action => { var _a; return (_a = action.toString) === null || _a === void 0 ? void 0 : _a.call(action); }); + processMutationAndState(app, options, encoder, triggeredActions, state); + }, get, api); + }; +} +exports.default = default_1; diff --git a/tracker/tracker-zustand/cjs/package.json b/tracker/tracker-zustand/cjs/package.json new file mode 100644 index 000000000..a3c15a7a6 --- /dev/null +++ b/tracker/tracker-zustand/cjs/package.json @@ -0,0 +1 @@ +{ "type": "commonjs" } diff --git a/tracker/tracker-zustand/cjs/syncod/chars.js b/tracker/tracker-zustand/cjs/syncod/chars.js new file mode 100644 index 000000000..53ac08db6 --- /dev/null +++ b/tracker/tracker-zustand/cjs/syncod/chars.js @@ -0,0 +1,18 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const chars = {}; +[ + "DEL", + "UNDEF", + "TRUE", + "FALSE", + "NUMBER", + "BIGINT", + "FUNCTION", + "STRING", + "SYMBOL", + "NULL", + "OBJECT", + "ARRAY" +].forEach((k, i) => (chars[k] = String.fromCharCode(i + 0xe000))); +exports.default = chars; diff --git a/tracker/tracker-zustand/cjs/syncod/encoder.js b/tracker/tracker-zustand/cjs/syncod/encoder.js new file mode 100644 index 000000000..bb424b6aa --- /dev/null +++ b/tracker/tracker-zustand/cjs/syncod/encoder.js @@ -0,0 +1,213 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const chars_js_1 = require("./chars.js"); +// @ts-ignore +// @ts-ignore +class Encoder { + // @ts-ignore + constructor(hash, slen = Infinity) { + // @ts-ignore + this._hash = hash; + // @ts-ignore + this._slen = slen; + // @ts-ignore + this._refmap = new Map(); + // @ts-ignore + this._refset = new Set(); + // @ts-ignore + } + // @ts-ignore + // @ts-ignore + _ref_str(str) { + // @ts-ignore + if (str.length < this._slen && str.indexOf(chars_js_1.default.DEL) === -1) { + // @ts-ignore + return str; + // @ts-ignore + } + // @ts-ignore + let ref = this._refmap.get(str); + // @ts-ignore + if (ref === undefined) { + // @ts-ignore + ref = this._hash(str); + // @ts-ignore + this._refmap.set(str, ref); + // @ts-ignore + } + // @ts-ignore + return ref; + // @ts-ignore + } + // @ts-ignore + // @ts-ignore + _encode_prim(obj) { + // @ts-ignore + switch (typeof obj) { + // @ts-ignore + case "undefined": + // @ts-ignore + return chars_js_1.default.UNDEF; + // @ts-ignore + case "boolean": + // @ts-ignore + return obj ? chars_js_1.default.TRUE : chars_js_1.default.FALSE; + // @ts-ignore + case "number": + // @ts-ignore + return chars_js_1.default.NUMBER + obj.toString(); + // @ts-ignore + case "bigint": + // @ts-ignore + return chars_js_1.default.BIGINT + obj.toString(); + // @ts-ignore + case "function": + // @ts-ignore + return chars_js_1.default.FUNCTION; + // @ts-ignore + case "string": + // @ts-ignore + return chars_js_1.default.STRING + this._ref_str(obj); + // @ts-ignore + case "symbol": + // @ts-ignore + return chars_js_1.default.SYMBOL + this._ref_str(obj.toString().slice(7, -1)); + // @ts-ignore + } + // @ts-ignore + if (obj === null) { + // @ts-ignore + return chars_js_1.default.NULL; + // @ts-ignore + } + // @ts-ignore + } + // @ts-ignore + // @ts-ignore + _encode_obj(obj, ref = this._refmap.get(obj)) { + // @ts-ignore + return (Array.isArray(obj) ? chars_js_1.default.ARRAY : chars_js_1.default.OBJECT) + ref; + // @ts-ignore + } + // @ts-ignore + // @ts-ignore + _encode_term(obj) { + // @ts-ignore + return this._encode_prim(obj) || this._encode_obj(obj); + // @ts-ignore + } + // @ts-ignore + // @ts-ignore + _encode_deep(obj, depth) { + // @ts-ignore + const enc = this._encode_prim(obj); + // @ts-ignore + if (enc !== undefined) { + // @ts-ignore + return enc; + // @ts-ignore + } + // @ts-ignore + const ref = this._refmap.get(obj); + // @ts-ignore + switch (typeof ref) { + // @ts-ignore + case "number": + // @ts-ignore + return (depth - ref).toString(); + // @ts-ignore + case "string": + // @ts-ignore + return this._encode_obj(obj, ref); + // @ts-ignore + } + // @ts-ignore + this._refmap.set(obj, depth); + // @ts-ignore + const hash = this._hash( + // @ts-ignore + (Array.isArray(obj) + // @ts-ignore + ? obj.map(v => this._encode_deep(v, depth + 1)) + // @ts-ignore + : Object.keys(obj) + // @ts-ignore + .sort() + // @ts-ignore + .map( + // @ts-ignore + k => + // @ts-ignore + this._ref_str(k) + chars_js_1.default.DEL + this._encode_deep(obj[k], depth + 1) + // @ts-ignore + ) + // @ts-ignore + ).join(chars_js_1.default.DEL) + // @ts-ignore + ); + // @ts-ignore + this._refmap.set(obj, hash); + // @ts-ignore + return this._encode_obj(obj, hash); + // @ts-ignore + } + // @ts-ignore + // @ts-ignore + encode(obj) { + // @ts-ignore + return this._encode_deep(obj, 0); + // @ts-ignore + } + // @ts-ignore + // @ts-ignore + commit() { + // @ts-ignore + const dict = {}; + // @ts-ignore + this._refmap.forEach((ref, obj) => { + // @ts-ignore + if (this._refset.has(ref)) { + // @ts-ignore + return; + // @ts-ignore + } + // @ts-ignore + this._refset.add(ref); + // @ts-ignore + if (typeof obj !== "string") { + // @ts-ignore + obj = (Array.isArray(obj) + // @ts-ignore + ? obj.map(v => this._encode_term(v)) + // @ts-ignore + : Object.keys(obj).map( + // @ts-ignore + k => this._ref_str(k) + chars_js_1.default.DEL + this._encode_term(obj[k]) + // @ts-ignore + ) + // @ts-ignore + ).join(chars_js_1.default.DEL); + // @ts-ignore + } + // @ts-ignore + dict[ref] = obj; + // @ts-ignore + }); + // @ts-ignore + this._refmap.clear(); + // @ts-ignore + return dict; + // @ts-ignore + } + // @ts-ignore + // @ts-ignore + clear() { + // @ts-ignore + this._refmap.clear(); + // @ts-ignore + this._refset.clear(); + // @ts-ignore + } +} +exports.default = Encoder; +// @ts-ignore diff --git a/tracker/tracker-zustand/cjs/syncod/index.js b/tracker/tracker-zustand/cjs/syncod/index.js new file mode 100644 index 000000000..975ce1f6e --- /dev/null +++ b/tracker/tracker-zustand/cjs/syncod/index.js @@ -0,0 +1,8 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.sha1 = exports.Encoder = void 0; +// TODO: SSR solution for all asayer libraries +const encoder_js_1 = require("./encoder.js"); +exports.Encoder = encoder_js_1.default; +const sha1_js_1 = require("./sha1.js"); +exports.sha1 = sha1_js_1.default; diff --git a/tracker/tracker-zustand/cjs/syncod/sha1.js b/tracker/tracker-zustand/cjs/syncod/sha1.js new file mode 100644 index 000000000..b50f484a5 --- /dev/null +++ b/tracker/tracker-zustand/cjs/syncod/sha1.js @@ -0,0 +1,96 @@ +"use strict"; +/* + * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined + * in FIPS PUB 180-1 + * Version 2.1a Copyright Paul Johnston 2000 - 2002. + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet + * Distributed under the BSD License + * See http://pajhome.org.uk/crypt/md5 for details. + */ +Object.defineProperty(exports, "__esModule", { value: true }); +function core_sha1(x, len) { + x[len >> 5] |= 0x80 << (24 - (len % 32)); + x[(((len + 64) >> 9) << 4) + 15] = len; + var w = Array(80); + var a = 1732584193; + var b = -271733879; + var c = -1732584194; + var d = 271733878; + var e = -1009589776; + for (var i = 0; i < x.length; i += 16) { + var olda = a; + var oldb = b; + var oldc = c; + var oldd = d; + var olde = e; + for (var j = 0; j < 80; j++) { + if (j < 16) + w[j] = x[i + j]; + else + w[j] = rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1); + var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)), safe_add(safe_add(e, w[j]), sha1_kt(j))); + e = d; + d = c; + c = rol(b, 30); + b = a; + a = t; + } + a = safe_add(a, olda); + b = safe_add(b, oldb); + c = safe_add(c, oldc); + d = safe_add(d, oldd); + e = safe_add(e, olde); + } + return Array(a, b, c, d, e); +} +function sha1_ft(t, b, c, d) { + if (t < 20) + return (b & c) | (~b & d); + if (t < 40) + return b ^ c ^ d; + if (t < 60) + return (b & c) | (b & d) | (c & d); + return b ^ c ^ d; +} +function sha1_kt(t) { + return t < 20 + ? 1518500249 + : t < 40 + ? 1859775393 + : t < 60 + ? -1894007588 + : -899497514; +} +function safe_add(x, y) { + var lsw = (x & 0xffff) + (y & 0xffff); + var msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return (msw << 16) | (lsw & 0xffff); +} +function rol(num, cnt) { + return (num << cnt) | (num >>> (32 - cnt)); +} +function str2binb(str) { + var bin = Array(); + var mask = (1 << 16) - 1; + for (var i = 0; i < str.length * 16; i += 16) + bin[i >> 5] |= (str.charCodeAt(i / 16) & mask) << (32 - 16 - (i % 32)); + return bin; +} +function binb2b64(binarray) { + var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + var str = ""; + for (var i = 0; i < binarray.length * 4; i += 3) { + var triplet = (((binarray[i >> 2] >> (8 * (3 - (i % 4)))) & 0xff) << 16) | + (((binarray[(i + 1) >> 2] >> (8 * (3 - ((i + 1) % 4)))) & 0xff) << 8) | + ((binarray[(i + 2) >> 2] >> (8 * (3 - ((i + 2) % 4)))) & 0xff); + for (var j = 0; j < 4; j++) { + if (i * 8 + j * 6 <= binarray.length * 32) + str += tab.charAt((triplet >> (6 * (3 - j))) & 0x3f); + } + } + return str; +} +function default_1(s) { + return binb2b64(core_sha1(str2binb(s), s.length * 16)); +} +exports.default = default_1; diff --git a/tracker/tracker-zustand/lib/index.d.ts b/tracker/tracker-zustand/lib/index.d.ts new file mode 100644 index 000000000..4abda5612 --- /dev/null +++ b/tracker/tracker-zustand/lib/index.d.ts @@ -0,0 +1,7 @@ +import { App } from "@openreplay/tracker"; +export interface Options { + filter: (mutation: any, state: any) => boolean; + transformer: (state: any) => any; + mutationTransformer: (mutation: any) => any; +} +export default function (opts?: Partial): (app: App | null) => Function; diff --git a/tracker/tracker-zustand/lib/index.js b/tracker/tracker-zustand/lib/index.js new file mode 100644 index 000000000..446ae8df9 --- /dev/null +++ b/tracker/tracker-zustand/lib/index.js @@ -0,0 +1,39 @@ +import { Messages } from "@openreplay/tracker"; +import { Encoder, sha1 } from "./syncod/index.js"; +function processMutationAndState(app, options, encoder, mutation, state) { + if (options.filter(mutation, state)) { + try { + const _mutation = encoder.encode(options.mutationTransformer(mutation)); + const _state = encoder.encode(options.transformer(state)); + const _table = encoder.commit(); + for (let key in _table) + app.send(Messages.OTable(key, _table[key])); + app.send(Messages.Zustand(_mutation, _state)); + } + catch (e) { + encoder.clear(); + app.debug.error(e); + } + } +} +export default function (opts = {}) { + const options = Object.assign({ + filter: () => true, + transformer: state => state, + mutationTransformer: mutation => mutation, + }, opts); + return (app) => { + if (app === null) { + return Function.prototype; + } + const encoder = new Encoder(sha1, 50); + const state = {}; + return (storeName = Math.random().toString(36).substring(2, 9)) => (config) => (set, get, api) => config((...args) => { + set(...args); + const newState = get(); + state[storeName] = newState; + const triggeredActions = args.map(action => { var _a; return (_a = action.toString) === null || _a === void 0 ? void 0 : _a.call(action); }); + processMutationAndState(app, options, encoder, triggeredActions, state); + }, get, api); + }; +} diff --git a/tracker/tracker-zustand/lib/syncod/chars.d.ts b/tracker/tracker-zustand/lib/syncod/chars.d.ts new file mode 100644 index 000000000..7e5cac119 --- /dev/null +++ b/tracker/tracker-zustand/lib/syncod/chars.d.ts @@ -0,0 +1,2 @@ +declare const chars: {}; +export default chars; diff --git a/tracker/tracker-zustand/lib/syncod/chars.js b/tracker/tracker-zustand/lib/syncod/chars.js new file mode 100644 index 000000000..c8c8c5db9 --- /dev/null +++ b/tracker/tracker-zustand/lib/syncod/chars.js @@ -0,0 +1,16 @@ +const chars = {}; +[ + "DEL", + "UNDEF", + "TRUE", + "FALSE", + "NUMBER", + "BIGINT", + "FUNCTION", + "STRING", + "SYMBOL", + "NULL", + "OBJECT", + "ARRAY" +].forEach((k, i) => (chars[k] = String.fromCharCode(i + 0xe000))); +export default chars; diff --git a/tracker/tracker-zustand/lib/syncod/encoder.d.ts b/tracker/tracker-zustand/lib/syncod/encoder.d.ts new file mode 100644 index 000000000..a20aa34b8 --- /dev/null +++ b/tracker/tracker-zustand/lib/syncod/encoder.d.ts @@ -0,0 +1,11 @@ +export default class Encoder { + constructor(hash: any, slen?: number); + _ref_str(str: any): any; + _encode_prim(obj: any): any; + _encode_obj(obj: any, ref?: any): any; + _encode_term(obj: any): any; + _encode_deep(obj: any, depth: any): any; + encode(obj: any): any; + commit(): {}; + clear(): void; +} diff --git a/tracker/tracker-zustand/lib/syncod/encoder.js b/tracker/tracker-zustand/lib/syncod/encoder.js new file mode 100644 index 000000000..1f49c826e --- /dev/null +++ b/tracker/tracker-zustand/lib/syncod/encoder.js @@ -0,0 +1,210 @@ +import _ from "./chars.js"; +// @ts-ignore +// @ts-ignore +export default class Encoder { + // @ts-ignore + constructor(hash, slen = Infinity) { + // @ts-ignore + this._hash = hash; + // @ts-ignore + this._slen = slen; + // @ts-ignore + this._refmap = new Map(); + // @ts-ignore + this._refset = new Set(); + // @ts-ignore + } + // @ts-ignore + // @ts-ignore + _ref_str(str) { + // @ts-ignore + if (str.length < this._slen && str.indexOf(_.DEL) === -1) { + // @ts-ignore + return str; + // @ts-ignore + } + // @ts-ignore + let ref = this._refmap.get(str); + // @ts-ignore + if (ref === undefined) { + // @ts-ignore + ref = this._hash(str); + // @ts-ignore + this._refmap.set(str, ref); + // @ts-ignore + } + // @ts-ignore + return ref; + // @ts-ignore + } + // @ts-ignore + // @ts-ignore + _encode_prim(obj) { + // @ts-ignore + switch (typeof obj) { + // @ts-ignore + case "undefined": + // @ts-ignore + return _.UNDEF; + // @ts-ignore + case "boolean": + // @ts-ignore + return obj ? _.TRUE : _.FALSE; + // @ts-ignore + case "number": + // @ts-ignore + return _.NUMBER + obj.toString(); + // @ts-ignore + case "bigint": + // @ts-ignore + return _.BIGINT + obj.toString(); + // @ts-ignore + case "function": + // @ts-ignore + return _.FUNCTION; + // @ts-ignore + case "string": + // @ts-ignore + return _.STRING + this._ref_str(obj); + // @ts-ignore + case "symbol": + // @ts-ignore + return _.SYMBOL + this._ref_str(obj.toString().slice(7, -1)); + // @ts-ignore + } + // @ts-ignore + if (obj === null) { + // @ts-ignore + return _.NULL; + // @ts-ignore + } + // @ts-ignore + } + // @ts-ignore + // @ts-ignore + _encode_obj(obj, ref = this._refmap.get(obj)) { + // @ts-ignore + return (Array.isArray(obj) ? _.ARRAY : _.OBJECT) + ref; + // @ts-ignore + } + // @ts-ignore + // @ts-ignore + _encode_term(obj) { + // @ts-ignore + return this._encode_prim(obj) || this._encode_obj(obj); + // @ts-ignore + } + // @ts-ignore + // @ts-ignore + _encode_deep(obj, depth) { + // @ts-ignore + const enc = this._encode_prim(obj); + // @ts-ignore + if (enc !== undefined) { + // @ts-ignore + return enc; + // @ts-ignore + } + // @ts-ignore + const ref = this._refmap.get(obj); + // @ts-ignore + switch (typeof ref) { + // @ts-ignore + case "number": + // @ts-ignore + return (depth - ref).toString(); + // @ts-ignore + case "string": + // @ts-ignore + return this._encode_obj(obj, ref); + // @ts-ignore + } + // @ts-ignore + this._refmap.set(obj, depth); + // @ts-ignore + const hash = this._hash( + // @ts-ignore + (Array.isArray(obj) + // @ts-ignore + ? obj.map(v => this._encode_deep(v, depth + 1)) + // @ts-ignore + : Object.keys(obj) + // @ts-ignore + .sort() + // @ts-ignore + .map( + // @ts-ignore + k => + // @ts-ignore + this._ref_str(k) + _.DEL + this._encode_deep(obj[k], depth + 1) + // @ts-ignore + ) + // @ts-ignore + ).join(_.DEL) + // @ts-ignore + ); + // @ts-ignore + this._refmap.set(obj, hash); + // @ts-ignore + return this._encode_obj(obj, hash); + // @ts-ignore + } + // @ts-ignore + // @ts-ignore + encode(obj) { + // @ts-ignore + return this._encode_deep(obj, 0); + // @ts-ignore + } + // @ts-ignore + // @ts-ignore + commit() { + // @ts-ignore + const dict = {}; + // @ts-ignore + this._refmap.forEach((ref, obj) => { + // @ts-ignore + if (this._refset.has(ref)) { + // @ts-ignore + return; + // @ts-ignore + } + // @ts-ignore + this._refset.add(ref); + // @ts-ignore + if (typeof obj !== "string") { + // @ts-ignore + obj = (Array.isArray(obj) + // @ts-ignore + ? obj.map(v => this._encode_term(v)) + // @ts-ignore + : Object.keys(obj).map( + // @ts-ignore + k => this._ref_str(k) + _.DEL + this._encode_term(obj[k]) + // @ts-ignore + ) + // @ts-ignore + ).join(_.DEL); + // @ts-ignore + } + // @ts-ignore + dict[ref] = obj; + // @ts-ignore + }); + // @ts-ignore + this._refmap.clear(); + // @ts-ignore + return dict; + // @ts-ignore + } + // @ts-ignore + // @ts-ignore + clear() { + // @ts-ignore + this._refmap.clear(); + // @ts-ignore + this._refset.clear(); + // @ts-ignore + } +} +// @ts-ignore diff --git a/tracker/tracker-zustand/lib/syncod/index.d.ts b/tracker/tracker-zustand/lib/syncod/index.d.ts new file mode 100644 index 000000000..f86224391 --- /dev/null +++ b/tracker/tracker-zustand/lib/syncod/index.d.ts @@ -0,0 +1,3 @@ +import Encoder from "./encoder.js"; +import sha1 from "./sha1.js"; +export { Encoder, sha1 }; diff --git a/tracker/tracker-zustand/lib/syncod/index.js b/tracker/tracker-zustand/lib/syncod/index.js new file mode 100644 index 000000000..a231b1554 --- /dev/null +++ b/tracker/tracker-zustand/lib/syncod/index.js @@ -0,0 +1,4 @@ +// TODO: SSR solution for all asayer libraries +import Encoder from "./encoder.js"; +import sha1 from "./sha1.js"; +export { Encoder, sha1 }; diff --git a/tracker/tracker-zustand/lib/syncod/sha1.d.ts b/tracker/tracker-zustand/lib/syncod/sha1.d.ts new file mode 100644 index 000000000..2720da68a --- /dev/null +++ b/tracker/tracker-zustand/lib/syncod/sha1.d.ts @@ -0,0 +1 @@ +export default function (s: any): string; diff --git a/tracker/tracker-zustand/lib/syncod/sha1.js b/tracker/tracker-zustand/lib/syncod/sha1.js new file mode 100644 index 000000000..7b428a06f --- /dev/null +++ b/tracker/tracker-zustand/lib/syncod/sha1.js @@ -0,0 +1,93 @@ +/* + * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined + * in FIPS PUB 180-1 + * Version 2.1a Copyright Paul Johnston 2000 - 2002. + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet + * Distributed under the BSD License + * See http://pajhome.org.uk/crypt/md5 for details. + */ +function core_sha1(x, len) { + x[len >> 5] |= 0x80 << (24 - (len % 32)); + x[(((len + 64) >> 9) << 4) + 15] = len; + var w = Array(80); + var a = 1732584193; + var b = -271733879; + var c = -1732584194; + var d = 271733878; + var e = -1009589776; + for (var i = 0; i < x.length; i += 16) { + var olda = a; + var oldb = b; + var oldc = c; + var oldd = d; + var olde = e; + for (var j = 0; j < 80; j++) { + if (j < 16) + w[j] = x[i + j]; + else + w[j] = rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1); + var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)), safe_add(safe_add(e, w[j]), sha1_kt(j))); + e = d; + d = c; + c = rol(b, 30); + b = a; + a = t; + } + a = safe_add(a, olda); + b = safe_add(b, oldb); + c = safe_add(c, oldc); + d = safe_add(d, oldd); + e = safe_add(e, olde); + } + return Array(a, b, c, d, e); +} +function sha1_ft(t, b, c, d) { + if (t < 20) + return (b & c) | (~b & d); + if (t < 40) + return b ^ c ^ d; + if (t < 60) + return (b & c) | (b & d) | (c & d); + return b ^ c ^ d; +} +function sha1_kt(t) { + return t < 20 + ? 1518500249 + : t < 40 + ? 1859775393 + : t < 60 + ? -1894007588 + : -899497514; +} +function safe_add(x, y) { + var lsw = (x & 0xffff) + (y & 0xffff); + var msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return (msw << 16) | (lsw & 0xffff); +} +function rol(num, cnt) { + return (num << cnt) | (num >>> (32 - cnt)); +} +function str2binb(str) { + var bin = Array(); + var mask = (1 << 16) - 1; + for (var i = 0; i < str.length * 16; i += 16) + bin[i >> 5] |= (str.charCodeAt(i / 16) & mask) << (32 - 16 - (i % 32)); + return bin; +} +function binb2b64(binarray) { + var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + var str = ""; + for (var i = 0; i < binarray.length * 4; i += 3) { + var triplet = (((binarray[i >> 2] >> (8 * (3 - (i % 4)))) & 0xff) << 16) | + (((binarray[(i + 1) >> 2] >> (8 * (3 - ((i + 1) % 4)))) & 0xff) << 8) | + ((binarray[(i + 2) >> 2] >> (8 * (3 - ((i + 2) % 4)))) & 0xff); + for (var j = 0; j < 4; j++) { + if (i * 8 + j * 6 <= binarray.length * 32) + str += tab.charAt((triplet >> (6 * (3 - j))) & 0x3f); + } + } + return str; +} +export default function (s) { + return binb2b64(core_sha1(str2binb(s), s.length * 16)); +} diff --git a/tracker/tracker/src/common/messages.gen.ts b/tracker/tracker/src/common/messages.gen.ts index 107416711..808ed0255 100644 --- a/tracker/tracker/src/common/messages.gen.ts +++ b/tracker/tracker/src/common/messages.gen.ts @@ -57,6 +57,7 @@ export declare const enum Type { AdoptedSSAddOwner = 76, AdoptedSSRemoveOwner = 77, Zustand = 79, + ReplaceVCSS = 83, } @@ -101,7 +102,7 @@ export type SetViewportScroll = [ export type CreateDocument = [ /*type:*/ Type.CreateDocument, - + ] export type CreateElementNode = [ @@ -445,6 +446,15 @@ export type Zustand = [ /*state:*/ string, ] +export type ReplaceVCSS = [ + /*type:*/ Type.ReplaceVCSS, + /*id:*/ number, + /*styles:*/ string, + /*sheetID:*/ string, + /*baseURL:*/ string, +] + +type Message = BatchMetadata | PartitionedMessage | Timestamp | SetPageLocation | SetViewportSize | SetViewportScroll | CreateDocument | CreateElementNode | CreateTextNode | MoveNode | RemoveNode | SetNodeAttribute | RemoveNodeAttribute | SetNodeData | SetNodeScroll | SetInputTarget | SetInputValue | SetInputChecked | MouseMove | ConsoleLog | PageLoadTiming | PageRenderTiming | JSException | 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 | ReplaceVCSS + -type Message = BatchMetadata | PartitionedMessage | Timestamp | SetPageLocation | SetViewportSize | SetViewportScroll | CreateDocument | CreateElementNode | CreateTextNode | MoveNode | RemoveNode | SetNodeAttribute | RemoveNodeAttribute | SetNodeData | SetNodeScroll | SetInputTarget | SetInputValue | SetInputChecked | MouseMove | ConsoleLog | PageLoadTiming | PageRenderTiming | JSException | 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 export default Message diff --git a/tracker/tracker/src/main/app/messages.gen.ts b/tracker/tracker/src/main/app/messages.gen.ts index 7bbbeb615..697b5aa96 100644 --- a/tracker/tracker/src/main/app/messages.gen.ts +++ b/tracker/tracker/src/main/app/messages.gen.ts @@ -11,7 +11,7 @@ export function BatchMetadata( timestamp: number, location: string, ): Messages.BatchMetadata { - return [ + return [ Messages.Type.BatchMetadata, version, pageNo, @@ -25,7 +25,7 @@ export function PartitionedMessage( partNo: number, partTotal: number, ): Messages.PartitionedMessage { - return [ + return [ Messages.Type.PartitionedMessage, partNo, partTotal, @@ -35,7 +35,7 @@ export function PartitionedMessage( export function Timestamp( timestamp: number, ): Messages.Timestamp { - return [ + return [ Messages.Type.Timestamp, timestamp, ] @@ -46,7 +46,7 @@ export function SetPageLocation( referrer: string, navigationStart: number, ): Messages.SetPageLocation { - return [ + return [ Messages.Type.SetPageLocation, url, referrer, @@ -58,7 +58,7 @@ export function SetViewportSize( width: number, height: number, ): Messages.SetViewportSize { - return [ + return [ Messages.Type.SetViewportSize, width, height, @@ -69,7 +69,7 @@ export function SetViewportScroll( x: number, y: number, ): Messages.SetViewportScroll { - return [ + return [ Messages.Type.SetViewportScroll, x, y, @@ -77,11 +77,11 @@ export function SetViewportScroll( } export function CreateDocument( - + ): Messages.CreateDocument { - return [ + return [ Messages.Type.CreateDocument, - + ] } @@ -92,7 +92,7 @@ export function CreateElementNode( tag: string, svg: boolean, ): Messages.CreateElementNode { - return [ + return [ Messages.Type.CreateElementNode, id, parentID, @@ -107,7 +107,7 @@ export function CreateTextNode( parentID: number, index: number, ): Messages.CreateTextNode { - return [ + return [ Messages.Type.CreateTextNode, id, parentID, @@ -120,7 +120,7 @@ export function MoveNode( parentID: number, index: number, ): Messages.MoveNode { - return [ + return [ Messages.Type.MoveNode, id, parentID, @@ -131,7 +131,7 @@ export function MoveNode( export function RemoveNode( id: number, ): Messages.RemoveNode { - return [ + return [ Messages.Type.RemoveNode, id, ] @@ -142,7 +142,7 @@ export function SetNodeAttribute( name: string, value: string, ): Messages.SetNodeAttribute { - return [ + return [ Messages.Type.SetNodeAttribute, id, name, @@ -154,7 +154,7 @@ export function RemoveNodeAttribute( id: number, name: string, ): Messages.RemoveNodeAttribute { - return [ + return [ Messages.Type.RemoveNodeAttribute, id, name, @@ -165,7 +165,7 @@ export function SetNodeData( id: number, data: string, ): Messages.SetNodeData { - return [ + return [ Messages.Type.SetNodeData, id, data, @@ -177,7 +177,7 @@ export function SetNodeScroll( x: number, y: number, ): Messages.SetNodeScroll { - return [ + return [ Messages.Type.SetNodeScroll, id, x, @@ -189,7 +189,7 @@ export function SetInputTarget( id: number, label: string, ): Messages.SetInputTarget { - return [ + return [ Messages.Type.SetInputTarget, id, label, @@ -201,7 +201,7 @@ export function SetInputValue( value: string, mask: number, ): Messages.SetInputValue { - return [ + return [ Messages.Type.SetInputValue, id, value, @@ -213,7 +213,7 @@ export function SetInputChecked( id: number, checked: boolean, ): Messages.SetInputChecked { - return [ + return [ Messages.Type.SetInputChecked, id, checked, @@ -224,7 +224,7 @@ export function MouseMove( x: number, y: number, ): Messages.MouseMove { - return [ + return [ Messages.Type.MouseMove, x, y, @@ -235,7 +235,7 @@ export function ConsoleLog( level: string, value: string, ): Messages.ConsoleLog { - return [ + return [ Messages.Type.ConsoleLog, level, value, @@ -253,7 +253,7 @@ export function PageLoadTiming( firstPaint: number, firstContentfulPaint: number, ): Messages.PageLoadTiming { - return [ + return [ Messages.Type.PageLoadTiming, requestStart, responseStart, @@ -272,7 +272,7 @@ export function PageRenderTiming( visuallyComplete: number, timeToInteractive: number, ): Messages.PageRenderTiming { - return [ + return [ Messages.Type.PageRenderTiming, speedIndex, visuallyComplete, @@ -285,7 +285,7 @@ export function JSException( message: string, payload: string, ): Messages.JSException { - return [ + return [ Messages.Type.JSException, name, message, @@ -297,7 +297,7 @@ export function RawCustomEvent( name: string, payload: string, ): Messages.RawCustomEvent { - return [ + return [ Messages.Type.RawCustomEvent, name, payload, @@ -307,7 +307,7 @@ export function RawCustomEvent( export function UserID( id: string, ): Messages.UserID { - return [ + return [ Messages.Type.UserID, id, ] @@ -316,7 +316,7 @@ export function UserID( export function UserAnonymousID( id: string, ): Messages.UserAnonymousID { - return [ + return [ Messages.Type.UserAnonymousID, id, ] @@ -326,7 +326,7 @@ export function Metadata( key: string, value: string, ): Messages.Metadata { - return [ + return [ Messages.Type.Metadata, key, value, @@ -338,7 +338,7 @@ export function CSSInsertRule( rule: string, index: number, ): Messages.CSSInsertRule { - return [ + return [ Messages.Type.CSSInsertRule, id, rule, @@ -350,7 +350,7 @@ export function CSSDeleteRule( id: number, index: number, ): Messages.CSSDeleteRule { - return [ + return [ Messages.Type.CSSDeleteRule, id, index, @@ -366,7 +366,7 @@ export function Fetch( timestamp: number, duration: number, ): Messages.Fetch { - return [ + return [ Messages.Type.Fetch, method, url, @@ -384,7 +384,7 @@ export function Profiler( args: string, result: string, ): Messages.Profiler { - return [ + return [ Messages.Type.Profiler, name, duration, @@ -397,7 +397,7 @@ export function OTable( key: string, value: string, ): Messages.OTable { - return [ + return [ Messages.Type.OTable, key, value, @@ -407,7 +407,7 @@ export function OTable( export function StateAction( type: string, ): Messages.StateAction { - return [ + return [ Messages.Type.StateAction, type, ] @@ -418,7 +418,7 @@ export function Redux( state: string, duration: number, ): Messages.Redux { - return [ + return [ Messages.Type.Redux, action, state, @@ -430,7 +430,7 @@ export function Vuex( mutation: string, state: string, ): Messages.Vuex { - return [ + return [ Messages.Type.Vuex, mutation, state, @@ -441,7 +441,7 @@ export function MobX( type: string, payload: string, ): Messages.MobX { - return [ + return [ Messages.Type.MobX, type, payload, @@ -453,7 +453,7 @@ export function NgRx( state: string, duration: number, ): Messages.NgRx { - return [ + return [ Messages.Type.NgRx, action, state, @@ -467,7 +467,7 @@ export function GraphQL( variables: string, response: string, ): Messages.GraphQL { - return [ + return [ Messages.Type.GraphQL, operationKind, operationName, @@ -482,7 +482,7 @@ export function PerformanceTrack( totalJSHeapSize: number, usedJSHeapSize: number, ): Messages.PerformanceTrack { - return [ + return [ Messages.Type.PerformanceTrack, frames, ticks, @@ -501,7 +501,7 @@ export function ResourceTiming( url: string, initiator: string, ): Messages.ResourceTiming { - return [ + return [ Messages.Type.ResourceTiming, timestamp, duration, @@ -518,7 +518,7 @@ export function ConnectionInformation( downlink: number, type: string, ): Messages.ConnectionInformation { - return [ + return [ Messages.Type.ConnectionInformation, downlink, type, @@ -528,7 +528,7 @@ export function ConnectionInformation( export function SetPageVisibility( hidden: boolean, ): Messages.SetPageVisibility { - return [ + return [ Messages.Type.SetPageVisibility, hidden, ] @@ -543,7 +543,7 @@ export function LongTask( containerId: string, containerName: string, ): Messages.LongTask { - return [ + return [ Messages.Type.LongTask, timestamp, duration, @@ -561,7 +561,7 @@ export function SetNodeAttributeURLBased( value: string, baseURL: string, ): Messages.SetNodeAttributeURLBased { - return [ + return [ Messages.Type.SetNodeAttributeURLBased, id, name, @@ -575,7 +575,7 @@ export function SetCSSDataURLBased( data: string, baseURL: string, ): Messages.SetCSSDataURLBased { - return [ + return [ Messages.Type.SetCSSDataURLBased, id, data, @@ -587,7 +587,7 @@ export function TechnicalInfo( type: string, value: string, ): Messages.TechnicalInfo { - return [ + return [ Messages.Type.TechnicalInfo, type, value, @@ -598,7 +598,7 @@ export function CustomIssue( name: string, payload: string, ): Messages.CustomIssue { - return [ + return [ Messages.Type.CustomIssue, name, payload, @@ -611,7 +611,7 @@ export function CSSInsertRuleURLBased( index: number, baseURL: string, ): Messages.CSSInsertRuleURLBased { - return [ + return [ Messages.Type.CSSInsertRuleURLBased, id, rule, @@ -626,7 +626,7 @@ export function MouseClick( label: string, selector: string, ): Messages.MouseClick { - return [ + return [ Messages.Type.MouseClick, id, hesitationTime, @@ -639,7 +639,7 @@ export function CreateIFrameDocument( frameID: number, id: number, ): Messages.CreateIFrameDocument { - return [ + return [ Messages.Type.CreateIFrameDocument, frameID, id, @@ -651,7 +651,7 @@ export function AdoptedSSReplaceURLBased( text: string, baseURL: string, ): Messages.AdoptedSSReplaceURLBased { - return [ + return [ Messages.Type.AdoptedSSReplaceURLBased, sheetID, text, @@ -665,7 +665,7 @@ export function AdoptedSSInsertRuleURLBased( index: number, baseURL: string, ): Messages.AdoptedSSInsertRuleURLBased { - return [ + return [ Messages.Type.AdoptedSSInsertRuleURLBased, sheetID, rule, @@ -678,7 +678,7 @@ export function AdoptedSSDeleteRule( sheetID: number, index: number, ): Messages.AdoptedSSDeleteRule { - return [ + return [ Messages.Type.AdoptedSSDeleteRule, sheetID, index, @@ -689,7 +689,7 @@ export function AdoptedSSAddOwner( sheetID: number, id: number, ): Messages.AdoptedSSAddOwner { - return [ + return [ Messages.Type.AdoptedSSAddOwner, sheetID, id, @@ -700,7 +700,7 @@ export function AdoptedSSRemoveOwner( sheetID: number, id: number, ): Messages.AdoptedSSRemoveOwner { - return [ + return [ Messages.Type.AdoptedSSRemoveOwner, sheetID, id, @@ -711,10 +711,24 @@ export function Zustand( mutation: string, state: string, ): Messages.Zustand { - return [ + return [ Messages.Type.Zustand, mutation, state, ] } +export function ReplaceVCSS( + id: number, + styles: string, + sheetID: string, + baseURL: string, +): Messages.ReplaceVCSS { + return [ + Messages.Type.ReplaceVCSS, + id, + styles, + sheetID, + baseURL, + ] +} diff --git a/tracker/tracker/src/main/modules/cssrules.ts b/tracker/tracker/src/main/modules/cssrules.ts index 60ae5a859..932b9453d 100644 --- a/tracker/tracker/src/main/modules/cssrules.ts +++ b/tracker/tracker/src/main/modules/cssrules.ts @@ -1,5 +1,10 @@ import type App from '../app/index.js' -import { CSSInsertRuleURLBased, CSSDeleteRule, TechnicalInfo } from '../app/messages.gen.js' +import { + CSSInsertRuleURLBased, + CSSDeleteRule, + TechnicalInfo, + ReplaceVCSS, +} from '../app/messages.gen.js' import { hasTag } from '../app/guards.js' export default function (app: App | null) { @@ -11,23 +16,46 @@ export default function (app: App | null) { return } - const processOperation = app.safe( - (stylesheet: CSSStyleSheet | CSSGroupingRule, index: number, rule?: string) => { - const sendMessage = - typeof rule === 'string' - ? (nodeID: number) => - app.send(CSSInsertRuleURLBased(nodeID, rule, index, app.getBaseHref())) - : (nodeID: number) => app.send(CSSDeleteRule(nodeID, index)) - // TODO: Extend messages to maintain nested rules (CSSGroupingRule prototype, as well as CSSKeyframesRule) - if (!stylesheet.ownerNode) { - throw new Error('Owner Node not found') + const processOperation = app.safe((stylesheet: CSSStyleSheet, index: number, rule?: string) => { + const sendMessage = + typeof rule === 'string' + ? (nodeID: number) => + app.send(CSSInsertRuleURLBased(nodeID, rule, index, app.getBaseHref())) + : (nodeID: number) => app.send(CSSDeleteRule(nodeID, index)) + // TODO: Extend messages to maintain nested rules (CSSGroupingRule prototype, as well as CSSKeyframesRule) + if (!stylesheet.ownerNode) { + throw new Error('Owner Node not found') + } + const nodeID = app.nodes.getID(stylesheet.ownerNode) + if (nodeID !== undefined) { + sendMessage(nodeID) + } // else error? + }) + + const replaceVirtualCss = app.safe((ctx: CSSGroupingRule) => { + let uppermostRuleset = ctx.parentRule + while (uppermostRuleset?.parentRule) { + uppermostRuleset = uppermostRuleset.parentRule + } + if (uppermostRuleset?.parentStyleSheet?.ownerNode) { + const entireStyle = uppermostRuleset.cssText + const parentNodeID = app.nodes.getID(uppermostRuleset.parentStyleSheet.ownerNode) + const ruleList = uppermostRuleset.parentStyleSheet.cssRules + let id = -1 + for (let i = 0; i < ruleList.length; i++) { + const rule = ruleList.item(i) + if (rule === uppermostRuleset) { + id = i + break + } } - const nodeID = app.nodes.getID(stylesheet.ownerNode) - if (nodeID !== undefined) { - sendMessage(nodeID) - } // else error? - }, - ) + if (parentNodeID && id >= 0) { + app.send(ReplaceVCSS(parentNodeID, entireStyle, id.toString(), app.getBaseHref())) + } + } else { + app.debug.error('Owner Node not found') + } + }) const patchContext = (context: typeof globalThis) => { const { insertRule, deleteRule } = context.CSSStyleSheet.prototype @@ -46,15 +74,15 @@ export default function (app: App | null) { context.CSSGroupingRule.prototype.insertRule = function (rule: string, index = 0) { const result = groupInsertRule.call(this, rule, index) as number - const entireStyle = this.parentStyleSheet?.cssRules - // const nodeID = getID(this.parentStyleSheet?.ownerNode) - // app.send(updateGroup(nodeID, entireStyle.csstext)) + replaceVirtualCss(this) return result } context.CSSGroupingRule.prototype.deleteRule = function (index = 0) { const result = groupDeleteRule.call(this, index) as number + replaceVirtualCss(this) + return result } } diff --git a/tracker/tracker/src/webworker/MessageEncoder.gen.ts b/tracker/tracker/src/webworker/MessageEncoder.gen.ts index 78151ba9f..87b505e38 100644 --- a/tracker/tracker/src/webworker/MessageEncoder.gen.ts +++ b/tracker/tracker/src/webworker/MessageEncoder.gen.ts @@ -8,233 +8,236 @@ import PrimitiveEncoder from './PrimitiveEncoder.js' export default class MessageEncoder extends PrimitiveEncoder { encode(msg: Message): boolean { switch(msg[0]) { - + case Messages.Type.BatchMetadata: - return this.uint(msg[1]) && this.uint(msg[2]) && this.uint(msg[3]) && this.int(msg[4]) && this.string(msg[5]) + return this.uint(msg[1]) && this.uint(msg[2]) && this.uint(msg[3]) && this.int(msg[4]) && this.string(msg[5]) break - + case Messages.Type.PartitionedMessage: - return this.uint(msg[1]) && this.uint(msg[2]) + return this.uint(msg[1]) && this.uint(msg[2]) break - + case Messages.Type.Timestamp: - return this.uint(msg[1]) + return this.uint(msg[1]) break - + case Messages.Type.SetPageLocation: - return this.string(msg[1]) && this.string(msg[2]) && this.uint(msg[3]) + return this.string(msg[1]) && this.string(msg[2]) && this.uint(msg[3]) break - + case Messages.Type.SetViewportSize: - return this.uint(msg[1]) && this.uint(msg[2]) + return this.uint(msg[1]) && this.uint(msg[2]) break - + case Messages.Type.SetViewportScroll: - return this.int(msg[1]) && this.int(msg[2]) + return this.int(msg[1]) && this.int(msg[2]) break - + case Messages.Type.CreateDocument: - return true + return true break - + case Messages.Type.CreateElementNode: - return this.uint(msg[1]) && this.uint(msg[2]) && this.uint(msg[3]) && this.string(msg[4]) && this.boolean(msg[5]) + return this.uint(msg[1]) && this.uint(msg[2]) && this.uint(msg[3]) && this.string(msg[4]) && this.boolean(msg[5]) break - + case Messages.Type.CreateTextNode: - return this.uint(msg[1]) && this.uint(msg[2]) && this.uint(msg[3]) + return this.uint(msg[1]) && this.uint(msg[2]) && this.uint(msg[3]) break - + case Messages.Type.MoveNode: - return this.uint(msg[1]) && this.uint(msg[2]) && this.uint(msg[3]) + return this.uint(msg[1]) && this.uint(msg[2]) && this.uint(msg[3]) break - + case Messages.Type.RemoveNode: - return this.uint(msg[1]) + return this.uint(msg[1]) break - + case Messages.Type.SetNodeAttribute: - return this.uint(msg[1]) && this.string(msg[2]) && this.string(msg[3]) + return this.uint(msg[1]) && this.string(msg[2]) && this.string(msg[3]) break - + case Messages.Type.RemoveNodeAttribute: - return this.uint(msg[1]) && this.string(msg[2]) + return this.uint(msg[1]) && this.string(msg[2]) break - + case Messages.Type.SetNodeData: - return this.uint(msg[1]) && this.string(msg[2]) + return this.uint(msg[1]) && this.string(msg[2]) break - + case Messages.Type.SetNodeScroll: - return this.uint(msg[1]) && this.int(msg[2]) && this.int(msg[3]) + return this.uint(msg[1]) && this.int(msg[2]) && this.int(msg[3]) break - + case Messages.Type.SetInputTarget: - return this.uint(msg[1]) && this.string(msg[2]) + return this.uint(msg[1]) && this.string(msg[2]) break - + case Messages.Type.SetInputValue: - return this.uint(msg[1]) && this.string(msg[2]) && this.int(msg[3]) + return this.uint(msg[1]) && this.string(msg[2]) && this.int(msg[3]) break - + case Messages.Type.SetInputChecked: - return this.uint(msg[1]) && this.boolean(msg[2]) + return this.uint(msg[1]) && this.boolean(msg[2]) break - + case Messages.Type.MouseMove: - return this.uint(msg[1]) && this.uint(msg[2]) + return this.uint(msg[1]) && this.uint(msg[2]) break - + case Messages.Type.ConsoleLog: - return this.string(msg[1]) && this.string(msg[2]) + return this.string(msg[1]) && this.string(msg[2]) break - + case Messages.Type.PageLoadTiming: - return this.uint(msg[1]) && this.uint(msg[2]) && this.uint(msg[3]) && this.uint(msg[4]) && this.uint(msg[5]) && this.uint(msg[6]) && this.uint(msg[7]) && this.uint(msg[8]) && this.uint(msg[9]) + return this.uint(msg[1]) && this.uint(msg[2]) && this.uint(msg[3]) && this.uint(msg[4]) && this.uint(msg[5]) && this.uint(msg[6]) && this.uint(msg[7]) && this.uint(msg[8]) && this.uint(msg[9]) break - + case Messages.Type.PageRenderTiming: - return this.uint(msg[1]) && this.uint(msg[2]) && this.uint(msg[3]) + return this.uint(msg[1]) && this.uint(msg[2]) && this.uint(msg[3]) break - + case Messages.Type.JSException: - return this.string(msg[1]) && this.string(msg[2]) && this.string(msg[3]) + return this.string(msg[1]) && this.string(msg[2]) && this.string(msg[3]) break - + case Messages.Type.RawCustomEvent: - return this.string(msg[1]) && this.string(msg[2]) + return this.string(msg[1]) && this.string(msg[2]) break - + case Messages.Type.UserID: - return this.string(msg[1]) + return this.string(msg[1]) break - + case Messages.Type.UserAnonymousID: - return this.string(msg[1]) + return this.string(msg[1]) break - + case Messages.Type.Metadata: - return this.string(msg[1]) && this.string(msg[2]) + return this.string(msg[1]) && this.string(msg[2]) break - + case Messages.Type.CSSInsertRule: - return this.uint(msg[1]) && this.string(msg[2]) && this.uint(msg[3]) + return this.uint(msg[1]) && this.string(msg[2]) && this.uint(msg[3]) break - + case Messages.Type.CSSDeleteRule: - return this.uint(msg[1]) && this.uint(msg[2]) + return this.uint(msg[1]) && this.uint(msg[2]) break - + case Messages.Type.Fetch: - return this.string(msg[1]) && this.string(msg[2]) && this.string(msg[3]) && this.string(msg[4]) && this.uint(msg[5]) && this.uint(msg[6]) && this.uint(msg[7]) + return this.string(msg[1]) && this.string(msg[2]) && this.string(msg[3]) && this.string(msg[4]) && this.uint(msg[5]) && this.uint(msg[6]) && this.uint(msg[7]) break - + case Messages.Type.Profiler: - return this.string(msg[1]) && this.uint(msg[2]) && this.string(msg[3]) && this.string(msg[4]) + return this.string(msg[1]) && this.uint(msg[2]) && this.string(msg[3]) && this.string(msg[4]) break - + case Messages.Type.OTable: - return this.string(msg[1]) && this.string(msg[2]) + return this.string(msg[1]) && this.string(msg[2]) break - + case Messages.Type.StateAction: - return this.string(msg[1]) + return this.string(msg[1]) break - + case Messages.Type.Redux: - return this.string(msg[1]) && this.string(msg[2]) && this.uint(msg[3]) + return this.string(msg[1]) && this.string(msg[2]) && this.uint(msg[3]) break - + case Messages.Type.Vuex: - return this.string(msg[1]) && this.string(msg[2]) + return this.string(msg[1]) && this.string(msg[2]) break - + case Messages.Type.MobX: - return this.string(msg[1]) && this.string(msg[2]) + return this.string(msg[1]) && this.string(msg[2]) break - + case Messages.Type.NgRx: - return this.string(msg[1]) && this.string(msg[2]) && this.uint(msg[3]) + return this.string(msg[1]) && this.string(msg[2]) && this.uint(msg[3]) break - + case Messages.Type.GraphQL: - return this.string(msg[1]) && this.string(msg[2]) && this.string(msg[3]) && this.string(msg[4]) + return this.string(msg[1]) && this.string(msg[2]) && this.string(msg[3]) && this.string(msg[4]) break - + case Messages.Type.PerformanceTrack: - return this.int(msg[1]) && this.int(msg[2]) && this.uint(msg[3]) && this.uint(msg[4]) + return this.int(msg[1]) && this.int(msg[2]) && this.uint(msg[3]) && this.uint(msg[4]) break - + case Messages.Type.ResourceTiming: - return this.uint(msg[1]) && this.uint(msg[2]) && this.uint(msg[3]) && this.uint(msg[4]) && this.uint(msg[5]) && this.uint(msg[6]) && this.string(msg[7]) && this.string(msg[8]) + return this.uint(msg[1]) && this.uint(msg[2]) && this.uint(msg[3]) && this.uint(msg[4]) && this.uint(msg[5]) && this.uint(msg[6]) && this.string(msg[7]) && this.string(msg[8]) break - + case Messages.Type.ConnectionInformation: - return this.uint(msg[1]) && this.string(msg[2]) + return this.uint(msg[1]) && this.string(msg[2]) break - + case Messages.Type.SetPageVisibility: - return this.boolean(msg[1]) + return this.boolean(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]) + 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 - + case Messages.Type.SetNodeAttributeURLBased: - return this.uint(msg[1]) && this.string(msg[2]) && this.string(msg[3]) && this.string(msg[4]) + return this.uint(msg[1]) && this.string(msg[2]) && this.string(msg[3]) && this.string(msg[4]) break - + case Messages.Type.SetCSSDataURLBased: - return this.uint(msg[1]) && this.string(msg[2]) && this.string(msg[3]) + return this.uint(msg[1]) && this.string(msg[2]) && this.string(msg[3]) break - + case Messages.Type.TechnicalInfo: - return this.string(msg[1]) && this.string(msg[2]) + return this.string(msg[1]) && this.string(msg[2]) break - + case Messages.Type.CustomIssue: - return this.string(msg[1]) && this.string(msg[2]) + return this.string(msg[1]) && this.string(msg[2]) break - + case Messages.Type.CSSInsertRuleURLBased: - return this.uint(msg[1]) && this.string(msg[2]) && this.uint(msg[3]) && this.string(msg[4]) + return this.uint(msg[1]) && this.string(msg[2]) && this.uint(msg[3]) && this.string(msg[4]) break - + case Messages.Type.MouseClick: - return this.uint(msg[1]) && this.uint(msg[2]) && this.string(msg[3]) && this.string(msg[4]) + return this.uint(msg[1]) && this.uint(msg[2]) && this.string(msg[3]) && this.string(msg[4]) break - + case Messages.Type.CreateIFrameDocument: - return this.uint(msg[1]) && this.uint(msg[2]) + return this.uint(msg[1]) && this.uint(msg[2]) break - + case Messages.Type.AdoptedSSReplaceURLBased: - return this.uint(msg[1]) && this.string(msg[2]) && this.string(msg[3]) + return this.uint(msg[1]) && this.string(msg[2]) && this.string(msg[3]) break - + case Messages.Type.AdoptedSSInsertRuleURLBased: - return this.uint(msg[1]) && this.string(msg[2]) && this.uint(msg[3]) && this.string(msg[4]) + return this.uint(msg[1]) && this.string(msg[2]) && this.uint(msg[3]) && this.string(msg[4]) break - + case Messages.Type.AdoptedSSDeleteRule: - return this.uint(msg[1]) && this.uint(msg[2]) + return this.uint(msg[1]) && this.uint(msg[2]) break - + case Messages.Type.AdoptedSSAddOwner: - return this.uint(msg[1]) && this.uint(msg[2]) + return this.uint(msg[1]) && this.uint(msg[2]) break - + case Messages.Type.AdoptedSSRemoveOwner: - return this.uint(msg[1]) && this.uint(msg[2]) + return this.uint(msg[1]) && this.uint(msg[2]) break - + case Messages.Type.Zustand: - return this.string(msg[1]) && this.string(msg[2]) + return this.string(msg[1]) && this.string(msg[2]) + break + + case Messages.Type.ReplaceVCSS: + return this.uint(msg[1]) && this.string(msg[2]) && this.string(msg[3]) && this.string(msg[4]) break - + } } - -} +}