}
diff --git a/frontend/app/components/shared/SessionSearch/SessionSearch.tsx b/frontend/app/components/shared/SessionSearch/SessionSearch.tsx
index 84fb770a8..1d25974cf 100644
--- a/frontend/app/components/shared/SessionSearch/SessionSearch.tsx
+++ b/frontend/app/components/shared/SessionSearch/SessionSearch.tsx
@@ -5,9 +5,9 @@ import SaveFilterButton from 'Shared/SaveFilterButton';
import { connect } from 'react-redux';
import { Button } from 'UI';
import { edit, addFilter, fetchSessions, updateFilter } from 'Duck/search';
-import SessionSearchQueryParamHandler from 'Shared/SessionSearchQueryParamHandler';
import { debounce } from 'App/utils';
+import useSessionSearchQueryHandler from 'App/hooks/useSessionSearchQueryHandler';
let debounceFetch: any = () => {}
@@ -24,6 +24,9 @@ function SessionSearch(props: Props) {
const { appliedFilter, saveRequestPayloads = false, metaLoading } = props;
const hasEvents = appliedFilter.filters.filter((i: any) => i.isEvent).size > 0;
const hasFilters = appliedFilter.filters.filter((i: any) => !i.isEvent).size > 0;
+
+ useSessionSearchQueryHandler({ appliedFilter, applyFilter: props.updateFilter });
+
useEffect(() => {
debounceFetch = debounce(() => props.fetchSessions(), 500);
}, [])
@@ -71,7 +74,6 @@ function SessionSearch(props: Props) {
return !metaLoading && (
<>
-
diff --git a/frontend/app/components/shared/SessionSearchField/SessionSearchField.tsx b/frontend/app/components/shared/SessionSearchField/SessionSearchField.tsx
index 84745c8ba..64904e358 100644
--- a/frontend/app/components/shared/SessionSearchField/SessionSearchField.tsx
+++ b/frontend/app/components/shared/SessionSearchField/SessionSearchField.tsx
@@ -15,7 +15,6 @@ interface Props {
fetchFilterSearch: (query: any) => void;
addFilterByKeyAndValue: (key: string, value: string) => void;
liveAddFilterByKeyAndValue: (key: string, value: string) => void;
- filterSearchList: any;
liveFetchFilterSearch: any;
}
function SessionSearchField(props: Props) {
diff --git a/frontend/app/components/shared/SessionSearchQueryParamHandler/SessionSearchQueryParamHandler.tsx b/frontend/app/components/shared/SessionSearchQueryParamHandler/SessionSearchQueryParamHandler.tsx
deleted file mode 100644
index e38729b2a..000000000
--- a/frontend/app/components/shared/SessionSearchQueryParamHandler/SessionSearchQueryParamHandler.tsx
+++ /dev/null
@@ -1,39 +0,0 @@
-import React, { useEffect } from 'react';
-import { useHistory } from 'react-router';
-import { connect } from 'react-redux';
-import { addFilterByKeyAndValue, addFilter } from 'Duck/search';
-import { updateFilter } from 'Duck/search';
-import { createUrlQuery, getFiltersFromQuery } from 'App/utils/search';
-
-interface Props {
- appliedFilter: any;
- updateFilter: any;
- addFilterByKeyAndValue: typeof addFilterByKeyAndValue;
- addFilter: typeof addFilter;
-}
-const SessionSearchQueryParamHandler = (props: Props) => {
- const { appliedFilter } = props;
- const history = useHistory();
-
- const applyFilterFromQuery = () => {
- const filter = getFiltersFromQuery(history.location.search, appliedFilter);
- props.updateFilter(filter, true, false);
- };
-
- const generateUrlQuery = () => {
- const search: any = createUrlQuery(appliedFilter);
- history.replace({ search });
- };
-
- useEffect(applyFilterFromQuery, []);
- useEffect(generateUrlQuery, [appliedFilter]);
-
- return <>>;
-};
-
-export default connect(
- (state: any) => ({
- appliedFilter: state.getIn(['search', 'instance']),
- }),
- { addFilterByKeyAndValue, addFilter, updateFilter }
-)(SessionSearchQueryParamHandler);
diff --git a/frontend/app/components/shared/SessionSearchQueryParamHandler/index.ts b/frontend/app/components/shared/SessionSearchQueryParamHandler/index.ts
deleted file mode 100644
index c13bb493d..000000000
--- a/frontend/app/components/shared/SessionSearchQueryParamHandler/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export { default } from './SessionSearchQueryParamHandler';
\ No newline at end of file
diff --git a/frontend/app/hooks/useSessionSearchQueryHandler.ts b/frontend/app/hooks/useSessionSearchQueryHandler.ts
new file mode 100644
index 000000000..40b1e80cb
--- /dev/null
+++ b/frontend/app/hooks/useSessionSearchQueryHandler.ts
@@ -0,0 +1,35 @@
+import { useEffect } from 'react';
+import { useHistory } from 'react-router';
+import { createUrlQuery, getFiltersFromQuery } from 'App/utils/search';
+
+interface Props {
+ appliedFilter: any;
+ applyFilter: any;
+}
+
+const useSessionSearchQueryHandler = (props: Props) => {
+ const { appliedFilter, applyFilter } = props;
+ const history = useHistory();
+
+ useEffect(() => {
+ const applyFilterFromQuery = () => {
+ const filter = getFiltersFromQuery(history.location.search, appliedFilter);
+ applyFilter(filter, true, false);
+ };
+
+ applyFilterFromQuery();
+ }, []);
+
+ useEffect(() => {
+ const generateUrlQuery = () => {
+ const search: any = createUrlQuery(appliedFilter);
+ history.replace({ search });
+ };
+
+ generateUrlQuery();
+ }, [appliedFilter]);
+
+ return null;
+};
+
+export default useSessionSearchQueryHandler;
diff --git a/frontend/app/player/web/managers/DOM/DOMManager.ts b/frontend/app/player/web/managers/DOM/DOMManager.ts
index 5ae59c5c4..8e0fb8b6b 100644
--- a/frontend/app/player/web/managers/DOM/DOMManager.ts
+++ b/frontend/app/player/web/managers/DOM/DOMManager.ts
@@ -4,7 +4,7 @@ import type Screen from '../../Screen/Screen';
import type { Message, SetNodeScroll } from '../../messages';
import { MType } from '../../messages';
import ListWalker from '../../../common/ListWalker';
-import StylesManager, { rewriteNodeStyleSheet } from './StylesManager';
+import StylesManager from './StylesManager';
import FocusManager from './FocusManager';
import SelectionManager from './SelectionManager';
import type { StyleElement } from './VirtualDOM';
@@ -289,11 +289,6 @@ export default class DOMManager extends ListWalker {
vn = this.vTexts.get(msg.id)
if (!vn) { logger.error("SetCssData: Node not found", msg); return }
vn.setData(msg.data)
- if (vn.node instanceof HTMLStyleElement) {
- doc = this.screen.document
- // TODO: move to message parsing
- doc && rewriteNodeStyleSheet(doc, vn.node)
- }
if (msg.tp === MType.SetCssData) { // Styles in priority (do we need inlines as well?)
vn.applyChanges()
}
diff --git a/frontend/app/player/web/managers/DOM/FocusManager.ts b/frontend/app/player/web/managers/DOM/FocusManager.ts
index c75f3ddc3..5a808766c 100644
--- a/frontend/app/player/web/managers/DOM/FocusManager.ts
+++ b/frontend/app/player/web/managers/DOM/FocusManager.ts
@@ -2,8 +2,7 @@ import logger from 'App/logger';
import type { SetNodeFocus } from '../../messages';
import type { VElement } from './VirtualDOM';
import ListWalker from '../../../common/ListWalker';
-
-const FOCUS_CLASS = "-openreplay-focus"
+import { FOCUS_CLASSNAME } from '../../messages/rewriter/constants'
export default class FocusManager extends ListWalker {
constructor(private readonly vElements: Map) {super()}
@@ -11,7 +10,7 @@ export default class FocusManager extends ListWalker {
move(t: number) {
const msg = this.moveGetLast(t)
if (!msg) {return}
- this.focused?.classList.remove(FOCUS_CLASS)
+ this.focused?.classList.remove(FOCUS_CLASSNAME)
if (msg.id === -1) {
this.focused = null
return
@@ -19,7 +18,7 @@ export default class FocusManager extends ListWalker {
const vn = this.vElements.get(msg.id)
if (!vn) { logger.error("Node not found", msg); return }
this.focused = vn.node
- this.focused.classList.add(FOCUS_CLASS)
+ this.focused.classList.add(FOCUS_CLASSNAME)
}
}
\ No newline at end of file
diff --git a/frontend/app/player/web/managers/DOM/StylesManager.ts b/frontend/app/player/web/managers/DOM/StylesManager.ts
index 295b95d2f..92f51aed9 100644
--- a/frontend/app/player/web/managers/DOM/StylesManager.ts
+++ b/frontend/app/player/web/managers/DOM/StylesManager.ts
@@ -1,19 +1,18 @@
import type Screen from '../../Screen/Screen';
import type { CssInsertRule, CssDeleteRule } from '../../messages';
+import { replaceCSSPseudoclasses } from '../../messages/rewriter/rewriteMessage'
type CSSRuleMessage = CssInsertRule | CssDeleteRule;
-const HOVER_CN = "-openreplay-hover";
-const HOVER_SELECTOR = `.${HOVER_CN}`;
-
-// Doesn't work with css files (hasOwnProperty)
-export function rewriteNodeStyleSheet(doc: Document, node: HTMLLinkElement | HTMLStyleElement) {
+// Doesn't work with css files (hasOwnProperty returns false)
+// TODO: recheck and remove if true
+function rewriteNodeStyleSheet(doc: Document, node: HTMLLinkElement | HTMLStyleElement) {
const ss = Object.values(doc.styleSheets).find(s => s.ownerNode === node);
if (!ss || !ss.hasOwnProperty('rules')) { return; }
for(let i = 0; i < ss.rules.length; i++){
const r = ss.rules[i]
if (r instanceof CSSStyleRule) {
- r.selectorText = r.selectorText.replace('/\:hover/g', HOVER_SELECTOR)
+ r.selectorText = replaceCSSPseudoclasses(r.selectorText)
}
}
}
@@ -29,7 +28,7 @@ export default class StylesManager {
this.linkLoadingCount = 0;
this.linkLoadPromises = [];
- //cancel all promises? tothinkaboutit
+ //cancel all promises? thinkaboutit
}
setStyleHandlers(node: HTMLLinkElement, value: string): void {
@@ -44,6 +43,7 @@ export default class StylesManager {
}
timeoutId = setTimeout(addSkipAndResolve, 4000);
+ // It would be better to make it more relyable with addEventListener
node.onload = () => {
const doc = this.screen.document;
doc && rewriteNodeStyleSheet(doc, node);
diff --git a/frontend/app/player/web/managers/MouseMoveManager.ts b/frontend/app/player/web/managers/MouseMoveManager.ts
index fa320ab13..2cb508f59 100644
--- a/frontend/app/player/web/managers/MouseMoveManager.ts
+++ b/frontend/app/player/web/managers/MouseMoveManager.ts
@@ -1,20 +1,14 @@
import type Screen from '../Screen/Screen'
import type { MouseMove } from "../messages";
-
+import { HOVER_CLASSNAME } from '../messages/rewriter/constants'
import ListWalker from '../../common/ListWalker'
-const HOVER_CLASS = "-openreplay-hover";
-const HOVER_CLASS_DEPR = "-asayer-hover";
export default class MouseMoveManager extends ListWalker {
private hoverElements: Array = []
constructor(private screen: Screen) {super()}
- // private getCursorTarget() {
- // return this.screen.getElementFromInternalPoint(this.current)
- // }
-
private getCursorTargets() {
return this.screen.getElementsFromInternalPoint(this.current)
}
@@ -25,12 +19,10 @@ export default class MouseMoveManager extends ListWalker {
const diffRemove = this.hoverElements.filter(elem => !curHoverElements.includes(elem))
this.hoverElements = curHoverElements
diffAdd.forEach(elem => {
- elem.classList.add(HOVER_CLASS)
- elem.classList.add(HOVER_CLASS_DEPR)
+ elem.classList.add(HOVER_CLASSNAME)
})
diffRemove.forEach(elem => {
- elem.classList.remove(HOVER_CLASS)
- elem.classList.remove(HOVER_CLASS_DEPR)
+ elem.classList.remove(HOVER_CLASSNAME)
})
}
diff --git a/frontend/app/player/web/messages/JSONRawMessageReader.ts b/frontend/app/player/web/messages/JSONRawMessageReader.ts
index ca193c326..c2499f4c3 100644
--- a/frontend/app/player/web/messages/JSONRawMessageReader.ts
+++ b/frontend/app/player/web/messages/JSONRawMessageReader.ts
@@ -2,7 +2,7 @@ import type { RawMessage } from './raw.gen'
import type { TrackerMessage } from './tracker.gen'
import translate from './tracker.gen'
import { TP_MAP } from './tracker-legacy.gen'
-import resolveURL from './urlBasedResolver'
+import rewriteMessage from './rewriter/rewriteMessage'
function legacyTranslate(msg: any): RawMessage | null {
@@ -30,7 +30,7 @@ export default class JSONRawMessageReader {
if (!rawMsg) {
return this.readMessage()
}
- return resolveURL(rawMsg)
+ return rewriteMessage(rawMsg)
}
}
diff --git a/frontend/app/player/web/messages/MFileReader.ts b/frontend/app/player/web/messages/MFileReader.ts
index b5fdde85c..a7411b155 100644
--- a/frontend/app/player/web/messages/MFileReader.ts
+++ b/frontend/app/player/web/messages/MFileReader.ts
@@ -2,7 +2,7 @@ import type { Message } from './message.gen';
import type { RawMessage } from './raw.gen';
import { MType } from './raw.gen';
import RawMessageReader from './RawMessageReader.gen';
-import resolveURL from './urlBasedResolver'
+import rewriteMessage from './rewriter/rewriteMessage'
import Logger from 'App/logger'
// TODO: composition instead of inheritance
@@ -77,7 +77,7 @@ export default class MFileReader extends RawMessageReader {
}
const index = this.getLastMessageID()
- const msg = Object.assign(resolveURL(rMsg), {
+ const msg = Object.assign(rewriteMessage(rMsg), {
time: this.currentTime,
_index: index,
})
diff --git a/frontend/app/player/web/messages/rewriter/constants.ts b/frontend/app/player/web/messages/rewriter/constants.ts
new file mode 100644
index 000000000..abd05897a
--- /dev/null
+++ b/frontend/app/player/web/messages/rewriter/constants.ts
@@ -0,0 +1,2 @@
+export const HOVER_CLASSNAME = "-openreplay-hover"
+export const FOCUS_CLASSNAME = "-openreplay-focus"
diff --git a/frontend/app/player/web/messages/urlBasedResolver.ts b/frontend/app/player/web/messages/rewriter/rewriteMessage.ts
similarity index 55%
rename from frontend/app/player/web/messages/urlBasedResolver.ts
rename to frontend/app/player/web/messages/rewriter/rewriteMessage.ts
index 53bf1ed81..d488c8362 100644
--- a/frontend/app/player/web/messages/urlBasedResolver.ts
+++ b/frontend/app/player/web/messages/rewriter/rewriteMessage.ts
@@ -10,24 +10,31 @@ import type {
RawAdoptedSsInsertRule,
RawAdoptedSsReplaceURLBased,
RawAdoptedSsReplace,
-} from './raw.gen'
-import { MType } from './raw.gen'
+} from '../raw.gen'
+import { MType } from '../raw.gen'
import { resolveURL, resolveCSS } from './urlResolve'
+import { HOVER_CLASSNAME, FOCUS_CLASSNAME } from './constants'
-// type PickMessage = Extract;
-// type ResolversMap = {
-// [Key in MType]: (event: PickMessage) => RawMessage
-// }
+const HOVER_SELECTOR = `.${HOVER_CLASSNAME}`
+const FOCUS_SELECTOR = `.${FOCUS_CLASSNAME}`
+export function replaceCSSPseudoclasses(cssText: string): string {
+ return cssText
+ .replace('/\:hover/g', HOVER_SELECTOR)
+ .replace('/\:focus/g', FOCUS_SELECTOR)
+}
+function rewriteCSS(baseURL: string, cssText: string): string {
+ return replaceCSSPseudoclasses(resolveCSS(baseURL, cssText))
+}
-// TODO: commonURLBased logic for feilds
-const resolvers = {
+// TODO: common logic for URL fields in all the ...URLBased messages
+const REWRITERS = {
[MType.SetNodeAttributeURLBased]: (msg: RawSetNodeAttributeURLBased): RawSetNodeAttribute =>
({
...msg,
value: msg.name === 'src' || msg.name === 'href'
? resolveURL(msg.baseURL, msg.value)
: (msg.name === 'style'
- ? resolveCSS(msg.baseURL, msg.value)
+ ? rewriteCSS(msg.baseURL, msg.value)
: msg.value
),
tp: MType.SetNodeAttribute,
@@ -35,35 +42,35 @@ const resolvers = {
[MType.SetCssDataURLBased]: (msg: RawSetCssDataURLBased): RawSetCssData =>
({
...msg,
- data: resolveCSS(msg.baseURL, msg.data),
+ data: rewriteCSS(msg.baseURL, msg.data),
tp: MType.SetCssData,
}),
[MType.CssInsertRuleURLBased]: (msg: RawCssInsertRuleURLBased): RawCssInsertRule =>
({
...msg,
- rule: resolveCSS(msg.baseURL, msg.rule),
+ rule: rewriteCSS(msg.baseURL, msg.rule),
tp: MType.CssInsertRule,
}),
[MType.AdoptedSsInsertRuleURLBased]: (msg: RawAdoptedSsInsertRuleURLBased): RawAdoptedSsInsertRule =>
({
...msg,
- rule: resolveCSS(msg.baseURL, msg.rule),
+ rule: rewriteCSS(msg.baseURL, msg.rule),
tp: MType.AdoptedSsInsertRule,
}),
[MType.AdoptedSsReplaceURLBased]: (msg: RawAdoptedSsReplaceURLBased): RawAdoptedSsReplace =>
({
...msg,
- text: resolveCSS(msg.baseURL, msg.text),
+ text: rewriteCSS(msg.baseURL, msg.text),
tp: MType.AdoptedSsReplace,
}),
} as const
-export default function resolve(msg: RawMessage): RawMessage {
- // @ts-ignore --- any idea?
- if (resolvers[msg.tp]) {
+export default function rewriteMessage(msg: RawMessage): RawMessage {
+ // @ts-ignore --- any idea for correct typing?
+ if (REWRITERS[msg.tp]) {
// @ts-ignore
- return resolvers[msg.tp](msg)
+ return REWRITERS[msg.tp](msg)
}
return msg
}
\ No newline at end of file
diff --git a/frontend/app/player/web/messages/urlResolve.ts b/frontend/app/player/web/messages/rewriter/urlResolve.ts
similarity index 100%
rename from frontend/app/player/web/messages/urlResolve.ts
rename to frontend/app/player/web/messages/rewriter/urlResolve.ts
diff --git a/mobs/ios_messages.rb b/mobs/ios_messages.rb
index 57e737714..342137877 100644
--- a/mobs/ios_messages.rb
+++ b/mobs/ios_messages.rb
@@ -35,7 +35,7 @@ message 92, 'IOSMetadata' do
string 'Value'
end
-message 93, 'IOSCustomEvent', :seq_index => true, :replayer => true do
+message 93, 'IOSCustomEvent', :replayer => true do
uint 'Timestamp'
uint 'Length'
string 'Name'
@@ -63,7 +63,7 @@ message 96, 'IOSScreenChanges', :replayer => true do
uint 'Height'
end
-message 97, 'IOSCrash', :seq_index => true do
+message 97, 'IOSCrash' do
uint 'Timestamp'
uint 'Length'
string 'Name'
@@ -71,7 +71,7 @@ message 97, 'IOSCrash', :seq_index => true do
string 'Stacktrace'
end
-message 98, 'IOSScreenEnter', :seq_index => true do
+message 98, 'IOSScreenEnter' do
uint 'Timestamp'
uint 'Length'
string 'Title'
@@ -85,7 +85,7 @@ message 99, 'IOSScreenLeave' do
string 'ViewName'
end
-message 100, 'IOSClickEvent', :seq_index => true, :replayer => true do
+message 100, 'IOSClickEvent', :replayer => true do
uint 'Timestamp'
uint 'Length'
string 'Label'
@@ -93,7 +93,7 @@ message 100, 'IOSClickEvent', :seq_index => true, :replayer => true do
uint 'Y'
end
-message 101, 'IOSInputEvent', :seq_index => true do
+message 101, 'IOSInputEvent' do
uint 'Timestamp'
uint 'Length'
string 'Value'
@@ -115,7 +115,7 @@ Name/Value may be :
"mainThreadCPU": Possible values (0 .. 100)
"memoryUsage": Used memory in bytes
=end
-message 102, 'IOSPerformanceEvent', :replayer => true, :seq_index => true do
+message 102, 'IOSPerformanceEvent', :replayer => true do
uint 'Timestamp'
uint 'Length'
string 'Name'
@@ -135,7 +135,7 @@ message 104, 'IOSInternalError' do
string 'Content'
end
-message 105, 'IOSNetworkCall', :replayer => true, :seq_index => true do
+message 105, 'IOSNetworkCall', :replayer => true do
uint 'Timestamp'
uint 'Length'
uint 'Duration'
@@ -163,7 +163,7 @@ message 110, 'IOSPerformanceAggregated', :swift => false do
uint 'MaxBattery'
end
-message 111, 'IOSIssueEvent', :seq_index => true do
+message 111, 'IOSIssueEvent' do
uint 'Timestamp'
string 'Type'
string 'ContextString'
diff --git a/mobs/run.rb b/mobs/run.rb
index 398068f95..a66e685a0 100644
--- a/mobs/run.rb
+++ b/mobs/run.rb
@@ -84,14 +84,13 @@ end
$context = :web
class Message
- attr_reader :id, :name, :tracker, :replayer, :swift, :seq_index, :attributes, :context
- def initialize(name:, id:, tracker: $context == :web, replayer: $context == :web, swift: $context == :ios, seq_index: false, &block)
+ attr_reader :id, :name, :tracker, :replayer, :swift, :attributes, :context
+ def initialize(name:, id:, tracker: $context == :web, replayer: $context == :web, swift: $context == :ios, &block)
@id = id
@name = name
@tracker = tracker
@replayer = replayer
@swift = swift
- @seq_index = seq_index
@context = $context
@attributes = []
# opts.each { |key, value| send "#{key}=", value }